Orders and fulfilment
Stripe’s Orders API is gone and has no server-side replacement, so an order is a record Beluga owns. Stripe remains the authority on payment; everything about fulfilment lives here.
The model
Section titled “The model”An order has an id and a short reference (the first eight hex digits, uppercased,
which is what a customer quotes), the buyer’s email, a status, currency, and
subtotalCents, shippingCents, taxCents, discountCents, totalCents and
refundedCents, all integer cents. It carries the shipping address Stripe
collected, an optional carrier and tracking number, an oversold flag, and a
timestamp.
Each line snapshots productName, variantLabel, sku and unitPriceCents
at purchase, so an order always renders as it was bought even after the product is
renamed, repriced or deleted. productId and variantId are nullable for that
reason. options holds the buyer’s non-priced choices.
Statuses
Section titled “Statuses”| Status | Set by | |
|---|---|---|
pending |
Checkout Session created | |
paid |
The Stripe webhook, and nothing else | Ordered |
processing |
The admin | Processing |
shipped |
The admin, with carrier and tracking | Shipped |
refunded |
The charge.refunded webhook, once the whole charge is covered |
Refunded |
cancelled |
The admin |
templateForStatus in server/email.ts maps a status to a template; add a status
and an .hbs pair and it is picked up. Until SMTP_URL is set, each email is
logged rather than sent.
Outbound events
Section titled “Outbound events”order.paid on payment, order.updated on any fulfilment change including
carrier and tracking, order.cancelled on cancel (not order.updated, so you do
not have to diff), and order.refunded on any refund. See
Outbound webhooks.
Oversold
Section titled “Oversold”Set when payment succeeded but stock ran out in the meantime. The money is taken, so the order is recorded and flagged for the merchant rather than silently dropped.
The admin
Section titled “The admin”Orders lists and filters by status. An order’s page shows the lines, the
address, the money breakdown, the fulfilment controls, and a refund button that
calls Stripe and stops there; see Refunds and restocking.
GET /api/admin/orders.csv streams the lot; see Order CSV export.
Customers
Section titled “Customers”A buyer retrieves a guest order by its unguessable session id from the
confirmation email. A customer account sees its order
history under /account, and only orders under a verified email are linked there.