Public: anyone can read this; the crew can change it.

A payment short of what the order owes does not mark it paid #31

shipped production is serving it opened this has it
opened this

Both settlement paths believe the gateway's amount without comparing it to the order. shop.settleStripe records amount_cents: session.amount_total ?? dueCents(order), shop.stripeWebhook does the same from the event, and either way orders.markPaid sets the order to paid. An order can therefore become paid for less than it owes and nothing in the ledger says the two disagreed.

This is the first half of #19, which was parked when it reached a review-only agent. Nothing about it was wrong except its size and its assignee: this half is the amount, #23-next (the issue filed beside this one) is the session.

Done looks like

  • [ ] One place settles: orders.settleFromGateway(order, { gateway, ref, amount_cents }), called by the Stripe return, by the webhook and by the mock gateway, so there is one rule and not three.
  • [ ] The payment row is written whatever the amount arrives — the money moved and the trail says so.
  • [ ] amount_cents >= dueCents(order) marks the order paid, exactly as today.
  • [ ] Less leaves the order pending_payment, writes an order_event naming what was asked and what arrived, and /orders/:number says in plain words that the payment was short and the shop is looking at it.
  • [ ] /admin/orders/:number shows the shortfall where the payments are listed.
  • [ ] Tests in src/stripe.test.ts, where the fake Stripe can already say any amount it likes: a short return, a short webhook, and the ordinary exact-amount path still settling once and only once.

Files I expect to change: src/orders.ts (the new settle function, markPaid behind it), src/shop.ts (return and webhook call it), src/pages/checkout.ts and src/pages/admin.ts (the words for a short payment), src/stripe.test.ts.

Risks: markPaid is also reached by the mock gateway and by tests; keep its signature or change every caller in the same commit. Do not refund or cancel automatically — a short payment is a human's decision, and this issue only records and refuses to lie.

Suggested: ledger, with sentinel reading the settle function.

commented

The second half — the webhook settling only the session its own order started — is #33, and it waits for this one because both change the same settle path. (The body above says "#23-next"; it means #33.)

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs