Payouts y Devoluciones

Qué es una reversa de un pago, cuándo puede ocurrir y cómo Shinkansen te la notifica.

Una devolución (o reversa) ocurre cuando un pago que ya había salido de forma exitosa es devuelto por el banco de destino: el dinero regresa a la cuenta de origen y la transacción, que estaba en ok, pasa a error.

Esto es posible porque las transferencias "instantáneas" en realidad son asíncronas: el banco de origen debita y envía el pago, y el banco de destino puede rechazarlo o devolverlo incluso minutos u horas después de que la operación se dio por exitosa. Es un evento poco frecuente, pero real.

¿Por qué se revierte una transferencia que ya estaba "ok"?

Nuestro CEO se explaya sobre este tema en el blog Cuando las transferencias se revierten, que te recomendamos leer para entender la mecánica detrás de las devoluciones 😁


¿En qué ocasiones puede ocurrir?

Las causas dependen de cada banco y de cada red de pagos, pero las más comunes son:

  • La cuenta de destino no existe o fue cancelada.
  • La cuenta de destino está bloqueada (por ejemplo, por prevención de lavado de dinero o por datos desactualizados del titular).
  • La moneda del pago no coincide con la de la cuenta de destino.
  • Un rechazo del banco de destino posterior a la acreditación inicial.

En algunos sistemas la devolución llega en segundos o minutos; en otros puede tardar bastante más (por ejemplo, en México un SPEI devuelto suele reflejarse en minutos, pero excepcionalmente puede tomar hasta 48 horas). Por eso una transacción puede quedar en ok y ser revertida más tarde.


¿Cómo lo maneja Shinkansen?

Shinkansen genera notificaciones de reversa de pagos (payout_reversal) para informarte cuando uno de tus pagos fue devuelto. Ten en cuenta:

  • La notificación de reversa solo aparece si antes hubo una respuesta que marcó el pago como ok. Si el pago nunca llegó a estar en ok (por ejemplo, falló de entrada), no hay reversa que notificar.
  • La notificación actualiza el estado de la transacción de ok a error. La dirección del cambio siempre es ok → error.
  • No genera una nueva respuesta (response): la reversa actualiza la transacción original, no crea otra.
  • Se envía a través del webhook notification_payout_reversal_endpoint, que puedes configurar en el Dashboard.

Desde tu punto de vista, recibir una notificación de reversa es básicamente un webhook:


Estructura de la notificación

La notificación de reversa viaja dentro de un mensaje con la cabecera habitual (document.header) y una lista de notifications. Cada notificación de reversa contiene:

Campo Descripción
notification_type Siempre "payout_reversal".
notification_id Identificador único de la notificación (asignado por el operador).
shinkansen_notification_id Identificador único de la notificación asignado por Shinkansen.
notification_date Fecha y hora en que se generó la notificación.
referenced_shinkansen_transaction_id El shinkansen_transaction_id del payout que fue devuelto.
referenced_transaction_id El transaction_id que tú asignaste a ese payout cuando lo creaste.
reversal_reason El motivo de la devolución. Tiene su propia lista de valores, independiente del response_status (ver más abajo).
reversal_message Detalle legible del motivo de la devolución.

Un ejemplo del contenido de una notificación de reversa:

{
  "shinkansen_notification_id": "0421c147-1d4a-484c-b855-9dcd8b9b67d9",
  "notification_type": "payout_reversal",
  "notification_id": "4e0309bd-7228-46ae-887e-41764f9d5ac7",
  "notification_date": "2026-06-30T14:41:00Z",
  "referenced_shinkansen_transaction_id": "6f11ea4d-d2fa-4da3-b102-8c07112c1635",
  "referenced_transaction_id": "6adf8e53-ab35-4573-9073-f902d9e00580",
  "reversal_reason": "error_creditor_account_not_found",
  "reversal_message": "Cuenta de destino inexistente"
}

reversal_reason tiene su propia lista de valores

A diferencia del response_status de una respuesta, reversal_reason es una lista independiente de motivos de devolución (aunque varios valores coinciden por nombre). Los valores posibles son:

  • error_creditor_account_not_found — la cuenta de destino no existe.
  • error_creditor_account_closed — la cuenta de destino está cerrada, cancelada o bloqueada.
  • error_creditor_account_currency_mismatch — la moneda del pago no coincide con la de la cuenta de destino.
  • error_creditor_account_detail_mismatch — los datos de la cuenta de destino no coinciden.
  • error_creditor_account_over_limits — el pago excede los límites de la cuenta de destino.
  • invalid — la devolución no corresponde a una causa específica de las anteriores.
  • error — error genérico informado por el banco.

Para el significado y qué hacer frente a cada tipo de error puedes apoyarte en Payouts - ¿Cómo manejar los errores?.


Probar una reversa en SimulatedBank

Puedes probar el flujo de devoluciones de punta a punta en el entorno de pruebas. Envía un payout exitoso desde tu cuenta de SimulatedBank y luego, sobre ese movimiento, presiona el botón Reverse payout y elige un reversal_reason. SimulatedBank devuelve los fondos a tu cuenta ficticia y envía una notificación payout_reversal al webhook que tengas configurado. Los pasos detallados están en Probar una reversa de payout en SimulatedBank.


Referencia de API

La estructura completa del webhook de reversas está documentada en la referencia de API: Receives payout reversal notifications from Shinkansen.

Ojo con la idempotencia y la validación de firma en las notificaciones

En las notificaciones, tú eres el servidor (mediante tu webhook) y nosotros el cliente que nos conectamos a ese endpoint.

Por ende es crítico que verifiques siempre la firma de Shinkansen en cada mensaje que llegue a tu webhook. Y también es igual de importante que manejes la idempotencia desde el lado servidor, verificando los ids de mensaje para evitar duplicados y respondiéndonos un 409 cuando te hayamos enviado un duplicado.