Getting started
Install NativeCOD, add the button to your theme, place a test order and go live.
NativeCOD adds a Cash on Delivery button and a one-page order form to your store. Shoppers pick one of your Shopify shipping rates and order without going through checkout, and each order arrives in Shopify as payment pending, tagged COD.
The setup guide
After you install NativeCOD from the Shopify App Store, a four-step setup guide opens: Add to theme, Design, Shipping and Go live. Reopen it any time from Dashboard › Need a hand? › Open the setup guide.
Turn on the app embed
The button is added with a theme app embed, so there's no code to edit. It works with any Online Store 2.0 theme.
- Click Open theme editor in the setup guide, or Turn on in the Dashboard checklist. NativeCOD is already selected under App embeds.
- Check that the NativeCOD form embed is on, then click Save.
- Back in NativeCOD, Dashboard › Status › App embed shows Active.
Place a test order
Turn on Form & button › Test mode. The button then only appears on pages whose address contains ?nativecod=test, and in the theme editor.
- Open a product with the parameter, for example
https://your-store.com/products/sneaker-care-kit?nativecod=test(use&nativecod=testif the address already has a?). Preview on store on the Form & button page does this for you. - Tap the COD button, enter an address you deliver to, such as one in Berlin, Germany, and order.
- Check the order under Orders in Shopify and on NativeCOD's COD orders page.
Go live
Turn off Test mode and keep Show on my store on. The badge on Form & button changes to Live and every shopper sees the button. Saved changes reach your storefront within a minute.
Order form
Choose the fields shoppers fill in, style the form and rewrite its texts.
The form shows the items, your shipping rates for the shopper's address, the totals and the order button. Logged-in customers get their details filled in.
Form fields
In Form & button › Form fields, switch fields on or off, edit their Label and Placeholder, set Width to Full or Half, tick Required and reorder them with the arrows.
| Field | Default |
|---|---|
| First name, Last name | On, half width. Last name is optional. |
| Full name (replaces first and last name) | Off. The last word becomes the order's last name. |
| Phone | Always on and required. |
| Address, City | On, required. |
| Address line 2, Region or province, Postcode | Off. |
| Country | Off. Without it, orders go to your default country. |
| On, optional. | |
| Order note | Off. Saved as the order note. |
| Marketing consent checkbox | Off, never required. Ticked, it adds the accepts-marketing tag. |
| Terms checkbox | Off. Required by default. |
Add custom field adds your own question: Short text, Paragraph, Dropdown (with Options (comma separated)) or Checkbox. Answers are saved in the order's Additional details under the field's label.
Form design
| Setting | Default |
|---|---|
| Form title, Text above the fields | CASH ON DELIVERY, Enter your delivery details |
| Order button | COMPLETE ORDER - {total}, where {total} is the order total |
| Small text below the button | Empty |
| Accent, Background, Text, Corner radius | Dark blue, white, near-black, 10 px |
| Show an icon next to the title | On |
| Let shoppers change the quantity | On: − and + buttons from 1 to 99, for one product ordered from a product page without a bundle or offer |
| Show a discount code field, Full-screen form on mobile, Right-to-left layout (Arabic, Hebrew) | Off |
Texts
You can rewrite the wording in any language; one set of texts serves all visitors. Most of it is in Form & button › Texts: the order summary, discount code, messages and errors, and thank-you texts. Button texts are on the Button tab, field labels on Form fields, the form title and order button on Form design, and repeat-order texts on Fraud protection.
Messages and errors also holds the texts your fraud rules show: Daily order limit reached, Order below the minimum total, Order above the maximum total and Too many items, where {max} is your Items per order. Cash on delivery off or paused shows while Show on my store is off or this month's orders are used up. When Shopify itself refuses an order, shoppers see your Something went wrong text and you see Shopify's reason on the COD orders page. A quantity offer's discount line shows the tier's title.
Shipping & addresses
Rates come from your Shopify shipping settings for each shopper's address.
NativeCOD never makes up shipping prices. Whenever the form opens or the shopper changes their country, region, city or postcode, Shopify calculates a draft order for that address and returns the rates from Settings › Shipping and delivery: zone rates, carrier-calculated rates and local delivery, but not local pickup. Totals include your automatic discounts and taxes, and each order carries the exact Shopify rate, so courier and fulfillment apps read it like a checkout order.
Check, hide and pre-select rates
On Shipping & orders, enter a Country, optionally a City and Postcode, and click Check rates to see every rate a shopper there gets for one of your active products. If there are none, add a shipping zone or local delivery area for that address.
- Hide in COD form keeps a rate out of the form; Show brings it back. Rates are hidden by name, ignoring capitals, so a renamed rate shows again. If every rate for an address is hidden, shoppers there can't order.
- Pre-selected rate: Cheapest first (default) sorts by price and selects the cheapest; Same order as Shopify selects Shopify's first rate. Shoppers can pick another.
Countries
- Default country: your store's country at first. Orders go to it when the form has no Country field.
- Countries shoppers can choose: Where my Shopify shipping zones deliver (default) or Only countries I pick, which refuses orders to countries not on Your countries. An empty list allows only the default country.
The Country field is off by default; turn it on, or click Show the Country field, if you offer several countries. It pre-selects the shopper's own country when it's offered. NativeCOD refreshes the zone countries when you save settings, and when you open the app if they're more than an hour old.
Phone numbers
Shopify needs international numbers, so NativeCOD removes spaces, drops a leading 0 (except for Italy) and adds the country code. For delivery to Germany, 0151 12345678, +49 151 12345678 and 0049 151 12345678 all become +4915112345678.
- Phone country code, such as
+356, is shown in the field and added to local numbers. Leave it empty to use each delivery country's code, which is best if you deliver to several countries. - Minimum digits in a local phone number: 7 by default, without the country code. Numbers can have up to 15 digits.
Orders in Shopify
What a COD order looks like in Shopify and what shoppers see after ordering.
Each COD order is a regular Shopify order, created from a draft order Shopify priced. These options are on Shipping & orders.
Payment status and tags
Orders are Payment pending with the terms in Payment status: Pending — due on fulfillment (default) or Pending — due on receipt. Mark them as paid once your courier pays you. Order tags (COD and NativeCOD by default, comma separated) help with filters, Shopify Flow and courier apps; shoppers who tick the marketing checkbox add accepts-marketing.
What's on the order
The shopper's Shopify shipping rate, their address as shipping and billing address, the phone in international format, the email and order note if given, and line item properties from your product form. Additional details list the payment method, the phone and, when they apply, the bundle name, your custom field answers and Accepts marketing.
With Save UTM parameters, ad click IDs and IP address on the order on (default), they also show the visit's UTM parameters, Facebook, TikTok and Google click IDs, landing page, referrer and IP address. The shopper's browser remembers the campaign details for 7 days, only if the visitor allows marketing in your cookie banner (or no consent is required where they are).
After the order
| After the order is placed | What shoppers see |
|---|---|
| Go to Shopify's order status page (default) | A short thank-you, then the order status page. With new customer accounts, Shopify asks shoppers to sign in to see it, so they get your thank-you message and a Continue shopping button instead. |
| Show a thank-you message in the form | Your thank-you message and a Continue shopping button. |
| Go to a custom page | A short thank-you, then your Custom thank-you page URL with ?order= and the order number. Without a URL, the thank-you message. |
Edit the thank-you texts in Form & button › Texts; {order_name} shows the order number.
Orders from the cart
The cart button orders the whole cart, with quantities and item properties. Quantity changes, offers and theme bundles are for product pages only, and discount codes from the cart aren't carried over. Empty the cart after an order from the cart (on by default) clears it afterwards.
Cash on Delivery fee
Charge a Cash on Delivery fee adds a fixed fee once to every COD order, such as your courier's cash handling cost. Set the Fee name (the line item on the order), the Amount (nothing is charged at 0) and whether to Charge tax on this fee. Shoppers see it in the order summary under your COD fee text. Shoppers paying in another currency are charged the amount converted at Shopify's exchange rate.
Bundles & offers
Use your theme's bundle picker or quantity offers inside the form, priced by Shopify.
Your theme's bundles
With Use the bundle picked on the product page on (default), a shopper who picks a bundle or quantity break, such as "Buy 2, get 1 free", gets the same quantity in the form. The bundle's name shows in the form and is saved on the order. It works with Shrine and Vault quantity breaks, Kaching-style pickers and any picker that changes the product form's quantity.
Quantity offers inside the form
For themes without a bundle picker, turn on Show quantity offers in the form and click Create offer. Offer cards only appear when the form opens from a product page and no theme bundle was picked.
| Setting | What it does |
|---|---|
| Active | Turn off to hide the offer without deleting it. |
| Products | All products or the ones you choose. If a product is in several active offers, the first one on the page is used. |
| Selected when the form opens | Automatic picks the tier matching the product page quantity, else the first. You can choose a tier instead. |
| Tiers | One card each: Quantity (1–50), Title, optional Badge and Discount: No discount, Percentage off or Amount off the total, never more than the tier's total. |
A tier sets the quantity, and its discount is added to that product's line on the order under the tier's title. When a discount doesn't fall evenly on every unit, as with Buy 2 get 1 free, Shopify needs the product split into one-unit lines to create the order as payment pending; the total stays the same.
Fraud protection
Stop fake, repeat and oversized orders before they reach Shopify.
When a rule on Fraud protection stops an order, nothing is created in Shopify and the shopper sees a message in the form.
Order limits
Orders per phone number, per day (default 3) and Orders per IP address, per day (default 6) count COD orders in the last 24 hours; 0 means no limit. Offices and mobile carriers share one IP, so keep the IP limit higher.
Repeat orders
When a shopper orders the same thing again soon after, often because the first order hasn't arrived, NativeCOD can Ask them to confirm first (default) with your question and a Button to order anyway, Block the new order with your message, or Allow it, show nothing. In both texts, {date} and {order_name} show the earlier order.
- Look back: 1, 3, 7 (default), 14 or 30 days.
- Recognise the shopper by: Phone number (on) and Email (off; only works when your form asks for one).
- Only when the same products are ordered (on) and Only while the earlier order isn't fulfilled (on), which ignores fulfilled or cancelled orders.
To keep orders private, an earlier order only counts if it came from the same browser or network.
Order size and block list
- Minimum order total and Maximum order total compare the full total, including shipping and fees, in your store's currency (Shopify converts orders in other currencies); 0 means none.
- Items per order: 50 by default, 0 for no limit.
- Block list: Phone numbers, Emails and IP addresses, one per line. Phone numbers match on their last digits (at least 6), so the country code is optional; emails and IP addresses must match exactly. Blocked shoppers see your general error message.
Always on
A Bot trap stops automated submissions, the Phone check validates numbers, and the Price check has Shopify recalculate the order before it's placed; if the total changed, the shopper sees your Prices changed text and the new total. The Abandoned forms switch is here too (see COD orders page).
Pixels
Send form and order events to your ad and analytics tools.
Send events to pixels already on my store (on by default) sends events to the Meta, TikTok, Google, Snapchat and Pinterest tags your theme or other apps load.
| Platform | Add to cart | Form opened | Order placed |
|---|---|---|---|
| Meta | AddToCart | InitiateCheckout | Purchase |
| TikTok | AddToCart | InitiateCheckout | CompletePayment |
| Google Analytics 4 | add_to_cart | begin_checkout | purchase |
| Google Ads | — | — | conversion |
| Snapchat | ADD_CART | START_CHECKOUT | PURCHASE |
addtocart | — | checkout |
Every event includes the order value and currency. Custom pixels in Settings › Customer events can listen for nativecod_open, nativecod_add_to_cart and nativecod_purchase.
Extra pixel IDs
For pixel IDs your store doesn't load yet, even if your theme loads other IDs from the same platform; separate several IDs with commas. NativeCOD loads the Meta and TikTok pixels for your IDs. When Meta, TikTok or GA4 IDs are set, that platform's events go only to them. Google Analytics 4 measurement IDs and Google Ads conversions (ID and label, like AW-123456789/AbC_dEfGhIjK, sent with each order) need the Google tag (gtag.js) on your store; NativeCOD adds your IDs to it without an extra page view. Snapchat and Pinterest only use their own tags.
Add to cart
- Send Add to cart when the COD form opens (off): sends Add to cart just before the checkout event.
- Also add the product to the Shopify cart (off): puts the product in the cart when the form opens from a product page, so Shopify Analytics and Shopify's own Meta, Google and TikTok channels count it. NativeCOD takes it out again after the COD order; if the shopper closes the form, it stays. Some cart drawer apps open when a product is added, so try it first.
Shopify Analytics counts COD orders as orders and sales, but not under "Reached checkout", which is only for Shopify's own checkout.
Visitor privacy
Events follow each visitor's cookie choices through Shopify's Customer Privacy API: ad platforms, including extra pixel IDs, wait for marketing consent, and GA4 for analytics consent. Campaign details for your orders are kept only with marketing consent too. Where consent isn't required, events are sent as usual.
COD orders page
Review every COD order and follow up on abandoned forms.
Orders
The Orders tab of COD orders lists every order placed with the form, newest first: order number, date, customer name, phone and city, shipping rate and total. Cart orders are marked From cart. Click a row to open the order in Shopify, where you fulfill it and mark it as paid. Orders stopped by your fraud rules aren't listed, and customer details are cleared from this list after 90 days.
When Shopify refuses an order, for example because an item can't be sold, the attempt is listed as Failed with Shopify's reason, the total and the shipping rate, but no customer details.
Abandoned forms
When a shopper enters a phone number, then closes the form or leaves the page without ordering, the Abandoned forms tab shows their name, phone (tap to call, or use the WhatsApp link), email, city, items, total and when they were Last active. If they return to the open form and order, the entry is removed. Forms are deleted after 90 days. Turn them off under Fraud protection › Abandoned forms.
Plans & billing
Every plan includes every feature; plans differ only in monthly COD orders.
| Plan | Monthly | Yearly | COD orders a month | Free trial |
|---|---|---|---|---|
| Free | $0 | $0 | 50 | — |
| Basic | $9.99 | $99 | 500 | 7 days |
| Pro | $24.99 | $249 | 3,000 | 7 days |
| Unlimited | $49.99 | $499 | Unlimited | 7 days |
Prices are in USD. Monthly plans are billed every 30 days; yearly billing gives two months free. Price changes only apply to new subscriptions (see our terms of service).
Billing and changing plans
Charges appear on your Shopify invoice. On Plans, pick Monthly or Yearly · 2 months free, click Upgrade or Downgrade and approve the charge in Shopify; the new plan applies straight away. Choosing Free, or uninstalling, cancels your subscription. The 7-day trial doesn't restart: if you change plans during it, the new plan gets the days left. Have a code from NativeCOD? Enter it under Promo code.
Monthly COD orders
Every order the form creates counts, including test orders and orders you cancel later. The count restarts on the 1st of each month (UTC).
Past your limit, orders keep coming for another 10% (up to 55 on Free, 550 on Basic and 3,300 on Pro). Then the COD button is paused: it's hidden and the form refuses orders until the 1st of the next month or until you upgrade. The Dashboard and Plans page warn you when you reach the limit. For more volume or an agency plan, contact us.
Troubleshooting
Fixes for the most common setup and ordering problems.
The COD button doesn't show
- Dashboard › Status › App embed should say Active. If not, turn on the NativeCOD form embed in your published theme and save.
- Show on my store must be on. In Test mode, the address needs
?nativecod=test. - If the Plans page says The COD button is paused, this month's orders, including the extra 10%, are used up.
- Check Product pages or Cart page and cart drawer, the Products rule and Only for visitors from these countries.
- A Custom position selector that matches nothing, or isn't valid CSS, is ignored and the button keeps its normal position. The Placement tab flags an invalid selector before you save.
- The button needs your theme's product form with an Add to cart button. Quick-add popups, product cards, recommendations and cart drawers are skipped. If your theme's product form is custom, contact us.
"Sorry, we don't deliver to this address yet."
Shopify has no rates for the address, or you've hidden them all. Test it with Check rates, then add a shipping zone or local delivery area that covers it. Without a Country field, orders go to your Default country, so your zones must include it; with Only countries I pick, the country must be on your list. If local delivery depends on postcodes, turn on the Postcode field.
"Enter a valid phone number."
The number is shorter than Minimum digits in a local phone number or longer than 15 digits, or Phone country code doesn't match the delivery country. NativeCOD knows most calling codes; if it doesn't know the delivery country's and Phone country code is empty, shoppers must type + and their country code.
The order isn't created
| The form says | Cause |
|---|---|
| Your Something went wrong text | The block list, the bot trap, a connection problem, or Shopify refused the order (see its Failed row on COD orders) |
| Your Daily order limit reached text | Orders per phone number, per day or Orders per IP address, per day |
| Your Order below the minimum total or Order above the maximum total text | Minimum order total or Maximum order total |
| Your Too many items text | Items per order |
| Your Prices changed text | Shopify's total changed; the shopper sees the new total and can order again |
| Your Cash on delivery off or paused text | Show on my store is off, or this month's orders are used up |
A discount code doesn't apply
Your Code that can't be used text under the field means Shopify couldn't apply the code to these items, so check its conditions in Shopify. Codes applied in the cart aren't carried into the form.
The total doesn't match a bundle's advertised price
NativeCOD charges what your Shopify discounts give. If a theme bundle such as "Buy 3, get 2 free" shows another total in the form, create an automatic discount in Shopify that gives exactly that deal.
Privacy & data
What NativeCOD stores, how long it keeps it and what happens when you uninstall.
This is a summary; our privacy policy has the full details.
What's stored
- Your store: name, domain, contact email, country, currency, settings and any suggestions you send.
- A copy of each COD order: number, total, items, shipping rate, the shopper's name, phone, email and city, and campaign details if you save them.
- One-way hashes of the phone, email, IP address and browser ID for order limits and repeat checks. They can't be turned back into the originals.
- Abandoned forms (when on) and daily totals for the Dashboard.
Shoppers' personal details are encrypted in our database, and connections use HTTPS. In the shopper's browser, local storage (not cookies) keeps the visit's campaign details for 7 days, if you save them and the visitor allows marketing, and, once they order, a random browser ID for repeat checks.
How long it's kept
| Data | Kept for |
|---|---|
| Abandoned forms | 90 days, then deleted |
| Shopper details and campaign data on our order copies | 90 days, then cleared; order numbers and totals stay for your statistics |
| Phone, email, IP address and browser ID hashes | 30 days |
Requests and uninstalling
Shoppers should contact your store about their data; you can forward requests to us. When Shopify sends a customer deletion request, NativeCOD clears that shopper's details from its order copies and deletes their abandoned forms.
When you uninstall, Shopify cancels your subscription and removes the app embed. Settings are kept for 48 hours, so a quick reinstall restores them; after that, all your store's data is deleted. Your COD orders stay in Shopify. To have your data deleted sooner, contact us.
Still stuck?
Email us with your store address and we'll help you set up.