Shopify makes it easy to accept cash on delivery, and leaves the hard part to you: knowing which COD orders the customer actually intends to pay for before the parcel leaves your warehouse. Shopify has no built-in step that asks the customer. What it does have is good plumbing for one: order tags, notes, filters and webhooks.
This guide covers the confirmation workflow you can run with Shopify alone, where it breaks down, and how an automated press-1-to-confirm call fits into the same tags your team already filters on.
Running a Shopify store with COD? See COD confirmation calls for Shopify: what changes in your admin, the setup steps and how to join the pilot.
How COD shows up on a Shopify order
Cash on delivery on Shopify is a manual payment method. You turn it on under Settings, Payments, manual payment methods, and it appears at checkout with the name you give it, typically "Cash on Delivery (COD)".
Three things follow from that:
- Payment status is pending. The order is created without payment, and someone marks it paid after the courier remits the cash.
- The gateway name is how COD is identified. In the order data the payment gateway name carries the manual method's name. Anything that wants to treat COD orders differently, including Shopify Flow and external tools, checks that name. If you rename the method, update those checks too.
- Nothing contacts the customer. Shopify sends its normal order confirmation email or SMS, which is a receipt, not a question. A customer who placed the order by mistake has no reason to reply to it.
The manual workflow (and where it breaks)
Most stores start with a person and a phone:
- Filter the Orders list to unfulfilled orders with a pending payment status, or save a view for it.
- Call each customer, read out the order and amount, and ask them to confirm.
- Tag the order:
COD-CONFIRMED,COD-CANCELLEDor something likeCOD-NO-ANSWER, and add a note with what was said. - Cancel the orders the customer refused, and let fulfilment pick only confirmed ones.
- Retry the no-answers later in the day.
Shopify Flow can take some of the clicking away: it can tag every new COD order automatically, so your team starts from a clean list. It cannot make the call, though.
This works until volume or timing gets in the way. Orders placed at night wait until someone is in. Retries depend on someone remembering. Notes vary by caller, so the history is hard to audit. And the calling team becomes the bottleneck right before the courier pickup cut-off, which is exactly when you need the answers.
The other common route is a confirmation app from the Shopify App Store. These generally fall into three groups: WhatsApp or SMS message flows, keypad (IVR) call flows, and AI voice calls. Almost all of them record the answer the same way, as an order tag, and leave payment status alone. That convention is useful: whatever tool you use, your fulfilment filters stay the same.
What a good confirmation step should do on Shopify
Before choosing a tool, it helps to write down what "confirmed" must mean in your admin:
- A tag per outcome that your team and your shipping tool filter on.
- A note recording when and how the customer answered.
- Real cancellation for refused orders, using Shopify's own cancel, so stock is restocked and the order leaves the queue.
- No change to payment status, because nothing has been paid yet.
- No call for orders that changed in the meantime: cancelled by the customer, or already confirmed by your team.
How call-based confirmation works on Shopify
With a call, the customer hears the order read out and answers with one key. Here is the flow Edesy's COD confirmation calls use.
1. The order reaches us by webhook
When an order is created, Shopify sends an orders/create webhook. Cancellations come through
orders/cancelled, and late payments through orders/paid, so a COD order that was paid online before
the call is not called. Each webhook is signed by Shopify (an HMAC of the body) and carries a webhook id,
which we use to ignore duplicate deliveries.
The phone number caveat. Shopify redacts the customer's name, phone and address from webhooks unless the app has access to protected customer data. Without it, every order would arrive without a phone number and nothing would be called. Setting up that access is part of connecting a Shopify store, and the connection test checks for it.
2. Rules decide which orders get a call
By default only unconfirmed COD orders are called. COD is recognised from the payment gateway name (the label is configurable if yours isn't "Cash on Delivery"), and an order already carrying your confirmed tag is treated as confirmed. You can add conditions, such as a minimum order amount.
3. The customer is called inside your calling window
Default rules, all adjustable: the first call goes out 2 minutes after the order, only between 9 am and 9 pm IST, with up to three attempts (30 minutes, then 2 hours apart) and a 48-hour give-up time. Night orders are called when the window opens the next morning.
Just before dialling, the order is checked again. If it was cancelled or confirmed in the meantime, the call is skipped.
The script reads out your store name, the order number and the COD amount in Hindi or English: press 1 to confirm, 2 to cancel. You can edit every line of it.
4. The answer is written back to the order
| Customer outcome | What changes in Shopify |
|---|---|
| Pressed 1 | Tag COD-CONFIRMED added (and a note, if you turn it on) |
| Pressed 2 | Order cancelled with Shopify's order cancel, tag COD-CANCELLED |
| No answer after all attempts | Tag COD-UNREACHABLE, for your team to decide |
| Answered, pressed nothing | Tag with your no-input label |
| Already cancelled or confirmed | Not called |
Tags are added with Shopify's tag API, so existing tags on the order are kept. A Shopify order has a single note field and writing to it replaces what is there, so the note is optional. Payment status is never changed. If Shopify doesn't accept an update at the moment the customer answers, the answer is kept and the update is retried in the background.
Because the result is just a tag, everything downstream keeps working: saved order views, Flow automations, and shipping tools that pick orders by tag. If your team already uses different labels, rename ours to match.
Integration status, stated plainly
Shopify is in pilot. We set up the connection with you during the pilot: the app access for customer phone numbers, your tag labels, your calling rules and your script. It is not a self-serve App Store install today.
If your store runs on a headless setup or a custom backend that can send a signed webhook, the custom store API is live now and can be used instead.
A rollout plan that keeps your team in control
- Agree the labels first. Decide the confirmed, cancelled and unreachable tags with your fulfilment team and set your saved views to them.
- Start with calls, not auto-cancel. For the first week, have "pressed 2" add a tag only, and let your team review before cancelling. Turn on real cancellation once you trust the flow.
- Keep a human for unreachable orders. One short manual call round for
COD-UNREACHABLEorders before pickup catches most of the rest. - Listen to recordings. Check that product names and amounts sound right in the language you chose.
- Measure against your own RTO. Compare refusal rates on confirmed versus unconfirmed orders in your courier data; our COD RTO calculator helps put a cost on it.
Pricing
Calls are paid as you go from a prepaid wallet. Share your monthly COD volume with us for pricing.
Next step: See COD confirmation for Shopify and join the pilot. We'll set up the store connection with you.