# From routes/airtime.py:48-75@airtime_bp.route("/validation", methods=["POST"])def airtime_validation(): data = request.get_json(force=True) transaction_id = data.get("transactionId") phone_number = data.get("phoneNumber") source_ip = data.get("sourceIpAddress") currency = data.get("currencyCode") amount = data.get("amount") # Basic validation logic (you can replace with real checks) if transaction_id and phone_number and currency and amount and source_ip: status = "Validated" else: status = "Failed" return jsonify({"status": status})
# From routes/airtime.py:78-108@airtime_bp.route("/status", methods=["POST"])def airtime_status(): data = request.get_json(force=True) phone_number = data.get("phoneNumber") description = data.get("description") status = data.get("status") request_id = data.get("requestId") discount = data.get("discount") value = data.get("value") if not phone_number or not status or not request_id and not discount and not value: return "BAD", 400 # Log or process the status here print(f"📲 Airtime status update for {phone_number}: {status} ({description})") # Respond with 200 OK and body "OK" return "OK", 200
Implement server-side validation to ensure amounts are within acceptable ranges and prevent fraud.
MIN_AMOUNT = 10MAX_AMOUNT = 1000if not (MIN_AMOUNT <= amount_value <= MAX_AMOUNT): return {"error": f"Amount must be between {MIN_AMOUNT} and {MAX_AMOUNT}"}, 400
Handle Callbacks Reliably
Always respond with 200 OK to status callbacks, even if processing fails internally. Log errors and process asynchronously if needed.
try: # Process the status update update_database(data) notify_user(data)except Exception as e: # Log error but still return 200 OK logger.error(f"Failed to process airtime status: {e}")return "OK", 200
Monitor Transaction Status
Keep track of request IDs and match them with status callbacks to ensure all transactions are accounted for.
# Store request ID when sendingtransaction = { "request_id": response["responses"][0]["requestId"], "phone": phone, "amount": amount, "status": "pending"}db.save(transaction)# Update when status callback is receiveddb.update({"request_id": request_id}, {"status": status})