Why Meta Pixel and Conversions API setup matters more for Pakistani COD stores
If you run Meta ads for a Shopify store in Pakistan, your Meta Pixel and Conversions API setup decides what Meta learns about your buyers. Meta's ad system optimises towards whatever you report as a Purchase. In a COD market, a Purchase on your thank-you page is not money in your bank. It is a promise that may be cancelled on the confirmation call, refused at the door, or returned by the courier.
OrderNation's 2026 study of about 170,000 Pakistani online orders found that 94.5% were cash on delivery. 37.3% of COD orders were cancelled before shipping, and 19.4% of shipped parcels came back as RTO. In their funnel, 100 COD orders placed became about 63 shipped and about 49 with cash collected.
So if your Pixel fires Purchase 100 times, Meta believes it found 100 buyers, but only about half of them paid. This guide walks through the setup step by step, the Pakistani details most guides skip (like the phone number format), and how to give Meta a cleaner signal.
The audience is big enough to be worth getting right. NapoleonCat, which compiles Meta's ad audience figures, counted 66,015,001 Facebook users in Pakistan in September 2026, about 27.6% of the population. DataReportal's Digital 2026 Pakistan report counted 79.9 million social media user identities in October 2025.
Pixel, Conversions API and data sharing: what each part does
There are two ways your store tells Meta that something happened. The Meta Pixel is code in the buyer's browser. The Conversions API (often shortened to CAPI) sends the same event from a server instead of the browser.
| Part | Where it runs | What it is good at | Weak point |
|---|---|---|---|
| Meta Pixel | Buyer's browser | Captures page views, add to cart, and browser cookies (fbp, fbc) that help match the visit to a Meta account | Shopify's help page says a browser-based ad blocker can stop the Pixel sharing data |
| Conversions API | Server | Sends events that ad blockers cannot block, and can carry customer details such as phone and name for matching | If sent alongside the Pixel without a shared event ID, the same order can be counted twice |
| Both together | Browser plus server | Best coverage, as long as Meta can tell the two copies are one event | Needs deduplication set up correctly |
On Shopify, the Facebook and Instagram by Meta app offers three customer data-sharing levels. According to Shopify's help centre, Standard uses only the Pixel. Enhanced adds the Conversions API and shares the customer's name, location, email address and phone number for matching. Maximum uses the same Pixel and Conversions API as Enhanced and is updated with Meta's latest advertising technology. For most COD stores, Standard leaves too much out.
Step-by-step: setting it up on a Shopify COD store
- Pick one source for each event. If you use the Facebook and Instagram app, and also a COD form app or theme code that fires its own Pixel, you may be sending Purchase two or three times. List every app that has your Pixel ID before changing anything.
- In the Facebook and Instagram app settings, set customer data sharing to Enhanced or Maximum so the Conversions API is switched on.
- If your COD form app sends its own Purchase (common, because the order is placed on the form and not on Shopify's checkout), make sure only one setup sends browser Purchase and one sends server Purchase, both with the same event ID.
- Use your Shopify order number as the event ID. Meta's server event documentation says event_id is optional but recommended for deduplication, and suggests a unique value such as an order number.
- Send the buyer's phone number in the correct format (see the next section). On a COD form, phone is often the only strong identifier you have, because many Pakistani buyers do not type an email.
- Place a test order, then open Events Manager and check that Purchase shows both Browser and Server, and that it is deduplicated rather than doubled.
- Check Event Match Quality for Purchase in Events Manager after a few days of orders, and fix whichever customer field is missing.
The Pakistani phone number format Meta needs
This is the most common mistake on Pakistani stores. Meta's customer information parameter rules say phone numbers must remove symbols, letters and any leading zeros, and must include a country code to be used for matching. Meta says to include the country code even if all your customers are in one country. Pakistan's country code is 92.
Buyers type 03001234567, 0300-1234567, +92 300 1234567 or 92 300 1234567. All of these must become one string before hashing.
| What the buyer typed | What Meta should receive (before hashing) | Rule applied |
|---|---|---|
| 03001234567 | 923001234567 | Drop the leading 0, add 92 |
| 0300-1234567 | 923001234567 | Remove the dash, drop the 0, add 92 |
| +92 300 1234567 | 923001234567 | Remove + and spaces |
| 0092 300 1234567 | 923001234567 | Remove leading zeros and spaces |
| 3001234567 | 923001234567 | Add 92 |
The numbers in this table are examples, not real customers. Meta's rules also say email should be trimmed and lowercased, city should be lowercase with no spaces or punctuation (so Dera Ghazi Khan becomes deraghazikhan), and country should be the two-letter code, which for Pakistan is pk. Meta requires these customer fields to be SHA-256 hashed; the Meta Business SDK and most Shopify apps hash them for you, so your job is mainly to make sure the raw value is in the right shape first.
If your COD form saves numbers as 03xx and your tracking app passes them straight through without adding 92, Meta may not be able to use them for matching. Ask your app's support how it formats Pakistani numbers.
How deduplication works, and how to spot double counting
When the Pixel and the Conversions API both send a Purchase for the same order, Meta needs to know they are one sale. Meta's deduplication documentation says the browser eventID must equal the server event_id, and the event name must match too, for example Purchase and Purchase. Meta keeps the first one it receives and discards matching events that arrive within 48 hours of the first.
There is a fallback that uses fbp or external_id instead of an event ID, but Meta says it generally works only when the browser event arrives first, and it does not deduplicate two browser events or two server events from the same source. If one app fires Purchase twice in the browser, both are kept.
- Sign of double counting: Meta reports more purchases than Shopify has orders for the same days.
- Sign of missing server events: Events Manager shows Purchase from Browser only.
- Sign of a bad event ID: both Browser and Server appear but the counts add up instead of overlapping.
- Sign of two apps firing: Purchase value in Meta is roughly double your Shopify sales.
RabbitROI's pixels for Meta, TikTok, Snapchat, Google and Pinterest send the Purchase event from browser and server with deduplication, so the same COD order is not counted twice.
Example: what Meta sees versus what you actually collect
Example only. Suppose you spend Rs 60,000 on Meta ads in a week and your store gets 100 COD orders. Using the OrderNation funnel above as a rough guide, about 63 are shipped and about 49 are paid for.
| Measure | What Meta sees | What really happened |
|---|---|---|
| Purchases | 100 | 49 paid orders |
| Cost per purchase | Rs 600 | About Rs 1,224 per paid order |
| Who Meta looks for next | People like all 100 order placers | You only want people like the 49 who paid |
Rs 60,000 divided by 100 is Rs 600. Rs 60,000 divided by 49 is about Rs 1,224. The ad spend has not changed, but the real cost per paid order is roughly double what Ads Manager shows. And because Meta optimises on the 100, it will keep finding people who resemble buyers who cancel on the call or refuse the parcel, as well as real buyers.
If you have also been double counting Purchase, Meta would show 200 purchases and Rs 300 each, and the gap becomes four times. This is why the deduplication check above comes first.
Giving Meta a cleaner signal: confirmed or delivered orders
You cannot stop the Purchase event from being a placed order, because that is when the buyer is on your site. What you can do is send a second, later event from your server once you know the order is real.
- Choose your stage: confirmed on call or WhatsApp, shipped, or delivered and paid. Confirmed is fastest; delivered is most accurate.
- Send a custom server event for that stage, with the same phone, name and city details as the original Purchase so Meta can match it.
- Watch the clock. Meta's server event rules say event_time can be up to 7 days before you send it, and if any event in a request is older than that, the whole request is rejected and no events are processed. A delivered event on a 9-day parcel to a far city is too late.
- In Events Manager, create a custom conversion on that event, and once it has steady volume, test an ad set that optimises for it against your current Purchase ad set.
- Keep Purchase running. A later event will have fewer events per week, and a new ad set needs enough of them to learn.
Because of the 7-day limit, confirmed is usually the practical choice for Pakistani COD stores: most confirmation calls happen within a day or two, while delivery to smaller cities can take longer. Measure your own confirmation and delivery times before you decide.
Weekly checklist for COD stores running Meta ads
- Compare Meta purchases with Shopify orders for the same 7 days. A big gap in either direction means a setup problem.
- Check Events Manager: Purchase should show both Browser and Server, deduplicated.
- Open Event Match Quality for Purchase and see which customer field is missing.
- Test one order with a 03xx number and confirm your app sends it as 92.
- Work out cost per paid order, not cost per purchase, before you scale a campaign.
- If you send confirmed orders, check none are older than 7 days when sent.
To see which campaigns actually make money after returns, RabbitROI shows net profit per ad campaign after returns, ad spend, product cost and shipping, along with RTO rates by courier, city and product.
FAQ
Do I need the Conversions API if I already have the Meta Pixel on Shopify?
For most stores, yes. Shopify's help centre says a browser-based ad blocker can stop the Pixel from sharing data. The Conversions API sends events from a server, so they still reach Meta. Use both, with the same event ID so Meta can deduplicate them.
How should I format Pakistani phone numbers for Meta?
Remove spaces, dashes and the plus sign, drop the leading zero and start with 92. So 0300-1234567 becomes 923001234567. Meta says phone numbers need a country code to be used for matching.
Why does Meta show more purchases than my Shopify orders?
Usually the same order is being sent twice: two apps firing Purchase, or Pixel and Conversions API events without a matching event ID. Meta only deduplicates when the event name and event ID match within 48 hours.
Can I tell Meta only about delivered COD orders?
You can send a later server event for confirmed or delivered orders and optimise towards it as a custom conversion. Meta only accepts events with an event time up to 7 days old, so for slow deliveries a confirmed event is often more practical.
Which data-sharing level should I choose in the Facebook and Instagram app?
Enhanced or Maximum. Both turn on the Conversions API and share customer details such as name, email and phone for matching. Standard uses only the browser Pixel.
Sources
- OrderNation: State of Online Shopping in Pakistan 2026
- Meta for Developers: Handling Duplicate Pixel and Conversions API Events
- Meta for Developers: Customer Information Parameters
- Meta for Developers: Server Event Parameters
- Meta for Developers: Conversions API Best Practices
- Shopify Help Center: Facebook data sharing
- NapoleonCat: Facebook users in Pakistan
- DataReportal: Digital 2026 Pakistan
Comments
No comments yet. Start the conversation.