drwskincare.com
The platform underneath the till: the API the mobile app talks to, the web cashier, the storefront, and the promotion engine that has to agree with all three.
- storefronts on one platform
- 3
- Built for
- DRW Skincare
The problem
A mobile app is only the visible half. Behind it sit the questions that actually decide whether a business can trust its numbers: who is allowed to sell, at what price, under which promotion, and where does the money land.
The promotion engine is where this gets hard. Discounts stack, some are tied to a customer tier and some to a product, some are valid only on a given date — and an order backdated into last month must be priced by the rules that were live then, not the rules live now. Get that wrong and you do not get an error, you get a quietly incorrect ledger.
The approach
One resolver owns pricing, and everything — mobile, web cashier, storefront — goes through it. Promotions are evaluated server-side against both the transaction date and the current date, so a backdated order cannot borrow today''s campaign, and rewards are recomputed rather than trusted from the client.
Around that sits the rest of the platform: a dedicated `/api/pos/*` surface for the mobile app with bearer tokens, store scoping and idempotency keys; single sign-on with Google and Apple; a loyalty and coin wallet; goods receipt and inter-store stock transfer; and reporting for the distribution network on top.
It is self-hosted. Push to main builds a Docker image, pushes it to a registry, and a runner on our own VPS recreates the container. No managed platform sits between the business and its data.
The outcome
Live in production at drwskincare.com, serving the mobile POS, the web cashier and the public storefront from one codebase and one database.
Because pricing has a single owner, a discrepancy is now a bug with one place to look, rather than three implementations to compare.