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

Construye tu integración paso a paso

De tu primera llamada a la API a los pagos reales: nueve pasos, en orden, con las solicitudes exactas y lo que debes comprobar antes de seguir.

La ruta de un vistazo

Sigue los pasos en orden. Cada uno termina con un punto de control: cuando se cumple, pasa al siguiente. Todo hasta el paso 8 corre con tu clave Test, así que no se mueve dinero real hasta que salgas a producción.

PasoQué hacesListo cuando
1. ClavesGuarda tu clave Test y la URL de la API en tu servidorTu servidor puede leer ambas desde su entorno
2. Primera llamadaLlama a GET /v1/banksRecibes un 200 con la lista de bancos
3. Elige un flujoEscoge el checkout alojado o un método directoSabes qué endpoint crea tus pagos
4. Primer pagoCrea un pago de prueba y complétaloEl GET muestra el pago COMPLETED
5. WebhooksRegistra un endpoint y verifica las firmaspayment.completed llega a tu servidor y pasa la verificación
6. Reintentos segurosAgrega idempotencia y recuperación por referenciaUna solicitud reintentada nunca crea un segundo pago
7. SaldosLee tu saldo y la retención de 24 hPuedes explicar disponible, retenido y reserva
8. PayoutsRetira o paga desde los fondos disponiblesUn payout de prueba se completa y llega payout.completed
9. Salir a producciónSolicita la revisión y luego cambia de claveTu primer pago real se completa

Paso 01

Obtén tus claves y prepara tu entorno

Tu cuenta tiene una clave Live y una Test. Usa la clave Test para todo hasta el paso 9: funciona de inmediato, corre en sandboxes y nunca mueve dinero real. Cópiala desde Portal → Credentials.

.env (solo servidor)bash
API_URL=https://api.pay.vexwallet.co
VEXPAY_API_KEY=vk_test_replace_me
VEXPAY_WEBHOOK_SECRET=whsec_replace_me

Punto de control: tu servidor lee API_URL y VEXPAY_API_KEY desde su entorno. Más detalle: Autenticación.

Paso 02

Haz tu primera llamada

Cada solicitud envía la clave en el encabezado x-api-key. La lista de bancos es una primera llamada segura: solo lee y no necesita configuración.

curlbash
curl "${API_URL}/v1/banks" \
  --header "x-api-key: ${VEXPAY_API_KEY}"
SDK Nodejavascript
import VexPay from '@vexpay/node';

const vexpay = new VexPay(process.env.VEXPAY_API_KEY);
const banks = await vexpay.banks.list();
SDK Pythonpython
import os
from vexpay import VexPay

vexpay = VexPay(os.environ["VEXPAY_API_KEY"])
banks = vexpay.banks.list()

Punto de control: una respuesta 200 con la lista de bancos. Un 401 significa que la clave falta o es incorrecta. Un SDK oficial (Node, Python, PHP, Laravel) te ahorra escribir tú mismo el HTTP, los reintentos y la verificación de webhooks.

Paso 03

Elige cómo pagan tus compradores

Empieza con el checkout alojado salvo que necesites tus propias pantallas de pago: una solicitud te da una página donde el comprador elige bolívares, stablecoins o pesos colombianos, y VEXPay ejecuta cada paso.

OpciónIdeal cuandoSe crea con
Checkout alojado (recomendado)Quieres todos los métodos sin construir una interfaz de pagoPOST /v1/checkout/sessions
Enlaces de pagoVendes sin código (WhatsApp, redes sociales)Portal → Payment links
C2PTu propia pantalla; el comprador autoriza con un token bancarioPOST /v1/payments/c2p/request y luego POST /v1/payments/c2p
Verificación de Pago MóvilEl comprador ya transfirió y te da la referenciaPOST /v1/payments/pago-movil/verify
Tarjeta (VPOS)Pagos con tarjeta en tu propio formulario (aplica alcance PCI)POST /v1/payments/vpos
USDT / USDCDepósitos en stablecoins por clientePOST /v1/crypto/deposit-addresses
Pesos colombianosCompradores en Colombia (Bre-B, Nequi, Daviplata)POST /v1/cop/payments

Punto de control: sabes qué endpoint crea tus pagos. GET /v1/payment-methods te dice qué métodos en bolívares puede ofrecer tu cuenta en este momento.

Paso 04

Crea y completa un pago de prueba

Crea una sesión de checkout para un pedido y envía al comprador a su url (o incrústala con @vexpay/js usando clientSecret). Guarda el id de la sesión con tu pedido.

curlbash
curl --request POST "${API_URL}/v1/checkout/sessions" \
  --header "content-type: application/json" \
  --header "x-api-key: ${VEXPAY_API_KEY}" \
  --data '{
    "amountUsd": 25.00,
    "description": "Pedido #1042",
    "reference": "order-1042",
    "successUrl": "https://shop.example/thanks",
    "cancelUrl": "https://shop.example/cart"
  }'
SDK Nodejavascript
const session = await vexpay.checkout.sessions.create({
  amountUsd: 25,
  description: 'Pedido #1042',
  reference: 'order-1042',
  successUrl: 'https://shop.example/thanks',
  cancelUrl: 'https://shop.example/cart',
});
// Redirige al comprador a session.url
Respuestajson
{
  "id": "cs_4f0c6f1e2b7d4c1a9e3f5a6b7c8d9e0f",
  "object": "checkout.session",
  "status": "open",
  "url": "https://pay.vexwallet.co/pay/cs-9f2a4b7c1d3e",
  "clientSecret": "cs-9f2a4b7c1d3e_secret_k8Jc…",
  "amountUsd": "25.00",
  "reference": "order-1042",
  "livemode": false
}
  1. Abre la url

    En modo prueba la página alojada muestra controles de prueba en lugar de datos bancarios reales: completa C2P con el código de Portal → Sandbox, pulsa Simular pago recibido en Pago Móvil o usa los botones de prueba de la página de USDT.

  2. Revisa el resultado

    GET /v1/checkout/sessions/:id muestra status: "paid" y el paymentId. GET /v1/payments/:id muestra el pago COMPLETED.

Punto de control: la sesión está paid y el pago COMPLETED, todo con livemode: false.

Paso 05

Entrega los pedidos a partir de webhooks firmados

Entrega los pedidos solo desde el servidor: con un webhook payment.completed verificado (o un GET que muestre el pago completado). Las redirecciones del navegador y los eventos de @vexpay/js son indicios, nunca una prueba.

Registrar (curl)bash
curl --request POST "${API_URL}/v1/webhooks" \
  --header "content-type: application/json" \
  --header "x-api-key: ${VEXPAY_API_KEY}" \
  --data '{
    "url": "https://shop.example/webhooks/vexpay",
    "events": ["payment.completed", "payment.failed", "payment.reversed", "payout.completed", "payout.failed"]
  }'
Verificar (Node)javascript
app.post('/webhooks/vexpay', express.raw({ type: 'application/json' }), async (req, res) => {
  const event = vexpay.webhooks.constructEvent(
    req.body, // bytes crudos, no JSON parseado
    req.headers['vexpay-signature'],
    process.env.VEXPAY_WEBHOOK_SECRET,
  );
  if (event.event === 'payment.completed') {
    // Pagos de checkout: identifica tu pedido con data.checkoutSession.reference
    await markOrderPaid(event.data.checkoutSession?.reference, event.data.paymentId);
  }
  res.sendStatus(200);
});
  • Guarda el secret de la respuesta de creación: nunca se vuelve a mostrar.
  • Deduplica con el encabezado VexPay-Event-Id: el mismo evento puede llegarte más de una vez.
  • Cada evento se envía una vez, sin reintento automático, y tu endpoint tiene 10 segundos. Encola el trabajo y responde 200 rápido; el paso 6 cubre lo que se te escape.
  • Usa POST /v1/notifications/test para enviarte una entrega de prueba.

Punto de control: un pago de prueba produce un payment.completed que pasa la verificación de firma y marca el pedido como pagado exactamente una vez. Más detalle: Webhooks.

Paso 06

Haz seguros los reintentos y recupera lo que se te escapó

  1. Envía Idempotency-Key en cada POST

    Usa el id de tu pedido. La misma clave y el mismo body dentro de 24 h repiten la primera respuesta (Idempotent-Replayed: true) en vez de crear un segundo pago. Los SDKs envían una automáticamente.

  2. Guarda los ids que recibes

    Guarda el id de la sesión, el paymentId y el payoutId con tu pedido. En payouts y comerciantes, externalRef es en sí la clave de idempotencia.

  3. Recupera por referencia

    Si una respuesta o un webhook nunca llegó, consulta el pago: GET /v1/payments/by-ref/:externalRef o GET /v1/checkout/sessions/:id. Decide según su estado, nunca por un timeout.

  4. Corre un job de conciliación

    Una vez al día (o cada hora), recorre GET /v1/balance/transactions y compara cada movimiento con tu contabilidad. La suma siempre es igual al total de tu ledger, así que nada puede esconderse.

Punto de control: repetir dos veces la misma solicitud de creación da el mismo pago, y un webhook perdido se detecta con la consulta o el job de conciliación. Más detalle: Idempotencia, Concilia tu saldo.

Paso 07

Lee tu saldo y la retención de 24 h

Cada pago completado llega a tu saldo, pero queda retenido 24 horas antes de que puedas enviarlo en un payout. GET /v1/balance muestra ambas partes y cuándo se libera el siguiente monto retenido.

GET /v1/balance (extracto)json
{
  "ledgerNetVes": "7342.50",
  "reserveVes": "0.00",
  "heldVes": "4342.50",
  "nextReleaseAt": "2026-10-20T00:48:52.784Z",
  "availableVes": "3000.00",
  "balanceHoldHours": 24
}

availableVes = ledgerNetVes − reserveVes − heldVes. Solo availableVes se puede enviar en un payout. Lo mismo aplica a USDT (held, heldUsdt) y a los pesos (heldCop). Punto de control: después de un pago de prueba puedes señalar el monto retenido y su hora de liberación. Explicación completa: Saldos, retenciones y payouts.

Paso 08

Envía payouts

A dónde va el dineroEndpointAntes del primer payout
Tu propia cuenta bancaria (Bs)POST /v1/payouts/instantGuarda y verifica tu cuenta de payouts (dos microdepósitos)
Un vendedor o proveedor (Bs)POST /v1/payoutsRegistra al comerciante y verifica su destino Pago Móvil
Una wallet cripto (USDT / USDC)POST /v1/crypto/payoutsTen saldo en USDT o USDC
Retira a tu cuenta (curl)bash
curl --request POST "${API_URL}/v1/payouts/instant" \
  --header "content-type: application/json" \
  --header "x-api-key: ${VEXPAY_API_KEY}" \
  --data '{ "monto": "1000.00", "concepto": "Retiro", "externalRef": "withdraw-2026-10-19" }'

Punto de control: un payout de prueba se completa y payout.completed llega a tu endpoint. Más detalle: Comerciantes y payouts, USDT y USDC.

Paso 09

Sal a producción

  • Los pasos 4–8 se cumplen con la clave Test, incluida al menos una entrega de webhook (Portal → Webhooks la muestra).
  • Tu perfil de negocio y el contacto del dueño están completos en el portal.
  • Manejas payment.failed, payment.reversed y payout.failed, no solo el camino feliz.
  • Tu job de conciliación corre y te alerta cuando los totales no coinciden.
  1. Solicita salir a producción

    Pulsa Request go-live en el portal. El equipo de VEX Pay revisa tu cuenta; mientras tanto las claves Live responden 403 live_mode_not_activated.

  2. Registra los webhooks Live

    Los endpoints de webhook pertenecen a cada clave: registra tu URL de producción con la clave Live y guarda su nuevo secreto.

  3. Cambia de clave

    Cuando recibas tenant.live_status_changed, crea una clave Live en el portal y despliégala. Haz un pago real pequeño y síguelo hasta tu saldo.