How the ledger works
The three ideas underneath Elite Balance, in plain words. Five minutes here makes every other page in these docs obvious.
A ledger, not a number
Most wallet plugins store your customer’s balance as a single number in a field, and every feature overwrites that number. When something goes wrong, there is nothing to check the number against.
Elite Balance stores every movement as a permanent row: what happened, how much, who did it, why, and the balance after it. The current balance is simply the last row’s result, and it must always equal the sum of every row before it. Nothing ever edits or deletes history; corrections are new rows.
This is how banks account for money, and it means three practical things for you:
- Any balance can be explained, movement by movement, forever.
- A “wrong balance” is detectable arithmetic, not a mystery. The
wp rb-elbal reconcilecommand checks every wallet against its own history. - Support conversations start from facts. The customer’s wallet page and your Transactions tab read from the same rows.
Nothing happens twice
Every operation carries a unique idempotency key. When the same operation arrives again (a payment gateway firing the same notification twice, a double-clicked button, a crashed import re-run), the ledger recognizes the key and replays the original result instead of writing a second row. Nobody gets charged or credited twice, no matter what retries.
You will occasionally see this working: a notice saying a form was already submitted, or a migration report counting replays. That is the ledger refusing to repeat itself.
Money is sacred
Changing an order’s status never silently moves wallet money. Trashing an order, marking it refunded, cancelling it: none of these touch a customer’s balance on their own (cancelling releases a not-yet-collected reservation, which is money that never moved in the first place). Moving money is always an explicit action a person takes, exactly how WooCommerce core treats refunds.
If you remember one thing: balances are provable, operations never repeat, and money only moves when someone decides it should.
Holds: how checkout reserves money
When a customer pays with their wallet, the money is not taken immediately. At order placement the plugin places a hold, reserving the amount from the available balance. When the order is paid (or reaches processing or completed), the hold is captured into a real debit. If the order is cancelled or fails first, the hold is released and the reservation disappears without the balance ever changing.
This mirrors how card authorizations work and it is why you may see two numbers for a wallet: the balance (what the ledger says) and the available balance (balance minus pending holds).
The transaction types you will see
| Type | Direction | What it means |
|---|---|---|
| Order payment | debit | A captured hold: wallet money collected for an order. |
| Refund to wallet | credit | A refund returned as store credit, linked to the real refund record. |
| Top-up | credit | The customer added funds through a payment gateway. |
| Balance adjustment | either | You (or a teammate) credited or debited manually, with a required reason. |
| Migrated balance | credit | The opening balance imported from a previous wallet plugin. |
Developers can register their own types; see the developer API.
Stuck, or found a gap in these docs? Tell us and a human who works on the plugin answers.
Contact support →