Razorpay
Adapter 0.1.0, documentation reviewed 2026-10-25. Overall status: limited.
Capabilities
| Error decoding | supported |
| API response parsing | supported |
| Webhook / notification parsing | supported |
| Timeline | limited |
| Event correlation | supported |
| Diagnostic rules | limited |
Supported input
| Format | Description | Status |
|---|---|---|
razorpay.api_error | Payments API v1 error envelope ({ error: { code, description, field, source, step, reason, metadata } }), also as wrapped by the official Node.js SDK ({ statusCode, error }) | supported |
razorpay.payment | Payment entity snapshots with status and the flat error_code, error_description, error_source, error_step and error_reason fields | supported |
razorpay.order | Order entity snapshots (created, attempted, paid) | supported |
razorpay.refund | Refund entity snapshots (pending, processed, failed) | supported |
razorpay.webhook | Webhook envelope (entity event, event, contains, payload, created_at) for payment.*, order.paid, refund.*, payment.dispute.*, settlement.processed, payout.* and downtime events; other families are shown as unknown event types | supported |
razorpay.collection | Collection responses (entity collection, items[]) of the entities above | limited |
razorpay.dispute | Dispute entity snapshots (phase, status, reason_code); reason_code values are not documented as a list | limited |
razorpay.settlement | Settlement entity snapshots; they carry no link to the payments they contain | limited |
razorpay.payout | RazorpayX payout entity snapshots and payout.* webhooks, with status_details.reason decoded from the payout table | limited |
razorpay.checkout_callback | Standard Checkout success handler and callback fields (razorpay_payment_id, razorpay_order_id, razorpay_signature); recognized, not analyzed | unsupported |
razorpay.s2s_create | Server-to-server JSON payment creation responses (razorpay_payment_id, next[] actions); recognized, not analyzed | unsupported |
Notification delivery
- Repeated deliveries are recognized by x-razorpay-event-id header; Razorpay documents that notifications can be delivered more than once.
- Delivery order: not guaranteed by the provider.
- Razorpay delivers webhooks at least once and documents duplicates as expected behavior, for example when the receiver answered after the 5-second timeout. Store the x-razorpay-event-id header of every processed event and skip repeats; the JSON body has no event id. For RazorpayX payouts, Razorpay also suggests deduplicating on payout id plus payout status. Base state changes on the entity's own state, not on arrival order.
Known limitations
- Payments API v1 JSON, payment, order, refund, dispute, settlement and payout entities, collections of them and the webhook envelope are analyzed. Standard Checkout handler fields and server-to-server creation responses are recognized but not analyzed. Route, Subscriptions, Invoices, Payment Links, QR codes, Smart Collect, Optimizer and other families were not researched; their webhooks are shown as unknown event types.
- Razorpay calls its payment reason tables "top" errors, so they are not exhaustive. Unknown reasons are decoded as unknown with insufficient confidence. The reason invalid_otp appears in Razorpay's own sample error but in no table; it is read like incorrect_otp with possible confidence.
- Several reasons have different meanings on different Razorpay pages (capture_failed, credit_not_permitted, international_transaction_not_allowed and others); the decoder states the disagreement and lowers confidence where the next step differs.
- The same reason string means different things for a payment and for a RazorpayX payout (for example insufficient_funds is the customer's balance in a payment and the merchant's balance in a payout). Payout status_details reasons are read only from the payout table. An API error body does not say which API answered it, so a reason that exists in both the payment and the RazorpayX tables is read as a payment reason unless the HTTP status or the reason itself points to RazorpayX, and the other reading is shown.
- The source value sets differ between Razorpay pages (for example bank appears in webhook samples but not in the netbanking list); undocumented source and step values are shown as supplied and flagged.
- The webhook body has no event id. The x-razorpay-event-id header is used as the delivery key only when a raw HTTP request with that header is pasted; a pasted JSON body has no delivery key, so repeated deliveries cannot be recognized from it. Whether created_at stays the same across retries is not documented.
- The X-Razorpay-Signature header and razorpay_signature fields cannot be verified from pasted data, so a pasted webhook or callback is never treated as authentic. Only the presence of the signature header is reported; its value is never copied.
- A webhook payload is a snapshot of the entity when the event occurred, so its status can lag the current state. Webhook order is not guaranteed. Several documented samples contradict the field rules (a failed card payment with captured true, refund.created already showing processed); the adapter keeps the event's own meaning and shows the snapshot status as supplied.
- Late authorisation: a failed payment can become authorized for up to 3 days, and payment.failed followed by payment.captured for the same payment is documented as expected. A failed payment is therefore not treated as final when deciding on retries.
- Only created_at is available per entity and per event; there are no per-transition timestamps. Entity snapshots have no event time; webhook created_at is used as the event time.
- Payments are linked by the pay_ id, orders by the order_ id (all attempts on one order form one group), refunds and disputes through payment_id. Settlements are not linked to payments: that link exists only in the reconciliation API, which is not analyzed. Payouts are linked only by their pout_ id. The order receipt and the payout reference_id are merchant references and are never used for linking.
- Dispute reason_code values are not documented as a list, and reason_description appears in no example; reason_code is shown as supplied. Refund statuses differ between pages (the FAQ names a Reversed status that the entity does not list).
- settlement.processed is described both as a completed transfer and as only the initiation of the transfer (the credit can take up to 3 hours); it is shown as a successful settlement step, not as confirmed credit.
- RazorpayX payouts are analyzed with limited status: processed is called terminal but can later become reversed, and reversed and failed can follow each other depending on the account type.
- Common API errors without a reason are decoded from the HTTP status and the documented description text, with possible confidence. Endpoint-specific error descriptions are not codes and are shown as the provider message only.
- Category and retry guidance per reason are PandaPayLens suggestions. Razorpay's own retry signals are its next-step advice per reason (for example retry after 30 minutes for some payout failures) and the RazorpayX 5XX rule (same X-Payout-Idempotency key and body).
Examples
- Razorpay: card payment webhooks: Authorized, captured, order paid and a partial refund in one timeline.
- Razorpay: late authorisation: A UPI payment that fails on timeout and is later authorized and captured.
Provider documentation
- Razorpay errors
- Common API errors
- Payment errors
- Card errors
- UPI errors
- Error source and step values per payment method
- Error reasons
- Understand the API
- Payment entity
- Payment life cycle
- Late authorisation
- Order entity
- Refund entity
- Refunds
- Dispute entity
- Settlement entity
- Webhooks
- All webhook events
- Webhook best practices
- Validate and test webhooks
- RazorpayX errors
- Payout status details
- Payout states and life cycle
PandaPayLens is not affiliated with Razorpay. Pasted notifications are never treated as verified: PandaPayLens does not check webhook signatures.