Skip to navigation

Guardar y reutilizar métodos de pago

Usa este flujo cuando necesitas guardar la tarjeta de un cliente y cobrarla después sin que vuelva a ingresar sus datos. Es útil para cobros mensuales de monto variable, cargos por consumo, cargos adicionales a una suscripción o renovaciones administradas por tu sistema.

El cliente siempre ingresa la tarjeta en un checkout alojado por Recurrente. Tu sistema guarda únicamente el payment_method_id retornado por Recurrente y lo usa para crear cobros futuros.

Antes de guardar una tarjeta, asegúrate de que el cliente acepte términos claros sobre cómo se harán los cobros futuros: frecuencia, cómo se calcula el monto, cuándo se cobra y cómo puede cancelar o actualizar su método de pago.

Flujo general

  1. Crea o identifica el cliente en Recurrente.
  2. Crea un checkout con mode: "setup" para tokenizar la tarjeta sin cobrarla.
  3. Envía el checkout_url al cliente.
  4. Cuando el cliente completa el checkout, guarda el payment_method.id.
  5. Usa POST /api/one_time_payments para cobrar ese método guardado cuando tengas el monto final.

Paso 1: Crear o identificar el cliente

Si ya tienes un cliente en Recurrente, usa su customer_id al crear el checkout de tokenización. Si solo tienes el user_id, también puedes enviarlo.

curl -X POST https://app.recurrente.com/api/customers \
-H "X-SECRET-KEY: tu_llave_secreta" \
-H "Content-Type: application/json" \
-d '{
"email": "cliente@example.com",
"full_name": "Ana Lopez"
}'

La respuesta incluye el id del cliente:

{
"id": "cus_abc123",
"user_id": "us_123456",
"email": "cliente@example.com",
"name": "Ana Lopez"
}

Paso 2: Crear un checkout de tokenización

Crea un checkout con mode: "setup". Este checkout no cobra nada; solo guarda la tarjeta para usos futuros.

Al guardar una tarjeta nueva, Recurrente verifica la cuenta con una autorización de monto cero, sin capturar dinero. Una autorización aprobada con un token permanente genera setup_intent.succeeded; un rechazo o una verificación fallida genera setup_intent.cancelled y la tarjeta no queda habilitada para cobros. Guardar la tarjeta no garantiza que los cobros futuros sean aprobados ni sustituye la autenticación que pueda necesitar un pago posterior.

curl -X POST https://app.recurrente.com/api/checkouts \
-H "X-SECRET-KEY: tu_llave_secreta" \
-H "Content-Type: application/json" \
-d '{
"mode": "setup",
"customer_id": "cus_abc123",
"success_url": "https://tusitio.com/metodo-guardado",
"cancel_url": "https://tusitio.com/metodo-cancelado",
"metadata": {
"billing_agreement_id": "ba_789"
}
}'

Recurrente responde con una URL alojada:

{
"id": "ch_eegw9j5zgqoae3ms",
"checkout_url": "https://app.recurrente.com/checkout-session/ch_eegw9j5zgqoae3ms"
}

Redirige al cliente a checkout_url o envíasela por email, WhatsApp o dentro de tu app.

Paso 3: Guardar el payment_method_id

Cuando el cliente completa el checkout, Recurrente emite setup_intent.succeeded. El método guardado viene dentro de data.checkout.payment_method.

{
"eventType": "setup_intent.succeeded",
"eventId": "act_123",
"data": {
"event_type": "setup_intent.succeeded",
"status": "succeeded",
"checkout": {
"id": "ch_eegw9j5zgqoae3ms",
"status": "paid",
"payment_method": {
"id": "pay_m_7v5ie3pw",
"type": "card",
"card": {
"last4": "4242",
"network": "visa"
}
}
},
"customer": {
"id": "cus_abc123",
"email": "cliente@example.com"
}
}
}

Guarda data.checkout.payment_method.id. Ese es el token que usarás para cobros futuros.

Si no recibes webhooks, consulta el checkout después de que el cliente vuelva a tu success_url: GET /api/checkouts/{id}. Cuando el checkout está completado, la respuesta incluye payment_method.id.

curl https://app.recurrente.com/api/checkouts/ch_eegw9j5zgqoae3ms \
-H "X-SECRET-KEY: tu_llave_secreta"
{
"id": "ch_eegw9j5zgqoae3ms",
"status": "paid",
"payment_method": {
"id": "pay_m_7v5ie3pw",
"type": "card",
"card": {
"last4": "4242",
"network": "visa"
}
}
}

Paso 4: Cobrar después con un monto variable

Cuando tu sistema sabe el monto a cobrar, crea un pago único con el payment_method_id guardado. Usa una llave de idempotencia única por intento de cobro para evitar duplicados si necesitas reintentar la solicitud.

curl -X POST https://app.recurrente.com/api/one_time_payments \
-H "X-SECRET-KEY: tu_llave_secreta" \
-H "Idempotency-Key: invoice-2026-06-cus-abc123" \
-H "Content-Type: application/json" \
-d '{
"payment_method_id": "pay_m_7v5ie3pw",
"items": [
{
"name": "Consumo de junio",
"amount_in_cents": 87500,
"currency": "GTQ",
"quantity": 1
}
]
}'

Respuesta exitosa:

{
"object": "one_time_payment",
"id": "on_123456789",
"status": "paid"
}

Si el banco rechaza el cobro, Recurrente responde con error y no debes reusar la misma Idempotency-Key para un nuevo intento de cobro. Crea un intento nuevo con una llave distinta cuando el cliente confirme que desea reintentar o actualice su método de pago.

Cobros variables asociados a una suscripción

Si el cliente ya tiene una suscripción y quieres agregar cargos variables, tienes dos opciones.

Para cobrar inmediatamente el método guardado de la suscripción:

curl -X POST https://app.recurrente.com/api/one_time_payments \
-H "X-SECRET-KEY: tu_llave_secreta" \
-H "Idempotency-Key: su-nehndm7j-extra-junio" \
-H "Content-Type: application/json" \
-d '{
"subscription_id": "su_nehndm7j",
"amount_in_cents": 5000,
"description": "Cargo por consumo adicional",
"mode": "now"
}'

Para agregar el cargo al próximo ciclo de la suscripción:

curl -X POST https://app.recurrente.com/api/one_time_payments \
-H "X-SECRET-KEY: tu_llave_secreta" \
-H "Content-Type: application/json" \
-d '{
"subscription_id": "su_nehndm7j",
"amount_in_cents": 5000,
"description": "Cargo por consumo adicional",
"mode": "next_cycle"
}'

mode: "next_cycle" crea un invoice_item pendiente. También admite montos negativos para créditos.

Actualizar la tarjeta guardada

Cuando el cliente necesite cambiar tarjeta, crea otro checkout mode: "setup". Al completarlo, guarda el nuevo payment_method.id.

Si el método pertenece a una suscripción, actualízala con:

curl -X PUT https://app.recurrente.com/api/subscriptions/su_nehndm7j \
-H "X-SECRET-KEY: tu_llave_secreta" \
-H "Content-Type: application/json" \
-d '{
"payment_method_id": "pay_m_nueva123"
}'

Si solo usas cobros variables con POST /api/one_time_payments, guarda el nuevo payment_method_id en tu sistema y úsalo para los siguientes cobros.

Consideraciones

  • POST /api/one_time_payments requiere que tu cuenta tenga cobros únicos habilitados.
  • El payment_method_id debe pertenecer a un cliente de tu cuenta.
  • Los cobros futuros pueden fallar aunque la tokenización haya sido exitosa. Maneja errores de banco y permite que el cliente actualice su tarjeta.
  • Los webhooks reales solo se envían para eventos de producción. Para validar el flujo completo de tokenización, usa una llave LIVE; el checkout de setup no cobra un monto.
  • Nunca recolectes ni almacenes números de tarjeta directamente. Usa siempre el checkout alojado de Recurrente.