Paradas (una carpeta de pagos con dirección propia)
Una Parada es una carpeta de pagos con una dirección web pegada. Tú la creas y vas metiendo y sacando lo que haga falta; la carpeta se queda y su enlace no caduca.
Para tu cliente es otra cosa: un minisitio de pagos. En vez de mandarle un enlace nuevo por cada pago, le mandas esa dirección una sola vez: ahí encuentra reunido todo lo que tiene pendiente contigo y paga cuando quiera.
El caso más evidente es un cliente que se repite —una mensualidad, un servicio recurrente—, pero el criterio de agrupación lo pones tú: por proyecto, por período, por sucursal, por mesa. Una Parada no sabe nada de clientes; es una carpeta con una dirección.
Y ese último caso tiene nombre propio en el catálogo de SPIDI: cuando la carpeta es un punto —una mesa, una habitación, un módulo— y su dirección va impresa en un código pegado ahí, es Express QR. El mecanismo es el que estás leyendo. → SPIDI Express
Si lo que quieres es una sola dirección de pago del comercio, no hace falta crear nada ni llamar al API: viene con la cuenta. → Mi SPIDI
Las Paradas son otra cosa: una por cada cliente, proyecto o punto, y ahí sí publicas tú lo que se debe.
Tres reglas de las Paradas que muerden después
- Borrar una Parada es definitivo, y no se puede si tiene solicitudes activas dentro: primero las quitas o las vences. La llamada es idempotente, así que repetirla no rompe nada.
- Reordenar no añade ni quita, solo cambia el orden de lo que ya está. Y admite un control
de concurrencia opcional,
order_version, que conviene usar si dos procesos tuyos pueden reordenar la misma Parada: sin él, gana el último que llegue. - Cuando una sesión se paga o vence, sale sola de lo activo y queda en el histórico de la Parada. No hay que retirarla a mano.
Por qué existen
Una sesión de pago vive como mucho 20 minutos. Eso está bien para un botón de «pagar ahora», y no sirve para nada que tenga que esperar: mandar una factura por WhatsApp, una mensualidad recurrente, dejarle a alguien un sitio donde pagar cuando le venga bien.
La Parada resuelve eso separando dos cosas que suelen confundirse:
| Qué es | Vida | |
|---|---|---|
| La Parada | La dirección, y lo que agrupas bajo ella | Permanente |
| Cada pago pendiente | Una Solicitud que colocas dentro | Su propia fecha de vencimiento |
La Parada no procesa pagos: los muestra. Lo que se paga son las Solicitudes que pongas dentro.
Dentro de una Parada van sesiones de pago, y sirven las dos formas. Lo que decide cuál te conviene no es el producto, es el plazo:
- Si lo que está dentro tiene que esperar —una mensualidad, una factura, algo que se paga en los próximos días— van Solicitudes, que llevan
due_date_sessiony pueden configurarse conkeep_activepara seguir siendo pagables después de su fecha. → Solicitud de pago - Si se paga en el momento —la cuenta de una mesa, un servicio que se liquida ahí mismo— un Botón encaja mejor: la dirección de la Parada se queda, y lo de dentro dura lo que dura el pago. → Botón web
Lo que no funciona es cruzar el plazo. Un Botón dentro de una Parada expira a los 20 minutos como cualquier otro, y la Parada no detiene su reloj: si lo pones esperando que aguante hasta mañana, tu cliente encontrará un enlace muerto.
1. Crea la parada
Una por cada cosa que quieras agrupar — el criterio lo pones tú. Se pueden crear varias de una vez.
Si agrupas cosas de personas distintas, cada una verá las de las demás. No es un límite que puedas configurar, es cómo funciona — y es lo que decide por ti si el criterio debe ser el cliente o puede ser otro.
curl -X POST https://sim-productos.abiertolab.com/api/v1/ext/payment-stops \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-d '{
"continue_on_error": true,
"spidi_id": "<uuid>",
"items": [{
"stop_title": "María Rodríguez",
"internal_reference": "CLI-00427",
"empty_state_message": "No tienes pagos pendientes"
}]
}'
| Campo | Qué poner |
|---|---|
stop_title | El título de la Parada — el nombre del cliente, del proyecto, de la mesa. Es lo que se ve como título de la página |
internal_reference | Tu referencia de ese cliente. Única, y con ella lo vuelves a encontrar |
empty_state_message | Lo que lee cuando no debe nada |
spidi_id | Un identificador UUID para el cliente |
continue_on_error | Si true, un ítem que falle no detiene a los demás |
internal_reference se le muestra al clienteAparece como subtítulo de cada solicitud en su página. No metas ahí notas internas, códigos de riesgo ni nada que no le dirías a la cara. Úsalo para lo que es: la referencia con la que tú lo identificas — un número de contrato, un código de cliente.
La respuesta trae lo único que hay que guardar:
{
"results": [{
"internal_reference": "CLI-00427",
"success": true,
"data": {
"stop_id": "stp_49299f00-968b-4641-99c8-e8291084010d",
"stop_url": "https://sandbox.mispidi.com/stop/s?id=stp_49299f00-968b-4641-99c8-e8291084010d",
"status": "active"
}
}]
}
stop_url que te devuelven, no la construyasGuárdala tal cual. Y si pierdes el stop_id, la recuperas: GET /api/v1/ext/payment-stops?internal_reference=CLI-00427 busca por coincidencia exacta.
2. Pon las solicitudes dentro
Dos pasos: creas las Solicitudes y luego las asocias a la parada.
# a) las solicitudes del mes, con su fecha y su comportamiento al vencer
curl -X POST https://sim-productos.abiertolab.com/api/v1/ext/payment-sessions/request/batch \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-d '{ "continue_on_error": true, "items": [ { "…": "ver la guía de Solicitud" } ] }'
# b) colgarlas de la parada
curl -X POST https://sim-productos.abiertolab.com/api/v1/ext/payment-stops/payment-sessions/batch \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-d '{
"continue_on_error": true,
"items": [{
"stop_id": "stp_…",
"op": "add",
"session_ids": ["<session_id_1>", "<session_id_2>"]
}]
}'
op admite cuatro operaciones, y elegir bien la de (b) simplifica mucho el código:
op | Qué hace | Cuándo usarla |
|---|---|---|
add | Añade a lo que ya hay | Vas sumando solicitudes sueltas |
remove | Quita las que digas | Anulaste una factura |
replace | Deja exactamente esta lista | Sincronizas contra tu sistema |
clear | Vacía la parada | El cliente quedó al día |
replace es el que quieres si tienes un sistema de carteraCon replace mandas el estado completo de la deuda de ese cliente hoy, y no necesitas recordar qué le enviaste el mes pasado. Es idempotente: repetir la misma llamada deja el mismo resultado. Con add sí tienes que llevar esa cuenta tú.
Y PATCH .../payment-sessions/reorder fija en qué orden las ve, que es tanto como decir qué le pones delante para que pague primero.
3. Qué ve tu cliente
Abre su URL y encuentra su nombre, y debajo la lista de lo que debe:
Mensualidad de agosto CLI-00427 Bs 350,00
Matrícula CLI-00427 Bs 120,00
[ Pagar ]
Elige una y va a su pantalla de pago. No tiene que registrarse en nada ni instalar nada.
Cualquiera que tenga ese enlace ve lo que ese cliente debe y puede pagarlo. En un pago recurrente suele ser lo deseable —quien pague, bienvenido— pero tenlo en cuenta antes de publicarla en un sitio abierto.
4. Consulta el estado de la cartera
# tus paradas, con cuántas solicitudes activas tiene cada una
curl "https://sim-productos.abiertolab.com/api/v1/ext/payment-stops?status=active&sort=updated_desc" \
-H "Authorization: Bearer <token>"
# el detalle de un cliente: sus solicitudes vivas, en orden
curl https://sim-productos.abiertolab.com/api/v1/ext/payment-stops/<stop_id> \
-H "Authorization: Bearer <token>"
El listado admite filtros por status, texto (q), internal_reference exacta, rango de fechas y paginación. Cada parada trae links_active_count: cuántas solicitudes pendientes tiene, sin abrir nada.
El detalle trae links_alive, con cada solicitud y su payment_url.
GET status antes de conciliarlinks_alive describe lo que se le muestra al cliente. Para saber si una solicitud sigue viva, pagada o vencida, consúltala por su sesión — GET /api/v1/ext/payment-sessions/status/{session_id} —, que es la fuente del estado.
Lo que hoy no está disponible
Tres operaciones del contrato todavía no están operativas:
| Operación | Alternativa mientras tanto |
|---|---|
PATCH /payment-stops/{stop_id} — modificar una parada | Bórrala y crea otra. Ojo: la nueva tiene otra stop_url, así que el cliente necesitará el enlace nuevo |
GET /payment-stops/{stop_id}/payment-sessions — histórico | Guarda los session_id que asocias y consúltalos por GET status |
POST /payment-stops/payment-sessions/query — consulta de varias paradas | Recorre listStops y consulta el detalle de las que te interesen |
Consecuencia práctica de la primera: el stop_title y la internal_reference que pongas al crear la parada no se pueden cambiar después. Piénsalos antes.
Probar en el simulador
Cada pago sobre una parada sigue el mismo ciclo de vida y la misma transacción a dos fases que cualquier otro, y dispara los mismos webhooks.
El simulador devuelve la forma de la respuesta —stop_id, stop_url, status…— pero no mantiene el estado de cada parada como sí hace con las sesiones de Botón y Solicitud. Sirve para ver la estructura de los datos y ajustar tu parser; para ejercitar el ciclo completo de una parada, usa el entorno de pruebas.
→ Las formas de recibir un pago · Solicitud de pago · Usar el simulador