> ## 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.

# Medio de pago registrado

> Aviso de que un usuario registró su cuenta bancaria y ya la puedes usar para cobrarle.

Cuando un usuario registra su cuenta bancaria en la [página de enrolamiento](https://devs.tapipay.la/es/portal-de-pagos/sdk-adhesiones.md), TapiPay te avisa con este webhook. Trae el `externalPaymentMethodId` de la cuenta, el mismo que devuelve [`GET /payment-methods`](https://devs.tapipay.la/es/recursos/debito-automatico#consultar-los-medios-de-pago-de-un-usuario) y que acepta [`POST /v2/debts/orders`](https://devs.tapipay.la/es/recursos/ordenes-de-pago), así que no necesitas consultar la API para empezar a cobrarle.

| `type` | Cuándo llega |
| - | - |
| `PAYMENT_METHOD_REGISTERED` | El usuario registró una cuenta y quedó vigente. |

> [!NOTE]
>
> Este webhook tiene **el mismo contrato que el [pago de una orden](https://devs.tapipay.la/es/webhooks/pago-de-orden.md)**: no trae `operationId` ni `companyName`, y su llave de idempotencia es `id`. Lo que se explica en [Campos comunes](https://devs.tapipay.la/es/webhooks.md#campos-comunes) no aplica acá, salvo el `hash`.

## Cuándo llega

Llega cada vez que el registro de la cuenta termina bien:

* **Cuenta nueva**: la primera vez que el usuario registra esa cuenta.
* **Registro repetido**: el usuario vuelve a registrar una cuenta que ya tenía vigente.
* **Reactivación**: el usuario vuelve a registrar una cuenta que se había [eliminado](https://devs.tapipay.la/es/recursos/debito-automatico.md#eliminar-un-medio-de-pago).

En los dos últimos casos el aviso llega con el **mismo `id`** y el mismo `registeredAt` que el de la cuenta nueva. Es la misma cuenta, así que lo tratas como un reenvío.

Por ahora el contrato cubre cuentas bancarias (`BANK_ACCOUNT`). Si te llega un aviso con otro `type` de medio, ignóralo: los demás tipos todavía no forman parte de este contrato.

No llega si el registro falla, ni por las cuentas que TapiPay carga por fuera del registro, por ejemplo en una migración.

## Configuración

Llega a la misma URL que los eventos de [órdenes de pago](https://devs.tapipay.la/es/webhooks/pago-de-orden.md): la que configuraste para órdenes en el onboarding o, si no tienes una propia, tu URL general.

Los mecanismos de seguridad son los mismos que en el resto de los webhooks: ver [Validar que la petición viene de TapiPay](https://devs.tapipay.la/es/webhooks/notificacion-de-pago.md#validar-que-la-petición-viene-de-tapipay).

`POST` con `Content-Type: application/json`. El header `notificationType` trae el mismo valor que `type`, para que puedas enrutar sin leer el cuerpo.

## El payload

| Campo | Tipo | Presente | Descripción |
| - | - | - | - |
| `type` | String | Siempre | `PAYMENT_METHOD_REGISTERED`. Úsalo para enrutar. |
| `hash` | String \| null | Siempre | Hash de verificación. `null` si no tienes llave pública configurada. |
| `id` | String (uuid) | Siempre | Identificador de la notificación. Es el mismo para todos los avisos de una misma cuenta. **Úsalo como llave de idempotencia.** |
| `companyCode` | String | Siempre | Código de la empresa con la que se registró la cuenta. |
| `externalClientId` | String | Siempre | Tu identificador del usuario. |
| `paymentMethod` | Object | Siempre | La cuenta registrada: `{ type, externalPaymentMethodId, isDefault, details }`. Nunca trae la cuenta ni la CLABE. |
| `registeredAt` | String | Siempre | Cuándo se registró la cuenta por primera vez, en ISO 8601 UTC. |

### `paymentMethod`

| Campo | Tipo | Descripción |
| - | - | - |
| `type` | String | Por ahora `BANK_ACCOUNT`. |
| `externalPaymentMethodId` | String (uuid) | Identificador de la cuenta. Envíalo en `POST /v2/debts/orders` para cobrar con esta cuenta. |
| `isDefault` | Boolean | `true` si es la cuenta predeterminada del usuario. Ver [Consultar los medios de pago de un usuario](https://devs.tapipay.la/es/recursos/debito-automatico.md#consultar-los-medios-de-pago-de-un-usuario). |
| `details` | Object | Por ahora siempre llega vacío (`{}`). |

> [!NOTE]
>
> Es el mismo objeto `paymentMethod` que llega en el [pago de una orden](https://devs.tapipay.la/es/webhooks/pago-de-orden.md), con dos campos más: `isDefault` y `details`.

## El hash

Si entregaste una llave pública RSA en el onboarding, `hash` viene cifrado con ella. Descífralo con tu llave privada: contiene tu usuario de integración o, en la versión `v2` de la seguridad, `{ "clientUsername", "operationId" }`. En `v2`, comprueba que `operationId` coincida con el `id` del cuerpo.

## Ejemplo

Corresponde a una integración sin llave pública, por eso `hash` viene en `null`.

```json theme={null}
{
  "type": "PAYMENT_METHOD_REGISTERED",
  "hash": null,
  "id": "0b8f3c6e-7a21-5d94-b3e8-2c6f9a1d4e57",
  "companyCode": "MX-S-12345",
  "externalClientId": "CLI-00042",
  "paymentMethod": {
    "type": "BANK_ACCOUNT",
    "externalPaymentMethodId": "b7e4a0c2-9f13-4e6d-8a25-71c3d9e0b4f8",
    "isDefault": true,
    "details": {}
  },
  "registeredAt": "2026-10-23T14:03:11.000Z"
}
```

## Recomendaciones

* **Procesa cada `id` una sola vez.** Además de los reintentos por falta de respuesta, el registro repetido y la reactivación reenvían el mismo `id`. Guarda los `id` procesados en almacenamiento persistente.
* **Guarda el `externalPaymentMethodId`** junto a tu usuario: es lo que necesitas para cobrarle con esa cuenta.
* **No uses `isDefault` como fuente de verdad.** La cuenta predeterminada puede cambiar después, por ejemplo si el usuario elimina una cuenta. Antes de decidir con qué cuenta cobrar, consulta [`GET /payment-methods`](https://devs.tapipay.la/es/recursos/debito-automatico#consultar-los-medios-de-pago-de-un-usuario).
* **Ignora los campos que no conozcas**: se pueden agregar campos nuevos, también dentro de `details`.

Los requisitos de tu endpoint (responder 2xx en menos de 5 segundos y ser alcanzable desde las IPs de TapiPay) son los mismos que en el resto de los webhooks: ver [Requisitos de tu endpoint](https://devs.tapipay.la/es/webhooks/notificacion-de-pago.md#requisitos-de-tu-endpoint).


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