Closing the Checkout Gap: Making Delivery Cost & Timing Visible

Pindo OMS · Product Manager ·

Order conversion (test arm)
30%63%
Paid-order conversion
35%48%

TL;DR

As PM for Pindo’s order management system, I owned two conversion metrics: basket-to-order and order-to-paid-order. A large drop appeared at the address-and-delivery stage. By rebuilding the funnel from page-based to event-based, I isolated the real leak — logged-in users abandoned after selecting an address but before proceeding to payment. Through user calls, a survey, and an order-concentration analysis, I found the cause wasn’t logistics but missing information: buyers couldn’t see when their order would arrive or what delivery would cost.

Instead of a heavy delivery-service integration, I shipped a lightweight, seller-defined shipping estimate on the shipment page. A clean A/B test — treatment up to 63% order conversion, control flat at ~30% — confirmed the lift, and paid-order conversion moved with it (35% → 48%). Shipping-info capture was added to seller onboarding to scale adoption.


Context

I was the product manager for the OMS at Pindo, responsible for two core metrics:

  • Basket-to-order conversion — turning a viewed basket into a placed order
  • Order-to-paid-order conversion — turning a placed order into a completed payment

When I took over, the existing funnel ran:

ad view → add to basket → basket view → address & delivery page → payment page → gateway → thank-you page

The data showed a substantial drop at the address & delivery page, but the page-based view was misleading and I couldn’t act on it directly.

Rebuilt event-based — each event firing on the action that moves the user forward, not on page load — the same journey looked like this:

Checkout funnel
Share of cart viewers
CART VIEWED 100% CONTINUE FROM CART 72.5% CONTINUE FROM SHIPPING 16.2% PURCHASE CLICKED 9.9% PAID 7.6% ▼ BIGGEST DROP-OFF AT THE SHIPPING GATE
EventShare of cart viewersStep conv.
Cart viewed
User lands on the cart page
100%
Continue from cart
Clicks “next” on the cart page
72.5%72.5%
Continue from shipping
Clicks “next” on the shipping page
16.2%22.4%
Purchase clicked
Clicks “purchase” on the payment page
9.9%61.2%
Paid
Payment completed at the gateway
7.6%76.6%

Note on Continue from shipping: reaching this event requires having logged in, selected an address, and committed to delivery.

The critical drop is the 72.5% → 22.4% step: a user counted here clicked forward from the cart but never clicked forward from the shipping page. Understanding what that single number was hiding is where the work started.


The first insight: the funnel hid two different problems

Users browsed as guests all the way up to basket view. They were only forced to log in when they tried to continue past the basket. That meant the 22.4% step was mixing two unrelated problems:

  1. Login friction — a self-contained problem with its own optimizations: OTP SMS deliverability, OTP codes being flagged as spam, OTP length, OTP autofill, and adding Digikala SSO to make logging in easier.
  2. An actual in-flow drop — abandonment happening inside the checkout flow itself, among already-logged-in users.

I split these into separate tracks so login work wouldn’t contaminate the analysis of the in-flow drop.

Note on the metric: the event-based view was for analysis only. The conversion metrics I owned were measured against the database, not derived from event or page-view counts — so the diagnostic reframe didn’t change the definition of the number I was accountable for.


Breaking the 22.4% into its three steps

Getting from “continue from cart” to “continue from shipping” is really three actions in sequence: logging in, having (or entering) an address, and confirming the delivery details to proceed. Reconstructed from database state (figures rounded), the population splits first:

Who reaches the cart gate
Users who continued from cart
NEW 80% RETURNING 20%

New users had to do all three steps; returning users arrived logged in with a saved address and faced only the last one. Each step’s conversion, among the users who reached it:

Step conversion inside the gate
Among users reaching each step
100% Log in 75% Enter address 60% Proceed to payment 40% NEW USERS CONVERT AT JUST 18% THROUGH THE GATE

Underneath the 22.4%, new users converted through the gate at about 18% — login, then address, then proceed — while returning users, already logged in with a saved address, converted at 40%. Two things fall out of this:

  • Login and address entry were the friction track. They compounded to lose over half of guest users (75% × 60%) before those users ever saw the delivery details — the self-contained problem with its own fixes (OTP, SSO).
  • The proceed step converted at 40% in both paths. Returning users — no login friction, no address friction, everything saved — stopped at the delivery-details step at exactly the same rate as users who had just fought through the whole flow. Whatever was losing people there was a property of the page itself, not of accumulated friction on the way to it.

That second observation is what pointed the investigation at the shipping page.


The real finding: a gap between selecting an address and proceeding to payment

With the event-based funnel in place, the churn concentrated in a specific spot: logged-in users selected an address but didn’t proceed to the payment page.

I dug into that page to understand why. After entering an address, if you were lucky the seller had defined a delivery price for the item — but you still had no estimate of when the order would ship or when you’d receive it.

To verify the hypothesis rather than assume it, I triangulated across three sources:

  1. User calls. Churned users were logged in, so we had their numbers. I called several directly. Recurring reasons:
    • Delivery price unclear (sometimes freight-forward / pay-on-delivery)
    • Delivery price too high
    • Expected to select a time slot
    • Wanted to know when the order would arrive — they might not be home when it ships
  2. A survey built from those reasons to quantify them. Unknown delivery time and unknown/high delivery price landed in the top 3.
  3. An order-concentration check before committing to a solution. ~50% of orders came from sellers in Tehran, but only ~12% of orders were same-city. This told me an inter-city logistics integration wouldn’t move the needle — most demand wasn’t same-city, so a same-city delivery service would have solved the wrong problem.

The conclusion: this was an information problem, not a logistics problem.


The decision: ship the lightest thing that solves it

I considered several solutions:

OptionTrade-off
Integrate a delivery service (e.g. DigiExpress) for selectable time slotsHeavy build; solves time-slot selection but overkill for an info gap, and weak fit given the same-city concentration
Estimate delivery time from order historyRequires reliable historical data; indirect
Let sellers pick their delivery service, then infer a rough estimateDepends on seller input + mapping logic
Seller-defined general shipping description (chosen)Familiar pattern (like Instagram shops: “orders before noon ship same day”); easy to implement; directly closes the info gap

I chose the seller-defined shipping description because it was easy to implement and a pattern users already understood from social commerce and other sites.

To populate it credibly, I sorted our top sellers, called them, asked how they actually priced and timed shipping, and used that to build a template other sellers could fill in.

For the experiment, the information was shown on the shipment page — the page I owned and the exact spot where the churn happened.


Validation: a clean A/B test, scoped deliberately

I ran the A/B test on logged-in users, splitting on user-ID parity — the new shipping information was shown to even IDs (treatment) and withheld from odd IDs (control).

What exactly was measured: in both arms, the metric was logged-in users’ order conversion on orders from the selected shops — the top sellers whose shipping template had been filled in. Treatment saw the new information on those orders; control didn’t. Orders from other shops weren’t part of the read, since there was no shipping information to show or withhold.

Why this split is valid: both groups were near-identical at ~30% historically and ran over the same period, so seasonality and marketing hit both arms equally — only the shipment-page change differed.

The ID-parity split also enforced the scope: only logged-in users have numeric user IDs (guests carry non-numeric session IDs), so even/odd splitting mechanically restricted the test to logged-in users — which is exactly the population that reaches the shipment page.

Why the test was a clean persuasion read: I deliberately scoped the experiment to the shipment page only, leaving the top of the funnel (ADP/PDP) untouched. That matters — if I’d disclosed delivery info earlier in the journey during the test, it could have changed who reached checkout (pre-qualifying buyers), and the checkout lift would have been partly a composition artifact rather than genuine persuasion. By holding the top of the funnel constant, the population reaching checkout was the same as control, so the lift reflects the feature actually changing minds at the decision point.

Result:

  • Order conversion: treatment ~30% → 63%; control flat at ~30% over the same window
  • Paid-order conversion: 35% → 48% (treatment vs. flat control)
  • Test duration: ~2 weeks at a 50/50 split

I no longer have access to the exact per-arm sample counts, but at full checkout traffic over two weeks, a 33-point gap between arms is far beyond what noise produces — the control arm holding flat at ~30% throughout is the strongest evidence the effect was real.

After the test confirmed the lift, I launched the shipment-page version to all users; the change held at 100% rollout.


Scope of the claim (being precise)

The honest headline is a 33-point order-conversion lift in the experiment, among logged-in users, on orders from the selected shops that had shipping info filled in — not a platform-wide doubling. Two reasons to state it that way:

  • The entire study concerns logged-in users — they’re the only ones who reach the shipment page, and the ID-parity split enforced that population.
  • The measurement was scoped to the selected shops. At test time, sellers with the shipping template filled in were roughly ~0.3% of the platform — the hand-picked top sellers I’d called — so the day-one blended effect on the platform-wide number was negligible.

On why the lift is so large: the 63% is the concentrated treatment effect — the change in behavior for buyers who actually saw the new information. The reading that fits the user research is that many buyers were treating unknown delivery cost and timing as a worst-case and abandoning; removing that uncertainty recovered them, even when the disclosed answer was only mediocre.

The platform-wide figure is a projection, never re-measured: at a hypothetical ~35% seller adoption, the concentrated +33pp would translate to roughly +11–12pp platform-wide (≈30% → low-40s%) — contingent on adoption actually climbing via onboarding. Reporting the scoped number alongside the projected one, each with its conditions, is more accurate — and more defensible — than quoting the big number on its own.


Scaling it

To make the win durable rather than one-off, shipping-info capture was added to seller onboarding, so every new seller provided it by default and adoption would climb over time.


What I’d redo

  • Instrument the funnel event-based from the start. The page-based funnel cost real calendar time: the first weeks went to discovering that the number I was staring at was two problems wearing one trench coat. The lesson I carry forward is to audit how a metric is constructed before trusting where it says the problem is.
  • Preserve the experiment’s statistics. The test was clean, but I didn’t retain the per-arm sample sizes and significance figures. For a result this large it doesn’t change the conclusion — but a defensible number deserves a defensible paper trail, and I’d archive the analysis alongside the launch doc now.