Start with the decision#
Separate payment orchestration from accounting: provider calls move an external payment state machine, while an immutable balanced ledger records what the product believes happened.
Mechanism and state flow#
- Create one payment intent with a stable business and idempotency key.
- Advance provider state through authorized attempts and asynchronous events.
- Record balanced immutable ledger entries for recognized financial events.
- Use compensating entries for refunds or corrections rather than rewriting history.
- Reconcile provider, bank, payout, and internal totals; route discrepancies and disputes to owned workflows.
Concrete example#
Captured order and refund
A successful capture posts equal debit and credit entries tied to the order and provider transaction. A later refund creates reversing entries and its own provider workflow; neither operation edits the original ledger rows.
Architecture consequence: Balance can be replayed and audited even when callbacks repeat, arrive late, or a dispute changes the economic outcome.
Trade-offs#
| Option | Choose when | Cost or limit |
|---|---|---|
| Provider-only records | A prototype has no independent balance or audit requirement. | Weak internal reconciliation and provider coupling. |
| Double-entry ledger | Money movement and auditability are core domain state. | More modeling, invariants, and operational controls. |
| Event-sourced accounting | Temporal reconstruction is a first-class requirement. | Event evolution, projections, and specialist review. |
Failure diagnosis#
- Failure
- The provider captured funds but the client timed out before receiving the response.
- Impact
- A naive retry can charge twice or the order can remain falsely unpaid.
- Detection
- Stable idempotency lookup, provider event, reconciliation mismatch, and age of unresolved intent.
- Mitigation
- Retry the same operation key, treat ambiguous outcomes as pending, process authenticated events idempotently, and reconcile before creating a new attempt.
- Trade-off
- Pending states complicate UX but preserve financial correctness.
Design checkpoint#
Work the scenario before revealing the checklist
- Name business, provider, attempt, event, and ledger identifiers.
- Write balanced entries for capture, fee, refund, and dispute.
- Define idempotency scope and retention.
- Specify reconciliation cadence, discrepancy states, and human ownership.
Use these prompts to extend the design. The useful answer is a reasoned change, not a memorized sentence.
- Why not update the original row for a refund?
- How do you handle duplicate and out-of-order webhooks?
- Which system is authoritative for customer access while reconciliation is pending?
Related practice problems
Use the manifest-backed prompts below to apply this lesson in a complete design.
- Reporting and reconciliationStripe
- Idempotent requestsStripe
- How disputes workStripe
Sources reviewed 2026-09-04. Validate product limits, legal obligations, and operational assumptions for the system you are designing.