How a paid personalisation upsell went from inconsistent cart states to a defined, testable customer journey, built in six hours without a rebuild.
Client
Zeitholz Watches
Platform
Shopify · 5 languages
Scope
Audit · debug · localise · QA
Coverage
Text + image engraving · couples watches · multi-product carts
Constraint
15-hour monthly retainer: repair, not rebuild
Delivered in
6h of an 8h estimate

The cart could retain a paid engraving product after its watch had been removed.
No errors. Just quiet trust leaks at checkout
Zeitholz sells wooden watches with an optional paid engraving: a high-margin personalisation upsell. Engraving is done in-house on equipment the store already owns, so beyond operator time the incremental cost is negligible. The flow never failed with a visible crash. Instead, it produced inconsistent cart states under particular combinations of cart actions, products, and engraving types:
- Removing an engraved watch could leave the paid engraving behind: an orphaned charge of €18 or €32 depending on the configuration, for a watch no longer in the cart.
- Removing the engraving charge on its own could leave engraving text or image data still attached to the watch.
- Engraving details could appear duplicated in the cart.
- The German word “GRAVUR” appeared untranslated on the English storefront.
- Image-based engravings gave customers weak confirmation that their upload was correct.
None of this threw an error. It created avoidable commercial risk instead: confused customers, abandoned carts, support requests, and incorrectly configured orders.
Each engraving lived in two places at once
Watch
+ custom properties
Paid engraving
€18 / €32 product
Two representations that must stay synchronised across every cart combination
Each engraving existed in two places at once: as a separate paid product in the cart, and as custom properties attached to its watch. Couples watches used a different engraving product and logic again.
The repair had to keep those representations synchronised across every combination: text and image engravings, one watch or several, regular and couples models, on any of five storefront languages. That architecture is why ordinary removal logic kept producing inconsistent states, and why the fix required understanding the bespoke implementation, not changing button copy.
Repair, not rebuild
- Modelled the state relationship between the watch, the paid engraving product, and the custom properties attached to the watch.
- Defined the invariants: a paid engraving must never exist without its watch, and a watch must never retain engraving data without its paid engraving.
- Built a regression matrix across product type, engraving type (text and image), cart composition, device, and language.
- Patched incrementally, retesting the matrix after every change instead of shipping one large risky patch.
- Stopped at the commercial objective, deliberately deferring enhancements that didn’t protect order integrity.
| Scenario | Before | After |
|---|---|---|
| Engraved watch removed | €18/€32 charge could remain | Engraving removed automatically |
| Charge removed alone | Data stayed on the watch | Blocked, with clear guidance to remove the engraved watch and re-add it without engraving |
| Multiple / couples watches | Engraving could associate with the wrong product | Each engraving stays tied to its intended watch |
| Image engraving | Weak confirmation, duplicated details | Upload preview added; cart presentation cleaned |
| Localisation | “GRAVUR” on the English store, untranslated properties | Relevant labels and properties localised across tested languages |
| Cart clarity | An ambiguous “Continue” jumped straight to the cart with items already added | Validation requires engraving content, and an explicit “Add watch with engraving to cart” action |
New interface strings were added through locale keys rather than hardcoded, and after scenario testing the principal behaviour was verified again on the published theme. Delivered in six hours, against an approved eight-hour estimate.

The modal action button showed €99.95, the watch price alone, while the customer was configuring an €18 engraving.

Validation plus an explicit “Add watch with engraving to cart” action, replacing a “Continue” that gave no warning the next screen was already the cart.

The cart could retain a paid engraving after its watch was removed.

The repaired cart: engraving linked to its watch, with a localised notice explaining how to remove it correctly.

Added for image engravings: a visible preview of the uploaded file, so customers get confirmation of exactly what will be engraved before adding to cart.
I considered them, but set them aside on purpose:
01A full popup redesign
02Simulated engraving placement previews
03Engraving editing from the cart
04A rebuild of the whole feature
→Distinguishing integrity fixes from attractive extras is what keeps a small retainer productive.
My role: customer-journey audit · requirements definition · Shopify theme debugging and implementation · localisation · regression testing
I turn fragile, bespoke ecommerce functionality into a defined and testable customer journey, without automatically recommending an expensive rebuild.
Custom functionality behaving unpredictably in your store?
I find the customer-journey bugs that can create confusion, abandoned carts, or misconfigured orders, and fix them without breaking what works.
2 retainer spots available