A WooPayments balance can include funds held in reserve, released later, adjusted, or moved into a payout after the original order period closes. An ending balance alone cannot explain which transactions created the hold, how old each reserve is, or whether a release reached available cash. A reserve subledger preserves that chain without treating a hold or release as new revenue.
Use this for WooCommerce stores with rolling reserves, dispute-related holds, delayed availability, multiple currencies, or month-end differences between orders, processor balances, payouts, and bank cash.
Quick answer
Create one reserve row per stable reserve or balance-transaction ID and currency. Link it to the source charge, order, dispute, hold amount, created time, expected release rule, actual release transaction, payout ID, and bank deposit. Age open rows daily. A reserve release moves cash classification; it does not create a second sale.
Test scenarios to run
Run the same controlled fixture across these branches. Write down the expected result before testing so a surprising response is easy to identify.
| Scenario | Fixture | Expected result |
| Normal hold and release | One reserve with documented release date | Open row closes against one release transaction and later payout |
| Partial release | Reserve released in two amounts | Both release IDs remain linked and residual stays open |
| Dispute hold | Hold tied to a disputed charge | Reason and resolution path remain separate from rolling reserve |
| Multi-currency | USD and EUR reserve rows | Each currency reconciles without hidden conversion or netting |
Diagnostic table
Use this table to connect the observed behavior to evidence and a verification step.
| Action | Evidence to collect | How to verify |
| Create the reserve subledger and stable key policy. | Export reserve or balance transaction ID, source charge, order ID, dispute ID, currency, held amount, created time, reason, and status. | Opening reserve plus holds minus releases and adjustments equals the closing reserve by currency. |
| Load opening rows, new holds, releases, adjustments, and related business IDs. | Record expected release date or rule, actual release transaction, release time, available-balance movement, payout ID, and bank deposit. | Every closed row has actual release IDs and no unexplained residual. |
| Reconcile each currency to the WooPayments reserve and available balances. | Separate rolling reserve, dispute hold, refund, fee, negative balance, and payout-in-transit entries. | Released cash maps to available balance, payout, and bank deposit without duplicate revenue. |
| Link released amounts to the payout and bank-clearing workflow. | Age open reserves by currency and reason, with owner and escalation threshold. | Every aged open row has reason, expected rule, evidence, owner, and escalation date. |
What to check first
- Export reserve or balance transaction ID, source charge, order ID, dispute ID, currency, held amount, created time, reason, and status.
- Record expected release date or rule, actual release transaction, release time, available-balance movement, payout ID, and bank deposit.
- Separate rolling reserve, dispute hold, refund, fee, negative balance, and payout-in-transit entries.
- Age open reserves by currency and reason, with owner and escalation threshold.
- Reconcile opening reserve plus new holds minus releases and adjustments to the closing processor reserve balance.
Field notes
- Use stable processor IDs as keys. Amount and date alone are not unique.
- Keep one subledger per settlement currency and document any approved currency conversion.
- An expected release date is a forecast until the processor produces an actual release transaction.
Useful command or data shape
Adapt paths, IDs, and privacy handling to the site before running commands or storing data on production.
reserve_id,currency,source_order,held,created,expected_release,actual_release,payout,status
res_901,USD,WC-10422,2400.00,2026-07-01,2026-08-01,2026-08-02,po_812,closed
res_922,USD,WC-10510,875.00,2026-07-14,2026-08-14,,,open
res_440,EUR,WC-9981,610.00,2026-06-30,policy_review,,,aged
Why this usually happens
- Reserve holds and releases occur on processor timing that differs from order and bank dates.
- Net payouts combine released funds with new charges, refunds, fees, disputes, and adjustments.
- Accounting teams may post the release as income because the original reserved sale is no longer visible in the current period.
Decision rule
Close a reserve only when actual release transactions fully explain the held amount and any released cash is traceable into available balance and payout. Never close from the expected date alone.
Production verification checklist
- Opening reserve plus holds minus releases and adjustments equals the closing reserve by currency.
- Every closed row has actual release IDs and no unexplained residual.
- Released cash maps to available balance, payout, and bank deposit without duplicate revenue.
- Every aged open row has reason, expected rule, evidence, owner, and escalation date.
Safe fix order
Use a sequence that makes each result easy to prove. Stop when new evidence changes the scope or owner of the problem.
- Create the reserve subledger and stable key policy.
- Load opening rows, new holds, releases, adjustments, and related business IDs.
- Reconcile each currency to the WooPayments reserve and available balances.
- Link released amounts to the payout and bank-clearing workflow.
- Review aged exceptions with processor evidence and an accountable owner.
Mistakes to avoid
- Do not change several production layers at once. Preserve the failing evidence and isolate one variable per test.
- Do not use a successful status or screen message as the only proof. Verify the business outcome and the underlying record.
- Do not leave debug logging, broad credentials, test orders, or temporary exceptions active after the review.
- Do not close the incident without recording the fixture, timestamps, owner, result, and rollback point.
Questions teams ask during testing
Can this be tested on staging?
Start on staging with production-like versions, cache, data shape, and integrations. Finish with one controlled production fixture when the result depends on real routing, provider, or edge behavior.
What evidence should be retained?
Keep the smallest useful set: stable IDs, UTC timestamps, sanitized request or log excerpts, expected result, actual result, version inventory, and the final verification.
When should the change be rolled back?
Roll back when a core revenue, privacy, security, or publishing path fails and the cause cannot be isolated inside the approved maintenance window.
What to tell the client or owner
Give the owner the affected versions, exact fixture, stable IDs, UTC timeline, before and after evidence, decision, rollback point, unresolved risks, and next review date.
When HandL WP should help
Bring in help when this affects leads, checkout, search visibility, security, paid media reporting, or a client production site. HandL WP can trace the issue through WordPress, hosting, cache, tracking, and Search Console, then verify the workflow after the technical fix.
If this is active on a production site, build a WooPayments reconciliation ledger.
Related HandL WP guides
Use these related guides when the same issue touches tracking, security, checkout, or crawler visibility.
Helpful references