Skip to main content
When a transaction is paid, the net amount (after fees and splits) is credited to the recipient’s wallet. This balance moves through stages — pending, available, and blocked — before it can be withdrawn. This page explains that cycle and the endpoints for checking balances and requesting withdrawals.
Wallets are organized by recipient and currency. The API aggregates all internal wallets for a recipient into a single view per currency — you do not need to deal with individual wallet IDs.

From payment to balance

1

Payment confirmed

A transaction is paid. The net amount (after fees and split) is credited to the recipient’s wallet.
2

Pending balance

Immediately after payment, the amount enters as pending. It cannot be withdrawn yet.
3

Available balance

After the release period, the amount moves from pending to available.
4

Withdrawal request

You request a withdrawal from the withdrawable balance. The withdrawal enters as requested and awaits approval. See withdrawal flow.

Balance stages

The balance query returns four values per currency, all in cents (integers):
availableBalance
integer
Available balance: already-released amount, summed across all wallets for the currency.
pendingBalance
integer
Pending balance: amount credited but still within the release period. Cannot be withdrawn.
blockedBalance
integer
Blocked balance: amount on hold (e.g., due to a dispute/chargeback or reserve). Reduces how much can be withdrawn.
withdrawableBalance
integer
Withdrawable balance: how much can actually be withdrawn right now. Calculated from available - blocked, applying the percentage withdrawal limit configured for your account and currency. This is the value to check before calling the withdrawal endpoint.
Always use withdrawableBalance to determine the amount for a withdrawal. availableBalance does not deduct the blocked amount or the account’s percentage limit.

Endpoints

All requests use the x-api-key header (see Authentication).
MethodRouteDescription
GET/wallets/owner/{ownerId}/balanceRecipient’s aggregated balance per currency
GET/withdrawals/configWithdrawal fees and minimum amount
POST/withdrawalsRequest a withdrawal
GET/withdrawalsList withdrawals (paginated)
GET/withdrawals/{id}Retrieve a withdrawal by ID
POST/withdrawals/{id}/cancelCancel a withdrawal that has not yet been approved
The detailed wallet statement (ledger entries, period summary) is covered in Wallets.

Check balance

ownerId
string
required
Recipient ID, in rec_... format.
Request
curl https://api.sandbox.z2pay.com/wallets/owner/rec_8a1f2c3d4e5f/balance \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX"
Response 200
{
  "recipientId": "rec_8a1f2c3d4e5f",
  "balances": [
    {
      "currency": "BRL",
      "availableBalance": 150000,
      "pendingBalance": 32000,
      "blockedBalance": 0,
      "withdrawableBalance": 150000
    }
  ]
}
balances contains one item per currency. If the recipient has no wallets, the array is empty. Values are in cents: 150000 = R$ 1,500.00.

Withdrawal configuration

Before requesting a withdrawal, fetch the configuration to know the fee and minimum amount. Monetary values are in cents.
currency
string
Filters the configuration by currency (ISO 4217, 3 letters, e.g. BRL). Optional.
Request
curl "https://api.sandbox.z2pay.com/withdrawals/config?currency=BRL" \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX"
Response 200
{
  "feePercentage": 0,
  "feeFixed": 367,
  "minimumAmount": 1000
}
feePercentage
number
Percentage fee applied to the requested withdrawal amount.
feeFixed
integer
Fixed withdrawal fee, in cents (e.g. 367 = R$ 3.67).
minimumAmount
integer
Minimum amount to request a withdrawal, in cents. Requests below this value are rejected.

Request a withdrawal

Requests a withdrawal for a recipient in a given currency. The withdrawal aggregates the balance across all wallets for that currency and enters with status requested, awaiting approval.
This endpoint returns 201 Created and accepts the optional Idempotency-Key header to prevent duplicate withdrawals on retries. See Conventions.
recipientId
string
required
Recipient ID, in rec_... format.
amount
integer
required
Gross withdrawal amount, in cents. Must be an integer greater than 0.
currency
string
default:"BRL"
Withdrawal currency (ISO 4217, exactly 3 letters, e.g. BRL). Optional — defaults to BRL when omitted.
Request
curl -X POST https://api.sandbox.z2pay.com/withdrawals \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX" \
  -H "Idempotency-Key: 9c1e7b40-2f3a-4d18-9a77-6b2c1d4e5f60" \
  -H "Content-Type: application/json" \
  -d '{
    "recipientId": "rec_8a1f2c3d4e5f",
    "amount": 50000,
    "currency": "BRL"
  }'
Response 201
{
  "id": "wdr_3b9c1a2d4e6f",
  "walletId": "wlt_7d2e1f0a3b4c",
  "tenantId": "comp_1a2b3c4d5e6f",
  "amount": 50000,
  "currency": "BRL",
  "fee": 367,
  "netAmount": 49633,
  "status": "requested",
  "bankAccountId": null,
  "paidAt": null,
  "pspTransferId": null,
  "statusHistory": [
    {
      "status": "requested",
      "changedBy": "api",
      "changedAt": "2026-06-24T13:45:00.000Z"
    }
  ],
  "image": null,
  "createdAt": "2026-06-24T13:45:00.000Z",
  "updatedAt": "2026-06-24T13:45:00.000Z"
}
netAmount is the amount the recipient actually receives: amount - fee. The fee is calculated at the time of the request based on the withdrawal configuration.
If the withdrawable balance is insufficient, the amount is below the minimum, or there is no active wallet for the currency, the API returns 409 Conflict. Check withdrawableBalance and minimumAmount before requesting. See Errors.

Withdrawal flow

A withdrawal moves through the following statuses:
requested → approved → processing → paid
Alternative paths: cancelled (cancelled by the merchant before approval), rejected (declined during review), and failed (processing failure).
Initial state immediately after the request. Awaiting manual approval. This is the only status in which a withdrawal can be cancelled via API.
The withdrawal was approved during review and moves on to processing.
The payment is being executed to the destination bank account.
cancelled: cancelled by the merchant while still in requested. rejected: declined during review. failed: failure during processing.
Track withdrawal transitions in real time by subscribing to webhook events (withdrawal.requested, withdrawal.paid, withdrawal.rejected). See Webhooks.

List withdrawals

Returns a paginated list of withdrawals for the account, with an optional filter by status.
status
string
Filter by status. Values: requested, approved, processing, paid, cancelled, rejected, failed. Optional.
page
integer
default:"1"
Page number.
limit
integer
default:"20"
Number of items per page (maximum 100).
Request
curl "https://api.sandbox.z2pay.com/withdrawals?status=paid&page=1&limit=20" \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX"
Response 200
{
  "data": [
    {
      "id": "wdr_3b9c1a2d4e6f",
      "walletId": "wlt_7d2e1f0a3b4c",
      "amount": 50000,
      "currency": "BRL",
      "fee": 367,
      "netAmount": 49633,
      "status": "paid",
      "paidAt": "2026-06-23T18:10:00.000Z",
      "createdAt": "2026-06-23T13:45:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 1,
    "totalPages": 1
  }
}

Retrieve withdrawal by ID

Returns the full details of a withdrawal, including the status history (statusHistory).
id
string
required
Withdrawal ID, in wdr_... format.
Request
curl https://api.sandbox.z2pay.com/withdrawals/wdr_3b9c1a2d4e6f \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX"
Response 200
{
  "id": "wdr_3b9c1a2d4e6f",
  "walletId": "wlt_7d2e1f0a3b4c",
  "tenantId": "comp_1a2b3c4d5e6f",
  "amount": 50000,
  "currency": "BRL",
  "fee": 367,
  "netAmount": 49633,
  "status": "paid",
  "bankAccountId": null,
  "paidAt": "2026-06-23T18:10:00.000Z",
  "pspTransferId": "psp_xfer_2c4e6a8b0d1f",
  "statusHistory": [
    { "status": "requested", "changedBy": null, "changedAt": "2026-06-23T13:45:00.000Z" },
    { "status": "approved", "changedBy": "user_9f8e7d6c5b4a", "changedAt": "2026-06-23T15:00:00.000Z" },
    { "status": "processing", "changedBy": null, "changedAt": "2026-06-23T17:30:00.000Z" },
    { "status": "paid", "changedBy": null, "changedAt": "2026-06-23T18:10:00.000Z" }
  ],
  "image": null,
  "createdAt": "2026-06-23T13:45:00.000Z",
  "updatedAt": "2026-06-23T18:10:00.000Z"
}
If the withdrawal does not exist, the API returns 404 Not Found. See Errors.

Cancel a withdrawal

Cancels a withdrawal only while it is in requested status (not yet approved).
This endpoint accepts the optional Idempotency-Key header.
id
string
required
Withdrawal ID, in wdr_... format.
reason
string
Cancellation reason (at least 1 character). Optional — a default reason is recorded when omitted.
Request
curl -X POST https://api.sandbox.z2pay.com/withdrawals/wdr_3b9c1a2d4e6f/cancel \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "Solicitado pelo lojista" }'
Response 200
{
  "id": "wdr_3b9c1a2d4e6f",
  "status": "cancelled",
  "amount": 50000,
  "currency": "BRL",
  "fee": 367,
  "netAmount": 49633,
  "updatedAt": "2026-06-24T14:02:00.000Z"
}
A withdrawal not found returns 404; a withdrawal that cannot be cancelled in its current status (e.g., already approved or paid) returns 409. See Errors.

Test in sandbox

In the sandbox you can simulate balance release and withdrawal settlement without moving real funds.

Sandbox overview

How the test environment works.

Simulate events

Force transitions to test the withdrawal flow.

See also

Wallets

Balance, statement, and period summary.

Fees

How fees are calculated.

Split

Splitting amounts between recipients.

Webhooks

Receive real-time withdrawal notifications.