The problem
A blind is a made-to-measure product: the price comes out of a formula involving width, height, fabric, valance and control type. An e-commerce platform works with fixed registered variants, not with formulas. In practice the customer asked for a quote over WhatsApp and someone worked it out by hand.
Shipping had the same problem by a different route. A 1.50 m blind becomes a 155 cm tube, and the express carrier configured in the store quoted R$ 8,911 per unit. It was not a bug: the dimensions were right and it was the package that blew past the limit of that shipping method.
What I built
- A configurator on the product page, inside the store’s Twig template, with the price updating at every choice of measurement, fabric, colour, valance and control type.
- A pricing and variant Worker, which receives the configuration, applies the business rule and creates the matching variant through the REST API, so that the configured item genuinely exists in the cart.
- Live shipping quotes: the Worker is registered in the store as a carrier, so checkout calls it, and it quotes at Braspress and returns real cost and delivery time.
- Home card prices calculated in the template from the value registered in the admin panel, so the store owner adjusts in one place and all 17 products follow.
Technical decisions
Not escaping the platform’s checkout. The temptation was to build a parallel cart. That would have broken coupons, shipping, reporting and the tax integration, everything the store already did. Creating the variant on demand was more work up front and less trouble forever.
Carrier credentials never pass through the theme, and a failed quote does not take down the sale. The Worker is what talks to Braspress, so username and password never reach the browser. And when the quote fails, the response comes back with an empty shipping list instead of an error: the buyer loses one delivery option, not the purchase.
Shipping dimensions declared, not calculated. The first version derived weight and volume from the area of the piece. But the operation packs everything into the same tube, so I moved to declaring the real package, with the length coming from the width of the blind. The shipping charged did not change, because across the whole size range the carrier bills by dimensional weight, and the number now describes what actually leaves the warehouse.
The business rule became a document before it became code. Every change to the pricing formula went into the documentation first and only then into the Worker. Without that there is no way to tell whether an odd price is a bug or the rule, and with a made-to-measure product that doubt comes up every week.
Tracking wrapped entirely in try/catch. The configurator submits the order through its own request and, because of that, skipped the platform’s analytics layer: the 17 products recorded visits and purchases, with nothing in between. I added the event call by hand, isolated, because an analytics failure must not stop anyone from buying.
How I verified it
The colour that vanished from the order. The store owner noticed an order arriving without the chosen colour. I called the configurator’s own calculation function live on three product pages and all three returned the variant name without the colour. It was not an isolated case: since a change made six weeks earlier, when each colour became a separate product, every order had been coming out that way. The colour selector was being cleared by the very redirect that took the buyer to the colour’s page.
The fix moved to deriving the colour from the page URL. Not using the product name was a deliberate choice: the operations manual handed to the client already asks them not to change URLs, whereas the name is something they do edit for SEO, and matching by name would have made the colour disappear again, silently, on the first rename. Before deploying, I validated on the real pages, deliberately including two colours with similar names to confirm they were not confused with each other.
The surcharge that looked like it was growing. An add-on showed up as ”+ R$ 98.00/m” on a 1.40 m blind, which gave the impression of a fee that climbed with size. I compared the final price with and without the accessory at three different widths: the difference divided by the width gave exactly the same rate in all three. The charge had been right from the start and only the label was wrong, so the fix went into the text and not into the calculation.