Skip to main content
This guide is the exact Stripe contract behind AgentRef’s website integration. Use it whenever your site already has the AgentRef tracking script installed and you need to make sure conversions are attributed correctly.

Routing decision first

Choose the route before changing code:
RouteUse whenWhat to do
Route A — Hosted Stripe on the AgentRef websiteA Stripe Payment Link, Buy Button, or Pricing Table is rendered on the website where AgentRef is installed.Keep the flow intact and verify the AgentRef script is on that page.
Route B — Website custom checkoutThe buy button is rendered on the website where AgentRef is installed, and that website calls your backend to create Stripe Checkout.Read window.AgentRef.getCheckoutMetadata() on the website and pass it into Stripe metadata.
Route C — External app checkoutThe buy button is rendered in a Chrome extension, desktop app, mobile app, external dashboard, or another surface where AgentRef is not installed.Stop before implementation, explain the required checkout-route code change, ask for approval, then route checkout through a checkout start page on the AgentRef website before redirecting to Stripe.
If Route C applies, it overrides Route B even when your backend creates the Stripe Checkout Session. Do not treat a metadata-only patch inside the external app as complete.

First, identify your Stripe checkout type

Checkout typeWhat AgentRef needs
Stripe Payment LinksScript on the page with the link. No backend bridge required.
Stripe Buy ButtonsScript on the page with the button. No backend bridge required.
Stripe Pricing TablesScript on the page with the pricing table. No backend bridge required.
Server-created Stripe Checkout SessionScript plus a metadata bridge from browser to server to Stripe.
Direct PaymentIntents / custom Stripe flowScript plus a metadata bridge into your payment intent or checkout backend.
External app, Chrome extension, desktop app, or mobile app checkoutRoute the buy button through a checkout start page on the website where the AgentRef script is installed, then redirect to Stripe.
AgentRef already instruments hosted Stripe surfaces by itself. If the page contains a real buy.stripe.com link, <stripe-buy-button>, or <stripe-pricing-table>, you do not need an extra helper script.
If a flow is both server-created and started from a Chrome extension, desktop app, mobile app, or external dashboard, treat it as an external app checkout. A metadata-only patch inside the external app is not enough unless that app can actually read the AgentRef cookies from the website where the script is installed.

Hosted Stripe surfaces

If you use Stripe Payment Links, Buy Buttons, or Pricing Tables, install the AgentRef script on the same page as the Stripe element and keep the rest of your flow intact.

What AgentRef does automatically

  • Appends client_reference_id=<click token> to buy.stripe.com links
  • Sets client-reference-id on stripe-buy-button
  • Sets client-reference-id on stripe-pricing-table
  • Watches for late-rendered Stripe elements with a MutationObserver
That means hosted Stripe surfaces work well for static sites, SPAs, and builders as long as the AgentRef script loads on the page where the visitor clicks.

Custom Checkout Sessions

If your CTA goes to your own route, API, server action, or backend first, the script alone is not enough. You need one small bridge: read the AgentRef checkout metadata in the browser and forward it into Stripe when your server creates the session.

Step 1: Read AgentRef metadata in the browser

window.AgentRef.ready(async function () {
  const agentrefMeta = window.AgentRef.getCheckoutMetadata();

  const response = await fetch('/api/create-checkout', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      priceId: 'price_123',
      agentrefMeta,
    }),
  });

  const { url } = await response.json();
  window.location.href = url;
});

Step 2: Pass the metadata into Stripe on the server

const session = await stripe.checkout.sessions.create({
  mode: 'subscription',
  line_items: [{ price: priceId, quantity: 1 }],
  success_url: 'https://example.com/success',
  cancel_url: 'https://example.com/pricing',
  metadata: {
    ...(agentrefMeta || {}),
  },
  subscription_data: {
    metadata: {
      ...(agentrefMeta || {}),
    },
  },
});

External apps and Chrome extensions

If the buy button does not live on the website where the AgentRef script is installed, do not send the user directly from that external surface to Stripe. This includes Chrome extensions, desktop apps, mobile apps, external dashboards, and any app surface running on a different origin. Do not treat a metadata-only patch inside the external app as complete. The AgentRef cookie usually lives on your website, not inside chrome-extension://... or another external origin. Instead, route the button to a checkout start page on your website:
Chrome extension or external app
-> https://your-domain.com/checkout/start?plan=pro
-> your website reads AgentRef attribution
-> your backend creates the Stripe Checkout Session with AgentRef metadata
-> redirect to Stripe Checkout
The checkout start page should run on the same root domain as your AgentRef script. In the simplest implementation, that page loads your normal app shell, calls window.AgentRef.getCheckoutMetadata(), sends the metadata to your existing checkout backend, and then redirects to the Stripe Checkout URL.
If an AI coding agent detects this external-app pattern, instruct it to stop before implementation, explain that checkout must route through the website first, and ask for approval before editing code. This is a code-change approval gate for the checkout-route rewrite, not a deployment approval gate. It avoids silent checkout-flow rewrites and incomplete metadata-only patches.

Exact metadata keys

AgentRef expects the metadata object to pass through unchanged:
{
  "agentref_cid": "clk_abc123",
  "agentref_pid": "550e8400-e29b-41d4-a716-446655440000",
  "agentref_source": "script_direct"
}
Do not rename these keys, flatten them differently, or trim them down to only one field. AgentRef’s Stripe webhook reads this contract exactly.

What not to do

  • Do not add a second attribution or reporting pipeline for the same Stripe payment.
  • Do not overwrite your own client_reference_id on custom Checkout Sessions unless that field is already reserved for AgentRef.
  • Do not send external app or Chrome extension buy buttons directly to Stripe when the AgentRef script only runs on your website.
  • Do not treat an external app request-schema or Stripe-metadata patch as complete if the flow still starts checkout outside the AgentRef website.
  • Do not let an AI coding agent silently reroute checkout without your approval.
  • Do not assume Shopify, Webflow Ecommerce, WooCommerce, Wix Stores, or other platform-native checkouts will magically pass this metadata into Stripe. If the platform owns checkout and does not expose Stripe session creation, treat that as a separate integration problem.

Verify the Stripe path

1

Verify the tracking cookies first

Open a real affiliate link and make sure agentref_cid and agentref_pid are present before checkout starts.
2

Trigger one live test checkout

Complete a test purchase through the exact flow you use in production.
3

Inspect Stripe

In Stripe, confirm that the session metadata includes agentref_cid, agentref_pid, and agentref_source, or that the hosted surface received a client_reference_id.
4

Inspect AgentRef

In AgentRef, confirm the conversion appears under Conversions and the tracking diagnostics no longer show a Stripe-event blocker.

Troubleshooting

ProblemWhat to check
Hosted Stripe link was clicked but no conversion appearedMake sure the AgentRef script was loaded on the same page as the link or Stripe element.
Custom session created but conversion missingCheck that your backend wrote the AgentRef keys into metadata and subscription_data.metadata or payment_intent_data.metadata.
Chrome extension or external app checkout is missing attributionRoute the buy button through a checkout start page on the website where the AgentRef script is installed, then create Stripe Checkout from there.
Pricing table or buy button renders lateAgentRef already watches the DOM for late Stripe elements. Usually this means the script was not installed at all or loaded on the wrong page.
Tracking health still shows a Stripe blockerYou may have clicks but no completed Stripe event yet. Finish one supported checkout flow end-to-end.

JavaScript Snippet

Core script behavior and window.AgentRef.

How Tracking Works

Full click-to-commission pipeline.

Debug Mode

Inspect hosted Stripe instrumentation and runtime warnings.