Integrating Tracking into Your Store
Who this document is for: store owners and developers connected to Advertorial Bandit.
Time to integrate: 15–30 minutes, depending on store complexity.
You will need: access to your site's HTML templates. No server-side changes required.
Table of Contents
- What It Is and Why You Need It
- How It Works (diagram)
- Step 0. What You Need to Know Before Starting
- Step 1. Adding the Script — Exactly One Tag
- Step 2. Marking Up Buttons — The Engine of Your Funnel
- Step 3. The Most Important Part — The Thank-You Page
- Step 4. Public JS API — For Advanced Users
- Step 5. Verification — What You Should See
- FAQ — 18 Questions and Answers
- Shopify — Step-by-Step Guide
- Custom-Built Stores (PHP/Laravel/Django/etc) — Examples
- Privacy and Legal
What It Is and Why You Need It
Imagine: your advertorial brings a visitor to your store, and they make a purchase. But how do you know the purchase happened specifically after reading that article? Without tracking, these are two unrelated events: someone read something, someone bought something.
Our script connects them.
Ad → Article (our domain) → Your store (your domain) → Purchase
↑ this link is our job
A ~5 KB script does exactly three things:
- Reads the visitor identifier from the URL (it arrives via the
?tid=parameter from the article) - Sends events to our system — store page view, add to cart, purchase
- Does not break your site — all code is in
try/catch, zero dependencies, loads asynchronously
After integration, you will see in the dashboard: how many people came from an article, how many reached the cart, how many purchased. This is the foundation for calculating the ROI of each specific article.
How It Works
- ·script reads tid from URL
- ·saves it in localStorage
store_page_viewadd_to_cartpurchasecollects everything into one journey
The cross-domain identifier tid is a UUID (36 characters), for example:
019b2f80-1234-7abc-89de-fedcba987654
It travels between domains via ?tid= in the URL. Once in your store, it is saved in the browser's localStorage — so it survives page refreshes or a return visit an hour later.
What If the User Loses Their tid?
If a person came directly (bookmark, search, typed URL) — the script generates a new tid. Such visits will not be attributed to an article, but are still recorded. This is normal: an article only gets attribution for visitors who actually arrived via a link from it.
Step 0. What You Need to Know Before Starting
| Question | Answer |
|---|---|
| Are server-side changes needed? | No. The script works entirely on the client side (browser). |
| Will the script slow down the site? | No. ~5 KB, async loading, does not block rendering. |
| Does the script break your JS? | No. All code is in try/catch, only window.bandit is used. |
| Is SSL required on the store? | No, but if the store is on HTTPS, the script must also load over HTTPS (we do). |
| Which browsers? | All modern ones. Chrome 60+, Firefox 60+, Safari 12+, Edge 79+. |
| Is CORS needed? | Already configured. The server responds with Access-Control-Allow-Origin: *. |
| What about the cookie banner? | See the "Privacy and Legal" section. |
Step 1. Adding the Script — Exactly One Tag
The simplest way is to insert one <script> tag into the <head> of your site. On every page.
<script src="https://yourfragranceworld.com/bandit-store.js"
data-endpoint="https://yourfragranceworld.com"
async></script>
Insert it into your shared template — usually header.tpl, layout.twig, _document.ejs, or equivalent. If you have multiple pages with different templates — insert it into each one.
Where Exactly in <head>?
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My Store</title>
<!-- ... other tags ... -->
→ <script src="https://yourfragranceworld.com/bandit-store.js"
→ data-endpoint="https://yourfragranceworld.com"
→ async></script>
</head>
<body>
<!-- store content -->
</body>
</html>
Script Attributes
| Attribute | Required | What It Does |
|---|---|---|
src | Yes | URL of the script on our server |
data-endpoint | Yes | Tracking API address. Always https://yourfragranceworld.com |
data-consent | No | "granted" (default) or "denied" — if the visitor has not given consent |
data-debug | No | If specified — events are logged to the browser console. Useful during setup, remove in production |
After Insertion
The script loads asynchronously and begins working immediately: it sends a store_page_view event on page load. Next — we mark up the buttons.
Installing via Google Tag Manager (GTM)
If you add the script through GTM (Custom HTML tag), there's a nuance: GTM injects the script asynchronously into <body>, and data- attributes on the tag may not be read. But it still works — the endpoint https://yourfragranceworld.com is already baked into the script by default, so it's enough to just insert the tag:
<!-- GTM → Tags → New → Custom HTML -->
<script src="https://yourfragranceworld.com/bandit-store.js" async></script>
Trigger: All Pages (on all store pages).
If you need to override settings (endpoint, consent) — set them via window.bandit.config before the script loads, in a separate Custom HTML tag with higher priority:
<script>
window.bandit = window.bandit || {};
window.bandit.config = { endpoint: "https://yourfragranceworld.com", consent: "granted" };
</script>
Important: the script locates its own tag by
srcand picks updata-attributes even whendocument.currentScriptis unavailable (as in GTM). And if nothing is configured — it uses the baked-in default endpoint. So in the simplest case, one line is enough.
Step 2. Marking Up Buttons — The Engine of Your Funnel
The script listens for clicks on elements with the data-bandit-event attribute. You simply add a few data attributes to your existing buttons. No JavaScript coding required.
Complete List of Events
| Event | When It Triggers | What Is Sent |
|---|---|---|
add_to_cart | Click on an "add to cart" button | product_id, value, currency |
begin_checkout | Click on a "checkout" button | product_id |
payment_click | Click on a "pay" button | product_id, value, currency |
purchase | Click on the "thank you for your order" page | order_id, value, currency |
Button Template
<button data-bandit-event="EVENT_TYPE"
data-bandit-product="PRODUCT_SKU"
data-bandit-value="AMOUNT"
data-bandit-currency="USD">
Button text
</button>
Where:
data-bandit-event— event type (required)data-bandit-product— SKU, article number, or product ID (recommended)data-bandit-value— amount in the store's currency, a number without spaces, e.g.29.90or1499.90data-bandit-currency— currency code:USD,EUR,GBP,RUB, etc.
The attribute can be on any element. Click on a button, link, div — the script will catch it.
Example 1. Product Card
<div class="product-card">
<img src="kettle.jpg" alt="SmartBoil Kettle Pro">
<h2>SmartBoil Kettle Pro</h2>
<p class="price">$29.90</p>
<p>New-generation induction kettle. Boils in 90 seconds.</p>
<button type="button"
class="btn btn-primary"
data-bandit-event="add_to_cart"
data-bandit-product="SB-KETTLE-PRO"
data-bandit-value="29.90"
data-bandit-currency="USD">
🛒 Add to Cart
</button>
</div>
Example 2. Cart — Multiple Items
If you have multiple items in the cart, it is enough to mark up only the total amount before checkout:
<div class="cart-summary">
<p>Items: 3</p>
<p>Total: $89.70</p>
<a href="/checkout"
class="btn btn-checkout"
data-bandit-event="begin_checkout"
data-bandit-product="SB-KETTLE-PRO,SB-FILTER,SB-MUG"
data-bandit-value="89.70"
data-bandit-currency="USD">
📦 Proceed to Checkout
</a>
</div>
Example 3. Payment Page
<form action="/pay" method="POST">
<!-- card fields, address... -->
<button type="submit"
id="pay-button"
data-bandit-event="payment_click"
data-bandit-product="SB-KETTLE-PRO"
data-bandit-value="29.90"
data-bandit-currency="USD">
💳 Pay $29.90
</button>
</form>
Example 4. Dynamic Store (React/Vue/SPA)
If buttons are added dynamically (via JavaScript), data attributes work exactly the same way — the script listens for clicks on document, it does not attach handlers to specific elements:
// React
<button
data-bandit-event="add_to_cart"
data-bandit-product={product.sku}
data-bandit-value={product.price}
data-bandit-currency="USD"
onClick={handleAddToCart}
>
Add to Cart
</button>
<!-- Vue -->
<button
data-bandit-event="add_to_cart"
:data-bandit-product="product.sku"
:data-bandit-value="product.price"
data-bandit-currency="USD"
@click="addToCart"
>
Add to Cart
</button>
Best practice: do not remove your store's native JS. Data attributes go in addition to your
onClick, not instead of it.
Step 3. The Most Important Part — The Thank-You Page
Purchase is the final event of the funnel. Without it, there is no conversion data. There are three ways to send it. Choose whichever is easiest for your store.
Method A. Automatic (Recommended) — One data attribute
Simply add a container with attributes to the thank-you page. On a click anywhere inside this container, the script sends the purchase event.
<!-- /thank-you page -->
<div data-bandit-event="purchase"
data-bandit-order-id="ORD-2026-001"
data-bandit-value="89.70"
data-bandit-currency="USD">
<h1>✅ Order Placed!</h1>
<p>Order number: ORD-2026-001</p>
<p>Amount: $89.70</p>
<p>We will send the tracking number to your email.</p>
</div>
Why a click and not page load?
The thank-you page can be refreshed (F5) — a duplicate purchase. The script is protected against duplicates (deduplication by order_id), but a click is more reliable: the user sees the page → understands the order is accepted → clicks somewhere → the event fires once.
Method B. Programmatic (Maximum Control)
If your store is an SPA, or the thank-you page is generated on the fly, use the JavaScript API:
<script>
// After the order is created on the server and the thank-you page has loaded:
window.bandit.purchase({
orderId: "ORD-2026-001", // unique order number (required)
value: 89.70, // order amount (required)
currency: "USD" // currency (required)
});
</script>
Important:
orderIdmust be unique. The server uses it to deduplicate repeated submissions. Use the real order number from your system.
Method C. Server-Side Injection (Laravel/Django/PHP/etc)
If your backend knows the order data when rendering the page, inject it directly into the template:
<!-- Laravel Blade -->
@if($order)
<script>
window.bandit.purchase({
orderId: "{{ $order->number }}",
value: {{ $order->total }},
currency: "{{ $order->currency }}"
});
</script>
@endif
<!-- Django Template -->
{% if order %}
<script>
window.bandit.purchase({
orderId: "{{ order.number }}",
value: {{ order.total|floatformat:2 }},
currency: "{{ order.currency }}"
});
</script>
{% endif %}
<!-- PHP / Twig / Smarty -->
<?php if ($order): ?>
<script>
window.bandit.purchase({
orderId: "<?= htmlspecialchars($order['number']) ?>",
value: <?= (float) $order['total'] ?>,
currency: "<?= htmlspecialchars($order['currency']) ?>"
});
</script>
<?php endif; ?>
Purchase Summary
| Method | When to Use | Complexity |
|---|---|---|
| A. data attribute | Simple HTML/template-based store | Minimal |
| B. JS API | SPA (React/Vue), dynamic stores | Moderate |
| C. Server-side injection | Laravel, Django, PHP — order is known on the server | Moderate |
Step 4. Public JS API — For Advanced Users
After the script loads, the window.bandit object is available. If your store uses complex logic (modal carts, AJAX checkout, web components) — the API gives you full control.
// Any event with arbitrary data
window.bandit.track("custom_action", {
action: "watched_video",
video_id: "tutorial-1",
duration_sec: 45
});
// Purchase
window.bandit.purchase({
orderId: "ORD-" + Date.now(),
value: 59.90,
currency: "USD"
});
// Get the current tid (useful for debugging)
console.log(window.bandit.getTid());
// → "019b2f80-1234-7abc-89de-fedcba987654"
// Consent management (cookie banner)
window.bandit.setConsent("denied"); // stop sending events
window.bandit.setConsent("granted"); // resume
Load Ordering (Important for SPAs!)
If your JS code calls window.bandit before the script has loaded — no problem. The script supports a command queue:
<head>
<!-- 1. Your code that registers the queue -->
<script>
window.bandit = window.bandit || function() {
(window.bandit.q = window.bandit.q || []).push(arguments);
};
// These calls go into the queue and execute after the script loads:
bandit('track', 'early_event', { note: 'I was here before the script loaded' });
</script>
<!-- 2. The script loads later, reads the queue, executes commands -->
<script src="https://yourfragranceworld.com/bandit-store.js"
data-endpoint="https://yourfragranceworld.com"
async></script>
</head>
Step 5. Verification — What You Should See
5.1 Quick Console Check
Add the data-debug attribute to the <script> tag (for testing only):
<script src="https://yourfragranceworld.com/bandit-store.js"
data-endpoint="https://yourfragranceworld.com"
data-debug
async></script>
Open the browser console (F12 → Console). You should see:
[bandit] track store_page_view {}
[bandit] track add_to_cart { product_id: "SB-KETTLE-PRO", value: 29.90, currency: "USD" }
[bandit] purchase ORD-001 29.90 USD
5.2 Network Check
Open the Network tab in DevTools (F12 → Network), filter by track. You should see POST requests to:
https://yourfragranceworld.com/api/track/v1/collect— response204 No Contenthttps://yourfragranceworld.com/api/track/v1/purchase— response204 No Content
5.3 Integration Checklist
Go through the items, checking off completed ones:
- Script inserted in
<head>on all store pages - Attribute
data-endpoint="https://yourfragranceworld.com"is specified - "Add to cart" buttons are marked up with
data-bandit-event="add_to_cart" - "Checkout" button is marked up with
data-bandit-event="begin_checkout" - "Pay" button is marked up with
data-bandit-event="payment_click" - Thank-you page sends
purchase(data attribute orwindow.bandit.purchase(...)) -
order_idis unique for each order (no hardcoding!) -
data-debugattribute is removed in production - When visiting the store via a link with
?tid=..., events are visible in the console - Network tab shows
POSTrequests with204 No Content
FAQ
Q1: What happens if the script fails to load?
Nothing. The store continues to work as usual. The script does not block rendering (async) and does not affect the site's functionality. Events for that visit will be lost — this is a deliberate trade-off (~5 KB script, on CDN, failure probability is near zero).
Q2: Does the script see form field contents, passwords, card numbers?
No. The script reads only the data- attributes that you yourself specified, and the page URL. It does not scan <input> elements, does not intercept form submissions, and does not touch cookies from other services.
Q3: Can I use the script only on some pages?
Technically — yes. But we recommend on all pages. Because:
store_page_viewshould fire when entering any store page- A user may land on
/product/abcdirectly, bypassing the homepage - A purchase can happen on any URL
Q4: What if I have an AJAX cart (item added without page reload)?
Data attributes on the add_to_cart button work regardless of whether the page reloads or not. A click is a click.
Q5: What if the user clicked "pay" but the payment failed?
The payment_click event is specifically the click, not payment confirmation. It is needed to measure the funnel (how many people reached the payment stage). A purchase is only recorded on the thank-you page — i.e., after the transaction has actually completed.
Q6: What if an order is not created immediately (e.g., cash on delivery)?
Use window.bandit.purchase(...) at the moment the order is actually created in your system. This could be via webhook, cron, or admin — the API is always available.
Q7: Is the script protected against duplicate purchase sends on F5 on the thank-you page?
Yes. The server deduplicates by (tid, order_id). Even if the event was sent twice, there will be only one record in the database.
Q8: How does the script distinguish between different users?
By tid — the cross-domain identifier. It arrives in the URL (?tid=...) from the article. If the user came on their own — the script generates a new tid and saves it in localStorage. A cookie is set, but only SameSite=Lax, without linking to other domains.
Q9: What if the user uses an ad blocker?
Ad blockers do not affect the script. It loads from our domain (yourfragranceworld.com), not from ad networks. The endpoint /api/track/v1/collect is a regular POST, not resembling trackers (google-analytics.com, facebook.com/tr, etc.). In our experience, ad blockers do not touch such requests.
Q10: How do I disable tracking for admin test orders?
If you know an order is a test — simply do not call window.bandit.purchase(...) in that scenario. Or temporarily call:
window.bandit.setConsent("denied");
Q11: Do I need to update the script?
No. You reference https://yourfragranceworld.com/bandit-store.js — we update the file on our side. The browser cache (1 hour via Cache-Control) will automatically pick up the new version.
Q12: Does the script support multiple currencies in one store?
Yes. The data-bandit-currency attribute is specified separately for each button. You can pass USD, EUR, GBP, etc. depending on the context.
Q13: What if I have two stores on different domains?
Install the script on each. tid is transmitted via URL, so:
- From article → store 1 (
shop1.com?tid=...) —tidis saved - From article → store 2 (
shop2.com?tid=...) —tidis saved separately - If the user navigated from store 1 to store 2 — the link is lost (different localStorage)
Q14: Does the script work on mobile devices?
Yes. sendBeacon and fetch keepalive are supported by all mobile browsers. The script size (~5 KB) is unnoticeable even on 3G.
Q15: Does the script affect Core Web Vitals (LCP, INP)?
No. The script loads with async, does not block HTML parsing. Event listeners use delegation (one handler on document) and passive mode.
Q16: Can I host the script on my own server?
Technically — yes. The bandit-store.js bundle is self-contained and has no dependencies. But we recommend referencing our URL — then you automatically receive updates.
Q17: Is X-Frame-Options or CSP required?
No. The script runs inside the page, does not use iframes. Content Security Policy does not block yourfragranceworld.com unless you have explicitly forbidden external scripts.
Q18: I've set everything up — how do I make sure the data is coming through?
Write to us in chat — we will check your tid in the admin panel and confirm that events are being recorded.
Shopify — Step-by-Step Guide
Shopify Specifics
- Theme customization is done via
theme.liquid— the main theme file - Thank-you page —
checkout/thank_you(Order Status). Available in Settings → Checkout → Order Status page → Additional scripts - Cart attributes — Shopify allows passing arbitrary data to the order via hidden form fields
Step S1. Add the Script to the Theme
Open Shopify Admin → Online Store → Themes → three dots → Edit code.
Find theme.liquid (usually in the root or layout/ folder). Inside <head>, add:
<!-- theme.liquid -->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
{{ content_for_header }}
<!-- ... other theme tags ... -->
<!-- Advertorial Bandit Tracking -->
<script src="https://yourfragranceworld.com/bandit-store.js"
data-endpoint="https://yourfragranceworld.com"
async></script>
</head>
Save the file.
Step S2. Mark Up Buttons in the Theme
In theme files (e.g., sections/main-product.liquid, snippets/product-form.liquid), find the buttons and add data attributes:
<!-- product-form.liquid: add to cart button -->
<button type="submit"
name="add"
class="product-form__submit button button--full-width"
data-bandit-event="add_to_cart"
data-bandit-product="{{ product.selected_or_first_available_variant.sku }}"
data-bandit-value="{{ product.selected_or_first_available_variant.price | money_without_currency }}"
data-bandit-currency="{{ cart.currency.iso_code }}">
{{ 'products.product.add_to_cart' | t }}
</button>
<!-- cart.liquid: checkout button -->
<button type="submit"
name="checkout"
class="cart__checkout-button button"
data-bandit-event="begin_checkout"
data-bandit-value="{{ cart.total_price | money_without_currency }}"
data-bandit-currency="{{ cart.currency.iso_code }}">
{{ 'sections.cart.checkout' | t }}
</button>
Step S3. Thank-You Page (Order Status)
Shopify does not allow editing the Order Status page HTML directly, but allows inserting "Additional scripts":
- Settings → Checkout → Order status page → Additional scripts
- Insert:
{% if first_time_accessed %}
<script>
window.bandit.purchase({
orderId: "{{ order.name }}",
value: {{ order.total_price | money_without_currency }},
currency: "{{ order.currency }}"
});
</script>
{% endif %}
first_time_accessed— critically important! Without it, the script would execute on every page refresh, sending duplicates (though the server would filter them out). Withfirst_time_accessed, the code only runs once on the first display.
Step S4 (Optional). Pass tid to the Order
If you want to additionally link tid with the order on the Shopify side, you can pass it through cart attributes:
In theme.liquid or the cart form, add a hidden field:
<input type="hidden" name="attributes[tid]" id="bandit-tid-input">
<script>
document.getElementById('bandit-tid-input').value =
window.bandit?.getTid() || '';
</script>
Then, in Shopify Admin, the order details will show a tid field with the identifier.
Custom-Built Stores (PHP/Laravel/Django/etc) — Examples
General Principle
Your server knows everything about the order: number, amount, currency, products. When rendering the thank-you page, you pass this data either via data attributes in HTML or via JavaScript.
Laravel (Blade)
{{-- resources/views/checkout/thank-you.blade.php --}}
@extends('layouts.shop')
@section('content')
<div class="thank-you-page">
<!-- Method 1: data attribute -->
<div data-bandit-event="purchase"
data-bandit-order-id="{{ $order->number }}"
data-bandit-value="{{ $order->total }}"
data-bandit-currency="{{ $order->currency }}">
<h1>Order #{{ $order->number }} placed!</h1>
<p>Amount: {{ number_format($order->total, 2, '.', ',') }} {{ $order->currency }}</p>
</div>
</div>
{{-- Method 2: JS API (alternative) --}}
@push('scripts')
<script>
window.bandit.purchase({
orderId: @json($order->number),
value: {{ $order->total }},
currency: @json($order->currency)
});
</script>
@endpush
@endsection
Django
{# templates/shop/thank_you.html #}
{% extends "base.html" %}
{% block content %}
<div class="thank-you-page"
data-bandit-event="purchase"
data-bandit-order-id="{{ order.number }}"
data-bandit-value="{{ order.total|floatformat:2 }}"
data-bandit-currency="{{ order.currency }}">
<h1>Order #{{ order.number }}</h1>
<p>Thank you for your purchase!</p>
</div>
{% endblock %}
WordPress / WooCommerce
If your site is on WordPress with WooCommerce, you can insert code via a hook:
// functions.php or a plugin
add_action('woocommerce_thankyou', function($order_id) {
$order = wc_get_order($order_id);
?>
<script>
window.bandit.purchase({
orderId: "<?= esc_js($order->get_order_number()) ?>",
value: <?= (float) $order->get_total() ?>,
currency: "<?= esc_js($order->get_currency()) ?>"
});
</script>
<?php
});
Or simpler — via a code insertion plugin (WPCode, Custom CSS & JS):
- Create a new snippet, type — JavaScript
- Pages → Thank You Page only
- Code:
if (window.bandit) {
var orderNumber = document.querySelector('.woocommerce-order-overview__order strong')?.textContent?.trim();
var totalText = document.querySelector('.woocommerce-order-overview__total .woocommerce-Price-amount')?.textContent?.trim();
var total = parseFloat(totalText?.replace(/[^0-9,.]/g, '').replace(',', '.')) || 0;
if (orderNumber && total > 0) {
window.bandit.purchase({
orderId: orderNumber,
value: total,
currency: 'USD'
});
}
}
PHP (Plain, No Framework)
<?php
// thank-you.php — after order creation
$order = getOrderFromDatabase($orderId);
?>
<!DOCTYPE html>
<html>
<head>
<title>Order Placed</title>
<script src="https://yourfragranceworld.com/bandit-store.js"
data-endpoint="https://yourfragranceworld.com"
async></script>
</head>
<body>
<h1>Thank you for your order, <?= htmlspecialchars($order['customer_name']) ?>!</h1>
<p>Order number: <?= htmlspecialchars($order['number']) ?></p>
<script>
// Wait for bandit-store.js to load
var check = setInterval(function() {
if (window.bandit) {
clearInterval(check);
window.bandit.purchase({
orderId: <?= json_encode($order['number']) ?>,
value: <?= (float) $order['total'] ?>,
currency: <?= json_encode($order['currency']) ?>
});
}
}, 100);
</script>
</body>
</html>
Privacy and Legal
What Is Collected
| Data | Example | Purpose |
|---|---|---|
tid (UUID) | 019b2f80-... | Cross-domain visit identifier |
| User-Agent | Mozilla/5.0 ... Chrome/125 | Mobile/desktop detection, bot filtering |
| IP (hashed) | a1b2c3d4... (SHA-256) | Anti-fraud, geo (country only). Irreversible hash. |
| Event timestamps | 2026-06-15T14:23:00Z | Action sequence, session duration |
| Page URL | https://shop.com/product/abc | Context: which page the event occurred on |
What Is NOT Collected
The script never reads or transmits:
- Input field contents (
<input>,<textarea>) - Passwords, card numbers, CVC
- Cookies from other sites
localStorageof other services- Geolocation via browser API
Cookie
The script sets one first-party cookie:
_bandit_tid = <UUID>
- Purpose: preserving
tidbetween visits to your domain - Lifetime: 90 days
- SameSite: Lax (not sent on cross-domain requests)
- HttpOnly: no (needed for reading from JavaScript)
- Third-party cookies: the script does not set them
GDPR / CCPA
tid does not contain personal data. It is a random UUID that cannot be linked to a specific person without additional information (which we do not have). IP is hashed irreversibly (SHA-256 + salt).
Recommendation: if you have a cookie banner and the user declined analytics, call:
window.bandit.setConsent("denied");
The script will stop sending events.
Contacts
Have questions? Having trouble setting things up?
- Email: support@yourfragranceworld.com
- Telegram: @yourfragranceworld_support
- Chat: in the Advertorial Bandit dashboard