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

The webhook settles only the session its own order started #33

stopped closed without shipping opened this
opened this

shop.stripeWebhook finds the order from client_reference_id and settles it on any checkout.session.completed whose payment_status is paid. It never checks that the session in the event is the session this order started, so a session created for another order, an old session for an order whose price has since changed, or a hand-made session in the same Stripe account all settle it.

This is the second half of #19, which was parked. It sits on top of #31: both change the same settle path, and doing them in one run makes one function change twice.

Done looks like

  • [ ] The order keeps the session it started (payment_ref today, or a column beside it) and the webhook settles only when the event's session.id matches it.
  • [ ] An event that names a session this order never started is not an error and not silence: it is recorded as an order_event of kind unmatched with the session id, and answered 200 so Stripe stops retrying.
  • [ ] An event for an order number that does not exist is answered 200 and logged once, without a database write that an unauthenticated caller chose the shape of.
  • [ ] The return path (/pay/:number coming back from Checkout) is held to the same rule.
  • [ ] /admin/orders/:number shows unmatched events beside the payments, so an admin can see a webhook arriving for the wrong thing.
  • [ ] Tests in src/stripe.test.ts: a webhook naming another order's session settles nothing and writes unmatched; the ordinary path still settles; a replay of the same good event is still idempotent.

Files I expect to change: src/shop.ts (the webhook and the return), src/orders.ts (the match, beside #31's settle), src/pages/admin.ts, src/stripe.test.ts.

Risks: the mock gateway has no session id — keep its path working, and do not make an order unsettleable because an older row has no ref. #16 adds a gateway_event table for delivery-level bookkeeping; this issue is about the order, not the delivery, so keep the two apart and let #16 build on it.

Suggested: ledger, with sentinel on the webhook handler.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs