Verify Paystack Payments in Flask
To verify a Paystack payment in Flask, make a GET request to https://api.paystack.co/transaction/verify/:reference using the requests library. Check that the status is "success", the amount matches your stored order, and the currency is correct. Use a database update with a condition to prevent double-granting.
Verification Helper
# helpers.py
import os
import requests
PAYSTACK_SECRET = os.environ.get('PAYSTACK_SECRET_KEY')
def verify_transaction(reference):
response = requests.get(
'https://api.paystack.co/transaction/verify/' + reference,
headers={'Authorization': 'Bearer ' + PAYSTACK_SECRET},
)
return response.json()
def verify_and_fulfill(reference, db):
order = db.get_order(reference)
if not order:
return {'error': 'Order not found'}
if order['paid']:
return {'success': True, 'already_fulfilled': True}
result = verify_transaction(reference)
if not result.get('status') or result['data']['status'] != 'success':
return {'error': 'Payment not successful'}
if result['data']['amount'] != order['amount_kobo']:
return {'error': 'Amount mismatch'}
if result['data']['currency'] != order['currency']:
return {'error': 'Currency mismatch'}
updated = db.mark_paid(reference)
if not updated:
return {'success': True, 'already_fulfilled': True}
return {'success': True, 'amount': order['amount_kobo'] / 100}
Verification Route
# app.py
from flask import request, jsonify
from helpers import verify_and_fulfill
@app.route('/api/verify')
def verify_payment():
reference = request.args.get('reference')
if not reference:
return jsonify({'error': 'Missing reference'}), 400
result = verify_and_fulfill(reference, db)
if result.get('error'):
return jsonify(result), 400
return jsonify(result)
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
Callback Route with Verification
@app.route('/payment/callback')
def payment_callback():
reference = request.args.get('reference') or request.args.get('trxref')
if not reference:
return 'Missing reference', 400
result = verify_and_fulfill(reference, db)
if result.get('success'):
return render_template('success.html', reference=reference)
return render_template('failed.html', error=result.get('error', 'Unknown'))
Retry Logic
import time
def verify_with_retry(reference, max_retries=3):
for attempt in range(max_retries):
try:
result = verify_transaction(reference)
if result.get('status') is not None:
return result
except requests.exceptions.RequestException:
pass
if attempt < max_retries - 1:
time.sleep(2 ** attempt)
return None
Common Mistakes
- Trusting form data for amounts. Always compare against your database.
- Mixing test and live keys. Both initialization and verification must use the same mode.
- Not checking currency. An attacker could pay in a different currency.
- Granting value before database check. Always check if the order exists and is not already fulfilled.
Key Takeaways
- ✓Verification is a single GET request to the Paystack API using the requests library.
- ✓Create a reusable verify_and_fulfill function for consistent logic across callbacks and webhooks.
- ✓Always check three things: status equals "success", amount matches your database, and currency is correct.
- ✓Use conditional database updates to prevent double-granting when webhook and callback race.
- ✓If the verify request fails, retry. The Paystack transaction state does not change.
- ✓Never trust redirect URL parameters as proof of payment.
Frequently Asked Questions
- Can I verify a transaction multiple times?
- Yes. The Paystack verify endpoint is idempotent. It returns the same result every time.
- What if my verification call fails?
- Retry with exponential backoff. The transaction state on Paystack does not change. The webhook will also deliver the event independently.
- Should I verify in the webhook handler too?
- Yes. Call the same verify_and_fulfill function from both the callback route and webhook handler. The idempotent logic ensures only one fulfills the order.
Learn Paystack Integration
KES 2,999
The definitive guide to building payment systems with Paystack — from your first transaction to production-grade payment infrastructure across Africa. 9 modules, 47 lessons. Free preview available.
Start Paystack Course