Retail & E-commerce

The carts that used to just leave

A grocery group's online checkout was losing more baskets than it converted. Rebuilding it recovered nearly a quarter of them.

This is an illustrative composite. It is drawn from delivery patterns across our work rather than published as a named client reference, and the figures describe the pattern rather than one audited engagement. We would rather label it than imply a reference we cannot put you in touch with.

Size
120 staff
Platforms
ForgeConnect

Context

A 120-staff grocery group with six branches and a delivery operation built on a rented storefront theme. Online was roughly a fifth of revenue and the fastest-growing fifth, but the checkout had been extended four times by three different contractors.

The problem

Around two-thirds of baskets were abandoned at checkout, and nobody could say at which step. Delivery slots were held for fifteen minutes whether or not the order completed, so a failed checkout also blocked a slot somebody else would have taken. On a Saturday that was a measurable amount of lost delivery capacity.

What we did

  1. 01Instrumented the existing checkout first and watched it for two weeks before changing anything, because rebuilding the wrong step is the expensive mistake here.
  2. 02Found two of the four drop-offs were a slot-picker that silently failed on mobile when a slot expired mid-session.
  3. 03Rebuilt checkout as a four-step flow with the slot held only after payment intent, releasing it immediately on abandonment.
  4. 04Wired abandoned baskets into a WhatsApp recovery message on the number the customer had already verified, with a one-tap return link.
  5. 05Kept the old checkout live behind a flag for three weeks and cut over branch by branch.

Architecture

Nothing here is a black box. You can read the architecture before you sign, and you own it after.

  1. 01StorefrontNext.js App Router, server-rendered, with the checkout steps as server actions validated by a Zod schema at the boundary.
  2. 02SlotsDelivery capacity in Postgres with a hold that expires by job rather than by client timer.
  3. 03PaymentsRazorpay payment intent; the slot converts to a booking only on a cleared intent.
  4. 04RecoveryJJ Tech Connect sends the WhatsApp recovery message and threads the reply back to the same basket.
  5. 05TelemetryStep-level funnel events on the event spine, so a future regression is visible the same week.

Results

The numbers the work closed against.

target recovery of abandoned baskets within eight weeks
23%target recovery of abandoned baskets within eight weeks

Basis: Assumes recovery messaging reaches the verified number on file and that payment-friction abandonments — the largest observed segment — are the recoverable ones. Segment sizes come from two weeks of funnel instrumentation.

target basket abandonment at checkout
66% → 41%target basket abandonment at checkout

Basis: 66% is measured on the existing checkout. The target removes the two drop-offs attributable to the slot picker failing on mobile; the remaining two are not assumed to change.

delivery slots per month released back to capacity
1,900delivery slots per month released back to capacity

Basis: Arithmetic: observed abandoned checkouts per month multiplied by the fifteen-minute hold each one blocked, converted to whole slots at the current slot length.

of parallel running before an old checkout is retired
3 weeksof parallel running before an old checkout is retired

Basis: A delivery standard, not a forecast. Both checkouts serve live traffic behind a flag until branch-by-branch cutover completes.

Stack

  • Next.js
  • Supabase Postgres
  • Razorpay
  • WhatsApp Business API
  • Vercel
  • Zod

Does this look like your business?

Tell us what is slow and what it is costing. We will point you at the closest precedent we have and say plainly where yours would differ.

Scope it with us