# Error mapping (/docs/server-to-server/error-mapping)

## Introduction [#introduction]

This document provides a comprehensive reference for all error codes returned by the Precium S2S API. Understanding these codes enables proper error handling, appropriate customer messaging, and informed decisions about transaction retries.

## Error Response Structure [#error-response-structure]

When a transaction fails, the API returns an error object with the following structure:

```json
{
  "error": {
    "code": "insufficient_funds",
    "description": "Insufficient funds",
    "type": "Insufficient funds",
    "friendly_header": "Insufficient funds",
    "friendly_message": "The transaction failed due to insufficient funds. Fund your account and try again later."
  }
}
```

## Error Categories [#error-categories]

Precium errors are categorised by type to help you implement appropriate handling logic:

| Category | Description | Typical Action |
|---|---|---|
| **Authentication failure** | 3DS authentication did not complete successfully | Allow customer retry with same or different card |
| **Charge decline** | Transaction was declined by issuer or acquirer | Investigate cause, may retry based on specific code |
| **Configuration error** | System configuration issue | Contact Precium support immediately |
| **Fraud flag** | Transaction blocked by fraud systems | Investigate, do not retry without review |
| **Insufficient funds** | Customer lacks available balance | Notify customer, retry later |
| **Invalid request** | Request format or content is invalid | Fix request and retry |
| **Invalid token** | Card token is no longer valid | Re-tokenize customer's card |
| **Network error** | Communication failure between systems | Automatic retry appropriate |
| **Provider error** | Issue with payment provider | Contact support, retry later |
| **Validation error** | Input data failed validation | Correct input and retry |

## MIT Retry Classification [#mit-retry-classification]

For Merchant-Initiated Transactions (MIT), errors are classified as **Soft** or **Hard** declines:

| Classification | Meaning | Action |
|---|---|---|
| **Soft** | Temporary issue, may succeed on retry | Implement retry schedule |
| **Hard** | Permanent issue, will not succeed on retry | Do not retry, request new payment method |

## Error Code Quick Reference [#error-code-quick-reference]

**Priority Levels**

| Priority | Response Time | Description |
|---|---|---|
| **URGENT** | Immediate | System configuration issue requiring immediate attention |
| **HIGH** | \< 4 hours | Significant issue affecting transactions |
| **MEDIUM** | \< 24 hours | Issue requiring investigation |
| **LOW** | Standard | Normal decline or validation error |

## Complete Error Code Catalogue [#complete-error-code-catalogue]

### Authentication Failures [#authentication-failures]

**`3ds_authentication_failed`**

| Attribute | Value |
|---|---|
| **Description** | 3DS authentication failed |
| **Priority** | LOW |
| **MIT Retry** | Not applicable (CIT only) |
| **Likely Cause** | Cardholder, 3DS provider, or issuing bank |

**Possible Causes:**

- Incorrect information entered during the 3DS challenge (OTP, password, biometric)
- The issuer's authentication system was temporarily unavailable
- Fraud prevention systems flagged the transaction as suspicious

**Merchant Action:**

- Allow the customer to retry the payment and authentication process
- Provide clear instructions for completing 3DS authentication
- Suggest using another card if available
- Offer an alternative payment method

**Customer Message:***"There was a problem with the authentication process. Try again - with another card if possible. If this issue persists, contact your bank for help, or use another payment method."*

**`timeout_3ds_enrollment_check`**

| Attribute | Value |
|---|---|
| **Description** | 3DS enrollment check timeout |
| **Priority** | HIGH |
| **MIT Retry** | Not applicable |
| **Likely Cause** | 3DS provider or network issues |

**Possible Causes:**

- The enrollment check was not completed within the timeout period
- Network issues between the provider and the 3DS provider

**Merchant Action:**

- Allow the customer to retry payment and authentication
- Monitor for patterns with specific issuers (BINs) or card types
- Contact Precium support if the issue persists

**Customer Message:***"There was a problem with the authentication process. Try again - with another card if possible."*

**`timeout`**

| Attribute | Value |
|---|---|
| **Description** | Operation timeout |
| **Priority** | LOW |
| **MIT Retry** | Not applicable |
| **Likely Cause** | Customer inaction or network issues |

**Customer Message:***"There was a problem with the authentication process. Try again - with another card if possible."*

### Charge Declines [#charge-declines]

**`do_not_honour`**

| Attribute | Value |
|---|---|
| **Description** | Transaction declined by issuer without specific reason |
| **Priority** | LOW |
| **MIT Retry** | Soft |
| **Likely Cause** | Issuer or cardholder |

**Customer Message:***"The transaction was declined by your bank for an unspecified reason. Try again later - with another card if possible. If this issue persists, contact your bank."*

**`insufficient_funds`**

| Attribute | Value |
|---|---|
| **Description** | Insufficient funds in account |
| **Priority** | LOW |
| **MIT Retry** | Soft |
| **Likely Cause** | Cardholder |

**Customer Message:***"The transaction failed due to insufficient funds. Fund your account and try again later, with another card if possible."*

**`authorization_failed`**

| Attribute | Value |
|---|---|
| **Description** | Payment authorization failed |
| **Priority** | LOW |
| **MIT Retry** | Soft |
| **Likely Cause** | Provider, acquirer, issuer, or Precium |

**Customer Message:***"The transaction failed unexpectedly. Try again later - with another card if possible."*

**`exceeded_account_limit`**

| Attribute | Value |
|---|---|
| **Description** | Account transaction limit exceeded |
| **Priority** | LOW |
| **MIT Retry** | Soft |
| **Likely Cause** | Cardholder or issuer |

**Customer Message:***"The transaction was declined by your bank due to your account limit being exceeded."*

**`exceeds_frequency_limit`**

| Attribute | Value |
|---|---|
| **Description** | Transaction frequency limit exceeded |
| **Priority** | LOW |
| **MIT Retry** | Soft |
| **Likely Cause** | Cardholder or issuer |

**Customer Message:***"The transaction was declined by your bank due to your account frequency limit being exceeded."*

**`exceeds_withdrawal_limit`**

| Attribute | Value |
|---|---|
| **Description** | Withdrawal limit exceeded |
| **Priority** | LOW |
| **MIT Retry** | Soft |
| **Likely Cause** | Cardholder or issuer |

**Customer Message:***"The transaction was declined by your bank due to your account withdrawal limit being exceeded."*

**`antifraud_general`**

| Attribute | Value |
|---|---|
| **Description** | Declined due to fraud detection |
| **Priority** | MEDIUM |
| **MIT Retry** | Hard |
| **Likely Cause** | Fraud detection systems |

**Possible Causes:**

- Incomplete or inaccurate client object data
- Different identifiers used with the same card details
- Access from a restricted country
- Velocity or value thresholds exceeded
- 3DS or CVV checks bypassed

**Customer Message:***"The transaction was blocked due to suspected fraud. Try again later, with another card if possible. If this issue persists, use another payment method or contact us for help."*

**`soft_decline_contact_support`**

| Attribute | Value |
|---|---|
| **Description** | Soft decline requiring manual review |
| **Priority** | HIGH |
| **MIT Retry** | Soft |
| **Likely Cause** | Fraud systems flagged for review |

**Customer Message:***"The transaction was blocked due to suspected fraud. Try again later - with another card if possible."*

**`transaction_not_permitted_to_cardholder`**

| Attribute | Value |
|---|---|
| **Description** | Transaction type not permitted for this card |
| **Priority** | LOW |
| **MIT Retry** | Hard |
| **Likely Cause** | Cardholder or issuer card restrictions |

**Customer Message:***"The transaction failed due to the card not supporting this transaction type. Try again with another card, or contact your bank for help."*

**`transaction_not_supported_or_not_valid_for_card`**

| Attribute | Value |
|---|---|
| **Description** | Transaction type not supported by card |
| **Priority** | LOW |
| **MIT Retry** | Hard |
| **Likely Cause** | Card restrictions |

**Customer Message:***"The transaction failed due to the card not supporting this transaction type. Try again with another card."*

### Fraud Flags [#fraud-flags]

**`blacklisted_tx`**

| Attribute | Value |
|---|---|
| **Description** | Transaction blocked - general blacklist |
| **Priority** | MEDIUM |
| **MIT Retry** | Hard |
| **Likely Cause** | Fraud systems |

**Customer Message:***"The transaction was blocked due to suspected fraud. Try again later, with another card if possible."*

**`blacklisted_tx_issuing_country`**

| Attribute | Value |
|---|---|
| **Description** | Card issued in blacklisted country |
| **Priority** | MEDIUM |
| **MIT Retry** | Hard |
| **Likely Cause** | Geographic restrictions |

**Customer Message:***"The transaction was blocked due to suspected fraud. Try again with another card if possible."*

**`blacklisted_tx_risk_score`**

| Attribute | Value |
|---|---|
| **Description** | Risk score threshold exceeded |
| **Priority** | MEDIUM |
| **MIT Retry** | Hard |
| **Likely Cause** | Combined risk factors |

**Customer Message:***"The transaction was blocked due to suspected fraud. Try again with another card if possible."*

**`suspected_fraud`**

| Attribute | Value |
|---|---|
| **Description** | Suspected fraudulent transaction |
| **Priority** | MEDIUM |
| **MIT Retry** | Hard |
| **Likely Cause** | Fraud detection systems |

**Customer Message:***"The transaction was blocked due to suspected fraud. Try again later - with another card if possible."*

### Invalid Token Errors [#invalid-token-errors]

**`expired_card`**

| Attribute | Value |
|---|---|
| **Description** | Card has expired |
| **Priority** | LOW |
| **MIT Retry** | Hard |
| **Likely Cause** | Cardholder, merchant token management |

**Customer Message:***"The transaction failed due to the card having expired. Try again with another card, or contact your bank for help."*

**`lost_card`**

| Attribute | Value |
|---|---|
| **Description** | Card reported as lost |
| **Priority** | MEDIUM |
| **MIT Retry** | Hard |
| **Likely Cause** | Card reported lost by cardholder |

**Customer Message:***"The transaction failed due to the card being reported as lost. Try again with another card."*

**`stolen_card`**

| Attribute | Value |
|---|---|
| **Description** | Card reported as stolen |
| **Priority** | MEDIUM |
| **MIT Retry** | Hard |
| **Likely Cause** | Card reported stolen |

**Customer Message:***"The transaction failed due to the card being reported as stolen. Try again with another card."*

**`restricted_card`**

| Attribute | Value |
|---|---|
| **Description** | Card restricted from this transaction type |
| **Priority** | LOW |
| **MIT Retry** | Hard |
| **Likely Cause** | Card restrictions by issuer |

**Customer Message:***"The transaction failed due to the card being restricted. Try again with another card."*

**`recurring_token_expired`**

| Attribute | Value |
|---|---|
| **Description** | Stored token has expired |
| **Priority** | HIGH |
| **MIT Retry** | Hard |
| **Likely Cause** | Token lifecycle |

**Customer Message:***"The transaction failed due to the card you saved having expired. Try again with another card."*

### Configuration Errors [#configuration-errors]

**`acquirer_configuration_error`**

| Attribute | Value |
|---|---|
| **Description** | Acquirer system misconfiguration |
| **Priority** | URGENT |
| **MIT Retry** | Soft |
| **Likely Cause** | Precium, merchant, or acquirer configuration |

**Customer Message:***"There was a problem processing payment due to a technical issue. Try again later."*

**`no_matching_terminal`**

| Attribute | Value |
|---|---|
| **Description** | No terminal configured for this transaction |
| **Priority** | URGENT |
| **MIT Retry** | Not retryable |
| **Likely Cause** | Routing or configuration issue |

**Customer Message:***"There was a problem processing payment due to a technical issue. Try again later."*

### Network Errors [#network-errors]

**`acquirer_connection_error`**

| Attribute | Value |
|---|---|
| **Description** | Connection to acquirer failed |
| **Priority** | URGENT |
| **MIT Retry** | Soft |
| **Likely Cause** | Network infrastructure |

**Customer Message:***"There was a problem processing payment due to a technical issue. Try again later."*

**`issuer_not_available`**

| Attribute | Value |
|---|---|
| **Description** | Card issuer system unavailable |
| **Priority** | LOW |
| **MIT Retry** | Soft |
| **Likely Cause** | Issuer or network issues |

**Customer Message:***"There was a problem processing payment due to a technical issue. Try again later."*

**`timeout_acquirer_status_check`**

| Attribute | Value |
|---|---|
| **Description** | Timeout checking payment status |
| **Priority** | HIGH |
| **MIT Retry** | Not specified |
| **Likely Cause** | Network timeout |

**Customer Message:***"There was a problem processing payment due to a technical issue. Please try again later."*

### Provider Errors [#provider-errors]

**`acquirer_error_cs`**

| Attribute | Value |
|---|---|
| **Description** | Internal acquirer error |
| **Priority** | HIGH |
| **MIT Retry** | Soft |
| **Likely Cause** | Provider system error |

**Customer Message:***"There was a problem processing payment due to a technical issue. Try again later."*

**`acquirer_internal_error`**

| Attribute | Value |
|---|---|
| **Description** | Acquirer internal system error |
| **Priority** | HIGH |
| **MIT Retry** | Soft |
| **Likely Cause** | Acquirer system issue |

**Customer Message:***"There was a problem processing payment due to a technical issue. Try again later."*

**`acquirer_routing_error`**

| Attribute | Value |
|---|---|
| **Description** | Acquirer routing error |
| **Priority** | HIGH |
| **MIT Retry** | Soft |
| **Likely Cause** | Routing configuration |

**Customer Message:***"There was a problem processing payment due to a technical issue. Please try again later."*

### Validation Errors [#validation-errors]

**`invalid_amount`**

| Attribute | Value |
|---|---|
| **Description** | Invalid transaction amount |
| **Priority** | LOW |
| **MIT Retry** | Not applicable |
| **Likely Cause** | Merchant input |

**Customer Message:***"There was a problem processing payment due to incomplete or invalid data. Check input data and try again."*

**`invalid_card_data`** / **`invalid_card_number`** / **`invalid_expires`**

| Attribute | Value |
|---|---|
| **Description** | Invalid card data format |
| **Priority** | LOW |
| **MIT Retry** | Not applicable |

<Callout type="info">
Note: Expiry must be in **MM/YY** format.
</Callout>

**Customer Message:***"There was a problem processing payment due to incomplete or invalid data."*

**Cardholder Name / Card Number / CVC / Expiry Validation Errors**

These include: `validation_card_number_invalid`, `validation_card_number_not_provided`, `validation_card_number_too_long`, `validation_cardholder_name_invalid`, `validation_cardholder_name_not_provided`, `validation_cvc_invalid`, `validation_cvc_not_provided`, `validation_expires_invalid`, etc.

- Implement client-side Luhn check validation for card numbers
- Ensure card numbers contain only digits
- CVC should be 3 digits (4 for Amex)
- Use **MM/YY** format for expiry dates

### Invalid Request Errors [#invalid-request-errors]

**`s2s_not_supported`**

| Attribute | Value |
|---|---|
| **Description** | S2S flow not configured |
| **Priority** | MEDIUM |
| **MIT Retry** | Not applicable |

**Customer Message:***"There was a problem processing payment due to a technical issue. Use another payment method."*

**`security_violation`**

| Attribute | Value |
|---|---|
| **Description** | Security policy violation |
| **Priority** | MEDIUM |
| **MIT Retry** | Not applicable |

**Customer Message:***"The transaction was blocked due to suspected fraud. Try again later - with another card if possible."*

**`unknown_payment_method`** / **`transaction_not_permitted_on_terminal`**

| Attribute | Value |
|---|---|
| **Description** | Requested payment method not recognized or not configured |
| **Priority** | MEDIUM |
| **MIT Retry** | Not applicable |

### Pre-Authorization and Capture Errors [#pre-authorization-and-capture-errors]

**`capture_amount_exceeds_authorization`**

| Attribute | Value |
|---|---|
| **Description** | Capture amount exceeds authorized amount |
| **Priority** | LOW |
| **MIT Retry** | Not applicable |
| **Likely Cause** | Merchant input |

**`authorization_expired`**

| Attribute | Value |
|---|---|
| **Description** | Pre-authorization has expired |
| **Priority** | MEDIUM |
| **MIT Retry** | Not applicable |
| **Likely Cause** | Authorization lifecycle |

**Customer Message:***"The payment authorization has expired. Please complete a new payment."*

**`void_not_permitted`** / **`already_captured`** / **`already_voided`** / **`partial_capture_not_supported`**

These errors relate to invalid capture, void, or refund operations. Check transaction status before attempting these operations.

### Refund and Void Errors [#refund-and-void-errors]

**`refund_amount_exceeds_original`** / **`refund_void_not_permitted`** / **`transaction_not_refundable`**

Track total refunded amounts and verify transaction status before attempting refunds or voids.

### Preauthorisation Errors [#preauthorisation-errors]

Preauthorisation is the zero-amount card-verification flow (`skip_capture: true` with a purchase total of 0). Its error codes retain the legacy `zero_auth_` prefix.

**`zero_auth_not_permitted`**

| Attribute | Value |
|---|---|
| **Description** | Preauthorisation not allowed |
| **Priority** | LOW |
| **MIT Retry** | Not applicable |

Contact Precium to enable preauthorisation.

### External 3DS/MPI Errors [#external-3dsmpi-errors]

**`invalid_external_3ds_data`**

| Attribute | Value |
|---|---|
| **Description** | External 3DS authentication data invalid |
| **Priority** | LOW |
| **MIT Retry** | Not applicable |

**Required Fields:**

- `is_external_3DS`: true
- `authentication_transaction_id`
- `cavv`
- `eci_raw`
- `xid` (for 3DS1) or `ds_trans_id` (for 3DS2)

**`external_3ds_not_enabled`**

| Attribute | Value |
|---|---|
| **Description** | External 3DS not configured |
| **Priority** | MEDIUM |
| **MIT Retry** | Not applicable |

Contact Precium to enable external 3DS and ensure you're using a Non-3DS brand.

### Webhook Errors [#webhook-errors]

**`webhook_signature_invalid`** / **`webhook_timestamp_expired`** / **`webhook_endpoint_unreachable`** / **`webhook_timeout`**

Verify the signature against the correct **public key** — `public_key` on the webhook object, or `GET /public_key/` for a per-purchase `success_callback`. Verification is asymmetric RSA PKCS#1 v1.5 over the SHA-256 digest of the *raw* body, so re-serialising the JSON before verifying will fail; there is no shared secret. Also confirm the endpoint is reachable and returns within 5 seconds, processing asynchronously.

### Network Token Errors [#network-token-errors]

**`invalid_network_token`** / **`cryptogram_expired`**

Request fresh tokens and cryptograms from MDES/VTS. Submit transactions promptly after cryptogram generation.

### Other Errors [#other-errors]

**`general_transaction_error`** / **`payment_rejected_other_reason`** / **`exceeded_acquirer_refund_amount`**

Contact Precium support for investigation.

## MIT Retry Decision Tree [#mit-retry-decision-tree]

```mermaid
flowchart TD
    A[MIT Transaction Failed] --> B{Check Error Code}
    B --> C{MIT Retry Classification}
    C -->|Hard| D[Do Not Retry]
    C -->|Soft| E{Retry Count?}
    C -->|Not Specified| F[Evaluate Manually]
    D --> G[Request New Payment Method]
    E -->|< 4| H[Schedule Retry]
    E -->|>= 4| I[Exhaust Retries]
    H --> J{Retry #}
    J -->|1| K[Wait 24h]
    J -->|2| L[Wait 48h]
    J -->|3| M[Wait 72h]
    J -->|4| N[Wait 96h]
    K --> O[Retry Transaction]
    L --> O
    M --> O
    N --> O
    I --> G
    F --> P{Error Category}
    P -->|Network/Provider| H
    P -->|Validation/Config| Q[Fix and Retry Immediately]
    P -->|Fraud/Card Invalid| D
```

## Error Handling Best Practices [#error-handling-best-practices]

**1. Implement Proper Error Categorisation**

```python
HARD_DECLINE_CODES = [
    'expired_card', 'lost_card', 'stolen_card', 'restricted_card',
    'recurring_token_expired', 'antifraud_general', 'blacklisted_tx',
    'suspected_fraud', 'transaction_not_permitted_to_cardholder'
]

SOFT_DECLINE_CODES = [
    'do_not_honour', 'insufficient_funds', 'authorization_failed',
    'exceeded_account_limit', 'exceeds_frequency_limit',
    'general_transaction_error', 'acquirer_connection_error',
    'issuer_not_available'
]
```

**2. Display Customer-Friendly Messages**

<Callout type="warning">
Never expose raw error codes to customers. Use the `friendly_header` and `friendly_message` fields from the error response.
</Callout>

**3. Log Comprehensively**

For troubleshooting, log: timestamp, purchase ID, error code, full error response, and request details (excluding sensitive card data).

**4. Set Up Alerts**

Configure alerts for URGENT priority errors (immediate), HIGH priority errors (within 4 hours), error rate thresholds, and unexpected error codes.

## Support Contact [#support-contact]

For unresolved errors or investigation requests:

- **Email:** support@precium.com
- **Priority Issues:** Reference the error code and purchase ID
- **Include:** Timestamp, purchase_id, error response, and steps to reproduce
