# Error Handling and Retries — Stripe Payments

Source: https://www.skillbyai.com/en/stripe-payments/r-errors

> Card errors versus API errors.

## Know which errors to retry

The Node.js library throws typed errors. A **card error** (`StripeCardError`) means the payment was declined or details were invalid; it has a human-readable message and often a `decline_code`, and retrying the same card blindly will not help, so ask the customer for another method. **Invalid request errors** mean your parameters are wrong: fix the code. **Authentication errors** mean a bad API key. **Rate limit errors** (HTTP 429), **connection errors** and **API errors** (Stripe-side problems) are usually transient and can be retried with exponential backoff and an idempotency key. Log the request ID (`err.requestId`) for support.

## Branching on error type

Server-side Node.js.

```javascript
try {
  await stripe.paymentIntents.create(params, { idempotencyKey });
} catch (err) {
  switch (err.type) {
    case 'StripeCardError':
      return { userMessage: err.message, declineCode: err.decline_code };
    case 'StripeRateLimitError':
    case 'StripeConnectionError':
    case 'StripeAPIError':
      return retryWithBackoff(() => stripe.paymentIntents.create(params, { idempotencyKey }));
    case 'StripeInvalidRequestError':
    case 'StripeAuthenticationError':
    default:
      logger.error({ requestId: err.requestId, type: err.type, msg: err.message });
      throw err;   // a bug or misconfiguration: alert, do not retry
  }
}

```

## Do not show raw decline codes to customers

Some decline codes, such as those suggesting fraud, should not be revealed. Show a general message and log the details for your team.

**Quiz:** Which error should NOT be retried automatically with the same card?

- [ ] A connection error
- [x] A card error such as a decline
- [ ] A rate limit error
- [ ] A temporary API error

*Answer:* A card error such as a decline. Declines need a different payment method or customer action.
