Saltar al contenido principal

Conceptos base (modelo mental)

Antes de escribir una línea de código conviene tener el modelo mental de un pago con SPIDI. Aquí está entero y en orden: cada idea usa solo lo anterior, y ninguna aparece de la nada.

Página canónica

Esta es la referencia del modelo mental. Otras secciones la enlazan en vez de repetirla.

Conceptos base: el modelo mental de un pago con SPIDIGuion: .docx · .yaml

1. A dónde va el dinero: el destino

Antes de recibir tu primer pago tienes que decidir una cosa: a dónde va a llegar el dinero.

Eso es un destino — en la API, un acuerdo (agreement, POST /api/v1/ext/agreements). Es un juego de reglas que dice cómo recibes: a qué cuenta bancaria tuya se acredita, qué métodos de pago aceptas, y si lo que llegue ahí se reparte con otros.

Se define una vez y se reutiliza. No creas un acuerdo por pago: creas uno por cada forma distinta de recibir que tenga tu negocio, y después lo usas en todos los pagos que vayan ahí. Un negocio con una sola cuenta tendrá uno; uno que separa ingresos por sucursal, o que reparte con socios en unos casos y no en otros, tendrá varios.

Un destino también puede bifurcarse. Si lo que llega ahí va a varias cuentas, se declara en el propio destino: el dinero se reparte al llegar. → Split

Cada destino tiene su agreement_id, y es lo que dice, en cada pago, por dónde lo enruta SPIDI.

El acuerdo de liquidación, a fondo

2. Cómo inicias un pago: la sesión

Con tus destinos definidos, recibir un pago es abrir una sesión de pago. Cada pago que recibes es una sesión, y la creas con una sola llamada.

Una sesión tiene dos partes.

Primero, por dónde lo enrutas. Pones el agreement_id del destino que quieras usar, y con eso ya está dicho a qué cuenta va el dinero y qué métodos aceptas — no lo repites en cada pago.

Después, los datos de este pago:

Qué dicesCon qué campos
Cuánto, y en qué moneda lo fijasamount_reference, currency_reference
A quién se lo pides y por qué conceptoidentifier_label, identifier, description
A dónde vuelve la persona al terminarsuccess_url, failure_url

Pones el precio en la moneda que uses para fijar precios —dólar, euro, bolívares— y SPIDI calcula lo que se paga en bolívares. La liquidación es siempre en bolívares.

Y después, lo que quieras añadir: a dónde te avisamos (webhook_url), cómo se reparte si ese destino se bifurca (split), y cuánto quieres que viva el enlace.

3. Qué te devuelve: el enlace de pago

La respuesta trae dos cosas que te importan: una payment_url, que es la pantalla donde tu cliente va a pagar, y un status, que arranca en pending.

Esa URL es lo único que tu cliente necesita ver. Cómo se la pones delante es tu decisión: un botón en tu propia web o app, o un enlace que le envías por correo, por WhatsApp, o como un QR que le muestras.

Usa la dirección que te devuelven, no la construyas

Guárdala tal cual viene en la respuesta. Armarla a mano a partir del identificador lleva a un enlace que no da error: lleva a una pantalla plausible donde se pierde el pago sin que nadie se entere.

4. Cuánto tiene que vivir ese enlace

Ahí está la decisión que conviene tomar bien. Las dos formas de sesión te devuelven una payment_url; lo que cambia es cuánto vive — y por eso sirven para cosas distintas.

BotónSolicitud
Viveduration_minutesminutos, de 5 minutos a 20 minutosdue_date_sessionuna fecha que pones tú
Se creande unapor lote
Para quéun checkout: tu cliente está ahí, decidiendo ahoraun pago que espera: una factura que mandas hoy y se paga la semana que viene
El error que esto te evita

La URL de un Botón también es una URL, así que se puede mandar por WhatsApp — y morirse antes de que la abran. Si el pago va a esperar, no uses un Botón.

Botón web · Solicitud de pago

5. Un pago ocurre en dos fases

Y aquí está el detalle que confunde a todo integrador. Una transacción no es un evento: son dos.

La primera fase es el pago. Tu cliente paga y el dinero sale de sus manos. No queda en poder de SPIDI: entra en una cuenta propia del banco, y el banco es su custodio. Tu cliente ya no puede echarse atrás. La sesión pasa a paid y se emite payment_session.paid.

Aquí ya puedes entregar. No esperes a la segunda fase para habilitar tu servicio o despachar tu producto: el dinero está en un banco y el banco lo custodia.

La segunda fase es la acreditación. El dinero se mueve desde esa cuenta del banco hasta la tuya —o hasta las de tus receptores, si el destino se bifurca—. Aquí se aplica la comisión del banco, y por eso lo que se acredita es el monto neto. Se emite payment_session.accredited.

Tarda entre uno y dos minutos, no segundos.

Transacción a dos fases

6. Cómo te enteras de cada fase

La sesión es el registro de la transacción, y las dos fases se ven ahí. Una sola consulta te da el estado completo:

GET /api/v1/ext/payment-sessions/status/{session_id}
→ data.status ← la fase 1
→ data.session_payment.receiver_credits ← la fase 2

El aviso no es la única fuente: es el atajo. Te avisa en cuanto ocurre, y así no tienes que preguntar. Llega por POST a tu webhook_url con tres cabeceras:

  • spidi-signature — el 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.
  • idempotency-key — para deduplicar reintentos.

Tu endpoint debe verificar la firma, deduplicar y responder 2xx. → Manejar notificaciones

El status nunca refleja la fase 2

Tras paid, el status se queda en paid. No existe un estado accredited: si sondeas esperándolo, esperas para siempre. Lo que cambia es que receiver_credits deja de venir null — es otro bucle y otra condición de salida.

Guarda el session_id de cada transacción

Si tu servidor estuvo caído, SPIDI reintenta y luego se rinde: no hay reenvío. Cuando vuelvas no habrá un aviso esperándote — habrá una sesión que puedes consultar. Pero no hay forma de listar tus sesiones, así que el session_id es tu única llave de vuelta.

Un aviso de acreditación por cada parte del acuerdo

Llega un evento por cada transacción de crédito: sin split, un solo payment_session.accredited; con split, una acreditación por receptor más el cierre, todas a tu mismo webhook_url. → Split

Las dos reglas de oro

  1. El estado real lo manda tu backend, no la redirección. Volver a success_url no significa que te pagaron: confírmalo con GET status o por el webhook.
  2. paid es el pago; la acreditación es cuándo lo ves en tu cuenta. Puedes entregar en paid. Y las dos fases se consultan en la sesión — el aviso solo te ahorra preguntar.

Siguiente paso

Ponlo en práctica: → Recibe tu primer pago.