Saltar al contenido principal
Cuando creas una orden de pago, el cargo a la cuenta del usuario se procesa después, en el lote que TapiPay envía al banco. El resultado te llega con este webhook: uno por cada movimiento del cargo.
Este webhook tiene su propio contrato, distinto del de los eventos de débito automático: no trae operationId ni companyName, y su llave de idempotencia es id. Lo que se explica en Campos comunes no aplica acá, salvo el hash.

Dos avisos por una orden confirmada

ORDER_PAYMENT_CONFIRMED informa el cobro, no el pago de la deuda. Después de confirmarlo, TapiPay aplica el pago a la deuda de la orden y te envía además la notificación de pago (type: SERVICE, status: confirmed). Así, una orden confirmada te genera dos avisos, que pueden llegar a URLs distintas.

Configuración

La URL de estos eventos se define en el onboarding y puede ser distinta de la de los demás webhooks. Si no configuraste una propia para órdenes, llegan a 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. 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

En paymentMethod, el tipo de cuenta va en type. En la respuesta de la orden y en GET /payment-methods el mismo dato se llama paymentMethodType. externalPaymentMethodId es el mismo valor en los tres lugares.
Por ahora code y description llegan siempre en null dentro de paymentProviderError y chargeback. El objeto sí viene siempre en su evento: léelo sin verificar que exista, pero contempla el null.

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.

Ejemplos

Una orden que se cobra y después se revierte, y otra cuyo cargo se rechaza. Los ejemplos corresponden a una integración sin llave pública, por eso hash viene en null.

Recomendaciones

  • Procesa cada notificación una sola vez. TapiPay reintenta si tu endpoint no responde 2xx a tiempo, así que la misma notificación puede llegar más de una vez, siempre con el mismo id. Guarda los id procesados en almacenamiento persistente.
  • No asumas un orden de llegada. Usa paymentAt para ordenar los movimientos de una misma orden.
  • Correlaciona por orderId o externalOrderId.
  • Ignora los campos que no conozcas: se pueden agregar campos nuevos.
  • Si no te llega un webhook, consulta la orden con GET /v2/debts/orders.
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.