Balance
The three endpoints giving the prepaid balance, its movements and the collection settings.
Overview
The wallet is the account's prepaid balance. It can pay an invoice, and renewals can be taken from it by themselves when asked.
Three endpoints answer three questions: how much is there, where the money went and how collection should work.
The wallet has a currency of its own and it is separate from the display choice on the profile. Always read an amount together with the currency beside it.
Reference
Reading the Wallet
Returns the wallet, the automatic payment setting and the warning setup in one call.
curl 'https://panel.example.com/api/v1/client/balance' \
-H "Authorization: Bearer $CLIENT_KEY"const res = await fetch('https://panel.example.com/api/v1/client/balance', {
headers: { Authorization: `Bearer ${clientKey}` },
});
const { data } = await res.json();
if (data.low_balance) promptTopUp(data.balance);$ch = curl_init('https://panel.example.com/api/v1/client/balance');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $clientKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The wallet currency can differ from the DISPLAY one on the profile; read the amount in its own.
$w = Kernel::internal('client:Balance/GetBalance', ['owner_id' => $uid])['data'];
$amount = $w['balance']['amount'];
$cur = $w['balance']['currency'];Reading the Wallet Movements
Returns what came into the wallet and what left it, newest first.
curl 'https://panel.example.com/api/v1/client/balance/transactions?type=down&limit=50' \
-H "Authorization: Bearer $CLIENT_KEY"const url = new URL('https://panel.example.com/api/v1/client/balance/transactions');
url.searchParams.set('type', 'down');
const res = await fetch(url, { headers: { Authorization: `Bearer ${clientKey}` } });
const { data, meta } = await res.json();$ch = curl_init('https://panel.example.com/api/v1/client/balance/transactions?type=down');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $clientKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// A movement is a HISTORICAL record: a refund adds a row the other way rather than removing the old one.
$rows = Kernel::internal('client:Balance/GetBalanceTransactions',
['owner_id' => $uid, 'type' => 'down'])['data'];
$paid = array_column($rows, 'invoice_id');Changing the Wallet Settings
Sets automatic payment and the low balance warning.
curl -X PATCH 'https://panel.example.com/api/v1/client/balance/settings' \
-H "Authorization: Bearer $CLIENT_KEY" \
-H 'Content-Type: application/json' \
-d '{"auto_pay_from_balance":true,"alert":{"enabled":true,"threshold":50}}'const res = await fetch('https://panel.example.com/api/v1/client/balance/settings', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${clientKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
alert: { enabled: true, threshold: 50 },
alert_recipients: [84],
}),
});
const { data } = await res.json();$ch = curl_init('https://panel.example.com/api/v1/client/balance/settings');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $clientKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['auto_pay_from_balance' => true]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The recipient list REPLACES: read the ones already on and merge before adding an address.
$cur = Kernel::internal('client:Balance/GetBalance', ['owner_id' => $uid])['data'];
$on = array_column(array_filter($cur['alert']['recipients'],
fn ($r) => $r['enabled'] && ! $r['owner']), 'id');
$on[] = $newAddressId;
Kernel::internal('client:Balance/UpdateBalanceSettings',
['owner_id' => $uid, 'alert_recipients' => $on]);Pitfalls
The wallet lives in its own currency while the one on the profile says how amounts are shown. The two can differ, and reading the balance in the display currency gives a wrong figure. The warning threshold is in the wallet's currency as well.
Writing the warning recipients overwrites the list: an address you leave out stops getting the warning. Sending only the address you meant to add closes the others. The account owner never enters this list and always gets the warning.
Turning the wallet collection of renewals on or off also takes the renewal invoices open at that moment down the new road. This is not a setting for the future: the collections waiting are hit at once. Make sure the balance covers them.
The backup card works after the wallet rather than in place of it: the balance is tried first and the card is charged when it falls short. Sending zero clears the chain, and a failed collection can suspend a service. Saving is refused on a card that has expired.
A wallet movement is never removed or corrected: a refund adds a new row the other way rather than taking the old one out. Read the balance from the wallet state rather than adding the movements up, since that value is fresh on every call.
Related Articles
Thanks for your feedback!
Our support team is here around the clock for anything you can't find above.