Theme
Errors
All errors use a stable envelope:
json
{
"error": {
"type": "card_error",
"code": "card_declined",
"message": "Your card was declined.",
"param": null
}
}| Field | Meaning |
|---|---|
type | High-level class of error. |
code | Machine-readable digid pay code (stable — build on these, not messages). |
message | Human-readable, safe to show customers for card_error. |
param | The request field the error relates to, if any. |
Types
| Type | HTTP | Meaning |
|---|---|---|
invalid_request_error | 400 | Malformed request, bad parameter, or contract violation (incl. raw card fields). |
card_error | 402 | The card/acquirer declined; safe to show to the customer. |
authentication_error | 401 | Missing/invalid key, or a secret key used from a browser context. |
idempotency_error | 400 | Idempotency-Key reused with a different payload. |
rate_limit_error | 429 | Too many requests. |
approval_error | 400 | Approval-gate violation (agent intent not approved). |
api_error | 500 | digid pay internal error — retry with backoff. |
digid pay codes
The canonical, buildable codes (minimum set, FR-8/9/10 + approvals):
| Code | When |
|---|---|
card_declined | The issuer declined the card. |
insufficient_funds | Decline — insufficient funds. |
expired_card | Decline — card expired. |
invalid_card | Decline — card invalid. |
authentication_required | SCA needed; intent is requires_action. |
expired_token | The payment token has expired. |
invalid_token | The payment token is not valid. |
used_token | The payment token was already used. |
raw_card_rejected | A raw card-number field was sent (token-only contract). |
approval_required | An agent intent needs human approval before it can process. |
idempotency_key_reused | Idempotency-Key sent again with a different payload. |
secret_key_from_browser | Secret key used in a browser context. |
resource_missing | Resource not found (cross-tenant returns 404). |
rate_limit_exceeded | Per-key rate limit exceeded. |
invalid_parameter | A parameter failed validation (param is set). |
insufficient_permissions | Key scope does not allow this action. |
api_error_internal | Internal 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 backoffIdempotent 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.