# Send orders to ad platforms and leads to your email list

> Connect Meta, TikTok and OpenAI Ads so they count your store's sales from the server, and EmailOctopus so leads and consenting shoppers join your list.

Source: https://www.coritan.com/docs/organizations/commerce/integrations/

In the dashboard:

- /dashboard/organizations/…/commerce/integrations: https://www.coritan.com/dashboard/organizations

**Integrations** connects the store to accounts you hold elsewhere. There are four:

- **Meta Conversions API** sends each order to Meta as a Purchase.
- **TikTok Events API** sends each order to TikTok as a CompletePayment event.
- **OpenAI Ads** sends each order to OpenAI Ads as a conversion.
- **EmailOctopus** adds new leads, and shoppers who agree to marketing, to one of your lists.

The store sends from its own server once the order or lead is saved, so an ad blocker in the shopper's browser cannot stop it and a slow platform never holds up checkout. Every integration is off until you turn it on.

## Before you begin

- Everyone who can open the Commerce tab sees the integrations and their deliveries. You need the Admin role to change one or to send a test.
- Have the account details ready. Each platform gives them in its own settings:

| Integration | Setting | Secret |
| --- | --- | --- |
| Meta Conversions API | **Pixel ID**, the dataset ID in Events Manager | An access token for the Conversions API, made in Events Manager |
| TikTok Events API | **Pixel code**, from TikTok Events Manager | An access token for the Events API |
| OpenAI Ads | **Pixel ID**, from your OpenAI Ads account | The conversions access token |
| EmailOctopus | **List ID**, from the list's Settings page | An API key, from your EmailOctopus account |

- For better matching on the ad platforms, have your storefront pass the shopper's click IDs with the cart. [Send ad tracking with the cart](/docs/organizations/storefront/store-api/#send-ad-tracking-with-the-cart) shows how.

## Turn on an integration

1. Open the organization, then **Commerce**, then **Integrations**.
2. On the integration's card, fill in its settings and its secret.
3. Turn on the first switch on the card, the one named after the integration, then select **Save changes**.

The card's badge reads **On**, **Test mode** or **Off**. The store refuses to turn an integration on without its required setting and its secret, and names the field that is missing.

The secret is write only. After you save it, the card says only that it is set: nobody can read it back, from the dashboard or the API. To change it, type the new one and save. To remove it, select **Remove …** and confirm; an integration that is on must be turned off first.

## What each integration sends

### The ad platforms

Meta, TikTok and OpenAI Ads each get one event for each order placed, with the order's total, its currency, and each line's SKU (the variant ID where a line has none) and quantity. The event ID is the order's ID, such as `order_01J8DSHP1043Q7VX2M4K9T`. Use the same ID in your browser pixel, and the platform counts the sale once. The shopper's email, phone, name, city, region, postcode and country are hashed with SHA-256 before they leave the store, and so is the customer ID. The click IDs, IP address and browser the storefront passed go with them.

### EmailOctopus

A new lead that gave consent joins the list with the **Lead tag**, and its source and popup design go in the list fields you name, or as tags such as `source: popup` when you name none. A shopper who turns on marketing in their account, or ticks the marketing box at checkout, joins with the **Sign-up tag**. When a shopper who consented places an order, they get the **Buyer tag**, and a tag for each discount code they used, such as `coupon: WELCOME10`.

An address on the store's [suppression list](/docs/organizations/commerce/marketing/#keep-an-address-off-the-flows) is never added. When a shopper unsubscribes from a store email, or you add their address to the list, the store marks them unsubscribed at EmailOctopus too.

Orders brought in with [Imports](/docs/organizations/commerce/imports/) are never sent.

## Try an integration with test mode

While **Test mode** is off, an integration sends live orders and leads only. Test orders and test leads are skipped.

With **Test mode** on, it sends every order and lead, test ones included, marked so nothing reaches your live reporting:

- Meta and TikTok get your **Test event code**, so events appear under Test events in Events Manager. Test mode needs the code.
- OpenAI Ads checks each event and records none of them.
- EmailOctopus contacts get the extra tag `test`.

**Send a test event** sends one sample order with test mode on, whatever the card says, and tells you what the platform answered. For EmailOctopus, **Check the connection** reads the list with your API key. You can send 10 tests an hour for each integration. A test is not listed in the deliveries.

## Read the deliveries

**Deliveries** lists what one integration sent, newest first. Choose the integration and a status. The filters are kept in the page address. **Show deliveries** on a card opens its list.

| Status | What it means |
| --- | --- |
| Sent | The platform took the event. |
| Failed | The platform refused it or could not be reached. The row shows the platform's answer. |
| Skipped | The store did not send it, and says why: a test order while test mode is off, an imported order, no consent, or an address on the suppression list. |

A failure the platform may recover from, such as a timeout, an HTTP 429 or a 5xx answer, is tried again, up to three times in all. A refusal, such as an HTTP 400 for a wrong pixel ID, is not tried again. Each order or lead is sent once per integration.

## Result

Your ad platforms count the store's sales, including the ones a browser pixel missed, and your email list grows with the leads and shoppers who agreed to hear from you.

## Troubleshooting

**Save changes** names a setting
: The value does not have the shape the platform uses, or the integration is on without it. The message says what the setting takes.

**Send a test event** is greyed out
: Save the required setting and the secret first, and save any changes on the card. Meta and TikTok also need the **Test event code**, since a test is sent in test mode. Hold the pointer over the button to see what is missing.

A test says the platform refused it
: The toast shows the platform's answer. An HTTP 400 or 401 usually means the pixel ID or the token is wrong, or the token has no access to that pixel.

Orders show as skipped
: They are test orders and test mode is off, or they were imported.

A lead did not reach EmailOctopus
: The lead gave no consent, or the address is on the suppression list. The delivery says which.

The cards cannot be changed
: Changing an integration needs the Admin role.

## Related

- [Collect leads](/docs/organizations/commerce/leads/)
- [Win back shoppers with marketing emails](/docs/organizations/commerce/marketing/)
- [Build a checkout with the Store API](/docs/organizations/storefront/store-api/)

## With the API

`GET https://api.coritan.com/api/v1/orgs/{org_slug}/commerce/integrations` answers every kind (`meta_capi`, `tiktok_events`, `openai_ads`, `emailoctopus`) with `enabled`, `test_mode`, `config` and `secret_set`, never the secret. `PUT /commerce/integrations/{kind}` changes one with any of `enabled`, `test_mode`, `config` and `secret`; a `config` key set to `null` removes it, and `"secret": ""` clears the secret. A wrong value answers `422` with `field`, such as `config.pixel_id`. `POST /commerce/integrations/{kind}/test` sends a test and answers `{ok, http_status, error}`, and `GET /commerce/integrations/{kind}/deliveries` lists the deliveries with the filter `status`.

```bash
curl -X PUT "https://api.coritan.com/api/v1/orgs/acme/commerce/integrations/meta_capi" \
  -H "Authorization: Bearer $CORITAN_TOKEN" -H "Content-Type: application/json" \
  -d '{"enabled": true, "config": {"pixel_id": "123456789012345"}, "secret": "'"$META_ACCESS_TOKEN"'"}'
```

## API

- `GET /api/v1/orgs/{org_slug}/commerce/integrations`: Every kind with whether it is on, test mode, its config and whether a secret is set (https://www.coritan.com/docs/api/reference/organizations/commerce/commerce/#op-get-api-v1-orgs-org-slug-commerce-integrations)
- `PUT /api/v1/orgs/{org_slug}/commerce/integrations/{kind}`: Turn a kind on or off, set test mode, change its config, set or clear its secret (https://www.coritan.com/docs/api/reference/organizations/commerce/commerce/#op-put-api-v1-orgs-org-slug-commerce-integrations-kind)
- `GET /api/v1/orgs/{org_slug}/commerce/integrations/{kind}/deliveries`: What the kind sent, skipped or failed to send, newest first (https://www.coritan.com/docs/api/reference/organizations/commerce/commerce/#op-get-api-v1-orgs-org-slug-commerce-integrations-kind-deliveries)
- `POST /api/v1/orgs/{org_slug}/commerce/integrations/{kind}/test`: Send one test event (test mode forced) and answer what the platform said (https://www.coritan.com/docs/api/reference/organizations/commerce/commerce/#op-post-api-v1-orgs-org-slug-commerce-integrations-kind-test)
