Rebasely Beta: data may be purged

examples/storefront Public

Markdown · 29 lines · 1.8 KiB · at e83464e

---id: 0010-payments-workertype: decisionowner: justinstatus: acceptedreviewed: 2026-10-15---# 0010 Put everything that talks to Stripe in a payments Worker## Context[[0005-stripe-payment-intents]] had storefront-api create PaymentIntents itself with `STRIPE_SECRET_KEY`, and a separate Worker, `storefront-stripe-webhook`, verify Stripe's webhooks. That left the secret key in the Worker with the largest surface (every public route, the admin routes, image uploads), and split Stripe code across two Workers that had to agree on metadata and on the `stripe` package version. Adding refunds would have meant a third place.## DecisionA `storefront-payments` Worker owns every Stripe call and both Stripe secrets ([[payments]]):- storefront-api calls its `PaymentsService` entrypoint over a service binding to create and cancel intents. It keeps the `Payments` interface and no Stripe code.- The webhook moves into it unchanged ([[payment-webhook]]), and `storefront-stripe-webhook` is deleted.- Results still reach orders through OrdersService ([[0006-one-writer-for-the-database]]).Still PaymentIntents confirmed with the Payment Element, still the order id as idempotency key. What changes is where the calls are made.## Consequences- A bug in a public route cannot read the Stripe secret key, because that Worker does not have it.- One Worker to change for refunds, a new API version or a second provider.- The two Workers bind each other, so a change to either interface has to be deployed in order. Checkout gains one service binding call, which stays inside Cloudflare.- Stripe's webhook endpoint moves to the payments Worker's route. Register the new URL in the Stripe dashboard before deleting the old Worker, and keep both signing secrets until the old endpoint stops receiving events.