# Administración de errores

Maneja las solicitudes fallidas, los eventos de webhook y los errores almacenados con un SDK de Stripe.

Usa un SDK de Stripe para detectar solicitudes de API fallidas, manejar notificaciones de webhook e inspeccionar errores almacenados. Los detalles de los errores te ayudan a decidir si debes corregir una solicitud, pedirle a tu cliente que actúe o investigar un resultado incierto. Selecciona el lenguaje de tu SDK para ver sus ejemplos y tipos de errores.

Elige tu próxima acción según lo que sepas sobre el resultado de la solicitud.

| Situación | Próxima acción |
| --- | --- |
| Los parámetros no son válidos o la autenticación falla | Corrige la [solicitud o clave de API](https://docs.stripe.com/error-handling.md#error-types) antes de volver a intentarlo. |
| Se rechaza un pago o requiere la acción del cliente | Maneja el [error de pago](https://docs.stripe.com/error-handling.md#payment-errors) y pídele al cliente que complete la acción requerida. |
| Una conexión falla o una solicitud sigue ejecutándose | [Vuelve a intentarlo de forma segura](https://docs.stripe.com/error-low-level.md#network-errors) con la misma clave de idempotencia y parámetros. |
| Un error del servidor u otra falla deja el resultado incierto | [Concilia la solicitud](https://docs.stripe.com/error-low-level.md#server-errors) antes de comenzar otra operación. |

## Before you begin

Antes de ejecutar los ejemplos, realiza lo siguiente:

- Instala un [SDK de Stripe](https://docs.stripe.com/sdks.md) admitido y su entorno de ejecución requerido. Para Python, usa Python&nbsp;3.9 o posterior. En estos ejemplos, se usan los servicios `v1` del SDK siempre que estén disponibles.
- Usa un entorno de prueba con [métodos de pago de prueba](https://docs.stripe.com/testing.md).
- Crea una [clave de API restringida](https://docs.stripe.com/keys/restricted-api-keys.md) solo con los permisos que se necesitan para los ejemplos que ejecutas. Consulta la [referencia de permisos](https://docs.stripe.com/keys/permissions-reference.md):
  - `payment_intent_write` para crear objetos `PaymentIntent`.
  - `payment_intent_read` para recuperar objetos `PaymentIntent`.
  - `charge_read` para recuperar objetos `Charge`.
- Carga tu clave [desde una variable de entorno segura o un administrador de secretos](https://docs.stripe.com/keys-best-practices.md). Para los ejemplos que leen `STRIPE_SECRET_KEY`, establece esa variable en tu clave restringida.
- Para los ejemplos de webhook, configura un [punto de conexión de webhook](https://docs.stripe.com/webhooks/quickstart.md), instala el entorno web del ejemplo y establece `STRIPE_WEBHOOK_SECRET` en el secreto de firma de ese punto de conexión. Cuando envíes eventos con la CLI de Stripe, usa el secreto de firma de `stripe listen`.

## Lee los detalles de los errores

Si una solicitud de API falla, usa la respuesta de error para identificar el problema. Guarda la ID de la solicitud para que puedas encontrar la solicitud en tus registros o compartirla con el soporte de Stripe. Según el error, la respuesta puede incluir los siguientes detalles:

| Propiedad | Descripción |
| --- | --- |
| `code` | El código de error. |
| `doc_url` | Un enlace a la documentación de Stripe para el código de error específico. |
| `message` | Una descripción del problema. |
| `param` | El parámetro de la solicitud asociado al error, si corresponde. |
| `request_log_url` | Un enlace al registro de solicitudes en el Dashboard de Stripe. |
| ID de la solicitud | Un identificador único de la solicitud, que comienza con `req_`. Los encabezados de respuesta contienen este valor. En los ejemplos, se muestra cómo leerlo desde una excepción o un valor de error del SDK. |
| `type` | La categoría del error. |

Usa estas técnicas para manejar los errores identificados a través de diferentes canales. Usa el [tipo de error](https://docs.stripe.com/error-handling.md#error-types) para elegir una respuesta.

| Técnica | Dónde se debe usar |
| --- | --- |
| [Maneja los errores de las solicitudes de API](https://docs.stripe.com/error-handling.md#catch-exceptions) | Excepciones o valores de error devueltos por solicitudes de API individuales. |
| [Supervisar webhooks](https://docs.stripe.com/error-handling.md#monitor-webhooks) | Fallas informadas a través de eventos, incluidas las fallas que ocurren después de que se completa una solicitud de API. |
| [Inspecciona los errores almacenados](https://docs.stripe.com/error-handling.md#use-stored-information) | Errores o información relacionada con errores almacenada en objetos. |

## Maneja los errores de las solicitudes de API

Los SDK de Stripe exponen las solicitudes de API fallidas como excepciones o valores de error. Manéjalos en tu aplicación y usa sus detalles para elegir una respuesta.

Para obtener información sobre los códigos de estado HTTP, la idempotencia y los reintentos, consulta [Manejo avanzado de errores](https://docs.stripe.com/error-low-level.md) y la [referencia de errores de la API](https://docs.stripe.com/api/errors.md).

# Python


Usa las cláusulas `try` y `except` de Python para detectar `stripe.StripeError` o sus subclases. Cada subclase representa un tipo diferente de error. Usa la [clase de excepción](https://docs.stripe.com/error-handling.md#error-types) para elegir una respuesta.


#### Python

```python
import stripe, logging
logging.basicConfig(level=logging.INFO)
# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
client = stripe.StripeClient('<<YOUR_SECRET_KEY>>')

def example_function(**kwargs):
  try:
    client.v1.payment_intents.create(params=kwargs)
  except stripe.CardError as e:
    logging.error("A payment error occurred: {}. (request id: {})".format(e.user_message, e.request_id))
  except stripe.InvalidRequestError as e:
    logging.error("An invalid request occurred. (request id: {})".format(e.request_id))
  # Add additional except cases for other Stripe exception types as needed.
  # See all exception types at https://docs.stripe.com/api/errors/handling?lang=python
  except stripe.StripeError as e:
    # All other Stripe errors
    logging.error("Status: {}, Code: {}, Message: {}, Request ID: {}".format(e.http_status, e.code, e.user_message, e.request_id))
  except Exception as e:
    logging.error("Another problem occurred, maybe unrelated to Stripe.")
  else:
    logging.info("No error.")
```

### Prueba los errores de las solicitudes de API

Ejecuta los siguientes escenarios en un entorno de prueba para probar tu controlador de errores. En los ejemplos, se seleccionan explícitamente los pagos con tarjeta para que los métodos de pago automáticos predeterminados no requieran un valor de `return_url` antes del resultado previsto. El formato de los registros y las ID de las solicitudes varían según el SDK.

#### Error de activación - Solicitud no válida

#### Python

```python
example_function(
  # The required parameter currency is missing
  amount=2000,
  confirm=True,
  payment_method_types=['card'],
  payment_method='pm_card_visa', # Esta es una tarjeta de prueba que siempre funciona correctamente cuando la usas en entornos de prueba. Usa esta y otras tarjetas de prueba para ver cómo funciona la gestión de errores en tu integración. En el código de producción, en este paso usarías un método de pago real.
)
```

```
An invalid request occurred.
```

#### Error de activación - Error de tarjeta

#### Python

```python
example_function(
  currency="usd",
  amount=2000,
  confirm=True,
  payment_method_types=['card'],
  payment_method='pm_card_chargeDeclinedFraudulent', # Esta es una tarjeta de prueba que siempre produce un error de pago por cargo fraudulento. Usa esta y otras tarjetas de prueba para ver cómo funciona la gestión de errores en tu integración. En el código de producción, en este paso usarías un método de pago real.
)
```

```
A payment error occurred: Your card was declined.
```

#### Error de activación - No hay error

#### Python

```python
example_function(
  currency="usd",
  amount=2000,
  confirm=True,
  payment_method_types=['card'],
  payment_method="pm_card_visa", # Esta es una tarjeta de prueba que siempre funciona correctamente cuando la usas en entornos de prueba. Usa esta y otras tarjetas de prueba para ver cómo funciona la gestión de errores en tu integración. En el código de producción, en este paso usarías un método de pago real.
)
```

```
No error.
```

## Supervisa webhooks

Usa *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) para conocer las fallas informadas a través de eventos. Estas pueden incluir fallas que no se devuelven en una respuesta de API, como las siguientes:

- Se pierde una disputa.
- Un pago recurrente falla.
- Tu front-end *confirma* (Confirming a PaymentIntent indicates that the customer intends to pay with the current or provided payment method. Upon confirmation, the PaymentIntent attempts to initiate a payment) un pago y, luego, se desconecta antes de recibir el resultado, pero tu servidor aún puede recibir el evento de falla.

En tu controlador de webhooks, [verifica la firma](https://docs.stripe.com/webhooks.md#verify-events) con el cuerpo de la solicitud sin procesar, el encabezado `Stripe-Signature` y el secreto de firma de tu punto de conexión antes de procesar el evento. Rechaza las cargas o las firmas no válidas con una respuesta `400`. Si usas Express, como en el ejemplo de Node.js, registra esta ruta antes de cualquier middleware que analice JSON, ya que la verificación requiere el cuerpo de la solicitud sin modificar.

Si restringes el tráfico entrante por dirección IP, permite las [direcciones IP de webhooks públicos](https://docs.stripe.com/ips.md) de Stripe.

En los siguientes ejemplos, se gestionan eventos con instantáneas, que incluyen el objeto afectado en `data.object`. En el caso de los eventos breves, sigue la [guía de procesamiento de eventos breves](https://docs.stripe.com/events/how-events-work.md#thin-events) para recuperar los detalles que necesites.

Después de verificar un evento con instantánea en el que se informa una falla, inspecciona el objeto afectado:

1. Ve a [event[‘data’][‘object’]](https://docs.stripe.com/api/events/object.md#event_object-data-object) para recuperar el objeto afectado.
2. Inspecciona el [error almacenado](https://docs.stripe.com/error-handling.md#use-stored-information), si el objeto contiene uno.
3. Usa el [tipo de error](https://docs.stripe.com/error-handling.md#error-types) para elegir una respuesta.

#### Python

```python
#! /usr/bin/env python3

import os
import stripe
import logging
endpoint_secret = os.environ['STRIPE_WEBHOOK_SECRET']

from flask import Flask, jsonify, request

app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def webhook():
    payload = request.get_data()

    # Get the event object
    try:
        event = stripe.Webhook.construct_event(
            payload, request.headers.get('Stripe-Signature', ''), endpoint_secret
        )
    except (ValueError, stripe.SignatureVerificationError):
        return jsonify(success=False), 400

    # Use the event type to find out what happened
    if event and event['type'] == 'payment_intent.payment_failed':

        # Get the object affected
        payment_intent = event['data']['object']

        # Use stored information to get an error object
        e = payment_intent['last_payment_error']
        if not e:
            return jsonify(success=True)

        # Use its type to choose a response
        if e['type'] == 'card_error':
          logging.error("A payment error occurred: {}".format(e['message']))
        elif e['type'] == 'invalid_request_error':
          logging.error("An invalid request occurred.")
        else:
          logging.error("Another problem occurred, maybe unrelated to Stripe")
    return jsonify(success=True)
```

### Prueba el manejo de webhooks

Configura las [pruebas locales de webhooks](https://docs.stripe.com/webhooks.md#test-webhook) y, luego, desencadena un pago fallido para probar tu controlador:

```bash
stripe trigger payment_intent.payment_failed
```

```bash
A payment error occurred: Your card was declined.
```

## Inspecciona los errores almacenados

Algunos objetos de Stripe almacenan detalles sobre una falla. Recupera el objeto e inspecciona sus propiedades de error para investigar el problema o agregar contexto a un evento. Por ejemplo, un `PaymentIntent` almacena el error de su intento de confirmación anterior en [last_payment_error](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-last_payment_error).

Un valor vacío no demuestra que el pago nunca falló, ya que Stripe borra `last_payment_error` cuando actualizas el `PaymentIntent`. Esta propiedad no es un registro histórico de errores.

1. Recupera el `PaymentIntent`.
2. Comprueba si `last_payment_error` contiene un error.
3. Si está presente, registra su tipo y la ID del `PaymentIntent`.

#### Python

```python
import stripe
import logging
# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
client = stripe.StripeClient('<<YOUR_SECRET_KEY>>')

payment_intent = client.v1.payment_intents.retrieve('{{PAYMENT_INTENT_ID}}')

e = payment_intent.last_payment_error
if e:
  logging.info("PaymentIntent {} experienced a {} error.".format(
    payment_intent.id,
    e.type,
  ))
```

Estos son algunos objetos comunes que almacenan información sobre errores.

| Objeto | Atributo | Valores |
| --- | --- | --- |
| [PaymentIntent](https://docs.stripe.com/api/payment_intents.md) | `last_payment_error` | [Un objeto de error](https://docs.stripe.com/error-handling.md#parse-error-data) |
| [SetupIntent](https://docs.stripe.com/api/setup_intents.md) | `last_setup_error` | [Un objeto de error](https://docs.stripe.com/error-handling.md#parse-error-data) |
| [Factura](https://docs.stripe.com/api/invoices.md) | `last_finalization_error` | [Un objeto de error](https://docs.stripe.com/error-handling.md#parse-error-data) |
| [SetupAttempt](https://docs.stripe.com/api/setup_attempts.md) | `setup_error` | [Un objeto de error](https://docs.stripe.com/error-handling.md#parse-error-data) |
| [Payout](https://docs.stripe.com/api/payouts.md) | `failure_code` | [Un código de error de pago](https://docs.stripe.com/api/payouts/failures.md) |
| [Refund](https://docs.stripe.com/api/refunds.md) | `failure_reason` | [Un código de error de reembolso](https://docs.stripe.com/api/refunds/object.md#refund_object-failure_reason) |

### Prueba los errores almacenados

Simula una falla en un entorno de prueba y, luego, recupera el objeto afectado para comprobar sus propiedades de error:

- [Pago rechazado](https://docs.stripe.com/testing.md#declined-payments).
- [Transferencia fallida](https://docs.stripe.com/connect/testing.md#account-numbers).
- [Reembolso fallido](https://docs.stripe.com/testing.md#refunds).

## Elige una respuesta por tipo de error

Usa el tipo de error para elegir una respuesta. Los nombres de las excepciones del SDK y los tipos de errores de la API sin procesar pueden diferir. Los errores almacenados, como `last_payment_error`, usan valores de tipo de API, como `card_error` y `invalid_request_error`. Compara estos valores con los tipos de API, no con los nombres de las excepciones del SDK.

En la biblioteca Python de Stripe, los objetos Error pertenecen a `stripe.StripeError` y sus subclases. Usa la documentación de cada clase para obtener consejos sobre cómo responder.

| Nombre | Excepción del SDK | Descripción |
| --- | --- | --- |
| Error de pago | [stripe.CardError](https://docs.stripe.com/error-handling.md#payment-errors) | Se produjo un error durante un pago, debido a alguno de estos motivos:
- [Pagos bloqueados](https://docs.stripe.com/error-handling.md#payment-blocked)
- [Pagos rechazados por el emisor](https://docs.stripe.com/error-handling.md#payment-declined).
- [Otros errores de pago](https://docs.stripe.com/error-handling.md#other-payment-errors). |
| Errores de solicitud no válida | [stripe.InvalidRequestError](https://docs.stripe.com/error-handling.md#invalid-request-errors) | Hiciste una llamada API con parámetros erróneos, en el estado equivocado o de forma no válida. |
| Error de conexión | [stripe.APIConnectionError](https://docs.stripe.com/error-handling.md#connection-errors) | Hubo un problema de red entre tu servidor y Stripe. |
| Error de API | [stripe.APIError](https://docs.stripe.com/error-handling.md#api-errors) | Se produjo un error del lado de Stripe. (Esto no suele ocurrir). |
| Error de autenticación | [stripe.AuthenticationError](https://docs.stripe.com/error-handling.md#authentication-errors) | Stripe no puede autenticarte con la información proporcionada. |
| Error de idempotencia | [stripe.IdempotencyError](https://docs.stripe.com/error-handling.md#idempotency-errors) | Utilizaste una [clave de idempotencia](https://docs.stripe.com/api/idempotent_requests.md) para algo inesperado, como repetir una solicitud con parámetros distintos. |
| Error de permiso | [stripe.PermissionError](https://docs.stripe.com/error-handling.md#permission-errors) | La clave API usada para esta solicitud no tiene los permisos necesarios. |
| Error de límite de velocidad | [stripe.RateLimitError](https://docs.stripe.com/error-handling.md#rate-limit-errors) | Hiciste demasiadas llamadas API en muy poco tiempo. |
| Error de verificación de firma | [stripe.SignatureVerificationError](https://docs.stripe.com/error-handling.md#signature-verification-errors) | Estás usando la [verificación de firma](https://docs.stripe.com/webhooks.md#verify-events) del *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) y no se pudo verificar que un evento de webhook sea auténtico. |

## Errores de pago

Los errores de pago pueden ocurrir con cualquier método de pago, incluso cuando el SDK los llama errores de tarjeta. Se dividen en tres categorías:

- [Pagos bloqueados](https://docs.stripe.com/error-handling.md#payment-blocked)
- [Pagos rechazados por el emisor](https://docs.stripe.com/error-handling.md#payment-declined)
- [Otros errores de pago](https://docs.stripe.com/error-handling.md#other-payment-errors)

Para elegir una respuesta, verifica el [código de error](https://docs.stripe.com/error-codes.md), el [código de pago rechazado](https://docs.stripe.com/declines/codes.md) y el [resultado del cargo](https://docs.stripe.com/api/charges/object.md#charge_object-outcome). Para identificar el cargo correcto, revisa si el error contiene un [PaymentIntent](https://docs.stripe.com/api/errors.md#errors-payment_intent) con un [último Cargo](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-latest_charge) y, luego, recupera ese `Charge`.

Si no encuentras el cargo o la búsqueda falla, usa el código de error de pago original. La ausencia de un cargo o una búsqueda fallida no significa necesariamente que Radar haya bloqueado el pago.

Utiliza una [clave de API restringida](https://docs.stripe.com/keys/restricted-api-keys.md) con `payment_intent_write` para crear objetos `PaymentIntent` y `charge_read` para recuperar objetos `Charge`. Consulta la [referencia de permisos](https://docs.stripe.com/keys/permissions-reference.md). Carga la clave desde la variable de entorno `STRIPE_SECRET_KEY` siguiendo la [guía de gestión de claves](https://docs.stripe.com/keys-best-practices.md).

Estos ejemplos utilizan `latest_charge`, que está disponible en la versión de la API&nbsp;2022-11-15 y en versiones posteriores. Si tu integración utiliza una versión de la API anterior, [actualízala](https://docs.stripe.com/upgrades.md) antes de usar estos ejemplos con un SDK actual.

#### Python

```python
import stripe, logging, os
client = stripe.StripeClient(os.environ['STRIPE_SECRET_KEY'])

def example_function(**kwargs):
  try:
    client.v1.payment_intents.create(params=kwargs)
  except stripe.CardError as e:
    charge = None
    payment_intent = getattr(e.error, 'payment_intent', None)
    charge_id = getattr(payment_intent, 'latest_charge', None)
    if charge_id:
      try:
        charge = client.v1.charges.retrieve(charge_id)
      except stripe.StripeError:
        logging.warning('Could not retrieve the charge; using the original payment error.')
    outcome = getattr(charge, 'outcome', None)
    if getattr(outcome, 'type', None) == 'blocked':
      logging.error("Payment blocked for suspected fraud.")
    elif e.code == 'card_declined':
      logging.error("Payment declined.")
    elif e.code == 'expired_card':
      logging.error("Card expired.")
    else:
      logging.error("Other card error.")
```

### Prueba de errores de pago

Utiliza tarjetas de prueba en un entorno de prueba para generar los tipos de errores que maneja tu integración:

- [Pagos bloqueados](https://docs.stripe.com/testing.md#fraud-prevention)
- [Rechazos y otros errores](https://docs.stripe.com/testing.md#declined-payments)

Ejecuta los siguientes escenarios con el controlador de errores para verificar su respuesta.

#### Error de activación - Bloqueado por presunto fraude

#### Python

```python
example_function(
  currency='usd',
  amount=2000,
  confirm=True,
  payment_method_types=['card'],
  payment_method='pm_card_radarBlock', # Esta es una tarjeta de prueba que siempre se bloquea por supuesto fraude cuando la usas en un entorno de prueba. Usa esta y otras tarjetas de prueba para ver cómo funciona la gestión de errores en tu integración. En el código de producción, en este paso usarías un método de pago real.
)
```

```
Payment blocked for suspected fraud.
```

#### Error de activación - Rechazado por el emisor

#### Python

```python
example_function(
  currency='usd',
  amount=2000,
  confirm=True,
  payment_method_types=['card'],
  payment_method='pm_card_visa_chargeDeclined', # Esta es una tarjeta de prueba que siempre rechaza el emisor cuando la usas en un entorno de prueba. Usa esta y otras tarjetas de prueba para ver cómo funciona la gestión de errores en tu integración. En el código de producción, en este paso usarías un método de pago real.
)
```

```
Payment declined.
```

#### Error de activación - Tarjeta vencida

#### Python

```python
example_function(
  currency='usd',
  amount=2000,
  confirm=True,
  payment_method_types=['card'],
  payment_method='pm_card_chargeDeclinedExpiredCard', # Esta es una tarjeta de prueba que siempre falla por vencimiento cuando la usas en un entorno de prueba. Usa esta y otras tarjetas de prueba para ver cómo funciona la gestión de errores en tu integración. En el código de producción, en este paso usarías un método de pago real.
)
```

```
Card expired.
```

#### Error de activación - Otro error de tarjeta

#### Python

```python
example_function(
  currency='usd',
  amount=2000,
  confirm=True,
  payment_method_types=['card'],
  payment_method='pm_card_chargeDeclinedProcessingError', # Esta es una tarjeta de prueba que siempre falla debido a un error de procesamiento cuando la usas en un entorno de prueba. Usa esta y otras tarjetas de prueba para ver cómo funciona la gestión de errores en tu integración. En el código de producción, en este paso usarías un método de pago real.
)
```

```
Other card error.
```

### Pago bloqueado por presunto fraude

|  |
| **Tipo** | `stripe.CardError` |
| **Resultado del cargo** | Recupera el cargo como se muestra en el ejemplo de [Errores de pago](https://docs.stripe.com/error-handling.md#payment-errors), que comprueba si hay un cargo disponible y maneja los errores de búsqueda. Después de una búsqueda exitosa, comprueba su resultado:

`getattr(getattr(charge, 'outcome', None), 'type', None) == 'blocked'`

Si no hay ningún cargo o resultado disponible, no infieras que el pago se bloqueó. |
| **Problema** | El sistema de prevención de fraudes de Stripe, {*Radar* (Radar Plus helps you fine-tune how Radar operates, get fraud insights on suspicious charges, and assess your fraud management performance from a unified dashboard), bloqueó el pago. |
| **Soluciones** | Este error se puede producir cuando tu integración funciona correctamente. Cáptalo y solicítale al cliente otro método de pago.

Para bloquear menos pagos legítimos, intenta lo siguiente:

- [Optimiza tu integración de Radar](https://docs.stripe.com/radar/optimize-risk-factors.md) para recopilar información más detallada.
- Para elementos de formularios optimizados prediseñados, usa [Payment Links](https://docs.stripe.com/payment-links.md), [Checkout](https://docs.stripe.com/payments/checkout.md) o [Stripe Elements](https://docs.stripe.com/payments/elements.md).

Los clientes de *Radar Plus* (Radar Plus helps you fine-tune how Radar operates, get fraud insights on suspicious charges, and assess your fraud management performance from a unified dashboard) tienen estas opciones adicionales:

- Para eximir un pago específico, añádelo a tu lista de permisos. (Radar Plus)
- Para cambiar tu tolerancia al riesgo, ajusta tu [ configuración de riesgo](https://docs.stripe.com/radar/risk-settings.md). (Radar Plus)
- Para cambiar los criterios para bloquear un pago, utiliza [reglas personalizadas](https://docs.stripe.com/radar/rules.md). (Radar Plus)

Puedes probar los ajustes de tu integración con [tarjetas de prueba que simulan fraude](https://docs.stripe.com/radar/testing.md). Si estableciste reglas de Radar personalizadas, sigue los consejos de prueba de la [documentación de Radar](https://docs.stripe.com/radar/testing.md). |

### Pago rechazado por el emisor

|  |
| **Tipo** | `stripe.CardError` |
| **Códigos** | `e.code == "card_declined"` |
| **Problema** | El emisor de la tarjeta rechazó el pago. |
| **Soluciones** | Este error puede ocurrir cuando tu integración funciona correctamente. Refleja una acción del emisor, y esa acción podría ser legítima. Usa el código de pago rechazado para determinar qué pasos debes seguir. Consulta la [documentación sobre códigos de pago rechazado](https://docs.stripe.com/declines/codes.md) para ver las respuestas adecuadas para cada código.

También puedes

- [Sigue las recomendaciones para reducir los rechazos de los emisores](https://docs.stripe.com/declines/card.md#reducing-bank-declines).
- Usa [Payment Links](https://docs.stripe.com/payment-links.md), [Checkout](https://docs.stripe.com/payments/checkout.md) o [Stripe Elements](https://docs.stripe.com/payments/elements.md) para los elementos de formulario prediseñados que implementan esas recomendaciones.

Prueba cómo tu integración gestiona los rechazos con [tarjetas de prueba que simulan pagos correctos y pagos rechazados](https://docs.stripe.com/radar/testing.md). |

### Otros errores de pago

|  |
| **Tipo** | `stripe.CardError` |
| **Problema** | Se produjo otro error de pago. |
| **Soluciones** | Este error puede ocurrir cuando tu integración funciona correctamente. Usa el código de error para determinar qué pasos debes seguir. Consulta la [documentación sobre códigos de error](https://docs.stripe.com/error-codes.md) para ver las respuestas adecuadas para cada código. |

## Errores de solicitudes no válidas

|  |
| **Tipo** | `stripe.InvalidRequestError` |
| **Problema** | Hiciste una llamada API con parámetros erróneos, en el estado equivocado o de forma no válida. |
| **Soluciones** | En la mayoría de los casos, el problema es de la solicitud misma. Puede ser que los parámetros no sean válidos o que la solicitud no pueda realizarse en el estado actual de tu integración.
- Consulta la [documentación sobre códigos de errores](https://docs.stripe.com/error-codes.md) para obtener más información sobre el problema.
- Si está presente, sigue el enlace en `e.error.doc_url` para consultar la documentación sobre el código de error. Verifica que el objeto de error exista antes de acceder a sus propiedades.
- Si el error está relacionado con un parámetro específico, usa `e.param` para determinar de cuál se trata. |

## Errores de conexión

|  |
| **Tipo** | `stripe.APIConnectionError` |
| **Problema** | Hubo un problema de red entre tu servidor y Stripe. |
| **Soluciones** | Trata el resultado del llamada de API como indeterminado. Es decir, no asumas que tuvo éxito o que fracasó.

Para saber si se realizó correctamente, puedes

- Recupera el objeto relevante desde Stripe y comprueba su estado.
- Escucha la notificación de webhook que indica si la operación se realizó correctamente o falló. [Verifica las firmas de webhook](https://docs.stripe.com/webhooks.md#verify-events) antes de procesar los eventos. Si restringes el tráfico entrante por dirección IP, permite las [direcciones IP de webhooks públicos](https://docs.stripe.com/ips.md) de Stripe.

Para ayudarte a recuperarte de errores de conexión, puedes hacer lo siguiente:

- Para la API&nbsp;v1, usa una [clave de idempotencia](https://docs.stripe.com/api/idempotent_requests.md) cuando crees o actualices un objeto. En caso de un error de conexión, reintenta con la misma clave y los mismos parámetros dentro de las primeras 24&nbsp;horas posteriores a la solicitud original. Después de ese plazo, Stripe puede eliminar la clave, y su reutilización puede ejecutar una solicitud nueva. Si aún se desconoce el resultado, asegúrate de realizar una conciliación antes de repetir la operación. Consulta [Gestión avanzada de errores](https://docs.stripe.com/error-low-level.md#idempotency) para obtener más detalles, además de la [idempotencia de la API&nbsp;v2](https://docs.stripe.com/api-v2-overview.md#idempotency) para conocer el comportamiento de la API&nbsp;v2.
- Configura los [reintentos automáticos para tu SDK](https://docs.stripe.com/error-low-level.md#network-retries). Los SDK de Stripe generan claves de idempotencia y repiten las solicitudes cuando es seguro hacerlo. Los valores predeterminados varían según el SDK y la versión.

Este error puede ocultar otros. Es posible que aparezca otro error después de que se resuelva el problema de conexión. Revisa que no haya errores en todas estas soluciones, al igual que lo harías en la solicitud original. |

## Errores de API

|  |
| **Tipo** | `stripe.APIError` |
| **Problema** | Se produjo un error del lado de Stripe. (Esto no suele ocurrir). |
| **Soluciones** | Trata el resultado de la llamada API como indeterminado. Es decir, no des por sentado que se realizó correctamente ni que falló.

Recurre a los *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) para obtener información sobre el resultado. Cuando sea posible, Stripe activará webhooks para todos los objetos nuevos que se creen mientras se resuelva un problema.

Para configurar tu integración de manera que se comporte de la forma más sólida en situaciones inusuales, consulta [esta página con información detallada sobre errores de servidores](https://docs.stripe.com/error-low-level.md#server-errors). |

## Errores de autenticación

|  |
| **Tipo** | `stripe.AuthenticationError` |
| **Problema** | Stripe no puede autenticarte con la información proporcionada. |
| **Soluciones** | - Usa la [clave de API](https://docs.stripe.com/keys.md) correcta.
- Asegúrate de no estar usando una clave que hayas [rotado o anulado](https://docs.stripe.com/keys.md#rolling-keys). |

## Errores de idempotencia

|  |
| **Tipo** | `stripe.IdempotencyError` |
| **Problema** | Utilizaste una [clave de idempotencia](https://docs.stripe.com/api/idempotent_requests.md) para algo inesperado, como repetir una solicitud con parámetros distintos. |
| **Soluciones** | - Después de usar una clave de idempotencia, reutilízala solo para llamadas API idénticas.
- Usa claves de idempotencia que no superen los 255 caracteres. |

## Errores de permisos

|  |
| **Tipo** | `stripe.PermissionError` |
| **Problema** | La clave API usada para esta solicitud no tiene los permisos necesarios. |
| **Soluciones** | - Asegúrate de no estar usando una [clave de API restringida](https://docs.stripe.com/keys-best-practices.md#limit-access) para un servicio al que no tiene acceso.
- No realices acciones en el Dashboard si iniciaste sesión con una [función de usuario](https://docs.stripe.com/get-started/account/teams/roles.md) que no tiene permiso para ella. |

## Errores de límite de frecuencia

|  |
| **Tipo** | `stripe.RateLimitError` |
| **Problema** | Hiciste demasiadas llamadas API en muy poco tiempo. |
| **Soluciones** | - Si una sola llamada API activa este error, espera y vuelve a intentarlo.
- Para gestionar el límite de velocidad de forma automática, reintenta la llamada API después de cierto tiempo. Aumenta exponencialmente ese período si el error persiste. Consulta la documentación sobre [límites de frecuencia](https://docs.stripe.com/rate-limits.md) para obtener más consejos.
- Si anticipas que tendrás un gran incremento del tráfico y quieres solicitar un aumento del límite de frecuencia, [ponte en contacto con soporte](https://support.stripe.com/) por adelantado. |

## Errores de verificación de firma

|  |
| **Tipo** | `stripe.SignatureVerificationError` |
| **Problema** | Estás usando la [verificación de firma](https://docs.stripe.com/webhooks.md#verify-events) del *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) y no se pudo verificar que un evento de webhook sea auténtico. |
| **Soluciones** | Este error puede ocurrir cuando tu integración funciona correctamente. Si usas una verificación de firma de webhook y un tercero intenta enviarte un webhook falso o malicioso, entonces la verificación falla y, como resultado, se devuelve este error. Cáptalo y responde con un código de estado `400 Bad Request`.

Si recibes este error y consideras que no debería ocurrir (por ejemplo, al usar webhooks que sabes que se originaron en Stripe), consulta la documentación sobre [cómo verificar las firmas de webhooks](https://docs.stripe.com/webhooks.md#verify-events). Asegúrate especialmente de estar usando el secreto del punto de conexión correcto. Esta clave es diferente de tu clave de API. |
