Balance and Payment Preference Hooks
The four hooks over the wallet, balance adjustments and the auto-payment chain.
Overview
Money enters or leaves a customer wallet four ways: a top-up request, credit from an invoice, a manual adjustment by an administrator, and a change in the auto-payment chain.
Currency is the trap here: a balance is kept in its own currency while an invoice may be in another. Check which one an amount is in before carrying it anywhere.
Reference
Following the auto-payment chain
Runs when the auto-payment chain of an account changes.
Hook::add('action:user.autopay_changed', 10, function ($uid, $autopayCtx) {
// An empty chain means renewals will fail.
if (!($autopayCtx['backup_card'] ?? null)) Acme::warnNoCard($uid);
});Following credit reaching the balance
Runs when credit from an invoice reaches a customer balance.
Hook::add('action:user.balance_credited', 10, function ($user_id, $amount, $currency, $invoice) {
// The amount is in the balance currency: do not mix it with the invoice one.
Acme::ledgerCredit($user_id, $amount, $currency);
});Following a balance adjustment
Runs when an administrator adjusts a balance by hand.
up credit, down debit.Hook::add('action:user.credit_adjusted', 10,
function ($user_id, $type, $amount, $new_balance, $cid) {
Acme::ledgerAdjust($user_id, $type, $amount, $new_balance);
});Following a top-up request
Runs when a customer asks to top up their wallet.
Hook::add('action:user.funds_added', 10, function ($uid, $amount, $fundsCtx) {
// The NET amount: tax and commission are not in it.
Acme::noteTopupIntent($uid, $amount);
});Pitfalls
What reaches a balance arrives in the balance currency and after conversion. It need not equal the invoice total; treating them as one number produces a gap in your books.
The amount in the top-up hook is net: tax and gateway commission are not in it. What the customer pays is higher, so do not record this number as the sum collected.
Related Articles
Thanks for your feedback!
Our support team is here around the clock for anything you can't find above.