Learn how to handle duplicate webhook events and terminal payment statuses in a reliable way.
order_id
, Cashfree allows multiple payment attempts until one succeeds. Each attempt generates a unique cf_payment_id
.
cf_payment_id
but the same order_id
.
payment_status = SUCCESS
as the final confirmation of payment for an order.
FAILED
, NOT_ATTEMPTED
, or PENDING
are transitional and should not be treated as final.Webhook idempotency flowchart
cf_payment_id
in your database and ensure it is processed only once, regardless of how many webhook retries you receive.
order_id
matches the one you created.payment_status
is SUCCESS
.FAILED → PENDING → SUCCESS
.SUCCESS
webhook.
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.
cf_payment_id
for a given order_id
to support reporting, reconciliation, or dispute management.
FAILED
or PENDING
statuses.
Always wait for a SUCCESS
webhook before finalising the payment status.