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

# Pago con tarjeta fallido

> Se rechazó un pago con tarjeta que tu usuario inició desde el portal.

Se dispara cuando se **rechaza un pago con tarjeta que inició tu usuario final**.

<Warning>
  **El `type` de este evento es `CARD_PAYMENT_STATUS`, no `CARD_PAYMENT_FAILED`.** El nombre es genérico a propósito, para poder reutilizarlo más adelante con confirmaciones y otros estados. Hoy el único caso que lo emite es el pago rechazado, así que `status` vale siempre `"FAILED"`.
</Warning>

<Tip>
  Enruta por `type` y después ramifica por `status`. Así tu handler sigue funcionando el día que este mismo `type` empiece a traer otros estados.
</Tip>

|                           |                        |
| ------------------------- | ---------------------- |
| **`type`**                | `CARD_PAYMENT_STATUS`  |
| **`status`**              | Hoy siempre `"FAILED"` |
| **Llave de idempotencia** | `operationId`          |

## El payload

| Campo                                | Tipo           | Presente    | Descripción                                                                            |
| ------------------------------------ | -------------- | ----------- | -------------------------------------------------------------------------------------- |
| `type`                               | String         | Siempre     | Siempre `"CARD_PAYMENT_STATUS"`.                                                       |
| `operationId`                        | String         | Siempre     | Identificador de la operación de pago.                                                 |
| `status`                             | String         | Siempre     | Hoy siempre `"FAILED"`.                                                                |
| `amount`                             | Number \| null | Siempre     | Monto del pago. La clave siempre viene; el valor es `null` si el evento no lo informa. |
| `companyCode`                        | String \| null | Siempre     | Código de la empresa. Mismo criterio que `amount`.                                     |
| `companyName`                        | String \| null | Siempre     | Nombre de la empresa. Mismo criterio que `amount`.                                     |
| `additionalData`                     | Object         | Condicional | Detalle del error del proveedor. **Se omite entero** si queda vacío.                   |
| `additionalData.errorDetail.code`    | String         | Condicional | Código de error del proveedor.                                                         |
| `additionalData.errorDetail.message` | String         | Condicional | Mensaje de error del proveedor.                                                        |
| `hash`                               | String \| null | Siempre     | Hash de verificación. `null` si no tienes llave pública configurada.                   |

<Note>
  El detalle del error va **anidado** en `additionalData.errorDetail`, un nivel más adentro que en [domiciliación con tarjeta fallida](/es/webhooks/domiciliacion-con-tarjeta-fallida), donde va directo en `additionalData`. Es la única diferencia de forma entre los dos eventos de tarjeta.
</Note>

<Warning>
  `additionalData` **se omite por completo** cuando no hay detalle que enviar: cuando `sendErrorInfo` está apagado en tu configuración, y también cuando está prendido pero el evento no trae detalle del proveedor.
</Warning>

```javascript theme={null}
// Correcto: contempla los dos niveles opcionales
const codigo = notificacion.additionalData?.errorDetail?.code ?? null;
```

## Ejemplos

<CodeGroup>
  ```json Con detalle de error theme={null}
  {
    "type": "CARD_PAYMENT_STATUS",
    "operationId": "b7c8d9e0-1122-3344-5566-7788990011aa",
    "status": "FAILED",
    "amount": 12000,
    "companyCode": "MX-S-12345",
    "companyName": "ACME",
    "additionalData": {
      "errorDetail": {
        "code": "CARD_DECLINED",
        "message": "Tarjeta rechazada por el emisor"
      }
    },
    "hash": "encrypted-base64-string"
  }
  ```

  ```json Sin detalle y sin monto informado theme={null}
  {
    "type": "CARD_PAYMENT_STATUS",
    "operationId": "b7c8d9e0-1122-3344-5566-7788990011aa",
    "status": "FAILED",
    "amount": null,
    "companyCode": "MX-S-12345",
    "companyName": "ACME",
    "hash": null
  }
  ```
</CodeGroup>

<Card title="Campos comunes, hash e idempotencia" icon="bookmark" href="/es/webhooks">
  Lo que comparten todos los webhooks de esta familia.
</Card>
