ARKA: a configurator and a real checkout on one page
ARKA is a carved walnut object that holds solid 50 mm spheres, made to order in a first run of twelve. Urbano DX designed the product, built the page, and runs the orders. Every decision a buyer makes changes the specification and the price in front of them, and a small API re-checks the whole configuration, including the shipping country, before Stripe is ever asked for a payment page.
Open ARKA
The product page opens on one form and one claim, with the render labelled as a render
Three decisions (sphere count, form, material) with mass and price recomputed on every change
The range: nine forms, each with its own dimensions, mass, and bench time behind the price
The specification table and the reserve form, both generated from the same source of truthWhat it is
A single page that sells a physical object. Nine forms, three sphere counts, four sphere-material choices, and an optional engraving, all of it made to order in a first run of twelve and shipped within six weeks. The imagery is rendered rather than photographed, and the page says so next to every picture instead of hoping nobody asks.
- Nine forms, from a long flat piece to a standing sculpture
- Copper, steel, ceramic, or a mixed set of spheres
- Live specification: dimensions, mass per sphere, total mass
- Every plate opens full screen and turns on rendered frames
What was built
A prerendered static page in front of a small FastAPI service. The catalogue is one source of truth: masses are computed from material density rather than typed in, the server mirrors only what it must validate, and a test fails the build if the two ever disagree. Reserving posts the configuration to the API, which re-checks the form, the material, the engraving, and the shipping country, creates the Stripe Checkout Session with that configuration attached, and emails the studio the intent. The webhook that confirms payment is idempotent, so a retry from Stripe cannot produce a second order.
- Configurator with live mass and price, no page reloads
- Server-side validation of every combination before payment
- Stripe Checkout Sessions carrying the configuration as metadata
- Idempotent payment webhook plus studio notification email
- Stack: Vite, React, TypeScript, FastAPI, Stripe, nginx
What it demonstrates
This is the difference between a payment link and commerce. A payment link cannot refuse an unshippable country, cannot keep the page and the payment agreeing on what was ordered, and cannot capture the buyer before the money. Moving those rules to the server is a day of work that removes a class of support tickets, and the same pattern carries straight over to client quote flows, booking flows, and configurable products.
- Product rules live on the server, not in the button
- Catalogue drift is a failed build, not a customer complaint
- The page still reads and sells with JavaScript blocked
- One pattern for any configure-then-pay flow