Skip to main content
When integrating with Cashfree Payment Gateway, it’s crucial to implement webhook idempotency to ensure your application processes only final and unique payment events. Below are the core principles and practices to follow.

Key concepts

The following are the key concepts:
  • Multiple payment attempts per order_id: For a single order_id, Cashfree allows multiple payment attempts until one succeeds. Each attempt generates a unique cf_payment_id.
  • Unique payment_id per attempt: Every retry—whether triggered by the user or automatically—will have a distinct cf_payment_id but the same order_id.
  • Terminal status: Only consider webhook events where payment_status = SUCCESS as the final confirmation of payment for an order.
Statuses such as FAILED, NOT_ATTEMPTED, or PENDING are transitional and should not be treated as final.

Webhook idempotency flowchart

Best practices

The following are the recommended best practices:
  • De-duplicate using cf_payment_id: Track cf_payment_id in your database and process each payment only once, regardless of how many webhook retries you receive.
  • Order-level validation: Update the order status only when you receive a webhook that meets all of the following conditions:
    • The order_id matches the one you created.
    • The payment_status is SUCCESS.
    • The order has not already been marked as paid.
  • Handle retried payments: Users may retry failed payments. As a result, you may receive multiple webhook events in the sequence: FAILED → PENDING → SUCCESS.
    Implement logic to update the order status only upon receiving the SUCCESS webhook.
  • Ignore duplicate FAILED webhooks: Webhook events with a FAILED status may be sent multiple times. Do not trigger any final actions for these statuses unless you are tracking them for logging or metrics.
  • Store payment attempts: Keep a log of all cf_payment_id for a given order_id to support reporting, reconciliation, or dispute management.
  • Use HTTPS endpoints: Your webhook URL must be publicly reachable from Cashfree. Production endpoints must use HTTPS.
  • Respond immediately: Your endpoint must return a successful HTTP 200 response immediately after receiving the webhook payload.
  • Verify signatures: Verify the webhook signature using the x-webhook-signature header before processing the payload to authenticate the request. For implementation details, see Webhook signature verification.
Do not mark the order as PAID on receiving FAILED or PENDING statuses. Always wait for a SUCCESS webhook before finalising the payment status.

Webhooks as the source of truth

Cashfree webhooks provide server-to-server communication. This means your server receives the payment status even if the customer closes the browser or application before being redirected back to your site. Webhooks are the recommended source of truth for your internal systems. You can monitor webhook delivery and retry history in the Logs section. See Webhook configuration.