Saltar al contenido principal

Webhooks: cómo te avisa SPIDI

Un pago ocurre en dos fases, y las dos te importan. Un webhook es cómo te enteras de cada una sin tener que preguntar: un aviso que SPIDI te envía por POST en cuanto algo pasa, sin depender de que la persona vuelva a tu sitio.

Qué es vs cómo se maneja

Esta página explica qué son los avisos y cuáles existen. Para implementarlos —verificar la firma, deduplicar, responder— ve a → Manejar notificaciones.

Webhooks: cómo te avisa SPIDIGuion: .docx · .yaml

Qué Trae un Aviso​

SPIDI hace POST a tu webhook_url con un cuerpo JSON y tres cabeceras:

  • spidi-signature — sello HMAC-SHA256 de spidi-timestamp + "." + el cuerpo crudo, con el secreto de tu cuenta.
  • spidi-timestamp — cuándo se generó. Entra en el cálculo de la firma, así que sin él no se puede verificar nada.
  • idempotency-key — identificador estable del envío, para deduplicar reintentos.
{ "event": "payment_session.paid", "data": { /* ... */ } }

El campo event es lo que tu código mira. Todo lo demás de esta página gira alrededor de él.

Los Cinco Eventos que Declara el Contrato​

event que recibesCuándoFase
payment_session.createdLa sesión de pago se creóantes de la fase 1
payment_session.paidEl débito al pagador salió bienfase 1
payment_session.accreditedTerminaron las acreditacionesfase 2
payment_session.accreditation_to_recipient_completedSe acreditó a un receptor del repartofase 2, uno por receptor
payment_session.accreditation_to_recipient_failedFalló la acreditación a un receptorfase 2

En un pago sin reparto verás dos: paid y accredited.

La Trampa: Dos de Ellos No Se Llaman como el Contrato los Titula​

Compara contra el campo event, no contra el título del contrato

La clave que titula cada webhook en la OpenAPI es una etiqueta del documento: no viaja por el cable. Y en dos casos no coincide con lo que llega:

Clave en la OpenAPIevent que viaja de verdad
payment_session.payment_completedpayment_session.paid
payment_session.accreditations_completedpayment_session.accredited

El fallo es silencioso. Un switch escrito leyendo los títulos del contrato no entra nunca en esas dos ramas: los avisos llegan, tu endpoint responde 2xx, y tu lógica no se ejecuta. Nada da error.

Cinco Declarados, Dos Observados​

Los cinco están en el contrato. Nosotros solo hemos visto llegar paid y accredited, y el simulador solo emite esos dos. Los otros tres están aquí porque el contrato los declara y tu receptor puede recibirlos: ante un event que no conozcas, ignóralo y responde 2xx — nunca rompas.

El que más conviene mirar es accreditation_to_recipient_failed. Es el único que dice que el dinero no llegó a un receptor, y no tiene equivalente en GET status: si no lo escuchas, un reparto fallido se te queda invisible.

Cuántos Avisos Llegan por un Pago​

Llega uno por cada transacción de crédito, y eso depende de si repartes:

  • Sin reparto — una sola parte, un solo payment_session.accredited.
  • Con reparto — una acreditación por receptor, más el cierre. Todas a tu mismo webhook_url: un partner no tiene webhook propio.

→ Split

Entrega: Reintentos, Deduplicación, y Qué Pasa si Estabas Caído​

Si tu endpoint no responde 2xx a tiempo, SPIDI reintenta con el mismo idempotency-key. Por eso tu receptor debe deduplicar: procesar una vez aunque llegue varias.

No escribas lógica que dependa de cuántos reintentos hay ni de cuánto esperan entre uno y otro. Diseña para recibir el mismo aviso un número indeterminado de veces, que es la única suposición que no se rompe.

Guarda el session_id: si SPIDI se rinde, es tu única llave de vuelta

Después de reintentar, SPIDI se rinde, y no hay reenvío. Cuando tu servidor vuelva no habrá un aviso esperándote — habrá una sesión que puedes consultar. Pero no hay forma de listar tus sesiones, así que sin el session_id guardado no tienes por dónde entrar.

El aviso es el atajo, no la única fuente. Las dos fases se consultan también en la sesión, con GET status: la fase 1 en data.status y la fase 2 en data.session_payment.receiver_credits. → Transacción a dos fases

→ Manejar notificaciones · Usar el simulador