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

The order page never waits on Stripe: settlement happens off the render path #41

open not picked up yet opened this
opened this

shop.orderPage calls settleStripe, which does a fetch to Stripe inside a GET, with a fifteen-second timeout. A shopper coming back from Checkout on a phone can wait on someone else's network before the first byte of their receipt, and every refresh of a pending order asks again. The bar is milliseconds on the common request, and the webhook is the path that is meant to carry this news.

Done looks like

  • [ ] GET /orders/:number makes no network call. It renders from the database, and a pending_payment order holding a cs_ reference says in plain words that the payment is being confirmed and that the page can be reloaded.
  • [ ] The confirmation is still asked for on the return, but off the render path: either the response is sent and the settle runs after it — the shape AGENTS.md asks for, "work that can wait is done after the response" — or Stripe returns to a POST that settles and redirects. Pick one, and say in the pull why.
  • [ ] A settle attempt is bounded at about three seconds, and at most one is in flight per order: a shopper hammering reload does not open ten sockets to Stripe.
  • [ ] A failed or refused attempt is an order_event, never a 500 and never a blank page.
  • [ ] An order whose webhook never arrives still settles — by the sweep #15 adds or by one attempt on the next visit, whichever the pull chooses, and the choice has a test.
  • [ ] The single settlement function #31 and #33 land stays the only thing that writes a charge; nothing about their rules is loosened to make this easier.
  • [ ] Tests, with the fake Stripe #14 already put in the suite: the order page answers in milliseconds while the fake holds its reply for a second; two returns at once write one charge; a Stripe that never answers leaves the order pending, with an event and a page that says so.

Files I expect to change: src/shop.ts, src/orders.ts, src/gateway.ts, src/pages/checkout.ts, src/stripe.test.ts.

Risks: this must not grow into a job framework — one process, work after the response, no queue and no dependency. It waits on #31 and #33 because all three rewrite the same settlement path, and taking this one first would put the other two in conflict.

Suggested: ledger.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs