Skip to main content
Use this recipe when the sale happens somewhere tapfiliate.js can’t report it: in your own backend, in an external checkout or billing system, or on another domain. The idea is simple. The browser records the affiliate’s click. You carry the click to the place that learns about the payment. That place creates the conversion through the API.
1

Record the click in the browser

Add tapfiliate.js to every page where affiliate links can land, as described in JavaScript tracking. Then keep an identifier of the click. There are two, pick one.
When detect records a click, its callback receives the click. Store click.id in your own first-party cookie:
The callback runs only on the page view where the click is recorded. A visitor who returns later without an affiliate link keeps the cookie you set.A click ID points to exactly one click. Prefer it when you can store it.
2

Carry it to the checkout

The ID has to reach the system that will know about the payment.
  • Your own backend. Read the cookie on the request that creates the order, or send the ID in a hidden form field. Save it on the order.
  • An external checkout or billing system. If it lets you attach your own data to a payment and sends that data back in its payment notification, put the ID there. A URL parameter on the checkout link or a hidden field in the checkout form works the same way.
  • Another domain. Cookies don’t travel between domains. Add the ID to the link or the form that takes the visitor there.
No ID means Tapfiliate recorded no affiliate click for this visitor. Don’t send a conversion for that order.
3

Create the conversion when the payment succeeds

From your server, send the stored ID with your order ID and amount. Use click_id or tracking_id, whichever you stored.
A 200 response is the created conversion, with its affiliate and commissions. All fields are in Create a conversion.
4

Confirm it worked

  • Set up a webhook for the Conversion created event, see Webhooks. It fires for conversions created through the API.
  • Or look the conversion up by your order ID:
Track a test sale through the whole flow before you launch.

No JavaScript on the landing page

If affiliate links land where you can’t run tapfiliate.js, create the click from your server. Read the affiliate’s referral code from the landing URL (the ref parameter by default) and send it with the visitor’s details:
The response holds only the click ID:
Save it on the visitor’s session or order and use it as click_id in step 3. Errors:
  • 404 — the referral code doesn’t exist in your account, or the asset or source doesn’t exist.
  • 400 — neither a referral code nor asset_id with source_id was sent, ip isn’t a valid IP address, or the affiliate isn’t approved in the program. The body says only Bad Request, so check these three.
  • 400 Program is archived — the program no longer accepts clicks.

Which identifier wins

You can send several identifiers in one conversion request. Tapfiliate uses exactly one, in this order:
  1. coupon
  2. click_id
  3. referral_code
  4. asset_id with source_id
  5. tracking_id
If the winner can’t be resolved, the request fails with 400. Tapfiliate does not fall back to the next identifier. A click_id of another account, for example, fails with Invalid click id even when a valid referral_code is sent too. One exception comes first: customer_id of an existing customer, in a program with recurring commissions, sends the conversion to that customer’s affiliate.

Choosing the program

The conversion never names a program. The identifier decides it:
  • click_id or tracking_id — the program of the click.
  • referral_code — an affiliate has a separate referral code in each program, so the code points to one program.
  • coupon — the program the coupon is assigned to.
If your account uses program groups, send program_group with a click_id or tracking_id. Tapfiliate then accepts only clicks in that group’s programs. With other identifiers program_group has no effect.

Retries and duplicates

external_id is unique in your account. A second conversion with the same external_id fails with 400 Duplicate conversion. There is already a conversion for External id '…'. That makes retries safe: treat this error as success. A retry that arrives while an earlier attempt with the same external_id is still running, or within 10 seconds after one failed, gets 400 To many concurrent attempts to create conversion with id '…' instead. Wait more than 10 seconds and retry. Without external_id there is no duplicate check. Each retry, for example after a timeout, creates another conversion.

Common pitfalls

  • Tracking the same sale twice. The browser and the server share the duplicate check by external_id. If tapfiliate.js reports the sale with one ID and your server with another, for example the order ID and the payment ID, you get two conversions. This often happens with coupons: tap('conversion') with coupons and an API call with coupon for the same order. Track each sale in one place, or use the same external_id in both.
  • Cookie expired. A conversion by click_id or tracking_id fails when the click is older than the program’s cookie time. To track a late payment anyway, add ?override_max_cookie_time=true to the request URL.
  • No identifier. A request without click_id, tracking_id, referral_code, coupon, asset_id with source_id or customer_id fails with Missing mandatory parameter(s).
More messages and what to do about them are in Errors.