гора.
Pharmacy Delivery Platform

Business logic

How the delivery platform works on the inside: orders, payments, drivers, loyalty.

~18 min read · 3502 words

TL;DR

Pharmacy Delivery Platform is a last-mile home delivery platform for a regulated niche (a category of goods that requires age verification). The region is Miami and its suburbs, Florida. The customer places an order through the website or Telegram, and within 30–90 minutes a driver delivers the goods.

The platform is multi-tenant: a single codebase serves several stores in one region. Inside live six user roles, five interaction interfaces, three Telegram bots, a loyalty program with a wallet and cashback, a referral system with QR campaigns, six delivery zones with their own rules, and six payment methods — from cash to cryptocurrency.

Key differences from a typical store with couriers: real real-time driver tracking, automatic cash reconciliation at the end of a shift, a premium subscription with bonuses and bypassed restrictions, analytics at the level of session replay and audit trail. The niche demands strict compliance — hence age verification, masking of personal data, and Twilio A2P registration.

Storefront — homepage and age verification

Pharmacy Delivery Platform — business logic

What this platform is

Imagine a regular grocery store in your neighborhood. You walk in, pick out goods, pay, carry them out. Now imagine a layer of technology between you and the store: you don't go in on foot — you open a website or Telegram, the cart is assembled on your phone, payment goes through with one tap, and an hour later a courier rings the doorbell. That's last-mile delivery: the "last mile" from the store's warehouse to the customer's door.

Pharmacy Delivery Platform does exactly this, but in a niche where every step is tightly regulated. The customer must pass age verification. The store must respect territorial restrictions. The driver must carry not only goods but also cash back — which means the platform counts every dollar down to the change.

Architecturally it is a multi-tenant system: the same codebase serves several stores at once. Each store sees only its own orders, customers, products, and employees. Under the hood this means that any database query is filtered by store_id, and no employee of one store can accidentally see another store's data.

The platform is interacted with through five different interfaces. The main channel is the public storefront website, through which most customers order. Then come four Telegram applications: one for buyers (a mini-store inside Telegram), the second for dispatchers (they see all incoming orders, assign drivers), the third for drivers (they receive their deliveries, mark statuses), and an admin panel for the business — where managers and owners view reports, manage products, prices, and staff.

The system has six roles: platform_admin (platform owner — can do everything), store_admin (administrator of a specific store), manager (manager without certain privileges), dispatcher (distributes orders among drivers), driver, customer.

In parallel with the interfaces, three Python bots run on Telegram — for customers, drivers, and dispatchers. The bots don't show pretty screens: their job is to deliver a notification instantly and provide a minimal set of commands.

How an order works from start to finish

Step 1. Storefront and catalog

The customer lands on the website. On the homepage — a hero block, banners of the day, product categories (10 categories total). The customer clicks on a category, lands on the listing, then on the product card with photos, description, reviews, and variants (for example, different dosages or volumes).

The cart is set up in an interesting way: until checkout, it lives in localStorage in the customer's browser. This means an unregistered user can build up a cart, close the tab, come back an hour later — and everything is still there. At the moment of checkout, the cart goes to the server and is attached to the user (after registration/login).

Catalog — product list with category filters

Step 2. Address and delivery zone

The customer enters an address. The system takes the ZIP code and looks it up in the delivery zones table. There are six zones: downtown Miami, Coral Gables, and four more. Each zone has its own rules — minimum order amount, estimated delivery time, additional distance fee.

If the ZIP isn't covered by any zone — the customer sees a friendly message "we don't deliver to your area yet" and an offer to leave an email to be notified about expansion.

A delivery zone isn't just a polygon on a map. It's a business rule: "for this ZIP code, from this amount, at this speed, with these restrictions."

Step 3. Delivery time

Next — choosing a time. Two modes. The first is express (ASAP): the driver picks up the order as soon as he can, delivery roughly 30–90 minutes. The second is a scheduled time slot: 15-minute slots over the next few days. Each slot has a capacity limit — after X orders the slot closes so as not to overload drivers.

On top of that, traffic windows operate — windows with congestion. These are rules in the admin panel: "ZIP 33129 is not delivered between 5:00 PM and 7:00 PM on weekdays." If the customer chooses a time and zone falling into such a window, the slot will be unavailable.

Step 4. Payment

Payment methods are a separate story. The platform accepts six types: Cash on Delivery, Zelle, CashApp, Venmo, internal wallet, and cryptocurrency in five forms — BTC (via xpub key), ETH, USDT, USDC, USDT TRC-20.

The customer can combine: for example, partially pay with the wallet (spend cashback), partially with cash.

Checkout — selecting address, time, payment method

Step 5. Promo code

A field for a promo code. The system validates the code — checks expiration, usage limits, minimum amount, attachment to a specific customer. Six types of promo codes are supported: percentage discount, fixed amount, free gift product, cashback to wallet, military discount (discount for military personnel with verification), first-order discount.

Step 6. Order created

The customer hits "Place order." The order is created in the database with status PENDING. And immediately a cascade of notifications fires.

Through Pushover, dispatchers receive a push notification with priority 2 — meaning the dispatcher's phone will ring loud and long (up to 30 seconds) until acknowledged. In parallel, a Telegram bot sends a short message with a link to the order.

Step 7. Dispatcher assigns a driver

The dispatcher sees the order either in the admin panel or in their Telegram mini-app. Inside — the items, address, time, payment method, customer notes. The dispatcher picks a driver from the list of available ones and assigns the order.

The status changes: PENDINGCONFIRMEDREADYASSIGNED. The driver gets a push (also Pushover, also loud) — "new order."

Step 8. Driver en route

The driver opens his mini-app, sees the details — pickup address, delivery address, route on the map. Drives to the store, marks "Picked up" (status PICKED_UP). Drives to the customer.

All this time the customer sees real-time tracking in their app: the driver's pin on the map and estimated time of arrival (ETA). The driver's geolocation streams over WebSocket every few seconds, ETA is recalculated via geocoding.

Step 9. Delivery and review

The driver arrives, hands over the goods, collects payment (if COD), taps "Delivered." Status — DELIVERED. The dispatcher gets a push with priority 1 (normal, no siren): "order delivered."

A few minutes later the customer receives a request for a review: rate the order and/or specific products.

Loyalty and retention program

Customer retention isn't a single feature, but a whole set of intertwined mechanics. I'll talk about each separately, but in reality they work together.

Wallet — internal wallet

After every order, the customer is credited with cashback — a percentage of the amount. This percentage depends on the customer's tier (more on tiers below). Cashback lands in the internal wallet and can be spent on the next order as part of the payment.

Every wallet operation is a separate transaction in the database. Credit, debit, refund, admin correction. The full history is visible to both the customer in their account and the administrator in the admin panel.

The wallet isn't just bonus points. It's real dollars the customer has already spent and gotten part back as motivation to return.

Affiliate program — referral program

Every registered customer is automatically generated a unique referral code. The customer can share a link of the form ?ref=CODE — a friend follows it, registers, places an order, and the referrer receives a commission to their wallet.

QR codes are generated automatically. On the hero block of the homepage, authenticated customers see a ready QR — point your phone, share.

Customer plans / Premium tier — customer levels

Three tiers: bronze, silver, gold. Bronze is the starter, given to everyone at registration. Silver and gold are paid subscriptions or are reached by spending volume. The higher the tier, the more perks:

  • Higher cashback rate
  • Access to unique payment methods (for example, cryptocurrency may be locked for bronze)
  • 24/7 ordering — bypasses the store's regular operating hours
  • Bypass ZIP restrictions — extended delivery zone
  • Bonus products when the tier is activated

Promo codes in mass batches

A marketer can generate 1000 unique promo codes with one click and export them as a CSV file. Use cases: print on a flyer and hand out on the street, attach to an order as a surprise, use in an ad campaign. Each code is single-use or multi-use, percentage or amount, with a configurable order amount limit.

QR campaigns

A separate mechanism for offline marketing. The marketer creates a campaign, attaches a promo code to it, gets a short URL like /c/CODE. The customer scans the QR — lands on the site — the promo code is already applied, the traffic source is recorded.

Then — analytics: how many scans, how many conversions, how much revenue the campaign brought in, average order value for that campaign. Campaigns can be compared with each other to understand which channel pays off.

Day-of-week promotions

A simple but working rule: "Monday — 15% off everything." Configured in the admin panel: day of week, discount percentage, minimum order amount. Optional: add a free product or accrue extra cashback.

Mix & Match — bundle discounts

A "buy N — get %" type of discount. Several tiers: buy 3 — 20% off, buy 5 — 30%. Tied to categories or specific products. You can compose "take any three from this category — get a discount."

Banners — dynamic banners

On the homepage — banners, different for mobile and desktop versions. Each banner has its own target URL: leads either to a category or to a promo page. The manager controls banners in the admin panel without involving a developer.

Reviews

The customer leaves reviews on orders and separately on specific products. Ratings are shown on product cards and form a "trust through-line" — social proof for new customers.

Mobile version — the main ordering channel

Customer communication channels

WhatsApp-first messaging

The main channel for transactional messages (order confirmation, delivery statuses) is WhatsApp. Under the hood — a multi-node gateway: up to 5 nodes (physical devices with WhatsApp Business) operating in round-robin with a sticky session — meaning the same customer always receives messages from the same node.

If WhatsApp doesn't deliver (the customer uninstalled the app, blocked the number, has no internet), the system automatically falls back to SMS.

SMS — two channels

SMS is sent via two paths. The first — Twilio A2P: commercial campaign registration in the US, required to comply with American carriers' rules. At the time of writing this, the campaign is submitted and undergoing TCR vetting (2–3 weeks).

The second channel — SMS Gate: an Android app on physical devices that send SMS as if from regular phone numbers. Also round-robin between devices. Used primarily for OTP codes during registration and login.

Email

Email — for forgot-password and rare bulk newsletters. Not the primary channel — most customers receive information via WhatsApp/Telegram.

Pushover for the team

The team (dispatchers, drivers, owners) receives notifications via Pushover. This is not a customer channel — it's an internal tool. Three priority levels:

  • New order → to dispatchers, priority=2 (loud siren for 30 seconds until acknowledged — critical so orders aren't lost)
  • Order assigned → to driver, priority=2 (loud notification)
  • Order delivered → to dispatchers, priority=1 (normal sound)

Telegram bots

Three separate bots:

  • Customer bot — a lightweight ordering channel without visiting the website
  • Dispatcher bot — a fallback channel if Pushover is unavailable
  • Driver bot — operational notifications about new deliveries

Authentication

Several login methods: OTP via SMS, Google OAuth, Telegram WebApp with HMAC validation (for mini-apps — the server verifies Telegram's signature to make sure the initData is genuine).

Business metrics and analytics

This is the most interesting part for the owner — what they see in the admin panel when they open it in the morning.

Daily KPIs and Lifetime KPIs

The first thing that loads on the admin panel home screen is cards with today's numbers: collection (revenue), sales, orders, users (new users). Next to them — the same metrics over the entire lifetime of the store.

Reconciliation report

The main financial report — reconciliation. Breaks revenue down into components: gross revenue, discounts, wallet used (debited from customer wallets), rewards used (free products and bonuses), net revenue, tax, delivery fees, COGS (cost of goods sold), profit margin.

When the owner opens the report, they don't see "the store earned X" — they see the full picture: how much money came in, how much went to discounts and gifts, how much remained after taxes and procurement.

Cash flow report

The money-movement report. Especially important in a niche with many COD orders. Breakdown: COD sales (how many orders paid in cash), cash in the driver's envelope (what was physically collected), digital payments (what went through Zelle/CashApp/Venmo/crypto), change-to-wallet (change credited to the customer's wallet instead of small bills), owner's cash (what ends up with the owner).

Driver report

For a selected period — a table by driver: number of deliveries, average delivery time, revenue, cash collected. Helps identify who is working efficiently, who needs help, who deserves a bonus.

End-of-day report

Final report for the shift. Closing the day — all the numbers, all the balances, all the discrepancies.

COG report

Cost-of-goods report. For each product — purchase price, sale price, margin in dollars and percent. Helps understand which products actually make money and which are sold at a loss.

Affiliate report

Top referrers: who brought the most customers, how much commission was credited to them, how much was paid out. You can drill into a specific referrer — their referrals, their orders, their wallet.

Funnel analytics

Conversion funnels in three places:

  • Registration funnel: OTP sent → code entered → registration completed → first order placed. At each step — conversion percentage and absolute count.
  • Login funnel: similar logic for sign-in.
  • Checkout funnel: added to cart → went to checkout → chose address → chose payment → tapped "Place order" → payment completed.

Funnels show where customers drop off. If 80% of people reach the payment selection but only 40% reach "Place order" — something is breaking at that step.

Conversion analytics

A separate screen — overall funnel from visit to order: Sessions → Product Views → Cart Adds → Checkout → Orders. With percentages at each step. This isn't about a specific customer — this is about the overall health of the store.

Activity Log + session replay

The most unusual part of analytics. The platform records customer actions: added a product to cart, removed it, changed quantity, navigated to a page, submitted a search with no results, encountered an error, hit a JS crash, didn't make it to checkout for reason X.

On top of that — rrweb session replay: recording customer sessions with masked inputs (all input fields are masked — no one will see what the customer typed in the "address" or "phone number" field). Authenticated sessions only, no longer than 15 minutes per recording. In the admin panel you can open a specific session and replay the customer's whole journey — like a video player.

When a customer complains "nothing worked for me" — you open their session, see what they actually did, and figure out the cause in 30 seconds.

Audit Trail

A change log for the platform administrator. Who changed a product price, stock level, customer wallet, and when. Changes within two seconds are grouped into a single record (so the log doesn't get cluttered if one editor saved three fields in a row).

Issues monitor

Top issues of the day. The most common reasons for checkout drop-off, JS errors in customer browsers, API endpoint failures. Helps quickly see what's broken right now.

What makes the project hard from the inside

From the outside, the platform looks like an ordinary store with couriers. Inside — dozens of non-trivial problems, each of which can cost money or customers if solved poorly.

Inventory race conditions

Scenario: only one last item left in the warehouse. Two customers tap "Place order" at the same time. Without protection — both will get a confirmation, but the warehouse is empty. One customer is going to be very upset.

The solution — database transactions with a WHERE inventory >= qty condition. If the first customer made it — the second gets an error before the order is even created, and they see "out of stock" instead of a confirmation.

Multi-tenant isolation

A single store_id filters everything: products, orders, customers, drivers. If that filter is missed in even one query — store A will see store B's data. In a regulated niche, this isn't just a bug, it's a potential legal consequence.

Real-time tracking

A WebSocket connection between the driver's app and the server. The driver pushes geolocation every few seconds. The server stores the latest position, computes ETA via geocoding, and forwards it to the customer. If the connection drops — reconnection is needed without losing context.

Compliance

Age verification for the category — a mandatory condition. Masking of personal data in screen recordings (rrweb maskAllInputs). Platform-level NDA. Twilio A2P registration to comply with American SMS carriers' rules.

Pushover priority=2

Not a technical thing, but an operational one. If a new order lands in the system but the dispatcher missed it — the order will be delayed. Pushover with priority 2 rings the phone with a loud siren for 30 seconds until the dispatcher acknowledges. This isn't "convenient" — it's critical so orders don't fall through the cracks.

Cash drop reconciliation

Drivers carry cash. At the end of a shift the platform reconciles three numbers: how much is expected from COD orders, how much is actually in the driver's envelope, how much was given to customers as change in the format "let's put the difference on the wallet rather than hand over coins." If the three numbers don't match — the discrepancy is escalated to the owner.

Time slots with capacity

15-minute slots with a cap on the number of orders. Once the cap is reached — the slot "goes dark" and is no longer shown to customers. This protects the drivers: otherwise one slot can be overfilled and break the entire delivery schedule.

Traffic windows

Rules like "ZIP 33129 is not delivered between 5:00 PM and 7:00 PM on weekdays." Each ZIP can have its own windows. In the admin panel the manager opens the "Traffic windows" screen and edits — without help from a developer.

Localization

The platform supports three locales: English, Russian, Spanish. Around 700 translation keys. All three must be maintained and verified — a customer in Miami may speak any of these languages.

Summary

The platform isn't a "site with a cart." It's a bundle of six user roles, five interfaces, three bots, six delivery zones, six payment methods, and a dozen intertwined retention mechanics. Every detail — from the priority of a push notification to a traffic window rule — is thought through so an order isn't lost, cash doesn't go missing, and the customer comes back.

The project operates in Miami, serves a regulated niche, and every decision in the code has to align with operational reality: couriers on the streets, dispatchers with loud phones, owners who at the end of the day reconcile reports down to the dollar.


Related sections

  • Admin panel — a deep dive into the admin area: what's inside, how the manager works, which reports are built.
  • Tech stack — the technical side: monorepo, NestJS, Next.js, PostgreSQL, Docker, GitHub Actions, real-time, queues, Pushover, and everything under the hood.
Pharmacy Delivery Platform — business logic · hiregora.com