Payment Operation Failure
Every operation you trigger on a payment deserves a clear answer. These webhooks deliver one instantly - so you can act before a missed capture or failed refund becomes a problem you discover too late.
Primer notifies you with a failure webhook whenever a payment operation attempt does not succeed and the payment status has not changed as a result. The following event types are supported:
PAYMENT.CAPTURE.FAILED- a capture attempt did not succeedPAYMENT.REFUND.FAILED- a refund attempt did not succeedPAYMENT.CANCELLATION.FAILED- a cancellation attempt did not succeedPAYMENT.AUTHORIZATION_ADJUSTMENT.FAILED- an authorization adjustment attempt did not succeed
These events are operational signals, not status changes. Receiving a PAYMENT.CAPTURE.FAILED event, for example, means the capture attempt was unsuccessful - it does not mean the payment has failed or that the authorization has been lost.
When does a failure webhook fire? Common scenarios include:
- Amount mismatch - you attempt to capture £100, but the remaining authorised amount is only £80
- PSP-side error - the processor returns a technical error or the request times out before a response is received
Particularly useful with Primer Workflows. If you trigger captures or refunds automatically through a Workflow, failure webhooks are the signal you need to keep your own systems in sync. Because the action happened upstream, your backend won’t know it failed unless Primer tells you - these events close that gap.
A webhook is emitted for every individual failed attempt. If the same operation fails multiple times, you will receive a separate event each time.
The webhook payload is intentionally minimal. To retrieve the full context - including the error reason, timeline, and processor response - call GET /payments/{id}?expand=transactions.events after receiving the event.
What to do when you receive a failure event
The right action depends on the failure type: for amount mismatches, you may want to retry the capture with a corrected amount; for PSP errors or timeouts, a retry after a short delay is often appropriate. In all cases, make sure your internal systems reflect the outcome - update your order management, notify your operations team if needed, and avoid leaving the payment in an ambiguous state on your end.
Testing failure webhooks in sandbox
The easiest way to trigger each failure event in your sandbox environment is to force a condition that will cause the processor to reject the operation. Because the failures are real processor responses, no special flags or mock modes are needed — you just need to engineer the right conditions.
PAYMENT.CAPTURE.FAILED— Authorise a payment, then attempt to capture an amount larger than what was authorised. The processor will reject the capture and the event will fire immediately.PAYMENT.REFUND.FAILED— Capture a payment, then refund it directly through your processor’s dashboard before sending the refund request to Primer. Since the funds have already been returned at the processor level, Primer’s refund attempt will fail and the event will fire.PAYMENT.CANCELLATION.FAILED— Authorise a payment, then capture it directly through your processor’s dashboard (outside of Primer). When you then send a cancel request through Primer, the processor will reject it since the payment is no longer in a cancellable state, since the capture already happened.
In all cases, once you receive the webhook, you can retrieve the full error detail by calling GET /payments/{id}?expand=transactions.events. The transactionEvent.id in the webhook payload corresponds directly to the event entry in the response, where you will find the processor status reason and the full operation timeline.
Documentation Index
Fetch the complete documentation index at: https://primer.io/docs/llms.txt
Use this file to discover all available pages before exploring further.
Headers
An HMAC signature generated using the webhook payload and a shared signing secret. This is then converted to a base64 encoded string.
A secondary signature that is added when you have rotated your secret within the past 24 hours.
Body
The type of the webhook raised.
PAYMENT.CAPTURE.FAILED, PAYMENT.CANCELLATION.FAILED, PAYMENT.AUTHORIZATION_ADJUSTMENT.FAILED, PAYMENT.REFUND.FAILED The date-time that the webhook was sent.
The Unix timestamp at which the webhook payload was signed.
"1689221338"
The notification configuration details.
The payload version.
"2.4"
The requested amount for the operation in minor units. Present for capture, refund, and authorization adjustment events. Not applicable for cancellation events.
Response
Return a 200 status to indicate that the data was received successfully