# Stripe Payment Links (https://www.getfounderhq.com/docs/analytics/revenue/connect-stripe/payment-links)

Attribute payments that people make on a Stripe-hosted Payment Link. This takes
about five minutes.

<Callout title="Before you start">
[Connect Stripe](/analytics/revenue/connect-stripe) first, and install the
[web SDK](/analytics/sdks/web) on the page that holds your buy button.
</Callout>

A hosted Payment Link runs on Stripe's domain, so you cannot put FounderHQ IDs
in the checkout code. You pass one opaque token instead. FounderHQ mints the
token on its own server, so the attribution survives even if the buyer never
comes back to your site.

## 1. Ask the SDK for a token

`paymentLinkToken()` returns a string that starts with `fhqref_`. The token is
valid for 30 days.

It returns `null` when the visitor has not granted consent, has opted out, or
when the SDK has no publishable key. Handle that case by sending the buyer to
the plain link.

## 2. Put the token on the link as `client_reference_id`

```tsx
// app/pricing/buy-button.tsx
"use client";

import { founderhq } from "@founderhq/events";

const PAYMENT_LINK = "https://buy.stripe.com/XXXX";

export function BuyButton() {
  async function checkout() {
    const token = await founderhq.paymentLinkToken();
    const url = new URL(PAYMENT_LINK);
    if (token) url.searchParams.set("client_reference_id", token);
    window.location.href = url.toString();
  }

  return <button onClick={checkout}>Buy the growth plan</button>;
}
```

Using a Stripe Pricing Table instead? Put the same token in the table's
`client-reference-id` attribute. FounderHQ reads both from the same field on
the completed Checkout Session.

## 3. Let the token do the rest

When the buyer pays, Stripe sends `checkout.session.completed` with your token.
FounderHQ exchanges the token for the visitor and the session that started the
purchase, then attributes the payment.

Renewals carry no token. FounderHQ binds the Stripe customer and subscription
on the first payment, so later renewals resolve through that binding.

## Verify

1. Open your pricing page in a browser and click the buy button.
2. Confirm the Stripe URL now carries `client_reference_id=fhqref_...`.
3. Pay with a Stripe test card on a test connection.
4. In FounderHQ, open Revenue. The payment shows the channel that brought the
   buyer, under Introduced by and Closed by.

## Troubleshoot

### The URL has no `client_reference_id`

`paymentLinkToken()` returned `null`. The visitor denied consent or opted out,
or the page origin is not in your publishable key's allowed origins. Add the
origin to the key.

### The payment arrives with no channel

The buyer opened the link from somewhere that never loaded your SDK, for
example an email link straight to Stripe. Send buyers through a page you own.
