Why Relying on Client-Side Payment Callbacks Fails
In standard payment flows, after the customer enters their UPI PIN, the gateway redirects their browser back to your success page. If the user closes their browser window early, loses mobile connection, or battery dies, your website never receives the confirmation callback. The customer's bank account is debited, but your database still marks the order as unpaid!
The Idempotent Server-to-Server Webhook Pattern
To guarantee 100% order reconciliation, you must implement asynchronous Server Webhooks:
- The payment gateway dispatches a cryptographically signed POST request (e.g.
payment.captured) directly to your server endpoint. - Verify the incoming
X-Razorpay-Signatureusing your secret webhook key and HMAC-SHA256 hashing. - Dispatch a background queue job to mark the order paid, deduct inventory, generate the GST invoice, and trigger customer WhatsApp confirmation.
- Enforce idempotency: Ensure that duplicate webhook retries never increment customer balances or dispatch duplicate physical shipments twice.