Guardar un método de pago para cobros futuros
Guarda un método de pago y realiza cobros sin intervención del cliente utilizando SetupIntent.
Un SetupIntent te permite inscribir el método de pago de un cliente sin realizar ningún cobro en ese momento. El cliente registra su tarjeta una sola vez en una página segura de Venti, y esta queda guardada y autorizada (con su mandato) para que puedas cobrarle después: cargos iniciados por ti, suscripciones o cobros recurrentes.
Casos de uso típicos:
- Guardar la tarjeta al crear la cuenta y cobrar al final del período (post-pago).
- Inscribir el método de pago antes de iniciar una suscripción.
- Actualizar la tarjeta de un cliente existente sin interrumpir sus cobros.
- Marketplaces o servicios con cobros variables iniciados por el comercio.
Esta guía cubre el flujo de integración completo. Los detalles de cada endpoint (parámetros, filtros, paginación) están en la referencia de API, sección Setup Intents.
Cómo funciona
El flujo tiene cuatro pasos:
- Creas un
SetupIntentdesde tu backend, asociado a un cliente. - Diriges al cliente a la URL que devuelve el objeto (redirección o iframe). Ahí el cliente ingresa su tarjeta en una página alojada por Venti — los datos de la tarjeta nunca pasan por tus servidores.
- Recibes la confirmación vía webhook (o consultando el estado del Setup Intent).
- Usas el método de pago inscrito para cobrar cuando corresponda.
Cada SetupIntent es de un solo uso y expira a las 24 horas de creado si el cliente no completa la inscripción.
Paso 1 — Crear el SetupIntent
Crea el SetupIntent desde tu backend con tu llave secreta. Debes identificar al cliente con customer_id (un cliente existente) o con customer_email (si no existe un cliente con ese email, se creará automáticamente).
curl -X POST https://api.ventipay.com/v1/setup_intents \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"customer_email": "[email protected]",
"notification_url": "https://tusitio.com/webhooks/venti",
"notification_events": ["setup_intent.succeeded"],
"metadata": { "referencia_interna": "usuario-8214" }
}'La respuesta incluye la URL a la que debes dirigir al cliente:
{
"id": "si_xxxxxxxxxxxxxxxxxxxx",
"object": "setup_intent",
"status": "pending",
"customer_id": "cus_xxxxxxxxxxxxxxxxxxxx",
"url": "https://pay.ventipay.com/setup/si_xxxxxxxxxxxxxxxxxxxx",
"valid_until": "2026-07-14T13:00:00.000Z",
"payment_method_id": null,
"live": true,
"metadata": { "referencia_interna": "usuario-8214" }
}Campos útiles al crear:
| Campo | Descripción |
|---|---|
customer_id | ID de un Customer existente. Obligatorio si no envías customer_email. |
customer_email | Email del cliente. Si no existe, se crea el Customer automáticamente. Obligatorio si no envías customer_id. |
payment_method_types | Arreglo opcional para restringir los tipos de método de pago que el cliente puede inscribir. Si lo envías, la url devuelta ya viene con el filtro aplicado. |
notification_url | URL donde recibirás los webhooks de este Setup Intent. Opcional si ya tienes webhooks configurados a nivel de cuenta. |
notification_events | Eventos que quieres recibir en notification_url (por ejemplo ["setup_intent.succeeded"]). |
metadata | Pares llave-valor para correlacionar con tu sistema. |
Guarda el
iddel Setup Intent junto a tu referencia interna (o usametadata). Lo necesitarás para conciliar el webhook con tu usuario.
Paso 2 — Dirigir al cliente a la URL
Tienes dos opciones de integración.
Opción A: Redirección (la más simple)
Redirige al cliente a la url del SetupIntent. Verá una página de Venti donde ingresa su tarjeta; al finalizar, la página muestra la confirmación. Tu backend se entera del resultado por webhook (Paso 3).
Opción B: Embebido en un iframe
Puedes embeber la página dentro de tu propio sitio:
<iframe
src="https://pay.ventipay.com/setup/si_xxxxxxxxxxxxxxxxxxxx"
style="width: 100%; height: 480px; border: none;"
></iframe>La página notifica el resultado a la ventana padre mediante postMessage, para que tu frontend reaccione sin recargar:
window.addEventListener('message', (event) => {
if (event.data.event === 'payment_method.attached') {
// Inscripción exitosa. event.data.data.payment_method contiene el método inscrito.
}
if (event.data.event === 'payment_method.attachment_error') {
// La inscripción falló. Puedes mostrar un mensaje y permitir reintentar.
}
});El
postMessagees una señal para tu interfaz (mostrar éxito, cerrar el iframe). La fuente de verdad para tu backend debe ser siempre el webhook o la consulta del SetupIntent — nunca confíes solo en un evento del navegador para habilitar cobros.
La página embebida acepta parámetros por query string para ajustarla a tu sitio, entre ellos cta_label (texto del botón principal). Por ejemplo:
https://pay.ventipay.com/setup/si_xxxxxxxxxx?cta_label=Guardar%20tarjeta
Paso 3 — Confirmar la inscripción
Cuando el cliente completa la inscripción, el SetupIntent pasa a succeeded y queda vinculado al método de pago creado (payment_method_id). Hay dos formas de enterarte:
Webhook (recomendado)
Recibirás un evento setup_intent.succeeded en tu notification_url (o en tus webhooks de cuenta). El evento incluye el SetupIntent con el customer y el payment_method expandidos:
{
"id": "evt_xxxxxxxxxxxxxxxxxxxx",
"object": "event",
"type": "setup_intent.succeeded",
"related_object": "setup_intent",
"related_id": "si_xxxxxxxxxxxxxxxxxxxx",
"live": true,
"data": {
"id": "si_xxxxxxxxxxxxxxxxxxxx",
"status": "succeeded",
"customer_id": "cus_xxxxxxxxxxxxxxxxxxxx",
"payment_method_id": "pm_xxxxxxxxxxxxxxxxxxxx",
"metadata": { "referencia_interna": "usuario-8214" },
"customer": { "...": "..." },
"payment_method": { "...": "..." }
}
}Guarda el payment_method_id (y/o el customer_id) en tu sistema: es lo que usarás para cobrar.
Consulta directa (polling)
También puedes consultar el estado en cualquier momento:
curl https://api.ventipay.com/v1/setup_intents/si_xxxxxxxxxxxxxxxxxxxx \
-H "Authorization: Bearer sk_live_..."Cuando status sea succeeded, el campo payment_method_id tendrá el método inscrito.
Estados posibles
| Estado | Significado |
|---|---|
pending | Creado, esperando que el cliente inscriba su método de pago. |
succeeded | Inscripción completada. payment_method_id queda asignado. Estado final. |
canceled | Cancelado por ti antes de completarse. Estado final. |
expired | Pasaron 24 horas sin completarse. Estado final. |
Los eventos de webhook asociados son setup_intent.created, setup_intent.succeeded y setup_intent.expired (este último se emite tanto cuando el Setup Intent expira como cuando lo cancelas).
Si el Setup Intent expiró o fue cancelado, simplemente crea uno nuevo — son de un solo uso.
Paso 4 — Cobrar con el método de pago inscrito
El método de pago queda guardado con mandato, es decir, con la autorización del cliente para cobros iniciados por el comercio. Para realizar un cobro, crea un pago y autorízalo con el payment_method_id inscrito:
# 1. Crear el pago
curl -X POST https://api.ventipay.com/v1/payments \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"amount": 15990,
"currency": "clp",
"customer_id": "cus_xxxxxxxxxxxxxxxxxxxx",
"description": "Plan mensual julio"
}'
# 2. Autorizarlo con el método de pago inscrito
curl -X POST https://api.ventipay.com/v1/payments/pay_xxxxxxxxxx/authorize \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"payment_method_id": "pm_xxxxxxxxxxxxxxxxxxxx"
}'El pago se crea en estado requires_authorization; al autorizarlo con el método inscrito, se ejecuta el cobro. Consulta la referencia de Payments para el detalle de captura, reembolsos y estados.
Además:
- Los métodos inscritos de un cliente se pueden listar con
GET /v1/customers/{id}/payment_methods. - Los mandatos asociados se pueden consultar en la sección Mandates de la referencia.
- Si usas Subscriptions, el método inscrito queda disponible para los cobros recurrentes del cliente.
Cancelar un SetupIntent
Si ya no necesitas que el cliente complete la inscripción (por ejemplo, canceló el registro en tu sitio), cancela el SetupIntent para invalidar su URL de inmediato:
curl -X POST https://api.ventipay.com/v1/setup_intents/si_xxxxxxxxxxxxxxxxxxxx/cancel \
-H "Authorization: Bearer sk_live_..."Solo se pueden cancelar SetupIntent en estado pending.
Updated about 6 hours ago

