Issuing Wallets
Create wallets for your customers and manage their balances.
Create a wallet
Each customer can hold one wallet per currency. Create it at account registration or on first use.
const wallet = await xtopay.wallets.create({
customer_id: "cus_abc123",
currency: "GHS",
metadata: {
tier: "pro",
},
});If the customer already has a wallet in that currency, the API returns the existing one — creation is idempotent on (customer_id, currency).
Retrieve a wallet
const wallet = await xtopay.wallets.retrieve("wal_a1b2c3");
// Or by customer and currency
const wallet = await xtopay.wallets.retrieveByCustomer({
customer_id: "cus_abc123",
currency: "GHS",
});Check balance
const wallet = await xtopay.wallets.retrieve("wal_a1b2c3");
console.log(wallet.balance); // e.g. 15000 (GHS 150.00)
console.log(wallet.balance_formatted); // "GH₵150.00"Always check wallet.balance server-side before allowing a debit — never trust a client-sent balance.
Wallet statuses
| Status | Meaning |
|---|---|
active | Normal — top-ups and debits allowed |
frozen | Debits blocked — top-ups still accepted |
closed | No activity allowed — remaining balance must be refunded |
Freeze or close a wallet from the dashboard or API:
await xtopay.wallets.freeze("wal_a1b2c3");
await xtopay.wallets.unfreeze("wal_a1b2c3");
await xtopay.wallets.close("wal_a1b2c3");Credit adjustment (admin credit)
Grant credit without a top-up payment — for promotions, goodwill credits, or referral bonuses:
await xtopay.wallets.credit({
wallet_id: "wal_a1b2c3",
amount: 1000, // GHS 10.00 — free credit
description: "Welcome bonus",
reference: "promo_welcome_2026",
});Admin credits do not generate a payment or charge the customer.
Balance expiry
Configure credits to expire after a set period — useful for promotional credits that shouldn't accumulate indefinitely:
await xtopay.wallets.credit({
wallet_id: "wal_a1b2c3",
amount: 500,
description: "Monthly bonus credits",
expires_at: "2026-08-01T00:00:00Z",
});Expired credits are removed automatically and a wallet.credit_expired webhook fires.