Your float
Billy pays billers out of a balance you fund in advance. This page explains where that money sits at every moment, and how to keep it topped up.
The float works like a prepaid balance. You load funds, Billy spends them paying your customers' bills. If the float can't cover a payment, the payment is declined — Billy never fronts money it hasn't been given.
wallet-funded payments, which is the default. Payments with funding_source: "collect" are funded by the end-user at checkout and never touch your float.Two balances, not one
Your wallet has two numbers, and the difference between them matters:
| Balance | What it is |
|---|---|
available | Money you can spend right now. A new payment must come out of here. |
held | Money promised to a payment that is still in flight. Yours, but not spendable. |
total | available + held — everything you have with Billy. |
credit_limit | How far available is allowed to go negative, if you've been approved for terms. Usually "0.00". |
spendable | available + credit_limit — the most a single payment can reserve right now. This is the number to check before paying. |
What happens to your money during a payment
Posting a bill takes a moment and can fail, so Billy sets the money aside the instant a payment starts rather than when it finishes. That's what stops ten simultaneous ₱1,500 payments from all looking affordable against a ₱1,500 balance.
- Reserve. The customer total moves from
availabletoheld. Yourtotaldoesn't change — nothing has been spent yet. - Then one of two endings:
- Capture — the bill posted. The held money leaves for the biller and your
totaldrops. This is the only step where money actually leaves. - Release — the bill was rejected. The hold goes straight back to
availableand you're exactly where you started. A failed payment costs you nothing.
- Capture — the bill posted. The held money leaves for the biller and your
held should be near zero almost always, because holds resolve in seconds. A held balance that stays high is a signal worth investigating — payments are starting and not finishing.Check your balance
GET /wallet
Authorization: Bearer $KEY
{
"data": {
"currency": "PHP",
"available": "8500.00",
"held": "1500.00",
"total": "10000.00",
"credit_limit": "0.00",
"spendable": "8500.00"
}
}
/wallet always returns your PHP float, which is the only bill-settlement currency today. If you hold balances in other currencies, list them all with:
GET /wallets
The wallet is created on first read, so a brand-new account gets a well-formed zero balance rather than a 404.
The statement
Every movement of money is recorded as an immutable ledger entry. Nothing is ever edited or deleted — corrections are new entries. That's what lets Billy prove your balance rather than merely assert it.
GET /wallet/ledger?per_page=25
| Type | What it means | Effect on total |
|---|---|---|
prefund | You added funds. | Up |
payment_accept | A payment started; the customer total moved from available to held. | Unchanged |
payment_confirm | The bill posted; the held money left for the biller. | Down |
payment_reject | The payment failed; the hold returned to available. | Unchanged |
refund | A settled payment was reversed; funds returned. | Up |
adjustment | A manual correction by Billy, with a reason attached. | Either |
Each line names which pocket it moved — available or held — and carries balance_after, that pocket's balance immediately after. One payment shows as several lines as its money moves between your own pockets.
accept (available → held) and a confirm (held out to the biller). The accept and confirm move the same money, not two separate charges — read balance_after on the available pocket to follow your spendable balance, rather than summing amounts.Adding funds
Create a top-up, then fund it. The float is credited when the money actually lands, not when you ask.
POST /top-ups
Authorization: Bearer $KEY
{
"amount": 50000.00,
"method": "bank_transfer",
"reference": "your-own-ref"
}
| Method | How it settles |
|---|---|
bank_transfer | Transfer to Billy's account using the reference. Confirmed by the Billy team once received. |
magpie | Card or e-wallet. The response includes a checkout_url to send the payer to; the float is credited automatically on confirmation. |
A top-up is pending until the funds arrive, then confirmed. Poll it, or listen for the webhook:
GET /top-ups/{id}
Running low
When your spendable balance falls to or below your threshold, Billy sends a wallet.low_balance webhook and emails the people on your account who can fund it. Alerts are capped at one per day while you stay low, and reset as soon as you top up — so a quiet weekend doesn't become dozens of notices.
Because the alert measures spendable, a partner on credit terms sitting at "0.00" available with headroom on their limit is healthy and won't be alerted.
When the float runs out
A payment that can't be covered is rejected outright:
HTTP/1.1 402 Payment Required
{
"message": "Wallet balance is insufficient for this payment.",
"code": "insufficient_balance"
}
Handle 402 distinctly from 422. A 422 means the request was wrong and retrying won't help; a 402 means the request was fine and will succeed once you top up. Nothing is reserved and nothing is charged.
Two payments can't spend the same peso
If two payments arrive at the same instant against a balance that only covers one, exactly one succeeds and the other gets a 402. Billy locks the wallet while it checks and deducts, so the second payment cannot read a balance the first has already claimed. You never need to serialise payments yourself to stay safe.