All work
D2C CommerceLive

One Bite Candy

One bite, endless delight

A bilingual candy storefront where the interesting engineering is invisible: a cash-first checkout, a courier network that never calls you back, and a deployment that ships itself.

Retail & FMCG · 2026
One Bite Candy — One bite, endless delight

Client / Sector

One Bite Candy - direct-to-consumer confectionery, jelly candy, chocolate, mixbox and gift packs

Market

Algeria, nationwide, French and Arabic

Engagement

Brand and UI, storefront, admin console and API engineering, carrier and payment integration, deployment pipeline

Status / Year

First production release, 2026

01 — Background

The situation

The default confectionery operation in Algeria runs on a notebook. An order arrives as a message, someone writes down a name and an address, someone else calls a courier, and the money comes back in cash at the customer's door days later. Every step works and none of them is a system, so the whole thing holds until volume rises and then quietly stops holding.

The two structural facts that shape any storefront built for this market are cash and carriers. Card penetration is low and trust in paying a new brand online is lower, so cash on delivery is not a fallback - it is the primary flow, and everything from address capture to order confirmation has to be designed for it. Delivery, meanwhile, is fragmented across dozens of private couriers, most of them reachable only through white-label aggregator platforms where every company has its own endpoint and its own credentials.

Language is the third fact. One Bite Candy speaks to a customer base that reads French and Arabic interchangeably, and a candy brand cannot afford a second-class Arabic experience where the layout is mirrored badly and the numbers run the wrong way. Both languages had to be first-class from the first commit, including the parts nobody thinks about - form validation messages, delivery states and carrier status labels.

02 — Constraints

What made this hard

Checkout has to assume nobody pays online

The order is not a transaction, it is a commitment to pay a courier later. That inverts the priorities of the whole flow: what matters is a phone number that answers, an address a driver can find, and a confirmation step the merchant can act on - while still making online card payment a first-class option for customers who prefer it.

The carrier network has no doorbell

The delivery aggregators used across Algeria are pull-only: they expose an API you can query, but they do not call your server when a parcel moves. Customers still expect a tracking page that shows where their order is, so the system has to manufacture the freshness that the carrier never pushes.

Two languages, two directions, one layout

Arabic is not a translation of the French storefront, it is a mirrored version of it. Direction, alignment, iconography, number and date formatting, and every carrier status string have to be handled as part of the layout contract rather than patched afterwards, or the Arabic side always feels like the afterthought it was.

The order lifecycle is not finished being designed

Cash-on-delivery operations keep inventing states: awaiting confirmation call, confirmed, dispatched, refused at the door, returned to sender, re-dispatched. A schema that treats the status set as fixed turns every operational lesson into a database migration and a deployment window.

A small brand team cannot own a release process

The people running a candy brand should be adding products and answering WhatsApp messages, not coordinating a deploy. Shipping had to be something the pipeline does correctly and safely, including when a build is broken, without anyone on the client side being on call for it.

03 — Method

How we approached it

We built One Bite Candy as an operations platform with a storefront attached, rather than a storefront with operations bolted on. The catalogue is the easy half; the half that determines whether the business works is what happens between an order being placed and a parcel being handed over in a wilaya six hundred kilometres away.

That led us to a single typed codebase holding three applications: the API and domain, the bilingual storefront, and the merchant console. A change to an order state or a money type therefore breaks the build rather than production. The domain layer is modelled explicitly, with commands for the things that change the world, because in a cash business the order lifecycle is the product.

01

Brand and storefront language

We set the visual system first: a bright, playful, confectionery identity that survives being rendered in two scripts and two reading directions. Every component was designed knowing it would exist in a mirrored version.

02

Domain and API

A typed API server over Postgres with a layered domain architecture, commands and queries separated, and money represented in integer minor units end to end. The order lifecycle was modelled as explicit transitions rather than as a status field anyone can set.

03

Bilingual storefront

The customer-facing application was built with a strict presentation pattern (page to view model to service to API client) so that business logic never leaks into components and both language variants render from the same view models rather than from duplicated screens.

04

Delivery and payments

We implemented a carrier provider abstraction with multiple Algerian delivery networks behind one interface, a merchant-facing settings screen for adding a carrier and its credentials, a dispatch command that creates the parcel, and a scheduled tracking refresh that keeps the customer's tracking page current. Cash on delivery and a local online payment rail sit side by side at checkout.

05

Deployment pipeline

The whole stack runs containerised behind a reverse proxy with automated certificates. A push to the main branch triggers type checking, a single build of each application, and a health-gated deployment that rolls itself back if an application does not come up cleanly.

04 — Delivery

What we shipped

Storefront

  • Bilingual French and Arabic catalogue with a fully mirrored right-to-left layout
  • Collections for jelly candy, chocolate, mixbox and gift packs
  • Product pages with variant and pack selection
  • Cart and checkout designed for cash-on-delivery address capture
  • Order tracking page showing a live carrier state in both languages
  • WhatsApp support entry points woven into the buying flow

Checkout, payments and delivery

  • Cash on delivery and local online card payment side by side
  • Wilaya and commune selection with delivery pricing at checkout
  • Nationwide coverage across all 58 wilayas
  • Order confirmation flow built around a callable phone number
  • Money handled in integer minor units from cart to invoice

Merchant console

  • Catalogue and collection management
  • Order pipeline with an extensible status vocabulary
  • Courier configuration: add a delivery company and the credentials it issued the merchant
  • Dispatch action that creates the parcel with the selected carrier
  • Scheduled tracking refresh across all active shipments
  • Role-separated admin application, deployed independently of the storefront

Platform

  • Single monorepo holding API, storefront and admin with shared types
  • Layered domain architecture with explicit commands and queries
  • Fully containerised stack behind a reverse proxy with automated TLS
  • Deploy on push with type checks, health gates and automatic rollback
  • Environment-driven configuration per deployment target, kept out of application code
05 — Under the hood

Engineering decisions

The choices that shaped the build, and what each one traded away.

01

The courier layer is an interface, not an integration

Algerian last-mile delivery is a field of white-label aggregators where each delivery company issues its own account and its own credentials. Hard-coding one carrier would have made switching a rewrite, so a carrier is a stored record behind a single provider interface, and the merchant adds or swaps one from the admin console. The cost is normalisation work: every provider has to be mapped onto one internal status vocabulary, and a carrier that invents a field we do not model still needs code rather than a settings change.

02

The carrier does not call us, so we call the carrier

With no delivery webhooks available, we built a scheduled refresh that batch-polls only shipments still in flight, writes the carrier state back to the order, and surfaces it as a live badge on the customer's tracking page. Polling everything constantly would be wasteful and would run into rate limits; polling nothing would leave customers refreshing a dead page. The trade-off we accepted is eventual consistency - a parcel that moves just after a cycle shows the previous state until the next one - and we made the interval configurable so freshness can be tuned against carrier limits.

03

Order status is a string column, not a database enum

A Postgres enum would have given us database-level guarantees and made every new operational state a migration coordinated with a deployment. Cash-on-delivery operations invent states faster than that - refused at the door, returned, re-dispatched - so the status is a bounded-length text column and the domain layer owns the valid set and the legal transitions. We gave up a database constraint to gain the ability to add a state in an afternoon, and paid for it by centralising every transition in one command instead of letting call sites write the field.

04

One money type, two number systems

All money is stored and computed as integers in minor units, so discounts, delivery fees and totals never accumulate floating-point drift. Presentation is then a locale concern: the same amount renders under French and Arabic conventions, alongside dates and carrier statuses that also localise. The trade-off is that every display surface must go through a formatter and no component may ever print a raw amount - a discipline that only holds because the presentation layer is strictly separated from the data.

05

Deploy on push, with a health gate and automatic rollback

A merchant team should never own a release ritual, so a push to the main branch type checks the whole workspace, builds each application once, and deploys it behind a health check that rolls back if the application does not come up. The honest limit of this design is that a health gate proves a process started, not that a release is good - so it protects against broken builds and bad configuration, not against a bad feature, which is still what code review is for.

ReactNode.jsDocker VPSEcoTrack deliverySlickPay
06 — Result

The outcome

One Bite Candy now has a storefront that takes orders in French and Arabic without either language feeling secondary, and a console where an order travels from placed, to confirmed, to dispatched with a carrier, to a tracking state the customer can read - inside one system rather than across a notebook, a phone call and a courier's own dashboard.

The operational leverage is in the carrier layer. Because delivery companies are configuration rather than code, the brand can change or add a courier as commercial terms change, without a development cycle and without a migration. That matters more in Algeria than it would elsewhere, because carrier relationships here are negotiated locally and change often.

This is a first production release. The platform, its deployment pipeline, its payment paths and its delivery integration are live; the brand's job now is merchandising: loading the full range, the photography and the campaigns on top of machinery that is already running. Building the operations layer before the catalogue is the right order for a business whose hard part is fulfilment, but it does mean the storefront's first weeks are about product, not engineering.

58

Wilayas reachable

Checkout resolves delivery against the full national wilaya list and dispatches to nationwide carrier networks.

2

Languages, fully mirrored

French and Arabic are both first-class. Arabic runs right to left across layout, forms, number formatting and carrier status labels, not as a translated overlay.

2

Payment paths at checkout

Cash on delivery and a local online card rail, offered side by side rather than one replacing the other.

3

Applications, one codebase

Storefront, merchant console and API server share types and domain rules from a single monorepo, so a contract change breaks the build rather than production.

07 — Trade-offs

Honestly

The compromise we are least comfortable with is the tracking cadence. Polling a carrier on a fixed interval is the correct answer to an ecosystem without webhooks, but it is still a workaround - it costs requests, it introduces a lag between reality and what the customer sees, and it will need retuning as order volume grows. If any Algerian aggregator ships real delivery webhooks, we would retire the poller the same week.

The other honest note is sequencing. We built the operations spine of carriers, payments, order lifecycle and deployment ahead of the catalogue and the campaign, which is deliberate for a business where fulfilment is the constraint, but it means the platform's capability is currently ahead of what a first-time visitor sees. The next phase is merchandising work, not platform work.

08 — Questions

Frequently asked

Can you build an online store in Algeria with cash on delivery and delivery to all 58 wilayas?

Yes, and we design for it as the primary flow rather than as an option. Checkout is built around a callable phone number, a wilaya and commune, and a findable address, with delivery pricing resolved nationally and online card payment offered alongside cash for customers who prefer it.

How do you integrate an Algerian courier or delivery aggregator into an online store?

We put carriers behind a single provider interface and store each delivery company as its own record with its own account details, so the merchant adds or switches a courier from the admin dashboard. Dispatch, parcel creation and status mapping are handled by the platform, and because these networks do not push updates, we run a scheduled refresh that keeps active shipments current.

Can an online store work properly in both Arabic and French?

It can, if right-to-left is part of the layout contract from the start. We build both languages from the same components and view models, with mirrored layout, localised number and date formatting, and translated operational strings including delivery statuses - so neither side reads like a translation of the other.

After launch, do I need a developer to add products or change couriers?

No. Products, collections, orders and courier configuration all live in the merchant console, and deployment is automated, so day-to-day commerce and delivery decisions are yours. Developers are only needed when the platform itself needs a new capability.

Building something in this territory?

Tell us what you are trying to ship and we will tell you how we would approach it.