Ad platforms and webshops

CCV Shop conversion tracking: a setup guide

CCV Shop conversion tracking: send paid orders to Meta and TikTok with a signed webhook, link them to ad clicks, set up, test and handle late payments.

·Updated ·10 min read·By the ROASaurus team

Key takeaways
  • CCV Shop conversion tracking is most complete when each paid order is sent from CCV's order data on the server, with a snippet on the order success page that links the order to the ad click.
  • One click on Create webhook makes CCV Shop report each order the moment it is marked paid, and every delivery must carry the private token of your store.
  • CCV Shop orders do not include the shopper's IP address, so the order success snippet matters more on CCV Shop than on most platforms.
  • The 5-minute check only looks at recently created orders, so orders paid days later depend on the webhook: keep it active.
  • Meta rejects server events more than 7 days after the order was created, so a very late bank transfer does not reach Meta.

CCV Shop conversion tracking means reporting every paid order in your CCV Shop webshop to ad platforms such as Meta and TikTok, so they credit the right ads and optimize on real sales. The most complete way is to send each purchase from CCV's order data on the server, and to add a short snippet to the order success page that links the order to the ad click.

CCV Shop is a hosted webshop platform from the Dutch company CCV, which says it runs 17,000 webshops. This guide explains how ROASaurus connects to it, how orders are linked to ad clicks, what reaches Meta and TikTok, the setup, testing, and how late payments work. For the general idea, read what server-side tracking is.

How does ROASaurus connect to CCV Shop?

ROASaurus uses three parts of CCV Shop, all described in CCV's API documentation:

CCV Shop partWhat ROASaurus uses it for
REST API, with a public key and a secret keyReads each paid order and its order rows
Webhook for the event orders.updated.ispaidCCV reports an order the moment its paid status changes
The order success page, with Vertoshop.jsThe snippet reads the order id there and links the order to the visitor
The API and the webhook deliver the order. The success page snippet links it to the ad click.
Order marked paidIn CCV Shop, after the payment
WebhookCCV posts the order id, signed with x-hash
ROASaurusReads the order and its rows with signed API calls
Ad platformsPurchase with event id order-58213
The data path for each paid order. ROASaurus checks that the order is paid before it sends anything.

Why do browser pixels miss CCV Shop purchases?

A browser pixel reports a purchase only when the shopper's browser loads the order success page and the pixel script runs. Several common situations break that:

  • The shopper pays by redirect, for example with iDEAL, and closes the tab before the success page loads.
  • An ad blocker or a browser privacy setting blocks the pixel script.
  • The visitor declines marketing cookies, so the pixel must not load.
  • The order is paid later, by bank transfer or on delivery, when no browser is involved.

In each case CCV Shop still marks the order as paid. ROASaurus sends that order from the server, so the purchase is reported whatever happened in the browser. The snippet on the success page has a different job: it tells ROASaurus which visitor, and so which ad click, the order belongs to.

The order-paid webhook and the 5-minute check

What Create webhook does

When you press Create webhook, ROASaurus registers a CCV webhook for the event orders.updated.ispaid, which CCV triggers when an order's paid property changes. The address is your store's webhook URL in ROASaurus, which contains your store key and a private token. CCV adds nothing to a webhook that identifies the shop, and its documentation advises putting an identifier in the address. The store key does that.

CCV gives each webhook its own 32-character secret key. When CCV returns that key, ROASaurus saves it, and from then on every delivery must carry a valid x-hash header. Each delivery must also carry your store's token. When ROASaurus receives a delivery, it ignores orders that are not paid, reads the full order and its order rows from the API, and sends the order only when CCV says it is paid.

Signed API calls

CCV requires every API call to be signed. ROASaurus sends three headers: x-public with your public key, x-date with the current time, and x-hash. CCV rejects a timestamp that differs more than 5 minutes from its server time. Your secret key itself is never sent.

How CCV Shop signs requests
API call (ROASaurus → CCV)
x-hash = HMAC-SHA512( public_key|METHOD|uri|body|timestamp , secret_key )

Webhook (CCV → ROASaurus)
x-hash = HMAC-SHA512( address|payload , webhook_key )

The 5-minute check

Every 5 minutes, ROASaurus also asks CCV for paid orders created since its last check, with 30 minutes of overlap, and records the ones it does not have yet. CCV filters orders by creation date only. So the check finds orders that are paid soon after they are placed, and an order paid days later reaches ROASaurus through the webhook only.

CCV counts a 200, 201, 202 or 204 answer as success. It keeps a delivery open and retries it on the next occurrence after a 307, 408, 503 or 504 answer, and marks any other answer as failed. It waits 2 seconds for a connection and 5 seconds for the answer.

How is a CCV Shop order linked to the ad click?

To credit an ad, the platform needs the click identifiers of the visitor who ordered, such as the Meta click id (fbc) and the TikTok click id (ttclid). The ROASaurus script stores them for each visitor when they land from an ad. ROASaurus does not get that visitor id from the CCV order, so it links orders to visitors in other ways:

MethodOn CCV ShopHow it works
1. Order success snippetYesIt reads the order id with Vertoshop.getOrder().getId(), plus the order total and currency, and fires a ROASaurus purchase with the event id order-58213
2. Earlier emailYesA hashed email the visitor gave earlier on your site, in a popup form or through an Identify call
3. IP address and browserNoCCV Shop orders do not include the shopper's IP address or browser, so this fallback has nothing to compare
On most other platforms the IP fallback catches some orders the snippet misses. On CCV Shop it cannot, so add the snippet.

ROASaurus waits briefly before it sends each purchase, so the success page event can arrive first, and it tries the matching again at send time. The Orders page shows the result per order in the Matched by column: thank_you, email or not matched.

An order that is not matched still goes to your ad platforms with hashed customer data from the order. It has no click identifiers, and because CCV orders carry no IP address or browser, it has none of those either. That lowers the share of events Meta can match to a person; Event Match Quality explains how Meta scores this. In ROASaurus attribution, an unmatched order shows as direct or unknown.

What reaches Meta and TikTok from a CCV order?

CCV order dataSent as
idThe event id order-58213 and the order id
total_price, currencyValue and currency (EUR when CCV gives no currency)
create_dateThe event time
Customer email, mobile or phone number, first and last nameHashed with SHA-256
Billing city, zip code and country codeHashed with SHA-256
Customer idHashed external id
Order rows: product number, product id, count, price and nameProducts with id, quantity and price
IP address and browserNot in CCV orders: taken from the success page event or the matched visitor
What ROASaurus reads from each CCV Shop order and how it appears in the server event.

Meta receives a Purchase through its Conversions API, and TikTok a CompletePayment through its Events API, both with the event id order-58213. TikTok now shows CompletePayment as Purchase in its reports. When you tick the option to also load the browser pixel, the success page snippet fires the same events in the browser with the same event id, and Meta and TikTok keep one copy. The same orders go to Snapchat, Pinterest, Reddit, X, Microsoft Ads, Taboola, LinkedIn and the other ad platforms when you connect them. Google Ads purchase conversions are sent from the Shopify checkout only, so ROASaurus does not send them from CCV Shop.

How to set up CCV Shop conversion tracking

  1. Add the store in ROASaurus

    Go to Add a store, pick CCV Shop and enter your shop address. The Connection tab then shows your script tag and the success page snippet.

  2. Find your API keys

    In CCV Shop, go to My webshop › Settings › General › API settings and click New API key. If you do not see it, install the API app from the CCV App Store first.

  3. Add the script to every page

    Paste the script tag in the Header HTML of your shop. CCV's help center places it under Mijn webshop › Instellingen › Lay-out › Layout, at the bottom of the page. An app code block in the header also works.

  4. Add the snippet to the success page

    Go to Mijn webshop › Instellingen › Algemeen › Teksten, open the text that is shown after an order is placed, switch to Source and paste the snippet there. CCV Shop then runs it on the order success page.

  5. Connect the API

    On the Connection tab, enter the public key and the secret key. Fill in Shop URL only when your API runs on another domain than your shop. Save, press Test connection, then Create webhook.

  6. Connect your ad platforms

    On Tracking & platforms, use Connect with Facebook or Add pixel for Meta, and Add pixel for TikTok. Tick the option to also load the browser pixel.

Consent

Outside Shopify, the ROASaurus script reads the visitor's choice from common consent tools: Cookiebot, OneTrust, IAB TCF banners and Google consent mode. With another cookie banner, call tlq('consent', true) when the visitor accepts marketing cookies and tlq('consent', false) when they decline. Until the visitor accepts, they have no visitor id or click ids, and no browser pixels fire. The paid order is still sent from the server with hashed customer data from the order. The consent help page explains the details.

How do you test CCV Shop conversion tracking?

  • Open your shop with ?roasaurus=connected in the address. An alert confirms that the script runs. ?roasaurus=debug logs what it sends to the browser console.
  • In the Event log, under Collected events, page views should show a visitor id.
  • Place an order and pay it, or mark it paid. Under Collected events, the Event log should show a Purchase with the CCV order id in its data. If it is missing, the success page snippet did not run.
  • On the Connection tab, Last order received shows the order and Last sync the last 5-minute check, with any error from CCV.
  • Under Server deliveries in the Event log, each connected platform gets a line with the status sent and the platform's response.
PageView visitor 51c0e9a7Script on every page
Purchase order-58213Order success snippet
webhook orders.updated.ispaidSignature checked, order paid
Meta Purchase sentMatched by thank_you
TikTok CompletePayment sentSame event id, deduplicated
Example of a healthy test order. Fetch orders now on the Connection tab runs the 5-minute check at once.

To see the event in Meta, paste the code from Events Manager › Test events into the Test event code field of your Meta pixel in ROASaurus, and remove it when you are done.

Late payments and other limits

Bank transfers and cash on delivery are paid after the order is placed. Here is what happens to an example bank transfer order, from the day it is placed:

WhenWhat happensResult
Day 0, at checkoutThe order is created, not paidNot sent: the 5-minute check asks for paid orders only
Day 0, about 35 minutes laterThe order's creation time leaves the check windowFrom now on, only the webhook can report it
Day 3You mark the order paidWebhook arrives, ROASaurus sends it. Event time Day 0 is 3 days old: Meta accepts it
Day 9, insteadYou mark the order paidWebhook arrives, ROASaurus sends it. 9 days is more than 7: Meta rejects it
Illustrative timeline. The event time is the order's creation date, and Meta accepts server events up to 7 days after the event time.
  • Cash on delivery. ROASaurus sends these orders when CCV marks them paid, usually after delivery. See cash on delivery tracking for when to count such orders.
  • Browser purchases before payment. The success page snippet runs when the order is placed, so the browser pixels report a bank transfer order before it is paid. If the payment comes more than 48 hours later, Meta and TikTok cannot merge the browser and server copies.
  • No IP fallback. Add the success page snippet, and capture emails earlier on your site where you can.
  • Cancellations and refunds are not sent. Once a purchase is sent, it stays in the ad platform.
  • Page views only, without code. Product views and adds to cart are detected automatically on Shopify only. On CCV Shop, a developer can send them with a tlq track call.

The CCV Shop integration page lists the connection facts in one place, and the help page for other webshops compares CCV Shop with the other platforms ROASaurus connects to, such as Lightspeed.

Sources

  1. CCV Shop: API Documentatie
  2. CCV: Webshop API
  3. Meta for Developers: Server Event Parameters
  4. Meta for Developers: Handling Duplicate Pixel and Conversions API Events
  5. TikTok Ads Manager: About Event Deduplication

In ROASaurus

Keep reading

Ad platforms and webshopsCash on delivery conversion tracking and external checkoutsCash on delivery conversion tracking: why pixels miss COD and external checkout orders, when to send the purchase, and how to handle refused orders.Ad platforms and webshopsGoogle Ads enhanced conversions on ShopifyEnhanced conversions add hashed customer data to Google Ads purchases on Shopify. How they work, how they differ from offline imports, and the setup.Ad platforms and webshopsLightspeed conversion tracking for eCom webshopsLightspeed conversion tracking for eCom (C-Series): send paid orders to Meta and TikTok from the server, link them to ad clicks, set it up and test it.
FAQ

Questions, answered

Where do I find my CCV Shop API keys?

In My webshop › Settings › General › API settings. If that page is missing, install the API app from the CCV App Store first.

What does the order success snippet do?

It reads the order id with Vertoshop.getOrder().getId(), plus the order total and currency, and fires the ROASaurus purchase with that id. ROASaurus uses it to link the order to the visitor and their ad click.

Why can ROASaurus not match CCV orders by IP address?

CCV Shop orders do not include the IP address or browser of the shopper. Without the snippet or an email the visitor gave earlier on the site, an order stays unmatched.

Are orders paid days later still sent?

Yes, through the order-paid webhook. The 5-minute check only looks at recently created orders, so keep the webhook active. Meta rejects events more than 7 days after the order was created.

How does ROASaurus use my CCV Shop secret key?

ROASaurus stores the secret key encrypted and uses it only to sign each API call with HMAC-SHA512, as CCV requires. The key itself is never sent to CCV, only the signature.

Every sale, traced to the ad that earned it

Server-side tracking, profit and lifetime value in one app. 14-day free trial, no credit card.

Start your free trial →