# Shopify Cash on Delivery Tracking

> Send Purchase only when a Cash on Delivery order is paid, and exclude the customers who never pay from your Facebook and TikTok ads.

A Cash on Delivery order is not a sale until the customer pays at the door. Some customers refuse the delivery and never pay. When those orders count as sales, your ad platforms learn from them and look for more customers like them.

By default, AnyTrack sends `Purchase` when Shopify creates an order, paid or not. This guide changes the trigger: AnyTrack sends `Purchase` when Shopify marks the order as paid. Unpaid orders arrive as an `OrderCreated` event instead. You then send `OrderCreated` to your pixels and exclude the customers who did not pay from your ads.

**Cash on Delivery: One Order, Two Outcomes**

With **Order paid** mapped to `Purchase`, a Cash on Delivery order sends `Purchase` only when the customer pays. An unpaid order stays an `OrderCreated` event, which you can exclude from your ads.

Shared start:

1. **Customer orders with Cash on Delivery**. Tools: Shopify. The order is created with payment pending. The customer pays when the order arrives.
2. **Order arrives as `OrderCreated`**. Tools: AnyTrack. The Order creation webhook sends the order. Order created is mapped to `OrderCreated`, not to `Purchase`. Data: OrderCreated (present), Purchase (missing).

The path splits here: does the customer pay?

Path 1, working path: Customer pays on delivery.

3. **You mark the order as paid**. Tools: Shopify. The Order payment webhook sends the payment. Order paid is mapped to `Purchase`. Data: Purchase (present).
4. **`Purchase` goes to your ad platforms**. Tools: Facebook Ads, TikTok Ads. The ad platforms learn from paid orders only.

Path 2: Customer refuses the delivery.

3. **The order stays unpaid**. Tools: Shopify. Nobody marks the order as paid, so no `Purchase` is sent. Data: Purchase (missing).
4. **Customer joins the Unpaid orders audience**. Tools: Facebook Ads, TikTok Ads. The audience includes `OrderCreated` and excludes paid orders.

Path 1 result: **Paid order counts as a sale**. Your campaigns optimize for customers who pay.

Path 2 result: **Excluded from your ads**. Your ad sets stop reaching customers who refused a delivery.

**One mapping makes the difference.** Give Order created its own event name, then map Order paid to `Purchase`. Unpaid orders then never count as sales, and they become an audience you can exclude.

<Prerequisites
  title="Before you begin"
  items={[
    { label: "The Shopify integration is installed, with its webhooks in Shopify. Refer to the Shopify integration guide.", done: true },
    { label: "Cash on Delivery is an active manual payment method in Shopify (Settings → Payments)", done: true },
    { label: "Your Facebook Pixel or TikTok Pixel is connected in AnyTrack", done: true },
    { label: "You have an active AnyTrack account on the Starter plan or higher to send conversions to ad platforms", done: false }
  ]}
/>

For the base setup, refer to the [Shopify integration guide](/docs/shopify).

## Step 1: Add the Order payment webhook in Shopify

🔑 Shopify admin (Settings → Notifications)

The **Order paid** event in AnyTrack needs one more Shopify webhook: **Order payment**.

1. In AnyTrack, open your Shopify integration and copy the **Webhook URL**.
2. In your Shopify admin, go to **Settings → Notifications**.
3. Scroll to the **Webhooks** section and click **Create webhook**.
4. In **Event**, select **Order payment**.
5. Leave the format as `JSON`.
6. Paste the AnyTrack Webhook URL.
7. Set the Webhook API version to the latest stable version.
8. Click **Save**.

<Callout icon="📘" theme="info">
Keep the **Order creation** webhook. It sends the `OrderCreated` event that you use in Step 3.
</Callout>

## Step 2: Map Order paid to Purchase in AnyTrack

🔑 AnyTrack Dashboard (Integrations → Shopify)

1. In AnyTrack, open your Shopify integration and go to **Shopify Integration Events**.
2. Find **Order created** and change its event name to `OrderCreated`.
3. Find **Order paid** and set its event to `Purchase`.
4. Save the integration.

<Callout icon="🚧" theme="warn">
**Order paid and Order created cannot share an event name**

AnyTrack does not accept the same event for **Order paid** and **Order created**. Give **Order created** its own name before you map **Order paid** to `Purchase`.
</Callout>

This mapping applies to every order, not only to Cash on Delivery. With Shopify's default payment capture (automatically at checkout), a card order is paid at checkout, so its `Purchase` arrives at once. If your store captures card payments manually or at fulfillment, AnyTrack sends `Purchase` when you capture the payment.

## Step 3: Send OrderCreated to your pixels and exclude unpaid orders

🔑 AnyTrack Dashboard (Tracking Pixels) and your ad accounts

This step turns unpaid orders into an audience. The audience holds the customers who placed an order and did not pay, or who refused the delivery. Exclude it from your ad sets, so you stop paying to reach these customers again.

### Send OrderCreated to your Facebook Pixel

1. In AnyTrack, go to **Tracking Pixels** and open your **Facebook Pixel**.
2. Select the `OrderCreated` event.
3. Enter the event name that Facebook receives, for example `OrderCreated`.
4. Click **Save**.

Do the same for your TikTok Pixel. For more about custom event names, refer to [Event Mapping](/docs/event-mapping).

### Build the Unpaid orders audience in Meta

1. In Meta Ads Manager, go to **Audiences**.
2. Click **Create audience**, then **Custom audience**.
3. Select **Website** as the source and select your pixel.
4. In the include rule, select the event that AnyTrack sends for `OrderCreated`.
5. Click **Exclude people** and select the `Purchase` event. This is the Facebook event that AnyTrack sends for `Purchase`.
6. Name the audience, for example "Unpaid orders", and create it.
7. Exclude the audience in your prospecting and retargeting ad sets.

Source: Meta Business Help Center, [How to create a website custom audience](https://www.facebook.com/business/help/1474662202748341).

### Build the Unpaid orders audience in TikTok

1. In TikTok Ads Manager, go to **Tools → Audiences**.
2. Click **Create audience**, then **Custom Audience**, then **Website Traffic**.
3. Include the people who triggered the event that AnyTrack sends for `OrderCreated`.
4. Use **Exclude People** to remove the people who triggered `CompletePayment`. This is the TikTok event that AnyTrack sends for `Purchase`. If you changed that mapping, select your mapped event.
5. Name the audience and click **Confirm**.
6. Exclude the audience in your ad groups.

Source: TikTok Business Help Center, [How to create a Website Traffic audience](https://ads.tiktok.com/help/article/how-to-create-a-website-traffic-audience).

<Callout icon="⚠️" theme="warning">
**Use the same time period for both rules**

Each rule has its own time period. Set the same period on the include rule and on the exclude rule. Make it longer than your delivery and payment time. If the exclude period is shorter, customers who paid stay in the Unpaid orders audience.
</Callout>

## Step 4: Test the setup

1. Place a test order on your store and select **Cash on Delivery**.
2. In AnyTrack, open the Shopify integration **Events Log**. The order shows as `OrderCreated`. No `Purchase` shows yet.
3. In your Shopify admin, open the order and click **Collect payment → Mark as paid**.
4. Click **Refresh** in the Events Log. The `Purchase` event shows.

## Video walkthrough

<YouTube id="aTuFD7maK9w" title="Shopify Cash on Delivery Tracking with AnyTrack" />

<FaqAccordion
  title="Frequently Asked Questions"
  icon="fa-duotone fa-circle-question"
  items={[
    {
      question: "What happens when a customer refuses the delivery?",
      answer: "Nobody marks the order as paid, so AnyTrack does not send <code>Purchase</code>. The customer stays in the Unpaid orders audience, and your ads stop reaching them."
    },
    {
      question: "Can I show ads to unpaid orders instead of excluding them?",
      answer: "Yes. Use the same Unpaid orders audience as a target, for example for a reminder ad. Exclusion is the default because these customers often refused the delivery."
    },
    {
      question: "The customer pays a few days after the order. Is the Purchase still attributed?",
      answer: "AnyTrack sends <code>Purchase</code> when you mark the order as paid. Each ad platform attributes the event within its own attribution window."
    },
    {
      question: "Do I still need the Order creation webhook?",
      answer: "Yes. It sends the <code>OrderCreated</code> event. Without it, the Unpaid orders audience stays empty."
    }
  ]}
/>
