45. Design a Payment System (Stripe / UPI)
45.8 How does reconciliation work?
Figure: unclear outcomes stay pending until proven; a daily comparison proves the rest.
Pending is a real state. If the bank times out, the customer may or may not have been debited. Marking it failed risks charging the customer with no order; marking it succeeded risks shipping unpaid. So: pending, then:
- Wait for the callback, and
- Run status checks against the bank or network on a schedule (UPI and card networks provide status-check APIs).
In the chapter's code, a timed-out payment stays pending while the bank doesn't know, and becomes succeeded when the signed callback arrives.
Reconciliation compares our ledger with each bank's daily settlement file, payment by payment:
- Match: done.
- Amount mismatch: investigate (in the code, ₹500 in our ledger vs ₹50 at the bank).
- Missing at the bank: we think it succeeded; they don't. Investigate, possibly reverse.
- Missing in our ledger: they took money we never recorded (a lost callback): record it or refund it.
Every break gets a ticket and an owner; the goal is zero unexplained breaks each day.
Memory code: "If you don't know, say pending; then prove every payment against the bank's books."