More in Developers

Tracker JavaScript reference

Everything the Refficks browser script, refficks.js, offers a developer: the attributes on its script tag, every function on window.refficks, what each sends, and what the server refuses. For a first install, follow Install the tracking script; this page is the reference behind it.

How the script behaves

  • It never breaks your page. Every function catches its own errors. A failed request is dropped, not retried, and nothing throws into your code.
  • It never reports money, except an order your confirmation page sends with sendOrder() when Settings › Developer › Website orders is on.
  • It never says which partner earns. Refficks works that out from the visitor's own clicks and codes.
  • It respects a refusal. A browser that sends Global Privacy Control, or a page without consent, gets nothing written and nothing sent. A partner's code seen in the address is held in memory for that page only.
  • Its clock is Refficks's. Whatever time the script sends, the server records the moment each request arrived.

Authentication

The script authenticates with your publishable key, rk_pub_…, as a bearer token on every request. Anybody can read it from your page, so it can only record tracking. A secret key (rk_live_…) must never be in a page; the script's address ignores one in ?a=.

The script tag

<script
  src="https://go.refficks.com/refficks.js?a=<PUBLISHABLE_KEY>"
  data-account="<PUBLISHABLE_KEY>">
</script>
Attribute Meaning
src with ?a=<PUBLISHABLE_KEY> Serves the script with your workspace's settings inlined: your link parameters (current and old), your consent setting, your verified other sites, the checkout links of the guides you chose, and whether a WooCommerce store is connected. Cached for five minutes. Without a valid key, the plain script on the default parameter rfi, cached for an hour.
data-account The publishable key. Required unless the key is in ?a=.
data-endpoint Where to send. Defaults to the host that served the script.
data-param An extra link parameter to read first, before your workspace's own list. It is added to the list, never replaces it.
data-consent "false": wait for consent(true) before writing or sending anything. "true": consent assumed. Either beats Wait for consent before tracking on Settings › Partners and payouts › Partner links. Absent: the setting decides.
data-auto-track "false": do not send a page view on load. Everything else still works.

The script sets itself up from its own tag. The global is window.refficks.

Not yet documented: the address your snippet loads from depends on the Refficks service you use. Copy the one on the Website tracking card, on Integrations › Connections; go.refficks.com is the production address in the API reference.

What it does by itself

On every page, once consent allows:

  1. Claims a partner's code. If the address carries one of your link parameters (?rfi=dana), the code is written to the rk_ref cookie, most recent first, five at most. On the page the code arrived on, that page view counts as the click, unless Refficks's redirect already counted it.
  2. Keeps a visitor id in the rk_vid cookie on your site, for 365 days. A visitor arriving through Refficks's redirect brings the id Refficks made for your workspace in the address, and the script adopts it when the browser has none of yours yet.
  3. Sends a page view (tracking.visit) with the page's path, and on the first page of a visit, the referring site.
  4. Carries the visitor between your sites. A link to another of your verified sites gets rk_vid added as it is clicked.
  5. Decorates checkout links for the guides you chose on Integrations › Where you sell: a Stripe Payment Link gets the partner's code as client_reference_id, a Stripe Buy Button or Pricing Table gets the client-reference-id attribute, a ThriveCart link gets passthrough[rk_vid], a Polar Checkout Link gets reference_id, a Memberstack checkout gets refficks_visitor in its metadata, and a checkout on another address you named gets rk_vid. A link that already carries its own value is left as you wrote it.
  6. Reports a WooCommerce order-received page, with the order key the page carries, when a WooCommerce store is connected.

A partner's link whose destination is the Stripe Payment Link itself (buy.stripe.com) opens no page of yours, so the script never runs. For that link Refficks's redirect adds the partner's code as client_reference_id as it sends the visitor on, under the same choice of guide, and leaves a client_reference_id you set yourself alone. It adds nothing for a browser that sends Global Privacy Control, as the script would not.

Functions

Call these once the script has loaded: wait for window.refficks to exist, as the short loop in the install guide does.

consent(granted)

window.refficks.consent(true);   // the visitor agreed
window.refficks.consent(false);  // they refused or withdrew
  • true, after false: writes down this page's partner code and a visitor id, and sends the page view. Repeating true sends nothing twice.
  • false: clears both cookies, and takes the script's additions back off your checkout links.

Returns nothing.

visitorId()

const id = window.refficks.visitorId(); // "01J9…" (26 characters) or null

Returns this browser's visitor id on your site, creating and storing one if there is none. Returns null while consent is withheld or the browser sends Global Privacy Control. Pass it to your server and on to Refficks as visitor_id, or to Stripe as metadata.refficks_visitor, to join a sale to the clicks. The id is your workspace's alone: another merchant sees a different one for the same browser.

referral() and referrals()

window.refficks.referral();  // "dana" or null
window.refficks.referrals(); // ["dana", "lee"]: most recent first, at most five

The partner codes this browser arrived with. Refficks credits the most recent one that is a real code, so a word in one of your own links cannot bury a partner's.

identify(customer, properties)

window.refficks.identify(
  { external_id: "<YOUR_USER_ID>", email: "sam@example.com", name: "Sam Rivera" },
  { plan: "pro" }
);

Says who is at this browser, after a sign-up or a log-in. Sends customer.created. customer takes external_id, email and name; send at least one, and the same id or email your billing system uses. properties is optional.

A browser's word is a browser's word: when the partner's click reaches a sale only because the browser named a customer Refficks already knew before that click, the commission waits for a person to approve it. Naming the customer with the same visitor_id from your server, with your secret key, removes the wait (Send events from your server).

Returns nothing.

lead(customer, properties)

window.refficks.lead({ email: "sam@example.com" });

Names the person at this browser without saying they made an account: somebody who booked a call or sent a form. Sends lead.created. It ties them to the partner the same way, so their later payment is credited, without counting as a sign-up for a referral reward. Returns nothing.

track(eventType, properties)

window.refficks.track("trial.started", { plan: "pro" });

Sends one event. The browser may send only tracking.visit (the default), customer.created, customer.updated, lead.created and trial.started. Anything else is refused: "That event type cannot be reported from a browser." Returns nothing.

reset()

window.refficks.reset();

Call it when somebody logs out. Clears rk_vid and rk_ref, so the next person on that computer starts a journey of their own and is not credited to the last person's partner. Takes the partner's code back off your checkout links. Asks the server nothing; what was recorded stays recorded.

order(order), item(item), buyer(customer), sendOrder(options)

Reports an order from your confirmation page. Only works while Settings › Developer › Website orders › Let my confirmation page report orders is on.

window.refficks
  .order({ order_id: "1001", currency: "USD", amount: 7200, coupon_code: "DANA20" })
  .item({ sku: "MUG", quantity: 3, unit_amount: 2400 })
  .buyer({ email: "sam@example.com" });

window.refficks.sendOrder({ signature: "<SIGNATURE_FROM_YOUR_SERVER>" })
  .then((result) => console.log(result));
// { sent: true, status: 202, cookieless: false, signature_verified: true }

order() starts a new order and clears any earlier one; item() and buyer() add to it. All three return window.refficks, so they chain.

Field Meaning
order_id Required. Your own order number. One order is recorded once, however often the page is reloaded.
currency Required. Three letters, such as USD.
amount The total in the currency's smallest unit: 7200 is USD 72.00.
total Instead of amount, the total as text, such as "72.00", for a page that only prints it
net_amount or net_total What commission is paid on, without tax and shipping, as minor units or as text. With neither, commission is paid on the total.
coupon_code The code the shopper typed
is_subscription, subscription_id For a subscription's first order
signature t=…,v1=… from your server, which marks the order verified. Also accepted in sendOrder({ signature }).
item sku, quantity, unit_amount One line: unit_amount is per unit, not the line total. Three at USD 24.00 is 2400.
buyer email, external_id, name Who bought

sendOrder() returns a promise that always resolves:

Result Meaning
{ sent: true, status: 202, signature_verified: true } Recorded and verified
{ sent: true, status: 202, signature_verified: false } Recorded unsigned: its commission waits for a person
{ sent: true, …, cookieless: true } The shopper had not consented, so the order went for its code alone, with no visitor and no buyer
{ sent: false, reason: "no consent" } No consent and no code: nothing sent
{ sent: false, reason: "no order" } order() was not called, or had no order_id
{ sent: false, reason: "network" } or "error" It did not reach Refficks
{ sent: false, status: 403 } Website orders are off, or on with no signing secret yet
{ sent: false, status: 409 } Stripe or a connected Shopify store already reports your sales

How to sign an order is in Install the tracking script. A signed report replaces an unsigned report of the same order, and an unsigned report after a signed one records nothing.

checkout({ reference, proof })

window.refficks.checkout({ reference: cart.id });

Says which visitor a store's cart belongs to, so the order the store reports later is credited through the partner's link even without a code. The script Refficks puts on a BigCommerce storefront calls it, and so does the script on a connected WooCommerce store's order-received page (with the order key as proof); nothing else needs to. A bare order number without its proof is refused: "A storefront reports its cart. An order number from a browser is not taken, because anybody could name the next one." Returns a promise that resolves to { sent, status }, or { sent: false, reason } with "no reference", "no consent" or "already sent".

chargebee(instance)

window.refficks.chargebee(Chargebee.getInstance());

Hands Chargebee's checkout the visitor id, as the custom field cf_refficks_visitor on the cart and on every checkout button, so the subscription Chargebee makes says who the buyer was. Only the visitor id, never a partner's code. Taken back off when consent goes or the person logs out. Returns true when a visitor id was handed over.

init(options)

Runs by itself from the script tag. Call it yourself only if you load the file in a way that cannot set its attributes, and pass at least account and endpoint. Without ?a= in the address, the script does not have your workspace's settings and reads only the default parameter rfi and any params you pass.

What the server refuses

The script sends to /t (events), /t/order (orders) and /t/checkout (carts). Each takes at most 1,200 requests a minute from one address.

Answer Message Why
401 "An API key is required." or "That API key is not valid." The key in the snippet is missing, shortened or mistyped
401 "That API key has expired." The key was revoked or has lapsed
422 "Revenue must be reported from your server, not from a browser." track() was sent an amount
422 "A partner can only be named from your server, not from a browser." An event or order named a partner
422 "That event type cannot be reported from a browser." track() with a type outside the five allowed
422 "A page view cannot name anybody. Name them with identify(), which sends customer.created." A page view carried a customer
422 "Which partner earns is decided from this visitor's own clicks, not from the page." An order carried a referral code
422 "Commission is worked out from the plan, never sent by a browser." An order carried a commission
403 "This account does not accept orders reported from a browser." Settings › Developer › Website orders is off
409 "Stripe already reports this account's payments, verified, so an order reported from a browser is not recorded, …" A sale Stripe or Shopify reports, refused as a duplicate

A repeat of the same event from the same browser within the same minute is recorded once, and answered 200 with "status": "duplicate".

When the script names unusually many people in an hour (at least 100, and five times the usual for that hour), your team is emailed, at most once a day, with the partners those people would be credited to. Nothing is refused.

Limits

  • Five partner codes per browser at most.
  • No local storage; two cookies and one session-storage marker. See Consent and privacy.
  • It does not run where an ad blocker stops it. Count clicks on our servers, on Settings › Partners and payouts › Partner links, records those clicks before the visitor reaches your site.
  • It cannot backdate a click, a page view or a sign-up.