Skip to main content

Error Codes

When a payment fails, Odus normalizes the processor-specific error into a standardized error code. Regardless of whether the payment was routed through Stripe, Adyen, PayPal, or any other gateway, the error response uses the same set of codes. This lets you build a single error-handling path in your integration instead of mapping each processor's errors individually.

Error information is returned in the outcome object on the transaction.

The outcome object

When a transaction fails, the response includes an outcome object with the following fields:

FieldTypeVisibilityDescription
statusstringPublicOperation result: success, partial, or failure.
errorCodestringSensitiveStandardized error code from the table below.
errorMessagestringSensitiveDetailed error message. May contain sensitive information (e.g. fraud).
safeErrorMessagestringPublicCustomer-safe error message that can be displayed in your UI.
declineTypestringSensitiveEither soft_decline or hard_decline.
retryStrategystringPublicRecommended retry strategy for the client.
processorCodestringSensitiveRaw error code returned by the payment processor.
processorMessagestringSensitiveRaw error message returned by the payment processor.
specialCodestring | nullPublicSpecial status codes such as confirmation_requested for 3DS redirects. null when no special status applies.
warning

Sensitive fields are only visible when using a secret API key. Requests made with a publishable key will not include these fields. Never expose sensitive fields to the customer — use safeErrorMessage instead of errorMessage.

Decline types

Every error code is classified as either a soft or hard decline:

TypeMeaning
soft_declineThe payment may succeed if retried. The issue is potentially temporary or resolvable by the customer.
hard_declineThe payment will not succeed on retry with the same card. The card is blocked, restricted, or revoked.

Error code reference

The table below lists every standardized error code, grouped by decline type.

Hard declines

These are non-recoverable. Do not retry the same card.

CodeDescriptionRetry StrategySafe Message
fraud_suspectedThe processor flagged the transaction as potentially fraudulent.never_retryYour card was declined. Please contact your bank.
card_restrictedThe card is restricted — lost, stolen, or blocked by the issuer.never_retryYour card was declined. Please contact your bank.
generic_hard_declineAuthorization was revoked or another non-recoverable decline occurred.never_retryYour card was declined. Please contact your bank.

Soft declines — card issues

The customer can resolve these by updating their payment method.

CodeDescriptionRetry StrategySafe Message
insufficient_fundsThe card does not have enough balance to cover the transaction.retry_after_delayYour card has insufficient funds. Please check your balance and try again.
invalid_card_detailsThe card number, CVV, or other details are incorrect.retry_with_new_payment_methodYour card details are invalid. Please check and try again.
expired_cardThe card is past its expiry date.retry_with_new_payment_methodYour card has expired. Please update your payment method.
authentication_failed3DS or other cardholder authentication failed.retry_with_new_payment_methodAuthentication failed. Please try again.
transaction_not_permittedThe card or account does not allow this transaction type.retry_with_new_payment_methodThis transaction type is not permitted on your card. Please contact your bank or try a different payment method.

Soft declines — processor / issuer errors

These are transient. Retrying may succeed without any customer action.

CodeDescriptionRetry StrategySafe Message
generic_issuer_errorThe card issuer returned a generic error. Typically temporary.retry_immediatelyThere was an error processing your card. Please try again later.
generic_processor_errorThe payment processor returned a generic error.retry_immediatelyThere was an error processing your card. Please try again later.
processor_rate_limitedThe processor is rate-limiting requests.retry_immediatelyThe payment processor is currently experiencing high traffic. Please try again in a few moments.
processor_timeoutThe processor did not respond in time.retry_immediatelyThe payment processor is taking too long to respond. Please try again later.

Soft declines — other

CodeDescriptionRetry StrategySafe Message
generic_declineA general decline with no specific reason from the processor.retry_after_delayYour card was declined. Please contact your bank.
cancelledThe customer cancelled the payment (e.g. closed the 3DS window).retry_after_delayThe authentication was cancelled.
not_supportedThe payment method or currency is not supported by the processor.retry_after_delayThis payment method is not supported. Please try a different one.
internal_errorAn error occurred within Odus while processing the payment.retry_after_delaySomething went wrong. Please try again later.

Retry strategies

Each error code maps to a recommended retry strategy. Use this to decide how your integration should respond to a failure.

StrategyMeaning
never_retryDo not retry. The card is permanently blocked, restricted, or flagged for fraud. Retrying may incur network penalties.
retry_with_new_payment_methodThe current card cannot be used. Ask the customer to provide a different card or payment method.
retry_after_delayThe issue may resolve on its own (e.g. insufficient funds). Wait before retrying.
retry_immediatelyThe failure is transient (processor timeout, rate limit). Retry right away.
tip

For subscription payments, Odus uses the retry strategy automatically when scheduling retries. See the retry policy guide for details.

Example response

A failed authorization returns the outcome on the latest transaction:

Failed payment response (secret key)
{
"id": "pay_a1b2c3",
"status": "open",
"displayStatus": "failed",
"latestTransaction": {
"outcome": {
"status": "failure",
"errorCode": "insufficient_funds",
"errorMessage": "Your card has insufficient funds. Please check your balance and try again.",
"safeErrorMessage": "Your card has insufficient funds. Please check your balance and try again.",
"declineType": "soft_decline",
"retryStrategy": "retry_after_delay",
"processorCode": "card_declined",
"processorMessage": "Your card has insufficient funds.",
"specialCode": null
}
}
}
info

When using a publishable key, the response only includes status, safeErrorMessage, retryStrategy, and specialCode. Sensitive fields like errorCode, errorMessage, declineType, processorCode, and processorMessage are omitted.