> ## Documentation Index
> Fetch the complete documentation index at: https://firespark.cloud/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Payment errors

> Fire spark payment error codes, which ones are retried, and how to show them.

Every failed intent stores an error with a **Fire spark code** and, when the provider sent one, the **provider code**. Codes are the same for every provider, so your channel handles errors once.

```json theme={null}
{
  "code": "CARD_DECLINED",
  "reason": "declined",
  "retryable": false,
  "message": "Card declined",
  "provider_code": "05",
  "provider_message": "Rechazada",
  "attempt": 1,
  "elapsed_ms": 8421
}
```

Show both codes so support can find the attempt, for example `Card declined (Transbank 05)`. `formatPaymentError(error, providerName)` from `@fire-spark/payments` builds that text.

## How retries work

* **Retryable** errors are retried automatically with the same attempt reference, up to `runtime.max_attempts`. The provider sees one payment, not several.
* If the provider doesn't answer in time, the result is **unknown**. Fire spark asks the provider for the attempt's status up to three times, then tries to void it. If it still can't tell, the intent fails with `AMBIGUOUS` and is flagged for review.
* A terminal that asks for a batch close gets one automatically, then the charge is retried once.
* QR and wallet payments are checked until `runtime.qr_ttl_ms` passes. After that they are cancelled with `WALLET_EXPIRED`.

## Codes

### Declined by the provider or the customer's bank

| Code | Meaning |
| - | - |
| `CARD_DECLINED` | Card declined |
| `INSUFFICIENT_FUNDS` | Insufficient funds |
| `EXPIRED_CARD` | Expired card |
| `INVALID_CARD` | Invalid card |
| `INVALID_PIN` | Invalid PIN |
| `LIMIT_EXCEEDED` | Limit exceeded |
| `FRAUD_SUSPECTED` | Rejected for security reasons |
| `WALLET_REJECTED` | Wallet payment rejected |
| `WALLET_EXPIRED` | Payment request expired |
| `INSUFFICIENT_BALANCE` | Insufficient balance (vouchers, wallets) |
| `TRANSFER_NOT_FOUND` | Transfer not found |
| `TRANSFER_ALREADY_USED` | Transfer already used for another payment |
| `TRANSFER_AMOUNT_MISMATCH` | Transfer amount doesn't match |
| `FINANCING_REJECTED` | Financing rejected |
| `FINANCING_EXPIRED` | Financing request expired |

None of these are retried. Ask the customer for another method.

### Customer

| Code | Meaning |
| - | - |
| `CANCELLED_BY_USER` | The customer cancelled |
| `USER_TIMEOUT` | The customer didn't answer a terminal prompt in time |

### Terminal, provider, and network

| Code | Meaning | Retried |
| - | - | - |
| `TERMINAL_UNAVAILABLE` | Terminal unavailable | Yes |
| `TERMINAL_BUSY` | Terminal busy | Yes |
| `TERMINAL_NOT_CONFIGURED` | Device settings missing or wrong | No |
| `TERMINAL_NEEDS_INIT` | Terminal needs initialization | No |
| `BATCH_CLOSE_REQUIRED` | Batch close required (handled automatically once) | No |
| `INVALID_CREDENTIALS` | The payment's credentials are wrong | No |
| `INVALID_REQUEST` | The provider rejected the request | No |
| `PROVIDER_UNAVAILABLE` | Provider unavailable | Yes |
| `NETWORK_ERROR` | Network error | Yes |
| `TIMEOUT` | The provider took too long | Yes |
| `AMBIGUOUS` | The result is unknown after checking; review the payment | No |
| `REVERSAL_NOT_ALLOWED` | The provider doesn't allow voiding or refunding this payment | No |
| `MANUAL_REVERSAL_REQUIRED` | Reverse the payment by hand in the provider's portal | No |
| `UNKNOWN` | Any other provider error | No |

Each method's page lists the provider codes it maps to these codes.

## Alerts

Payment failures and terminal failures can trigger [monitoring alerts](https://firespark.cloud/docs/guides/monitoring-alerts.md). Intents that end in `AMBIGUOUS` or `MANUAL_REVERSAL_REQUIRED` need someone to check the provider's portal.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.