Payment API Error Codes Reference

A quick-reference lookup for common error codes and decline reasons from major payment APIs. Covers Stripe decline codes, Adyen result codes, HTTP status mapping, retry-safe classification, and troubleshooting steps for each error type.

Stripe Decline Codes

When a PaymentIntent or Charge fails, Stripe returns an error object with a decline_code (for card declines) or an error.code (for other errors). The error.message provides a human-readable description suitable for logging, while error.type categorizes the error (card_error, api_error, idempotency_error, etc.).

CodeHTTPRetry SafeDescriptionTroubleshooting
card_declined402DependsGeneric decline. The card issuer declined the transaction. May succeed on retry if a soft decline.Ask the customer to contact their bank or try a different card.
insufficient_funds402Yes (later)The card has insufficient funds to complete the purchase.Customer should add funds and retry. Safe to retry after a delay.
expired_card402NoThe card has expired.Customer must provide a new card. Do not retry.
incorrect_cvc402NoThe CVC number provided is incorrect.Customer should re-enter the CVC. Repeated failures may indicate fraud.
incorrect_number402NoThe card number is incorrect.Customer should verify and re-enter the card number.
processing_error402YesAn error occurred while processing the card.Retry the transaction. If persistent, try a different card.
authentication_required402Yes (with 3DS)The card requires 3D Secure authentication.Re-attempt with 3DS authentication. Use stripe.handleNextAction() on the client.
rate_limit429YesToo many requests sent in a given time period.Implement exponential backoff. Stripe allows 100 read and 100 write requests per second in live mode.
api_connection_errorN/A (client)YesNetwork connectivity issue between your server and Stripe.Retry with exponential backoff. Check your network and DNS resolution.
idempotency_key_in_use409NoThe idempotency key is being used by another in-progress request.Wait for the original request to complete, or use a different idempotency key.
fraudulent402NoThe charge has been declined as Stripe Radar suspects it is fraudulent.Do not retry. Review in Stripe Dashboard. Consider adding to a block list.
lost_card402NoThe card has been reported lost.Do not retry. Do not inform the customer the card is reported lost (security).
stolen_card402NoThe card has been reported stolen.Do not retry. Do not inform the customer the card is reported stolen (security).

Adyen Result Codes

Adyen returns a resultCode in the payment response. For refusals, the refusalReason and refusalReasonCode fields provide more detail. The additionalData.refusalReasonRawfield contains the issuer's raw response code.

Result CodeCategoryRetry SafeDescriptionTroubleshooting
AuthorisedSuccessN/APayment was successfully authorized.Proceed with capture (if not auto-captured).
RefusedDeclineDependsGeneric refusal. Check refusalReason for details (e.g., DECLINED, CVC_DECLINED, BLOCK_CARD).Check additionalData.refusalReasonRaw for the issuer-specific code.
ErrorErrorYesA system error occurred during processing.Retry the transaction. Contact Adyen support if persistent.
CancelledTerminalNoThe shopper or merchant cancelled the payment before completion.Create a new payment if the shopper wants to try again.
PendingAsyncNo (wait)The payment result is not yet known. Applies to bank transfers, boletos, and other async methods.Wait for the AUTHORISATION webhook notification with the final result.
ReceivedAsyncNo (wait)The payment request was received and is being processed (common for direct debit).Wait for the final notification. Do not treat as a successful payment.
RedirectShopperActionN/AThe shopper must be redirected to complete payment (3DS, bank redirect, wallet).Redirect to the URL in the action object. Handle the return URL callback.
IdentifyShopperAction (3DS2)N/A3DS2 fingerprinting required. Collect device data for frictionless authentication.Execute the 3DS2 fingerprint action via Drop-in/Components or manually.
ChallengeShopperAction (3DS2)N/A3DS2 challenge required. The issuer needs additional shopper verification.Present the challenge UI. Submit the result via /payments/details.
PresentToShopperActionN/APresent payment details to the shopper (voucher, QR code, bank transfer instructions).Display the voucher/QR code from the action object. Wait for async confirmation.

HTTP Status Codes

Payment APIs use standard HTTP status codes, but their meaning can vary by provider. This table covers the common codes you will encounter.

StatusMeaningRetryableUsage in Payment APIs
200OKN/ASuccessful request. Check the response body for business-level status (Stripe: status field, Adyen: resultCode).
400Bad RequestNo (fix request)Malformed request parameters. Missing required fields, invalid values, or incorrect types.
401UnauthorizedNo (fix auth)Invalid or missing API key. Verify your authentication credentials.
402Payment RequiredDependsStripe-specific: the card was declined. Check the error code for retry eligibility.
403ForbiddenNoThe API key does not have permission for this operation. Check API key permissions and scopes.
404Not FoundNoThe requested resource does not exist. Verify the ID and endpoint path.
409ConflictNoIdempotency key conflict (Stripe) or concurrent modification. Wait and retry with a new key if appropriate.
422Unprocessable EntityNo (fix request)Adyen: the request was well-formed but contained invalid parameters for the payment method or configuration.
429Too Many RequestsYes (with backoff)Rate limit exceeded. Implement exponential backoff. Check Retry-After header if provided.
500Internal Server ErrorYesServer-side error at the provider. Safe to retry with exponential backoff and idempotency key.
502/503Bad Gateway / Service UnavailableYesProvider infrastructure issue. Retry with backoff. Typically transient.

Error Handling Best Practices

  • Always use idempotency keys on mutations: Include an idempotency key on every POST request so that retries do not create duplicate charges.
  • Categorize errors by retryability: Build your error handler to distinguish between retryable errors (network issues, rate limits, processing errors) and terminal errors (expired card, stolen card, invalid request). Only retry retryable errors.
  • Implement exponential backoff: Start with a 1-second delay, doubling each retry, with jitter to prevent thundering herd. Cap at a maximum delay (e.g., 60 seconds) and a maximum retry count (e.g., 5).
  • Log raw error responses: Store the full error object (code, message, decline_code, refusalReason) for debugging. Do not expose raw error details to end users -- use friendly messages instead.
  • Handle async payment methods: Bank transfers, BNPL, and voucher payments return pending/received states. Do not treat these as failures. Wait for the webhook notification with the final result.

Disclaimer: Error codes, decline reasons, and retry policies are subject to change by each provider. This reference covers common cases but is not exhaustive. Consult the official documentation for Stripe and Adyen for complete and current error code listings.