Saltar al contenido principal

Botón web

El Botón es la sesión para cuando tu cliente está delante, decidiendo ahora: el enlace solo tiene que durar lo que dure la compra. Creas la sesión, llevas a la persona a su payment_url y confirmas el pago desde tu backend. → Las formas de recibir un pago

¿Primera vez?

Si es tu primer pago, sigue el tutorial paso a paso. Esta guía es la referencia concentrada del Botón.

Botón web: recibir el pago dentro de tu web o appGuion: .docx · .yaml

1. Crea la sesión de Botón

curl -X POST https://sim-productos.abiertolab.com/api/v1/ext/payment-sessions/buttons \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-d '{
"amount_reference": 50,
"currency_reference": "USD",
"identifier_label": "Pedido",
"identifier": "ORD-0001",
"description": "Compra en mi tienda",
"success_url": "https://miapp.com/pago-exitoso",
"failure_url": "https://miapp.com/pago-fallido",
"agreement_id": "<agreement_id>",
"webhook_url": "https://miapp.com/webhooks/spidi"
}'

Campos obligatorios: amount_reference, currency_reference, identifier_label, identifier, description, success_url, failure_url, agreement_id. La respuesta trae data.payment_url y data.session_id; la sesión nace en pending (lo lees con GET status).

Comprueba tu payment_url antes de dárselo a nadie

Ábrelo una vez, con una sesión de prueba, y confirma que muestra el monto que esperas.

Un enlace de pago mal formado no da error: lleva a una pantalla plausible donde le piden datos a tu cliente, y ahí se pierde el pago sin que nadie se entere. Es un minuto de comprobación que se hace una sola vez, al integrar, y evita el fallo más silencioso de todo el ciclo.

2. Lleva a la persona al pago

<a href="<payment_url>" class="btn-spidi">Pagar con SPIDI</a>

Al terminar, SPIDI la redirige a tu success_url (o failure_url).

3. Confirma desde tu backend

No confíes en la redirección

Volver a success_url no garantiza el pago. Confírmalo con GET status o por el webhook. → Success URL: verificar status.

curl https://sim-productos.abiertolab.com/api/v1/ext/payment-sessions/status/<session_id> \
-H "Authorization: Bearer <token>" # -> { "data": { "status": "paid" } }

4. Procesa el aviso (webhook)

Al pagar, llega payment_session.paid a tu webhook_url (firmado). Verifícalo y responde 2xx. → Manejar notificaciones.

paid no es el dinero acreditado

paid confirma el débito (fase 1) — no que el dinero ya está en manos del receptor. La acreditación (fase 2) no cambia el status: te llega por el webhook payment_session.accredited, o la consultas en data.session_payment.receiver_credits, en la misma respuesta del status. → Transacción a dos fases.

Botón para App (móvil)

Si integras desde una app móvil, abres la misma payment_url desde la app: por deeplink al navegador (con retorno a tu app mediante las success_url/failure_url) o dentro de un WebView. La confirmación (consultar status + webhook) es idéntica a la del Botón web.

El retorno a tu app depende de tu plataforma

El esquema de deeplink y el manejo del WebView cambian según el sistema y la versión con la que compiles. Trátalos como detalle de tu app, no del API: compruébalos en tu propio entorno antes de publicar. Lo que no cambia es la confirmación — status más webhook— y eso sí es idéntico al Botón web.

Qué texto poner en el botón

SPIDI recomienda una etiqueta concreta, y viene con su razón:

Pagar con Bs y Cripto Desarrollado por SPIDI (debajo, en pequeño)

Los dos elementos hacen trabajos distintos:

  • "Pagar con Bs y Cripto" dice de entrada las dos cosas que quien paga necesita saber para decidirse: que puede pagar en bolívares, y que también puede en cripto. Nombrar la moneda reduce la fricción de "¿esto cuánto me va a costar?".
  • "Desarrollado por SPIDI" evita que el botón se perciba como un monedero desconocido. Es un respaldo visible, no una marca de agua: quien duda antes de pulsar, duda menos si reconoce quién está detrás.

No es obligatorio y puedes adaptarlo a tu producto. Pero si vas a cambiarlo, conserva las dos ideas —la moneda y el respaldo—, que son las que hacen el trabajo.

Reglas del Botón

  • Vigencia: la eliges tú, con duration_minutes: desde 5 minutos hasta 20 minutos. Ese máximo es el techo y no hay forma de pedir más. Si no envías el campo, la sesión caduca pronto. Ver Límites y reglas de operación.
  • Monto mínimo: 14 VES. Por debajo, la creación devuelve 400.
  • Horario: no se permiten operaciones en las horas cercanas a la medianoche (ventana de corte diario).
  • Monedas de referencia (currency_reference): son cinco, y el contrato las declara como una lista cerrada — USD (dólar BCV), EUR (euro BCV), COP (peso colombiano), USDT y VES (bolívar). Cualquier otro valor te devuelve 400. Cada una tiene su tasa correspondiente.
Si el enlace tiene que viajar hasta otra persona, el Botón no es la pieza

El techo del Botón es 20 minutos, y eso es poco para mandar un enlace por WhatsApp o por correo y esperar a que lo abran. Para eso están las Solicitudes, que llevan su propia fecha de vencimiento y —si lo pides con due_date_reached_behavior: keep_active— pueden seguir siendo pagables después de esa fecha. → Solicitud de pago · Paradas.

Dos detalles que conviene comprobar antes de producción

La ventana de medianoche y las tasas de cada moneda pueden cambiar sin que cambie el contrato: compruébalas contra el entorno real antes de asumirlas. La lista de monedas no — está en el contrato como valores admitidos de currency_reference y se valida en cada petición.

Probar sin pago real

En el simulador, fuerza el desenlace en vez de pagar a mano:

curl -X POST https://sim-productos.abiertolab.com/control/sessions/<session_id>/outcome \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"leg":1,"outcome":"paid"}'

Usar el simulador