Full integration walkthrough
The common end-to-end pattern: JavaScript snippet on the landing page, signup on your backend, and conversions from your payment gateway.
This is the most common PartnerBee integration. It combines all three methods:
the snippet captures the referral, your backend registers the customer
through the REST API, and your payment gateway drives the conversion.
The scenario
- A JavaScript snippet runs on your landing page.
- Signup posts to your backend, which registers the customer.
- A payment gateway (Stripe, Asaas, Vindi, ...) charges the customer and that is
what generates the conversion.
Landing page (snippet) Your backend Payment gateway
────────────────────── ──────────────────── ────────────────
?ref=slug
└─ cookie ba_aff ───────► signup
POST /api/customers ─────────► (customer created)
charge succeeds
POST /api/conversions ◄──────── (or gateway webhook)
Where each attribution id comes from
You never invent these values. Each one has a source:
| Field | What it is | Where you get it |
|---|---|---|
cookie_id | The tracked click | The ba_aff cookie the snippet sets (read it on your backend). Or the cookie_id returned by POST /api/clicks if you track clicks server-side. |
ref | The affiliate link slug | The ?ref=<slug> URL parameter. Accepted anywhere cookie_id is. |
click_id | The click's id (UUID) | Returned by POST /api/clicks. Only if you track clicks server-side instead of using the snippet. |
customer_id | Your gateway's customer id | Your payment provider (e.g. Stripe cus_...). |
With the snippet you only ever handle the ba_aff cookie value and pass it as
cookie_id. You do not need click_id.
Step 1: capture the referral (snippet)
Install the JavaScript snippet on your landing page. When
a visitor arrives via ?ref=<slug>, the snippet registers the click and stores
the resulting tracking id in the first-party cookie ba_aff (falling back to the
raw slug if the request is slow). That cookie value is what you read next.
Nothing else to do here.
Step 2: link the customer to the referral
This is the step that connects the browser (where the snippet captured the
referral) to your customer record. The link is always the ba_aff cookie
value: you attach it to your customer_id. There are two ways to do it. Pick
one, you do not need both.
Option A: from your backend (REST API)
When the signup posts to your backend, read the ba_aff cookie (send it along in
the signup request) and register the customer, attributing by the cookie value:
POST https://api.partnerbee.app/api/customers
Authorization: beeaff-<your-key>
Content-Type: application/json
{
"customer_id": "cus_123", // the id your gateway will use for this customer
"cookie_id": "<ba_aff value>", // the referral captured by the snippet
"status": "trial"
}Use this when your backend can see the ba_aff value (same-domain cookie, or you
forwarded the referral through the signup request).
Option B: from the browser (snippet on the dashboard)
If it is easier to link from the client, keep the snippet on the page shown right
after signup (your dashboard) and call the sign-up command with your customer id:
<script>
bee('trial', 'cus_123'); // or bee('customer', 'cus_123')
</script>The snippet reads the ba_aff cookie itself and sends { customerId, cookieId }
to PartnerBee, creating the same trial customer. You do not pass the referral
by hand. This is the client-side equivalent of Option A. It only requires that the
ba_aff cookie is readable on the dashboard page (see
Cookie scope).
Either way, the result is identical:
customer_idis now tied to the affiliate.
Because of that link, later charges can be attributed bycustomer_idalone,
with no cookie, which is exactly what you need on the server side at payment
time. The call is idempotent oncustomer_id, so retries are safe.
Step 3: record the conversion from the gateway
When the gateway confirms a payment, record the conversion. Two ways, pick one.
Option A: your backend reports it (REST API)
On the gateway's payment-success callback, attribute the conversion by
customer_id:
POST https://api.partnerbee.app/api/conversions
Authorization: beeaff-<your-key>
Content-Type: application/json
{
"customer_id": "cus_123", // same id from step 2
"external_id": "invoice_988", // your unique id for this charge (idempotency)
"amount": 199.90
}No cookie is needed here. PartnerBee looks the customer up by customer_id and
credits the original affiliate. external_id keeps it idempotent, so a retried
callback never double-counts.
Option B: the gateway calls PartnerBee directly (Integrations)
Store the referral in the gateway's metadata at checkout (key
ref_bee_affiliate) and point the gateway webhook at
https://api.partnerbee.app/webhooks/{provider}/{organizationId}. PartnerBee
records the conversion for you. See Integrations.
First charge vs renewals
When a conversion is attributed only by customer_id (no click/cookie),
PartnerBee treats it as a recurring charge (kind: "recurring"). For the very
first sale, if you want it recorded as initial, do one of:
- include the
cookie_idon that first conversion as well (it will be attributed
asinitial), or - pass
"kind": "initial"explicitly on the first conversion.
Every following renewal is attributed by customer_id only and is correctly
recurring. See Recurring revenue for the customer
lifecycle and the commission window.
Common implementation patterns
The steps above are the general shape. In practice, teams wire it up in one of
three ways depending on their architecture. All three end at the same place: a
customer linked to an affiliate, and conversions attributed by customer_id.
Pattern 1: same-domain, backend link
Landing page and app are on the same domain, so the ba_aff cookie is readable
on your backend.
- Snippet on the landing page captures the referral.
- At signup, your backend reads the
ba_affcookie and calls
POST /api/customerswithcookie_id. - On payment, your backend calls
POST /api/conversionsbycustomer_id(or a
gateway webhook does it).
Best when you control one domain end to end.
Pattern 2: cross-domain, referral carried in payment metadata
Signup or checkout happens on a different domain or a hosted payment page, so the
cookie does not travel. Carry the referral through the payment instead. This is a
common shape for subscription products with a hosted checkout.
- Snippet on the landing page captures the referral into
ba_aff. - Your front reads
ba_affand sends it into the checkout request (e.g. a
ref_bee_affiliatefield). - The payment provider stores it in the charge/subscription metadata.
- Your post-checkout backend reads it from the provider metadata and calls
POST /api/customerswithref(the slug) and the providercustomer_id. - Conversions come from the provider webhook, or your backend
callsPOST /api/conversionsbycustomer_id.
Best when the checkout is hosted or lives on another service, and the referral
must survive several hops.
Pattern 3: client-side only
No backend calls at all. The snippet does everything.
bee('detect')on the landing page.bee('trial', customerId)on the page shown right after signup.bee('conversion', conversionId, amount)on the thank-you / payment-success
page.
Best for static sites or when you would rather not add server-to-server calls.
Requires the ba_aff cookie to be readable on each page (see
Cookie scope).
Summary
| Step | Where | Call | Attribution |
|---|---|---|---|
| 1 | Landing (snippet) | bee('detect') | captures cookie |
| 2 | Backend, signup | POST /api/customers | by cookie_id |
| 3 | Backend / gateway | POST /api/conversions or webhook | by customer_id |
Updated about 2 months ago

