Book a live demoBook a demo →
IndiSell

Tracking COD orders in Google Ads and Meta: server-side setup for Shopify India

A COD order converts at the doorstep, days after the click — and browser pixels never see it. How offline conversions, Meta CAPI and enhanced conversions fit together, what to send when, and how to retract the ones that cancel.

I The IndiSell team8 min read

In this article
  1. 1.Three mechanisms, one loop
  2. 2.What to send, and when
  3. 3.Hashing and matching
  4. 4.Deduplication
  5. 5.Where the delivery status comes from
  6. 6.How to know it's working

If half your orders are cash on delivery, half your revenue is invisible to the platforms spending your ad budget. The pixel fires a 'purchase' when the order is placed, but a COD order is not revenue until it is delivered — and a meaningful share never is. Google and Meta then optimise toward orders that look like conversions and quietly return as RTO. Fixing this is a server-side job. Here is the shape of it; the reasoning is in why your ad platforms can't see half your revenue.

Three mechanisms, one loop

  • Google Ads offline conversions — upload a conversion after the fact, keyed to the click id (gclid) captured at checkout, with the delivered order's value.
  • Meta Conversions API (CAPI) — send the purchase event from your server, deduplicated against the pixel by a shared event id, with hashed identity for matching.
  • Enhanced conversions — attach hashed email and phone to every event so both platforms can match the conversion to a signed-in user without a cookie.

What to send, and when

  • At checkout: capture gclid, fbclid, UTMs and the landing page, and store them on the order. Without the click id there is nothing to attribute later.
  • On prepaid payment: send the purchase immediately — server-side, with the event id your pixel used, so nothing double-counts.
  • On COD placement: send nothing as a purchase yet, or send a low-weight 'COD order placed' event if you want the signal for audiences.
  • On COD delivery: upload the purchase with the actual value. This is the conversion that should train the bidding.
  • On cancellation or RTO: send a retraction or adjustment so the conversion is removed. A platform that keeps counting returned orders keeps bidding for them.

Hashing and matching

Both platforms accept SHA-256 hashed email and phone. Normalise first — lowercase, trimmed, phone in E.164 with the country code — or the hashes will not match anything. Because a phone-first checkout verifies the number by OTP, the phone hash is reliable, which is why match rates on Indian stores are usually better on phone than email.

Deduplication

Keep your existing pixels; do not rip them out. Give every event a single id shared between the browser pixel and the server upload, keyed to the order. Meta dedupes on that id; for Google, the server upload is the source of truth for COD while the browser tag covers prepaid, and the order id stops the two from overlapping.

Where the delivery status comes from

The loop closes only if delivery outcomes flow back to whatever sends the conversions. Courier webhooks — Shiprocket, Delhivery, NimbusPost and others — report delivered, RTO and NDR; a checkout that ingests them can upload the delivered conversion and retract the returned one without anyone touching a spreadsheet. Conversions & analytics does exactly this, but the pattern holds however you build it.

How to know it's working

Compare the platform's reported conversions to delivered orders from your own dashboard, weekly, for a month. They should converge. When they do, switch bidding strategies to optimise on the server-side conversion action — that is the moment the ad budget starts chasing shoppers who actually pay.

Want these numbers for your store?

See it live on a private preview of your checkout.

Ready to fix the leak between add-to-cart and paid?

See it live on your own store — a private preview link runs the real checkout for you before a single shopper sees it.

See it on your store
20-min walkthrough · no commitment
Book a demo