Skip to content

[finance][P1 HIGH] Credit-funded B2C bookings break the sum(legs) === Payment.amount money invariant #1347

Description

@teetangh

Summary

For a B2C checkout funded partly (or fully) by referral credit, the recorded payment legs violate the invariant that the legs sum to the Payment.amount. The CARD leg is stored post-credit, and the REFERRAL_CREDIT leg is recorded positive, so sum(legs) !== Payment.amount. This breaks downstream money reconciliation, refund math, and any auditor that sums legs.

Where it lives

  • lib/payments/operations/checkout.ts:3346-3399 — leg construction for the credit + card split; the CARD leg is post-credit.
  • lib/payments/operations/checkout.ts:2953 — the amount/legs assembly point.

Concretely: for an invoice of ₹X paid as (Credit=C, Card=X−C), the CARD leg is ~X−C (post-credit) while the REFERRAL_CREDIT leg is +C (positive), so the two legs sum to X (not a mismatch in magnitude) — but the semantics are inverted: a credit-leg that is positive rather than a negative offset, with the card leg already reduced, means a naive sum(legs) === amount check or a refund that re-adds credit can double-count. The invariant is documented as sum(legs) === Payment.amount and the current encoding makes it unverifiable/unstable.

Why it is real

Money-integrity: refund-on-cancellation and the ledger post either over- or under-attribute the credit, and SonarQube/static checks cannot validate the invariant because the encoding is internally inconsistent.

Suggested fix direction

  • Decide the canonical encoding (recommend: CARD leg = full pre-credit amount, REFERRAL_CREDIT leg = negative offset, so CARD + CREDIT = amount), and make checkout emit it.
  • Add a unit test asserting sum(legs) === Payment.amount for credit-funded, fully-credit, and cash bookings.
  • Check the refund/reversal engine (refund.ts, reversal-engine.ts) against the chosen encoding.

Terms

payments · credit · referral · checkout · ledger · money invariant · refund

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingcriticalCritical priority itemsfinancePayments, refunds, earnings, payouts, invoicing, ledgerlaunch: pre-mvpGates launch — money, data, or a failure we would not detect

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions