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

Concilia tu saldo

Lista cada movimiento de tu saldo VES, reconstrúyelo con exactitud y maneja los contracargos de tarjeta de forma automática.

Movimientos del saldo

GET /v1/balance/transactions lista cada movimiento de tu saldo VES, del más reciente al más antiguo: pagos, comisiones, retiros, reversos, contracargos de tarjeta, ajustes, transferencias a vendedores y conversiones. Cada movimiento tiene un id estable, un type, un amountVes con signo (negativo = salida) y el paymentId / payoutId / chargebackId vinculado.

curlbash
curl "${API_URL}/v1/balance/transactions?limit=100" \
  --header "x-api-key: ${VEXPAY_API_KEY}"
Node SDKjavascript
let total = 0;
for await (const m of vexpay.balance.transactions.list({ limit: 100 })) {
  total += Number(m.amountVes);
}
const balance = await vexpay.balance.retrieve();
// total === Number(balance.ledgerNetVes)
Respuestajson
{
  "items": [
    { "id": "6b1f…", "type": "chargeback", "amountVes": "-4000.00", "paymentId": "a3c9…", "chargebackId": "c71e…", "externalRef": "order-1042", "description": "Card chargeback (fraud)", "createdAt": "2026-10-08T14:02:11.000Z" },
    { "id": "5e0a…", "type": "fee", "amountVes": "-140.00", "paymentId": "a3c9…", "description": "Platform fee", "createdAt": "2026-10-01T10:00:00.000Z" }
  ],
  "nextCursor": "MjAyNi0xMC0wMVQxMDowMDowMC4wMDBafDVlMGE…"
}
  • Envía nextCursor como cursor para movimientos más antiguos; nextCursor: null es la última página. Los movimientos nuevos nunca desplazan las páginas que estás recorriendo.
  • Filtra con type (repetido o separado por comas), paymentId, payoutId, from (inclusive) y to (exclusive).
  • La suma de amountVes de todos los movimientos es igual a ledgerNetVes de GET /v1/balance; menos reserveVes y heldVes, es igual a availableVes. Los movimientos que siguen en la retención de 24 h traen availableAt. Si tu contabilidad no cuadra, el movimiento que te falta está en esta lista.

Contracargos de tarjeta

Cuando un tarjetahabiente disputa un pago con tarjeta (VPOS), el banco aplica un contracargo. VEXPay debita el monto del contracargo — más una comisión de contracargo, si la hay — de tu saldo VES disponible y envía payment.chargeback. La comisión de plataforma del pago original no se devuelve. Un contracargo por el monto total también marca el pago REVERSED y envía payment.reversed con reversalType: "chargeback".

  • ledgerEntryIds son los ids de los movimientos que creó el evento — búscalos en GET /v1/balance/transactions?paymentId=… para registrar el débito sin adivinar.
  • Tu saldo puede quedar negativo. Mientras lo esté, los retiros y conversiones responden insufficient_balance hasta que nuevos cobros lo cubran.
  • Cuando se resuelve la disputa recibes payment.chargeback_closed: outcome: "won" devuelve el monto y la comisión (nuevos movimientos chargeback_reversal, el pago vuelve a COMPLETED); outcome: "lost" no cambia nada más.
  • Puede haber contracargos parciales; un pago puede tener varios, nunca por más de su monto.

Eventos de contracargo

Ambos eventos usan el sobre firmado estándar (VexPay-Signature, VexPay-Event-Id) y solo se entregan a endpoints que los listan. data tiene los mismos campos en ambos; payment.chargeback_closed agrega outcome y closedAt.

CampoTipoSignificado
chargebackIdstring (uuid)Id estable del contracargo. El mismo valor en ambos eventos.
paymentId / externalRefstringEl pago con tarjeta que recibió el contracargo y tu referencia.
method"VPOS"Solo pagos con tarjeta.
status"open" | "won" | "lost"Estado del contracargo cuando se envió el evento.
outcome"won" | "lost"Solo en payment.chargeback_closed.
amountVesstring, 2 decimalesMonto del contracargo (positivo). Puede ser parcial.
feeVesstring, 2 decimalesComisión de contracargo debitada además del monto ("0.00" si no hay).
reasonstringfraud | not_recognized | not_received | duplicate | other.
bankDebitedAtISO 8601Cuándo el banco debitó el contracargo.
paymentStatusstringEstado del pago después del evento: REVERSED para un contracargo total (abierto o perdido), COMPLETED para uno parcial o tras ganar la disputa.
vesAmount / usdAmountstring, 2 decimalesMontos del pago original.
ledgerEntryIdsstring[]Ids de los movimientos de saldo que creó este evento (vacío al cerrarse como perdido). Búscalos en GET /v1/balance/transactions.
createdAt / closedAtISO 8601Cuándo se registró / resolvió el contracargo.
livemodebooleanfalse en entregas de modo de prueba.

Ejemplos de body

Un contracargo total de Bs 4.000,00 con comisión de Bs 50,00 sobre el pago order-1042, y luego la disputa cerrada. livemode se agrega a cada objeto data.

payment.chargebackjson
{
  "event": "payment.chargeback",
  "data": {
    "chargebackId": "c71e2f4a-8d1b-4c3e-9a6f-2b5d7e9c1a03",
    "paymentId": "a3c9b8d2-5e4f-4a1b-8c7d-6e5f4a3b2c10",
    "externalRef": "order-1042",
    "method": "VPOS",
    "status": "open",
    "amountVes": "4000.00",
    "feeVes": "50.00",
    "reason": "fraud",
    "bankDebitedAt": "2026-10-07T00:00:00.000Z",
    "paymentStatus": "REVERSED",
    "vesAmount": "4000.00",
    "usdAmount": "100.00",
    "ledgerEntryIds": [
      "6b1f0c2e-3d4a-4b5c-8d9e-0f1a2b3c4d5e",
      "7c2a1d3f-4e5b-4c6d-9e0f-1a2b3c4d5e6f"
    ],
    "createdAt": "2026-10-08T14:02:11.000Z",
    "livemode": true
  },
  "timestamp": "2026-10-08T14:02:11.412Z"
}
payment.chargeback_closed (ganado)json
{
  "event": "payment.chargeback_closed",
  "data": {
    "chargebackId": "c71e2f4a-8d1b-4c3e-9a6f-2b5d7e9c1a03",
    "paymentId": "a3c9b8d2-5e4f-4a1b-8c7d-6e5f4a3b2c10",
    "externalRef": "order-1042",
    "method": "VPOS",
    "status": "won",
    "outcome": "won",
    "amountVes": "4000.00",
    "feeVes": "50.00",
    "reason": "fraud",
    "bankDebitedAt": "2026-10-07T00:00:00.000Z",
    "paymentStatus": "COMPLETED",
    "vesAmount": "4000.00",
    "usdAmount": "100.00",
    "ledgerEntryIds": [
      "8d3b2e4a-5f6c-4d7e-0f1a-2b3c4d5e6f70",
      "9e4c3f5b-6a7d-4e8f-1a2b-3c4d5e6f7081"
    ],
    "createdAt": "2026-10-08T14:02:11.000Z",
    "closedAt": "2026-10-22T09:30:00.000Z",
    "livemode": true
  },
  "timestamp": "2026-10-22T09:30:00.518Z"
}
payment.chargeback_closed (perdido)json
{
  "event": "payment.chargeback_closed",
  "data": {
    "chargebackId": "c71e2f4a-8d1b-4c3e-9a6f-2b5d7e9c1a03",
    "paymentId": "a3c9b8d2-5e4f-4a1b-8c7d-6e5f4a3b2c10",
    "externalRef": "order-1042",
    "method": "VPOS",
    "status": "lost",
    "outcome": "lost",
    "amountVes": "4000.00",
    "feeVes": "50.00",
    "reason": "fraud",
    "bankDebitedAt": "2026-10-07T00:00:00.000Z",
    "paymentStatus": "REVERSED",
    "vesAmount": "4000.00",
    "usdAmount": "100.00",
    "ledgerEntryIds": [],
    "createdAt": "2026-10-08T14:02:11.000Z",
    "closedAt": "2026-10-22T09:30:00.000Z",
    "livemode": true
  },
  "timestamp": "2026-10-22T09:30:00.518Z"
}
payment.reversed (contracargo total)json
{
  "event": "payment.reversed",
  "data": {
    "paymentId": "a3c9b8d2-5e4f-4a1b-8c7d-6e5f4a3b2c10",
    "externalRef": "order-1042",
    "status": "REVERSED",
    "method": "VPOS",
    "usdAmount": 100,
    "vesAmount": 4000,
    "bcvRate": 40,
    "feeVes": 140,
    "netVes": 3860,
    "cardLast4": "4242",
    "reversedAt": "2026-10-08T14:02:11.000Z",
    "reversalRef": "chargeback:c71e2f4a-8d1b-4c3e-9a6f-2b5d7e9c1a03",
    "reversalType": "chargeback",
    "chargebackId": "c71e2f4a-8d1b-4c3e-9a6f-2b5d7e9c1a03",
    "chargebacks": [
      { "chargebackId": "c71e2f4a-8d1b-4c3e-9a6f-2b5d7e9c1a03", "status": "open", "amountVes": "4000.00", "feeVes": "50.00", "reason": "fraud", "bankDebitedAt": "2026-10-07T00:00:00.000Z" }
    ],
    "createdAt": "2026-10-01T10:00:00.000Z",
    "livemode": true
  },
  "timestamp": "2026-10-08T14:02:11.430Z"
}
GET /v1/balance/transactions?paymentId=…json
{
  "items": [
    {
      "id": "7c2a1d3f-4e5b-4c6d-9e0f-1a2b3c4d5e6f",
      "type": "chargeback_fee",
      "amountVes": "-50.00",
      "paymentId": "a3c9b8d2-5e4f-4a1b-8c7d-6e5f4a3b2c10",
      "chargebackId": "c71e2f4a-8d1b-4c3e-9a6f-2b5d7e9c1a03",
      "externalRef": "order-1042",
      "description": "Chargeback fee",
      "createdAt": "2026-10-08T14:02:11.000Z"
    },
    {
      "id": "6b1f0c2e-3d4a-4b5c-8d9e-0f1a2b3c4d5e",
      "type": "chargeback",
      "amountVes": "-4000.00",
      "paymentId": "a3c9b8d2-5e4f-4a1b-8c7d-6e5f4a3b2c10",
      "chargebackId": "c71e2f4a-8d1b-4c3e-9a6f-2b5d7e9c1a03",
      "externalRef": "order-1042",
      "description": "Card chargeback (fraud)",
      "createdAt": "2026-10-08T14:02:11.000Z"
    },
    {
      "id": "5e0a9b8c-7d6e-4f5a-8b9c-0d1e2f3a4b5c",
      "type": "fee",
      "amountVes": "-140.00",
      "paymentId": "a3c9b8d2-5e4f-4a1b-8c7d-6e5f4a3b2c10",
      "externalRef": "order-1042",
      "description": "Platform fee",
      "createdAt": "2026-10-01T10:00:00.000Z"
    },
    {
      "id": "4d9f8a7b-6c5d-4e4f-9a8b-7c6d5e4f3a2b",
      "type": "payment",
      "amountVes": "4000.00",
      "paymentId": "a3c9b8d2-5e4f-4a1b-8c7d-6e5f4a3b2c10",
      "externalRef": "order-1042",
      "description": "Payment collected",
      "createdAt": "2026-10-01T10:00:00.000Z"
    }
  ],
  "nextCursor": null
}

ledgerEntryIds de payment.chargeback son los movimientos chargeback y chargeback_fee de arriba. Si se gana la disputa, payment.chargeback_closed trae los ids de dos nuevos movimientos chargeback_reversal (+4.000,00 y +50,00). Si se pierde, ledgerEntryIds viene vacío y nada más se mueve.