Guía para desarrolladores
Sitio de VEXPayReferencia de API
Explorar documentación

Débito automático con domiciliación

Tu cliente autoriza una sola vez y cada factura se debita de su cuenta bancaria en bolívares a la tasa del día. Sin perseguir enlaces ni pagos manuales.

Cómo funciona

La domiciliación es una autorización permanente que el cliente le da a su banco para pagarte. Con collectionMethod: "charge_automatically", VEX Pay debita cada factura de la cuenta bancaria del cliente en bolívares, a la tasa vigente de tu cuenta (BCV o mercado) en el momento del débito, sin que el cliente tenga que hacer nada. Los precios siguen en dólares.

  1. Envía el enlace de autorización

    Crea una sesión de autorización para el cliente y envíale su url (por WhatsApp, por correo o redirigiéndolo desde tu app).

  2. El cliente autoriza

    En la página “Domiciliación bancaria” confirma su nombre, cédula/RIF, teléfono y banco, y acepta el texto de autorización. VEX Pay envía la solicitud a su banco y registra un método de pago en estado pending.

  3. El cliente la acepta en su banca en línea

    El último paso ocurre en su banco: entra a su banca en línea y acepta la solicitud de domiciliación. La página se lo indica. Una vez aceptada queda activa de inmediato y no vence: sigue vigente hasta que el cliente la cancele en su banco.

  4. Suscríbelo con débito automático

    Crea la suscripción con charge_automatically. Cada factura se debita en sus intentos de cobro; el primer débito aceptado deja el método de pago en active.

Paso 01

Crea el enlace de autorización

curlbash
curl --request POST "${API_URL}/v1/setup-sessions" \
  --header "content-type: application/json" \
  --header "x-api-key: ${VEXPAY_API_KEY}" \
  --data '{
    "customer": "cus_…",
    "successUrl": "https://example.com/cuenta/listo"
  }'
Node SDKjavascript
const session = await vexpay.setupSessions.create({
  customer: 'cus_…',
  successUrl: 'https://example.com/cuenta/listo',
});
// Envía session.url al cliente ya: solo viene en esta respuesta.
Python SDKpython
session = vexpay.setup_sessions.create({
    "customer": "cus_…",
    "successUrl": "https://example.com/cuenta/listo",
})
PHP SDKphp
$session = $vexpay->setupSessions->create([
    'customer' => 'cus_…',
    'successUrl' => 'https://example.com/cuenta/listo',
]);
Respuestajson
{
  "id": "seti_3fd84b2d9ad14f74a2d90f2f56984db5",
  "object": "setup_session",
  "url": "https://pay.vexwallet.co/billing/setup/7c1e…",
  "customer": "cus_…",
  "status": "open",
  "paymentMethod": null,
  "successUrl": "https://example.com/cuenta/listo",
  "expiresAt": "2026-10-22T14:00:00.000Z",
  "createdAt": "2026-10-21T14:00:00.000Z",
  "livemode": false
}
  • La url vale por 24 horas y una sola vez, y solo viene en esta respuesta: envíala de inmediato. GET /v1/setup-sessions/:id devuelve la sesión sin ella.
  • status es open, complete (autorizada; trae paymentMethod) o expired. Si venció, crea una nueva. Solo vence el enlace: la domiciliación que el cliente autoriza con él no vence.
  • Guarda primero phone, idNumber y bankCode en el cliente y la página llegará prellenada.
  • successUrl (https) agrega un botón “Volver a <tu negocio>” cuando el cliente termina.

Paso 02

Lo que ve el cliente

Una página a tu nombre, titulada Domiciliación bancaria, con: nombre del titular, cédula o RIF, el teléfono asociado a su cuenta, su banco y esta autorización, que debe marcar:

Al pulsar Autorizar domiciliación, la página muestra Solicitud enviada y le recuerda aceptar la solicitud en su banca en línea. VEX Pay guarda el texto aceptado, la hora, la IP y el navegador como constancia del consentimiento. Si el banco rechaza la solicitud, la página indica qué dato revisar (por ejemplo, la cédula) y el cliente puede intentarlo de nuevo.

Recibes payment_method.attached con un pm_… en estado pending. Lista los métodos de un cliente con GET /v1/customers/:id/payment-methods.

Paso 03

Suscríbelo con débito automático

curlbash
curl --request POST "${API_URL}/v1/subscriptions" \
  --header "content-type: application/json" \
  --header "x-api-key: ${VEXPAY_API_KEY}" \
  --data '{
    "customer": "cus_…",
    "price": "price_…",
    "collectionMethod": "charge_automatically"
  }'
Node SDKjavascript
const subscription = await vexpay.subscriptions.create({
  customer: 'cus_…',
  price: 'price_…',
  collectionMethod: 'charge_automatically',
});
Python SDKpython
subscription = vexpay.subscriptions.create({
    "customer": "cus_…",
    "price": "price_…",
    "collectionMethod": "charge_automatically",
})
PHP SDKphp
$subscription = $vexpay->subscriptions->create([
    'customer' => 'cus_…',
    'price' => 'price_…',
    'collectionMethod' => 'charge_automatically',
]);
  • Sin paymentMethod, la suscripción usa el método autorizado más reciente del cliente que no esté inactivo. Si no tiene ninguno, responde 400 payment_method_required.
  • El correo es opcional con débito automático, pero recomendado: por ahí el cliente recibe los avisos de cobro, los recibos y, si un débito falla, la factura para pagarla a mano.
  • Para cambiar una suscripción existente usa POST /v1/subscriptions/:id con { "collectionMethod": "charge_automatically" }; aplica desde la próxima factura.
  • El precio debe caber en el límite por cobro a la tasa de hoy (ver más abajo); si no, crear o cambiar la suscripción responde 400 amount_exceeds_limit.

Cada débito

  • 3 días antes de una renovación el cliente recibe el Aviso de cobro, con el monto en dólares y un estimado en Bs a la tasa de hoy.
  • En cada intento de cobro el monto en Bs se calcula con la tasa vigente de tu cuenta (BCV o mercado) y se debita con el concepto “Factura <número>”. Como sigue la tasa, el monto puede variar de un período a otro.
  • El banco suele confirmar el débito en pocos minutos. Si se acepta, la factura queda pagada, el método de pago pasa a active y el recibo muestra los Bs debitados y la tasa. Cuando el débito sale bien no se envía el correo de la factura.
  • Por factura solo hay un débito en curso a la vez: mientras uno está pendiente, los intentos siguientes lo esperan.
  • El dinero entra a tu saldo como cualquier otro cobro en bolívares, con tu tarifa de cobros en bolívares más la comisión de facturación (ver Suscripciones y facturación).

Límite por cobro: Bs 1.500.000

Un débito automático puede ser de Bs 1.500.000 como máximo. Como los precios están en dólares, la validación usa la tasa vigente de tu cuenta:

  • Al crear o cambiar la suscripción. Crear una suscripción charge_automatically, o pasar una a esa forma de cobro, con un precio que ya supera Bs 1.500.000 a la tasa de hoy responde 400 amount_exceeds_limit. El mensaje indica el máximo aproximado en USD a la tasa de hoy. No se crea ni se cambia nada; usa send_invoice para ese precio.
  • Al momento del cobro. Si la tasa se mueve y una factura termina por encima del límite, no se envía el débito. Recibes invoice.payment_failed con failureCode: "amount_exceeds_limit" (y paymentId: null), el cliente recibe la factura por correo para pagarla en su página, y los intentos restantes de esa factura envían recordatorios en lugar de débitos.

Cuando un débito falla

Recibes invoice.payment_failed con un failureCode. La primera vez, además, se le envía la factura al cliente por correo para que pueda pagarla de otra forma. El siguiente intento diario vuelve a debitar, salvo que el método esté inactivo.

failureCodeSignificadoQué pasa después
affiliation_pendingEl cliente todavía no aceptó la domiciliación en su banca en líneaSe reintenta en el próximo intento; pídele al cliente que la acepte
insufficient_fundsSaldo insuficienteSe reintenta en el próximo intento
payment_method_inactiveEl cliente canceló la domiciliación en su banco, o el banco la suspendióEl método pasa a inactive (payment_method.updated) y no se vuelve a debitar; los intentos siguientes envían la factura por correo. Envía un enlace de autorización nuevo
amount_exceeds_limitEl monto en Bs supera Bs 1.500.000 a la tasa vigente (no se envió ningún débito)No se debita esta factura; se envía por correo y los intentos siguientes mandan recordatorios
otroEl banco rechazó el débito; failureMessage trae el motivo en españolSe reintenta en el próximo intento

Si fallan todos los intentos, la suscripción se cancela por falta de pago como cualquier otra, y pagar su factura después la reactiva. Ver Suscripciones y facturación.

Administra los métodos de pago

EstadoSignificado
pendingAutorizado en la página; aún sin débitos aceptados
activeSe aceptó al menos un débito
inactiveEl banco reportó la autorización inactiva; no se vuelve a debitar
  • GET /v1/payment-methods/:id devuelve un método; muestra phoneLast4 y bankCode, nunca el teléfono ni la cédula completos.
  • DELETE /v1/payment-methods/:id lo desvincula: no se vuelve a debitar (payment_method.detached). Las suscripciones que lo usaban mantienen charge_automatically y sus facturas se envían por correo hasta que asignes otro método con POST /v1/subscriptions/:id y paymentMethod.
  • Una domiciliación no vence. El cliente puede cancelarla cuando quiera desde su banca en línea; el banco no avisa de la cancelación, así que te enteras en el siguiente débito: falla con payment_method_inactive, el método pasa a inactive y recibes payment_method.updated.

Modo de prueba

Con tu clave de prueba no se contacta a ningún banco y no hace falta habilitar nada: las sesiones de autorización y charge_automatically siempre funcionan, la autorización siempre se aprueba y cada débito se resuelve al instante. La página de autorización muestra “Modo de prueba”. Los últimos 4 dígitos del teléfono que el cliente escribe en la página de autorización eligen el resultado de cada débito:

El teléfono termina enResultado
0001affiliation_pending (aún no aceptada)
0002insufficient_funds
0003payment_method_inactive
cualquier otroAceptado: la factura queda pagada

Combina una terminación con un precio de prueba diario ("interval": "day") para ver fallos, reintentos y la cancelación en pocos días. En modo de prueba los correos solo llegan al correo de tu perfil de negocio.