Reconcile your balance
List every movement of your VES balance, rebuild it exactly, and handle card chargebacks automatically.
Balance movements
GET /v1/balance/transactions lists every movement of your VES balance, newest first: payments, fees, payouts, reversals, card chargebacks, adjustments, seller transfers and conversions. Each movement has a stable id, a type, a signed amountVes (negative = money out) and the linked paymentId / payoutId / chargebackId.
curl "${API_URL}/v1/balance/transactions?limit=100" \
--header "x-api-key: ${VEXPAY_API_KEY}"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){
"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…"
}- Pass
nextCursorascursorfor older movements;nextCursor: nullis the last page. New movements never shift the pages you are walking. - Filter with
type(repeat or comma-separate),paymentId,payoutId,from(inclusive) andto(exclusive). - The sum of
amountVesover all movements equalsledgerNetVesfromGET /v1/balance; minusreserveVesandheldVesit equalsavailableVes. Movements still under the 24h balance hold carryavailableAt. If your ledger disagrees, the movement you are missing is in this list.
Card chargebacks
When a cardholder disputes a card (VPOS) payment, the bank charges it back. VEXPay debits the charged-back amount — plus a chargeback fee, when there is one — from your available VES balance and sends payment.chargeback (see Chargeback events below). The platform fee of the original payment is not returned. A chargeback for the full amount also marks the payment REVERSED and sends payment.reversed with reversalType: "chargeback".
ledgerEntryIdsare the ids of the movements the event created — find them inGET /v1/balance/transactions?paymentId=…to book the debit without guessing.- Your balance can go negative. While it is negative, payouts and conversions answer
insufficient_balanceuntil new collections cover it. - When the dispute is decided you receive
payment.chargeback_closed:outcome: "won"returns the amount and fee (newchargeback_reversalmovements, payment back toCOMPLETED);outcome: "lost"changes nothing more. - Partial chargebacks are possible; a payment can have several, never more than its amount.
Chargeback events
Both events use the standard signed envelope (VexPay-Signature, VexPay-Event-Id) and are only delivered to endpoints that list them. data has the same fields in both; payment.chargeback_closed adds outcome and closedAt.
| Field | Type | Meaning |
|---|---|---|
| chargebackId | string (uuid) | Stable id of the chargeback. Same value in both events. |
| paymentId / externalRef | string | The card payment that was charged back and your reference for it. |
| method | "VPOS" | Card payments only. |
| status | "open" | "won" | "lost" | State of the chargeback when the event was sent. |
| outcome | "won" | "lost" | Only in payment.chargeback_closed. |
| amountVes | string, 2 decimals | Charged-back amount (positive). Partial chargebacks are possible. |
| feeVes | string, 2 decimals | Chargeback fee debited on top of the amount ("0.00" when none). |
| reason | string | fraud | not_recognized | not_received | duplicate | other. |
| bankDebitedAt | ISO 8601 | When the bank debited the chargeback. |
| paymentStatus | string | Payment status after the event: REVERSED for a full chargeback (open or lost), COMPLETED for a partial one or after a won dispute. |
| vesAmount / usdAmount | string, 2 decimals | Amounts of the original payment. |
| ledgerEntryIds | string[] | Ids of the balance movements this event created (empty when closed as lost). Match them in GET /v1/balance/transactions. |
| createdAt / closedAt | ISO 8601 | When the chargeback was recorded / decided. |
| livemode | boolean | false for test-mode deliveries. |
Example bodies
A full Bs 4,000.00 chargeback with a Bs 50.00 fee on payment order-1042, then the dispute closed. livemode is added to every data object.
{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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 of payment.chargeback are the chargeback and chargeback_fee movements above. When the dispute is won, payment.chargeback_closed carries the ids of two new chargeback_reversal movements (+4,000.00 and +50.00). When it is lost, ledgerEntryIds is empty and nothing else moves.