To reconcile cash on delivery on Shopify, match every line of the courier's remittance report to a Shopify order by tracking number, then mark only those orders as paid. Anything left over is a mismatch: delivered but not remitted, remitted short, refused but marked paid, or paid but still pending. Do it on a fixed day, with one named owner.
Cash on delivery is the payment method where the money arrives last. Until it does, three systems each hold a different opinion about the same order, and none of them is lying. They're just early.
Why doesn't Shopify know a COD order was paid?
Because nobody told it. Cash on delivery is a manual payment method in Shopify, so the order sits at "Payment pending" until someone marks it paid. The courier collects the cash at the door, keeps it for a while, and pays it out later in a batch, usually with a report listing which shipments the money covers. Depending on your contract, its own charges may already be taken out.
So "delivered" and "paid" are two different events, often days apart. If your store treats them as one, your reports are off from the first order.
What goes wrong between the courier and Shopify?
Four things, and every COD store meets all of them eventually:
- Delivered, but not in the remittance. The courier's tracking says delivered, the cash hasn't shown up in any payout. It may be in the next batch. It may not.
- Remitted, but short. The amount paid out is less than the order total. A partial delivery, a changed order, a fee you didn't expect, or a mistake. Each one is answered differently.
- Refused, but marked paid. Someone marked the order paid when it shipped, then the customer refused it. Shopify now reports revenue that is sitting in a returns cage.
- Remitted, but still pending. The cash arrived and nobody updated Shopify. Finance chases money you already have.
How do you reconcile COD, step by step?
- Pick a day. Reconcile after each courier payout, or weekly if payouts are frequent. Not "when someone has time".
- Export both sides. The courier's remittance report, and your Shopify COD orders with payment pending, including their tracking numbers.
- Match on the tracking number. Not the customer name, not the amount. Names repeat and amounts collide; a tracking number belongs to one shipment.
- Mark matched orders paid. In the Shopify admin that's the order's Collect payment, then Mark as paid. With many orders, an integration or a bulk tool can do it, but only from the remittance, never from the delivery status.
- Tag what's left.
cod-short,cod-missing,cod-returned. Tags are searchable, so next week starts with a filtered list instead of a memory. - Close the returns. A refused parcel gets cancelled and restocked in Shopify once it's back in the warehouse, so stock and revenue both stop pretending.
- Send the courier the list. Missing and short shipments, by tracking number, in one message. Couriers answer lists faster than they answer feelings.
Should the courier integration mark orders paid automatically?
Only from the money, not from the parcel. An integration that marks an order paid when tracking says "delivered" creates problem 3 at scale. If the courier offers remittance data through its API or a file, use that as the trigger. If it doesn't, the weekly sheet is the trigger, and that's fine.
The integration still matters for everything before payout: booking the shipment with the amount to collect, and pushing tracking back to the order. I covered that in courier tracking on Shopify, and COD is one of the rows on my OMS rollout task sheet.
Who should own COD reconciliation?
One person, by name. Not "finance", not "ops", and definitely not "the courier". Whoever owns it doesn't have to fix every mismatch, they have to make sure none of them is still open next week.
COD isn't free money with a delay. It's a loan you gave a courier, and someone should keep the ledger.
If your COD orders and your courier payouts have stopped agreeing, tell me what you're working with and I'll tell you where I'd start.






