Recover failed Adyen payments
Adyen exposes richer refusal reasons than most gateways, which makes decline-code-aware recovery especially effective. The trade-off is a stricter webhook contract: notifications must be acknowledged correctly or Adyen keeps redelivering them.
The Adyen events recovery depends on
- AUTHORISATION (success: false)
- A recurring authorisation was refused — open a recovery case.
- AUTHORISATION (success: true)
- The retry cleared. Close the case.
- RECURRING_CONTRACT
- A stored payment detail changed — a good moment to retry a stalled case.
Verifying Adyen webhooks
- Scheme
- HMAC-SHA256 over a pipe-delimited payload of key notification fields
- Signature location
- additionalData.hmacSignature inside the notification item
Build the signing string from the documented field order, sign it with your binary-decoded HMAC key, and always reply with the literal body [accepted].
// Adyen sends a batch of notification items
for (const { NotificationRequestItem: item } of body.notificationItems) {
if (!verifyAdyenHmac(item, process.env.ADYEN_HMAC_KEY!)) {
return new Response("Invalid signature", { status: 401 });
}
if (item.eventCode === "AUTHORISATION" && item.success === "false") {
await rrlabs.enqueueRecovery({
provider: "adyen",
externalId: item.pspReference,
declineCode: item.reason, // e.g. "Refused", "Expired Card"
});
}
}
return new Response("[accepted]");Decline playbook for Adyen
| Failure signal | Recovery action |
|---|---|
| Refused — Not enough balance | Retry after a few days; no customer action is required. |
| Expired Card | Stop retrying the stored detail and request a new one via the customer area link. |
| 3D Not Authenticated | Route the customer to a fresh authenticated payment session rather than retrying silently. |
| Referral / Acquirer Fraud | Do not retry automatically. Escalate for manual review. |
What happens after a payment fails
T+0s
Payment failed
Provider webhook received and verified
T+2s
AI analysis
Decline reason classified, amount at risk scored
T+5s
Dynamic email
Copy generated for that decline code and customer
Day 2
Smart retry
Retry scheduled only when the decline code is retryable
Day 2
WhatsApp push
Second channel used when the email went unanswered
On success
Recovered
Counted only when the provider confirms the charge
Timings describe the configured workflow, not a guaranteed outcome. Every step is skipped when the decline reason makes it counter-productive.
Frequently asked questions
- Why must Adyen webhooks return [accepted]?
- Adyen treats any other response as a delivery failure and retries the notification, which would create duplicate recovery cases if not deduplicated by pspReference.
- Which Adyen refusal reasons are worth retrying?
- Balance and temporary issuer refusals usually are. Expired cards, authentication failures and fraud referrals need customer or manual action instead.
Connect Adyen with read-only credentials
RRLabs reads failure events and orchestrates recovery. It never holds card data and never becomes the merchant of record.
Get early access