Guía para desarrolladores
Referencia de API
Explorar documentación

Verifica comerciantes y envía payouts

Registra comerciantes con uno o más métodos Pago Móvil, confirma microdepósitos por método y paga destinos verificados con montos VES exactos e idempotencia por ítem.

Tres reglas de oro

  • Los montos de payout siempre son strings explícitos del tenant con exactamente dos decimales — el gateway nunca calcula ni convierte FX para payouts.
  • La idempotencia se aplica por externalRef a nivel de ítem ANTES de tocar el banco.
  • Todo CreditoInmediato AC00 se reconcilia con el mismo poll de ConsultarOperaciones que ya usa débito inmediato.

Reglas de externalRef

Tú siempre eliges externalRef. La API nunca genera uno. Envía tu propio id estable (id de usuario, liquidación, número de pedido) para poder consultar los registros después.

ReglaDetalle
ObligatorioRequerido en POST /v1/merchants, POST /v1/payouts y en cada ítem de POST /v1/payouts/batch.
Longitud1–64 caracteres tras trim.
AlcanceÚnico por tenant. El mismo string puede existir bajo otro tenant.
PropiedadSolo lo envía el cliente. Generate en el portal es una ayuda de UI para pruebas manuales; las integraciones de producción deben enviar su propio valor en el JSON.
Replay (mismo payload)Devuelve el comerciante o payout existente (200) y no vuelve a tocar el banco.
Conflicto (payload distinto)Devuelve 409 external_ref_conflict — salvo que el comerciante no tenga métodos de payout (p. ej. tras limpieza por BE01 o un alta sin método); entonces POST /v1/merchants con bankCode+phone adjunta un método nuevo (200), o sin ellos actualiza la identidad del shell (200).
RecuperaciónGET /v1/merchants?externalRef=…, GET /v1/merchants/:id, GET /v1/payouts/by-ref/:externalRef, GET /v1/payouts/:id

Verificación de comerciante

PasoEndpoint
1. AltaPOST /v1/merchants (bankCode + phone opcionales crean el primer método; omite ambos para un comerciante sin método)
2. Agregar otro método (opcional)POST /v1/merchants/:id/payout-methods
3. Disparar microabonosPOST /v1/merchants/:id/payout-methods/:methodId/verify/start
4. Confirmar montosPOST /v1/merchants/:id/payout-methods/:methodId/verify
5. Listar métodosGET /v1/merchants/:id/payout-methods
6. Marcar método por defectoPOST /v1/merchants/:id/payout-methods/:methodId/default
7. Eliminar un métodoDELETE /v1/merchants/:id/payout-methods/:methodId
8. EstadoGET /v1/merchants/:id o GET /v1/merchants?externalRef=…
9. Listar listos para pagarGET /v1/merchants?status=verified&isActive=true&limit=25
10. Desactivar / reactivarPATCH /v1/merchants/:id `{ "isActive": false|true }`
11. Borrar (sin payouts)DELETE /v1/merchants/:id — 409 merchant_has_payouts si hay historial
Altabash
curl --request POST "${API_URL}/v1/merchants" \
  --header "content-type: application/json" \
  --header "x-api-key: ${VEXPAY_API_KEY}" \
  --data '{
    "externalRef": "usr_7f3a",
    "name": "Maria Perez",
    "identification": "V12345678",
    "contactEmail": "maria@mail.com",
    "contactPhone": "04141234567",
    "bankCode": "0134",
    "phone": "04145555555"
  }'
Alta (sin método)bash
curl --request POST "${API_URL}/v1/merchants" \
  --header "content-type: application/json" \
  --header "x-api-key: ${VEXPAY_API_KEY}" \
  --data '{
    "externalRef": "usr_7f3a",
    "name": "Maria Perez",
    "identification": "V12345678",
    "contactEmail": "maria@mail.com",
    "contactPhone": "04141234567"
  }'
# → payoutMethods: [], message: "No payout method exists…"
Listar / agregar métodosbash
curl "${API_URL}/v1/merchants/MERCHANT_ID/payout-methods" \
  --header "x-api-key: ${VEXPAY_API_KEY}"

curl --request POST "${API_URL}/v1/merchants/MERCHANT_ID/payout-methods" \
  --header "content-type: application/json" \
  --header "x-api-key: ${VEXPAY_API_KEY}" \
  --data '{
    "bankCode": "0105",
    "phone": "04141234567"
  }'
Verificar métodobash
curl --request POST "${API_URL}/v1/merchants/MERCHANT_ID/payout-methods/METHOD_ID/verify/start" \
  --header "x-api-key: ${VEXPAY_API_KEY}"

curl --request POST "${API_URL}/v1/merchants/MERCHANT_ID/payout-methods/METHOD_ID/verify" \
  --header "content-type: application/json" \
  --header "x-api-key: ${VEXPAY_API_KEY}" \
  --data '{ "amount1": "0.37", "amount2": "0.82" }'
Default / eliminarbash
curl --request POST "${API_URL}/v1/merchants/MERCHANT_ID/payout-methods/METHOD_ID/default" \
  --header "x-api-key: ${VEXPAY_API_KEY}"

curl --request DELETE "${API_URL}/v1/merchants/MERCHANT_ID/payout-methods/METHOD_ID" \
  --header "x-api-key: ${VEXPAY_API_KEY}"
Listar / estadobash
curl "${API_URL}/v1/merchants?status=verified&isActive=true&limit=25" \
  --header "x-api-key: ${VEXPAY_API_KEY}"

curl "${API_URL}/v1/merchants?externalRef=usr_7f3a" \
  --header "x-api-key: ${VEXPAY_API_KEY}"

curl "${API_URL}/v1/merchants/MERCHANT_ID" \
  --header "x-api-key: ${VEXPAY_API_KEY}"
Desactivarbash
curl --request PATCH "${API_URL}/v1/merchants/MERCHANT_ID" \
  --header "content-type: application/json" \
  --header "x-api-key: ${VEXPAY_API_KEY}" \
  --data '{ "isActive": false }'
Borrar comerciantebash
curl --request DELETE "${API_URL}/v1/merchants/MERCHANT_ID" \
  --header "x-api-key: ${VEXPAY_API_KEY}"
# 200 → { "deleted": true, "merchantId": "…", "externalRef": "…" }
# 409 → { "error": "merchant_has_payouts", "payoutCount": N }

Borrar un comerciante

Borra de forma permanente un comerciante (y sus métodos de payout) cuando nunca ha recibido un payout. Libera el externalRef del tenant para volver a registrar el mismo id de vendedor. Prefiere PATCH isActive:false si ya hay historial de payouts.

ResultadoDetalle
DELETE /v1/merchants/:idAcotado al tenant por x-api-key. El id del path es el UUID del gateway.
200 OK`{ "deleted": true, "merchantId", "externalRef" }` — comerciante y métodos eliminados; externalRef queda libre.
404Comerciante no encontrado para este tenant.
409 merchant_has_payoutsExiste al menos un payout (`payoutCount`). Desactiva con PATCH `{ "isActive": false }` en su lugar.
curlbash
curl --request DELETE "${API_URL}/v1/merchants/00000000-0000-4000-8000-000000000000" \
  --header "x-api-key: ${VEXPAY_API_KEY}"
Respuesta 200json
{
  "deleted": true,
  "merchantId": "00000000-0000-4000-8000-000000000000",
  "externalRef": "usr_7f3a"
}
Respuesta 409json
{
  "error": "merchant_has_payouts",
  "payoutCount": 3
}

Buscar un comerciante por externalRef

Dentro de un tenant, cada comerciante queda identificado de forma única por el externalRef que enviaste al registrarlo. Prefiere consultar por esa ref cuando tu sistema guarda el id de vendedor/usuario, no el merchantId del gateway. La auth es la API key del tenant (`x-api-key`) — la búsqueda siempre queda acotada a ese tenant.

EndpointDevuelve
GET /v1/merchants?externalRef={ref}Detalle de un solo comerciante (misma forma que GET /v1/merchants/:id), con payoutMethods[]
GET /v1/merchants/:idEl mismo detalle cuando ya tienes el UUID del gateway
GET /v1/merchantsLista paginada (`items`, `nextCursor`) si omites externalRef
curlbash
curl "${API_URL}/v1/merchants?externalRef=usr_7f3a" \
  --header "x-api-key: ${VEXPAY_API_KEY}"
JavaScriptjavascript
const merchant = await fetch(
  `${process.env.API_URL}/v1/merchants?externalRef=${encodeURIComponent('usr_7f3a')}`,
  { headers: { 'x-api-key': process.env.VEXPAY_API_KEY } }
).then((r) => r.json());
// merchant.merchantId, merchant.status, merchant.payoutMethods

Payouts simple y batch

EndpointPropósito
POST /v1/payoutsPagar un comerciante verificado y activo (payoutMethodId opcional)
POST /v1/payouts/batchPagar varios; resultado por ítem
GET /v1/payoutsListar payouts (filtro status opcional)
GET /v1/payouts/:idConsultar por id
GET /v1/payouts/by-ref/:externalRefConsultar por externalRef
Payout simplebash
curl --request POST "${API_URL}/v1/payouts" \
  --header "content-type: application/json" \
  --header "x-api-key: ${VEXPAY_API_KEY}" \
  --data '{
    "merchantId": "00000000-0000-4000-8000-000000000000",
    "payoutMethodId": "00000000-0000-4000-8000-000000000001",
    "monto": "1523.40",
    "concepto": "Liquidacion semana 30",
    "externalRef": "po_9c21"
  }'

POST /v1/payouts/batch paga a varios comerciantes verificados en una solicitud. Cada ítem es su propio payout (su externalRef, status y webhooks). Los fallos son por ítem — no revierten a los demás.

Payout batchbash
curl --request POST "${API_URL}/v1/payouts/batch" \
  --header "content-type: application/json" \
  --header "x-api-key: ${VEXPAY_API_KEY}" \
  --data '{
    "externalRef": "corte_semana_30",
    "items": [
      {
        "merchantId": "00000000-0000-4000-8000-000000000000",
        "payoutMethodId": "00000000-0000-4000-8000-000000000001",
        "monto": "1523.40",
        "concepto": "Liquidacion semana 30",
        "externalRef": "po_9c21_seller"
      },
      {
        "merchantId": "00000000-0000-4000-8000-000000000002",
        "monto": "210.00",
        "concepto": "Liquidacion semana 30",
        "externalRef": "po_9c21_partner"
      }
    ]
  }'
Respuesta 201json
{
  "batchId": "00000000-0000-4000-8000-000000000010",
  "items": [
    {
      "payoutId": "00000000-0000-4000-8000-000000000011",
      "status": "completed",
      "reference": "12345678",
      "failureCode": null,
      "externalRef": "po_9c21_seller",
      "merchantId": "00000000-0000-4000-8000-000000000000",
      "payoutMethodId": "00000000-0000-4000-8000-000000000001",
      "merchantName": "Maria Perez",
      "monto": "1523.40",
      "concepto": "Liquidacion semana 30",
      "bankCode": "0134",
      "destination": "…5555",
      "operationId": null,
      "createdAt": "2026-07-28T16:00:00.000Z",
      "settledAt": "2026-07-28T16:00:01.000Z"
    },
    {
      "payoutId": "00000000-0000-4000-8000-000000000012",
      "status": "pending",
      "reference": null,
      "failureCode": null,
      "externalRef": "po_9c21_partner",
      "merchantId": "00000000-0000-4000-8000-000000000002",
      "payoutMethodId": "00000000-0000-4000-8000-000000000003",
      "merchantName": "Socio CA",
      "monto": "210.00",
      "concepto": "Liquidacion semana 30",
      "bankCode": "0102",
      "destination": "…1234",
      "operationId": "AC00-OP-EXAMPLE",
      "createdAt": "2026-07-28T16:00:00.000Z",
      "settledAt": null
    }
  ]
}
Listar / estadobash
curl "${API_URL}/v1/payouts?status=pending&limit=25" \
  --header "x-api-key: ${VEXPAY_API_KEY}"

curl "${API_URL}/v1/payouts/PAYOUT_ID" \
  --header "x-api-key: ${VEXPAY_API_KEY}"