Browse Product guides

Affiliates with any checkout or platform

Use this path when Plandalf does not read the platform directly. The browser captures a referral token, your checkout stores it with the order, and your server reports paid sales and refunds.

Capture the click

<script src="https://acme.plandalf.dev/js/plandalf-track.js" async></script>

The tracker writes a first-party pf_rt cookie and supports consent gating with data-config-referral-consent="required". It auto-detects the broadest registrable cookie domain the browser accepts, so www.example.co.uk can share the cookie with checkout.example.co.uk. Localhost, IP addresses and rejected public suffixes fall back to a host-only cookie.

You can override the cookie domain three ways:

<script
  src="https://acme.plandalf.dev/js/plandalf-track.js"
  data-config-referral-cookie-domain="example.co.uk"
  async
></script>
plandalf("init", {
  referral: { cookieDomain: "example.co.uk" },
});

The server config can also provide cookie_domain from the affiliate program.

For another checkout domain, decorate links:

<script
  src="https://acme.plandalf.dev/js/plandalf-track.js"
  data-config-referral-decorate="checkout.example-shop.com"
  async
></script>

Decoration runs when users click matching anchors. It does not cover programmatic redirects or form posts.

Store the token

plandalf("ready", async (sdk) => {
  const referral = await sdk.referral();
  document.querySelector("[name=referral_token]").value = referral?.token ?? "";
});

On the server, you can also read the pf_rt cookie on your own domain.

Report payment

When payment succeeds, call the sales API from your server. Never call it from browser code.

curl --fail-with-body -X POST "https://acme.plandalf.dev/api/v1/affiliate/sales" \
  -H "Authorization: Bearer $PLANDALF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "source": "my-shop",
    "external_id": "order_10492",
    "currency": "USD",
    "amount_cents": 30000,
    "tax_cents": 0,
    "referral_token": "rt_01J9Z4K7...",
    "customer": { "email": "sam@example.com", "external_id": "cus_881" }
  }'

If the buyer used a partner code and no token is available, send code. Code-only sales are credited by the live API; they are not automatically held for review unless a separate review rule is added later.

Subscriptions

Follow the subscription setup guide for first-payment and renewal payloads. Send the same stable customer ID on each invoice and a different sale ID for each paid invoice.

Send each paid subscription invoice as one sale. For Stripe subscriptions you run yourself, prefer the native Stripe source or report invoice.paid events only; do not report both the subscription Checkout Session and the first invoice as separate sales unless you use a shared external ID that dedupes them.

Refunds

Report refunds with the original sale external ID. For a test sale, include "test": true on the refund as well.

Planned platform shortcuts

Shopify and WordPress affiliate-source apps are planned. Until they ship, use the sales API or the native Stripe source.

Feature detail