Back to my work Case study, NextGen Mobile

An online phone store with no platform fees.

NextGen Mobile sells handsets in Rajshahi. I built them a custom storefront, a typo-tolerant search engine, cash-on-delivery checkout and an order console, running on 1 Cloudflare Worker with 0 runtime dependencies. No monthly platform fee and no commission on any sale.

The build

The storefront I built.

The NextGen Mobile homepage
Storefront, checkout and admin, built from scratch
The work

The work, up close.

15 screens from the live site, and what each one does.

The NextGen Mobile homepage with a rotating promotional banner
Storefront

Pages load without a framework

Every page is rendered as finished HTML in a Cloudflare Worker at the edge. No JavaScript framework loads before the first product appears, which matters on the mobile connections most of this traffic uses.

0 runtime dependencies, 0 client framework

The pre-owned product row on the NextGen Mobile homepage
Real stock, front and centre

Stock appears on the homepage

Pre-owned handsets are the shop's main line, so they occupy a row on the homepage with price, colour options and a direct buy action. Landing to product page is 1 tap, with no menu required.

Price, colours and a buy action on every card

The full product catalogue with category filters and sorting
Catalogue

8 categories, filtered without a reload

One catalogue page handles category filters, text queries and sorting by price or discount. Each combination is a real URL, so a filtered view can be shared in a message or linked from a Facebook post and still land correctly.

Every filter state is a shareable URL

The pre-owned category listing with 25 handsets
Pre-owned

25 pre-owned handsets, listed individually

25 pre-owned handsets, each with its own colour options and pricing. Every second-hand unit differs in condition and storage, so each gets a full product page rather than a row in a list.

Own product page per unit, colours included

The search overlay showing iPhone results for the misspelling ifone
Search

Search corrects misspelled model names

A live query: the customer typed "ifone" and the overlay returned every iPhone in stock. The relevance engine was written for this catalogue, with edit-distance typo tolerance, a 31 entry synonym table of the terms buyers here use, and tokenization covering Bengali and English.

Typo tolerance, 31 synonyms, Bengali and English

Search results page for the query iphone
Results

Search results keep the filters

A search result loads the same catalogue view as a category, keeping the filter chips and sort control rather than a reduced results list. Weighted scoring ranks exact matches first, then prefix matches.

Search and browse share one interface

The iPhone 13 256GB product page
Product page

Price, specs, colour and 2 buy actions

Price, key specifications, colour choice, quantity and 2 actions. Buy Now goes straight to checkout, Add to cart keeps the customer browsing. Product structured data on every page lets the listing appear correctly in search results.

Product schema on every listing

The Samsung Galaxy S25 Ultra product page showing colour variants
Variants

Colour is recorded as part of the order

Selecting a finish changes the cart line, so the same handset in 2 colours becomes 2 lines. The shop packs exactly what was ordered instead of phoning to confirm, which removes a common cause of failed cash-on-delivery deliveries.

Colour carried through cart, order and email

The slide-in cart drawer after adding a handset
Cart drawer

The cart drawer keeps the customer on the page

The drawer opens over the product page so browsing continues. Rapid taps are queued and applied in order, so a double tap on a slow connection cannot produce an incorrect cart total.

Requests serialized to survive slow connections

The cart page showing a handset, subtotal and total
Cart

The cart lasts 14 days without an account

The cart is a signed cookie lasting 14 days, with no account and no database write. Every item and quantity is revalidated against the live catalogue on each read, so a stale or edited cookie cannot produce an unfulfillable order.

14 day cart, revalidated on every read

The cash-on-delivery checkout with contact, address and delivery zone
Checkout

Checkout is built for cash on delivery

Navigation is removed so there is 1 path forward. The phone field accepts Bengali numerals and the +880 and 880 prefixes, normalising them to a dialable number. Selecting a delivery zone updates the total in place, with Bangladeshi digit grouping.

Bengali numeral input, +880 normalization

The order tracking page with a phone number lookup
Order tracking

Order tracking by phone number, no account

No registration and no password. A customer enters the number they ordered with and sees their orders, statuses and totals in Dhaka time. This removes the most common reason customers phone the shop.

No accounts, no passwords, no signup step

The admin sign-in screen for the order console
Admin

The admin is behind a token-gated login

The console sits behind a token gate. Tokens are compared in constant time so the check cannot be probed by timing, the session cookie is scoped to the admin path only, and every order screen is excluded from search engines. Shown here is the public sign-in screen.

Constant-time token check, admin-scoped session

Trust guarantees covering authenticity, delivery speed, cash on delivery and support
Trust

4 guarantees stated on the homepage

Authenticity, delivery speed, payment on arrival and a phone number to call are stated on the homepage. For second-hand handsets these 4 answers decide the sale before the specifications are read.

Authenticity, delivery speed, COD and phone support

The homepage FAQ accordion covering delivery, payment and authenticity
FAQ

5 buying questions answered on the homepage

Delivery time, cash on delivery, authenticity, how to order and how to track. Keeping these on the homepage rather than a policy page lets a hesitant buyer resolve the doubt without navigating away. The content carries FAQ structured data.

FAQ structured data, no separate policy page

The client.

NextGen Mobile is a Rajshahi phone retailer built on buy, sell and exchange, trading brand new and pre-owned handsets with 100% genuine stock and cash on delivery anywhere in Bangladesh.

100%Genuine stock
3Ways to trade
2Delivery zones
At a glance

The engagement, on paper.

Client
NextGen Mobile, a mobile phone retailer in Rajshahi, Bangladesh.
Trade
Brand new and pre-owned handsets, plus buy, sell and exchange in store.
Scope
Storefront, catalogue, search engine, cart, cash-on-delivery checkout, order tracking, admin console, and transactional email.
Stack
A single Cloudflare Worker rendering HTML at the edge. No framework and no runtime dependencies.
Data
Cloudflare D1. Orders are the only records stored, so a product view never touches the database.
Search
A custom relevance engine written for this catalogue, not a plugin.
Ownership
The shop owns the code, the orders and the customer data. No platform account sits in the middle.
The challenge

6 problems with selling phones online here.

6 conditions in this market that an off-the-shelf store handles badly.

Every used handset is different

Pre-owned stock has no clean model catalogue behind it. Condition, storage and colour vary unit by unit, and a generic product template flattens exactly the detail a buyer needs.

Cash on delivery puts the risk on the shop

Nothing is paid until a courier is at the door. A wrong number or a vague address is not a support ticket, it is a handset that travelled across the country and came back.

Handset prices change weekly

Handset pricing shifts week to week. Anything that makes a price change slow or awkward means the site is quietly wrong for days at a time.

Demand arrives from Facebook, not search

Customers come from a Facebook page and word of mouth. They land expecting to see stock immediately, not to be introduced to a brand they already know.

Platform fees cut into hardware margins

Phone retail runs on thin margins. A monthly subscription and a cut of every sale take a meaningful share of the profit on each handset sold.

Buyers misspell model names

Customers search in a mix of English and Bangla, shorten names, and misspell them. A search box that only matches exact strings returns nothing and loses the sale.

The goals

7 goals, in order.

Agreed before development started, in the order they were solved.

01

Put the stock in front of them

A visitor arriving from Facebook should see real handsets and real prices in the first screen, with no brand introduction in the way.

02

Answer the trust question first

Authenticity, delivery and payment on arrival are the decision. State them on the homepage rather than burying them in a policy page.

03

Keep the path to an order short

From landing to a placed order in as few steps as possible, with no account, no password and no page that exists only to collect an email.

04

Match how people actually search

Handle misspellings, shortened names and mixed Bangla and English, because the alternative is an empty results page.

05

Make cash on delivery safe to run

Capture a dialable phone number and a real address at the point of order, so the shop can confirm before anything is dispatched.

06

Give the shop one place to work

Every order in one console, with a status that moves forward and tells the customer automatically when it does.

07

Keep the platform theirs

No subscription, no cut of each sale, and no third party holding the customer list. The shop owns what it paid for.

My strategy

The decisions I made.

6 build decisions and what each one traded off.

Render at the edge, keep the catalogue out of the database

The product list is compiled into the Worker itself, so browsing never queries anything. Only checkout, tracking and the admin touch storage. It removes the slowest part of a typical store and the most common thing to fall over under load.

Ship zero runtime dependencies

Nothing from the package ecosystem runs in production. That is a deliberate trade: I wrote more ourselves, and in exchange the shop has no plugin to update, no supply chain to audit, and nothing that breaks because a maintainer pushed a release.

Keep the cart in a cookie instead of an account

Requiring registration to hold a cart loses buyers who were 1 tap from ordering. A signed cookie holds it for 14 days with no database write, and every read is revalidated against the live catalogue so it can never be trusted blindly.

Treat the phone number as the account

In a cash-on-delivery market the phone number is already the identity: it is how the shop confirms, how the courier calls, and what the customer remembers. Building accounts on top of that would add a password to forget and nothing else.

Write the search engine instead of installing one

Off-the-shelf search assumes customers type catalogue English. This one handles edit-distance typos, a synonym table of the words buyers here actually use, and Bengali script in the same query. It is more work, and it is the difference between results and an empty page.

Make the shop the owner of the platform

On a rented platform the storefront stops the month the billing does, and the customer list belongs to someone else. Building it as owned software means the code, the orders and the data stay with the business.

The commerce engine

The commerce engine.

8 systems behind the storefront.

Catalogue and categories

8 categories with filtering, text query and sorting by price or discount, all expressed as real URLs that can be shared and linked.

Colour variants

A finish is part of the cart line, not a note. The same handset in 2 colours is 2 lines, and the colour follows the order into the confirmation email.

Relevance search

Edit-distance typo tolerance, a domain synonym table, Bengali and English tokenization, and weighted scoring that puts exact matches first.

Cart

A signed 14 day cookie with no database write, capped and revalidated against the live catalogue on every read.

Cash-on-delivery checkout

Bengali numeral input, +880 and 880 folding, address and name validation, and errors returned with every field still filled in.

Delivery zones

Rajshahi and the rest of Bangladesh priced separately, each with its own stated arrival window, recalculating the total as the customer chooses.

Order numbers and price snapshots

Order references are generated from cryptographic randomness so they cannot be guessed or counted, and every line stores the price it was bought at.

Order tracking

A phone number lookup returning orders, statuses and totals in Dhaka time, with no account to create.

Running the shop

How the shop runs it.

4 systems the owner works with, and what each covers.

01 · The admin console

  • A private order console, reachable only with the shop's admin token
  • Tokens compared in constant time, so the check cannot be probed by measuring it
  • A session cookie scoped to the admin path alone and expiring after 7 days
  • Every order, with customer, items, colour, total and current status on 1 screen
  • Excluded from search engines and from the sitemap by default

02 · The order workflow

  • 5 states covering the real life of an order: pending, confirmed, shipped, delivered, cancelled
  • Status changes from a dropdown that saves on selection, no separate edit screen
  • Orders arrive as pending so nothing dispatches before the shop phones to confirm
  • Each line keeps the price it was ordered at, so a later price change never rewrites history
  • Timestamps rendered in Dhaka time rather than server time

03 · Automated customer email

  • 3 templates: an alert to the shop, a receipt to the customer, and a status update
  • Itemised tables with product thumbnails, totals and a status badge, in HTML and plain text
  • Moving an order to confirmed, shipped, delivered or cancelled emails the customer automatically
  • Sent after the response, so a slow mail provider can never delay a checkout
  • Keyed for idempotency and retried once on a transient failure, so no duplicate receipts
  • A local preview harness renders every template and fails the build on a broken variable

04 · The content layer

  • Products, categories and colour options held in 1 structured catalogue file
  • Banners, promotions and FAQ copy separated out from page code
  • Policy pages kept as their own content, editable without touching layout
  • Adding a product means 1 entry: name, category, price, colours and specifications
  • Sitemap, category pages and structured data all regenerate from that catalogue automatically
The comparison

This platform against a rented store.

10 differences between this build and a subscription platform.

Rented platformWhat I built
Running costA subscription every month, indefinitelyNo ecommerce platform subscription
Per saleA percentage of every orderThe full margin stays with the shop
Cash on deliveryAdded on through a pluginThe default the checkout was designed around
Phone numbersGeneric international validationBengali numerals and +880 folded to a dialable number
Delivery pricingBroad zones set by the platformRajshahi and nationwide, priced and timed separately
SearchWhatever the theme ships withA relevance engine written for this catalogue
Page weightA theme plus its plugin stack1 Worker, no client framework, no runtime dependencies
Customer dataHeld inside a platform accountIn the shop's own database
TrackingThird-party pixels by defaultNo third-party trackers at all
OwnershipAccess ends when billing stopsThe code and the data belong to the business
What was built

The platform, by the numbers.

Counts from the delivered build. Not traffic or revenue figures.

47Crawlable pages
25Handsets listed
0Runtime dependencies
0Third-party trackers
Business impact

What this gets the shop.

How the build changes the way the shop operates. Not separately measured outcomes.

The margin stays in the shop

No monthly platform fee and no percentage of each sale, which on thin hardware margins is the difference between a channel that pays and one that does not.

Orders confirm themselves

Every status change emails the customer without anyone remembering to. The shop moves a dropdown and the communication has already happened.

Fewer calls asking where it is

Customers check their own order with the number they ordered on, which removes the most common reason the shop phone rings.

Searches end in a product, not a blank page

A misspelled model name still returns the right handset, so demand that arrives with imperfect spelling still reaches something buyable.

Nothing follows the customer

No advertising pixels and no third-party analytics, so the site carries no tracking baggage and needs no consent banner in front of the stock.

The platform is an asset

The code, the orders and the customer list are the shop's property. Nothing switches off because an invoice went unpaid.

Questions

The short version.

What did you build for NextGen Mobile?

A complete commerce platform, not a theme on top of an existing one:

  • Storefront: homepage, catalogue with filters and sorting, 8 category views, and a product page for every handset.
  • Search: a custom relevance engine with typo tolerance, a synonym table, and Bengali and English tokenization.
  • Buying: a slide-in cart drawer, a signed 14 day cart cookie, and a cash-on-delivery checkout built for Bangladeshi phone numbers and delivery zones.
  • After the order: phone-number order tracking, and 3 transactional email templates covering the shop alert, the customer receipt, and status updates.
  • Operations: a token-gated admin console with a 5 state order workflow.
Why not just use Shopify or WooCommerce?

They are good products. They are a poor fit for this particular shop:

  • The cost lands in the wrong place: a monthly fee plus a cut of each sale is painful against handset margins.
  • Cash on delivery is an afterthought: both are designed around card payment, with COD added through a plugin rather than assumed.
  • The local details are wrong by default: Bengali numeral input, +880 handling, Bangladeshi digit grouping and Rajshahi delivery zones all need working around.
  • Search cannot be fixed: platform search matches strings, and this catalogue needed a relevance model of its own.
  • The honest trade: a custom platform costs more to build and needs a developer to add a product. In exchange there is no rent, no transaction cut, and no landlord.
How does cash on delivery work on the site?

Nothing is charged online. The site's job is to capture an order the shop can safely dispatch against:

  • A dialable number: Bengali numerals and the +880 and 880 prefixes are folded into a single valid Bangladeshi mobile format before the order is accepted.
  • A real address: name, address and delivery area are validated at checkout, and errors come back with every field still filled in.
  • A zone and a timeframe: Rajshahi and the rest of the country are priced separately, each with its own stated arrival window, and the total updates as the customer chooses.
  • Confirmation before dispatch: orders arrive as pending, and the shop phones to confirm before anything is sent.
How does the shop manage orders day to day?

Through a private console, in a single screen:

  • Getting in: an admin token, compared in constant time, with a session scoped to the admin path and expiring after 7 days.
  • The order book: every order with customer, items, colour, total and status listed together.
  • Moving an order on: 5 states from pending to delivered or cancelled, changed from a dropdown that saves on selection.
  • The customer is told automatically: confirmed, shipped, delivered and cancelled each send a branded email without anyone writing one.
  • Adding stock: products are held in a structured catalogue and published by me, so a new handset is a request to me rather than a form in the console.
Can you build this for my shop?

Yes, and this is the model I would recommend for most product businesses selling locally:

  • Best fit: shops with real margin pressure, a cash-on-delivery or local-payment market, and enough order volume that platform fees are noticeable.
  • What you get: the storefront, the checkout, the order system and the admin, built around how your market actually buys.
  • What you own: the code, the orders and the customer data, on infrastructure in your own name.
  • What to weigh: a custom platform is a larger upfront build than installing a theme, and it pays back through fees you stop paying.
  • Next step: book a free call and tell me what you sell.
Keep exploring

More case studies.

View all
Your turn

Stop paying platform fees on your own store.

If platform fees and transaction cuts are reducing your margin on every sale, an owned platform removes both.