Skip to content

Errors

All errors use a stable envelope:

json
{
  "error": {
    "type": "card_error",
    "code": "card_declined",
    "message": "Your card was declined.",
    "param": null
  }
}
FieldMeaning
typeHigh-level class of error.
codeMachine-readable digid pay code (stable — build on these, not messages).
messageHuman-readable, safe to show customers for card_error.
paramThe request field the error relates to, if any.

Types

TypeHTTPMeaning
invalid_request_error400Malformed request, bad parameter, or contract violation (incl. raw card fields).
card_error402The card/acquirer declined; safe to show to the customer.
authentication_error401Missing/invalid key, or a secret key used from a browser context.
idempotency_error400Idempotency-Key reused with a different payload.
rate_limit_error429Too many requests.
approval_error400Approval-gate violation (agent intent not approved).
api_error500digid pay internal error — retry with backoff.

digid pay codes

The canonical, buildable codes (minimum set, FR-8/9/10 + approvals):

CodeWhen
card_declinedThe issuer declined the card.
insufficient_fundsDecline — insufficient funds.
expired_cardDecline — card expired.
invalid_cardDecline — card invalid.
authentication_requiredSCA needed; intent is requires_action.
expired_tokenThe payment token has expired.
invalid_tokenThe payment token is not valid.
used_tokenThe payment token was already used.
raw_card_rejectedA raw card-number field was sent (token-only contract).
approval_requiredAn agent intent needs human approval before it can process.
idempotency_key_reusedIdempotency-Key sent again with a different payload.
secret_key_from_browserSecret key used in a browser context.
resource_missingResource not found (cross-tenant returns 404).
rate_limit_exceededPer-key rate limit exceeded.
invalid_parameterA parameter failed validation (param is set).
insufficient_permissionsKey scope does not allow this action.
api_error_internalInternal failure — retry with backoff.

Internal-reference mapping

digid pay normalises internal engine codes into the public catalogue above so merchants never depend on internal values. Where an internal code has a public equivalent, the mapping is applied at the facade and only the public code is ever returned. If you ever see an unmapped internal code, treat it as an api_error_internal and report it — it is never a contract you should build on.

Handling by status code

text
401  → check keys / mode; never retry unauthenticated
402  → card_error: show the message, allow retry with a fresh token
429  → retry with Retry-After
400  → fix the request; read `code` + `param`
404  → resource missing or not yours
500  → retry with exponential backoff

Idempotent retries

For any transient failure (api_error, rate_limit_error, network), retry the same request with the same Idempotency-Key. That guarantees no double charge.

digid pay — built in Europe.