Balance & payments
Read the wallet balance and handle 402 Payment Required with a signed top-up link.
Fleeex is prepaid, so two things matter to an integration: knowing the balance, and gracefully handling the moment it runs out.
Read the balance
const { balanceMicros, currency } = await client.getBalance();
// balanceMicros is EUR micro-units: 1_000_000 = €1.00getBalance() returns a BalanceResponse.
Amounts are in micro-units to avoid floating-point drift — divide by 1,000,000
for the major unit.
const eur = balanceMicros / 1_000_000; // e.g. 4_250_000 → 4.25Like a proxied call, getBalance() throws PaymentRequiredError if the
(app, user) has no funded, authorized wallet.
Handle 402 Payment Required
When the wallet isn't funded/authorized, both the proxy and getBalance() raise a
typed PaymentRequiredError carrying a signed, short-lived top-up link. Send the
end user there to fund the wallet:
import { PaymentRequiredError } from "@fleeex/sdk";
try {
await client.chat.completions.create({ model, messages });
} catch (err) {
if (err instanceof PaymentRequiredError) {
redirect(err.topupUrl); // send the end user through Checkout
} else {
throw err;
}
}PaymentRequiredError exposes topupUrl, code, correlationId, and status
(always 402). The message is intentionally generic — Fleeex never reveals whether a
wallet exists — so the actionable part is topupUrl. See the
error reference.
Handle it in one place
Repeating that try/catch everywhere is tedious. Register the onPaymentRequired
hook once, and it fires whenever a 402 is mapped (from a proxied call or
getBalance()), just before the error is thrown:
const client = new FleeexClient({
apiKey,
userId,
onPaymentRequired: (err) => redirect(err.topupUrl),
});The hook runs first; the call still rejects with the PaymentRequiredError, so any
local try/catch continues to work.
Avoid the 402 entirely
To check up front — before a first chat call — whether a user is connected and
funded, use getConnection(), which returns status
without ever raising a 402.