A fake COD order costs you twice. The second one is worse.
You lose the courier fee — everyone knows that part. The part most shops never see is that the fake order was reported to Meta as a purchase, and the optimiser went looking for more people like that.
Your ad budget learns from whatever you report
Cash on delivery confirms the instant it is placed. If a purchase event goes out at that moment, it goes out for the real orders and the fake ones alike. Meta cannot tell them apart — it only knows what you told it. So it finds more of the audience that "converted", and the next batch is worse than the last.
Nobody has to do anything clever for this to keep running.
Report the purchase when it is true, not when it is hopeful
One setting decides the moment Meta hears about an order. Nothing else about your checkout changes, and prepaid orders are untouched — the money already arrived, so the purchase is already true.
- At checkoutAs soon as the order is scored and looks realFastest signal back to Meta. Fake orders never reach it.
- On confirmationWhen you confirm the order — usually your phone callThe default. A human has spoken to the shopper.
- On deliveryWhen the courier marks it deliveredThe strictest. Delivery is the only truth that cannot be argued with.
Every cash-on-delivery order is scored before it becomes a number in your ad account
Signals are grouped into families. A family contributes its strongest signal and never the sum, so one bad phone number seen three different ways counts once, not three times. The score lands the order in one of three places.
- 01
Order history
What this phone number has done at your shop before, and whether other shops on the platform have had trouble with it.
- 02
Delivery outcomes
Whether parcels to this number get delivered or come back, drawn from courier delivery history.
- 03
Ordering pattern
How this order sits against the recent run of orders from the same number, including ones still open.
- 04
Contact consistency
Whether the name, number and address hold together as something a courier could actually deliver to.
- 05
Earned trust
Signals that push the score DOWN. A customer who has taken delivery from you before is protected, not re-examined every time.
Every order gets a risk score
Five signal familiesReal
Straight through. The shopper notices nothing.
Review
Lands in a review queue with the reason attached. You decide.
Held
Flagged, and no purchase is reported to Meta for it.
The rules, their weights and the score at which each outcome begins are not published, and will not be. A shop can read every decision made about its own orders; nobody gets the rulebook. That is the difference between a filter and a checklist for getting past one.
What it refuses to do
Some of the strongest signals available are left out or held back on purpose. These are the decisions worth knowing about before you trust anything with your orders.
An IP address never blocks an order on its own
Mobile carriers put thousands of real shoppers behind one address, so an address is only ever a supporting signal. On its own it can hold an order for a phone call, and it never marks one as fraud.
No AI decides anything
The engine is a deterministic set of rules. The same order scores the same way twice, every decision can be explained in a sentence, and there is no model that can hallucinate a verdict about a real customer.
It never cancels an order
The worst outcome the system can produce on its own is holding an order for you to look at. Cancelling is a decision a person makes.
Raw shopper data never leaves your shop
What crosses between shops is a reputation band — high, medium, or nothing — against a one-way hash. Never a name, a number, an address, or a count.
Every shop on the platform is a little harder to defraud than the last
A number that has caused trouble at other shops arrives at yours already carrying that history — as a band, never as data you could read back. A new shop on its first day is not starting from nothing.
- Your own history counts for more than the platform’s.
- Marking an order fraud or legitimate teaches the system, for you and everyone.
- A number nobody has enough history on is checked against courier delivery records instead.
Off by default, and reversible at every step
Two switches, both yours to throw
Nothing runs until the platform enables it for your shop and you turn it on yourself. Switch it off and checkout behaves exactly as it did before.
A queue, not a verdict
Held and review orders collect in one tab with the reason on each. Mark one legitimate and it is released, purchase event and all.
Every decision is on the record
Each score is stored with the order and written to an audit trail. Nothing about how your orders were judged is hidden from you.
Tuned to your shop
A jewellery shop and a grocery shop do not carry the same risk. The point at which an order is held is yours to set.
What that actually means here
Not a number we would like you to take on trust — a list of properties that hold in the code and can be checked.
Scored off the request path
Screening runs on a worker behind a durable queue. A slow courier lookup can never make a shopper wait at checkout, and a failure retries instead of dropping the order.
Runs exactly once per order
Delivery is at-least-once, so every scorer eventually runs twice. Each claim is recorded, and a purchase event is unique on the order number, so a duplicate is a no-op rather than a second report to Meta.
One shop can never read another
Every table is isolated at the database level with Postgres row-level security, enforced under the engine rather than by the application remembering to filter.
The rules are unit tested
The engine is a pure function over its inputs, covered by tests for the rules, the thresholds, correlation and duplicates. The browser and the server run the same case table, so a rule changed on one side fails the other side’s tests.
Logs carry no shopper data
Order and decision identifiers, never a phone number or an address. Metrics carry no shop label either — an operator can see the platform’s health without seeing whose orders they are.
Reversible and observable
A kill switch per shop or platform-wide, a documented runbook for when it misbehaves, and counters for checks, held conversions and courier lookups.
Where the money actually shows up
Ad spend aimed at buyers
The optimiser stops being taught that fake orders are conversions, so the budget goes back to finding people who take delivery.
Fewer parcels going out to nobody
A held order is one the courier never collects — no delivery fee, no return fee, no stock in a van for three days.
Your packing team keeps working
Suspicious orders collect in one place instead of being spotted at the packing bench, or not at all.
Good customers stop getting punished
Earned trust lowers the score. The regular who orders every week is not treated like a first-time risk forever.
Honest numbers to plan from
Reported revenue that matches delivered revenue is the difference between scaling a campaign and scaling a loss.
Nothing new to learn
No separate console, no extra bill, no integration. It is a tab in the orders you already work through.
Turn it on for one week and read the queue
It is off until you switch it on, it changes nothing about how shoppers check out, and the review tab tells you within days whether your shop has the problem. Start there.