Skip to content

Integrate your site

Three small pieces connect your product to OpenPartner. Budget about an hour, including the end-to-end test.

partner link click → your site (SDK captures referral)
→ signup (identify stitches user ↔ click)
→ payment (read from your Stripe, or a server event, drives commission)

1. Add the SDK to your website

Install @openpartner/sdk on your marketing site and app, and initialize it once per page load:

import { OpenPartner } from '@openpartner/sdk';
export const op = OpenPartner.init({
apiUrl: 'https://app.openpartner.dev/api/t/<your-workspace>',
});

On a white-label domain use https://portal.yourbrand.com/api; self-hosted installs use their own API URL.

No bundler? Paste the script tag into your site’s <head> instead. Admin → Integrations shows it with your workspace filled in:

<script src="https://app.openpartner.dev/op.js" data-api-url="https://app.openpartner.dev/api/t/<your-workspace>"></script>

That’s the whole page-level integration: when a visitor arrives through a partner’s link, the SDK captures the referral token and keeps it alive across sessions — surviving Safari’s cookie limits and multi-week gaps between first click and signup. The script tag also hands it to any Stripe Payment Links, Pricing Tables and Buy Buttons on the page.

2. Identify users when they sign up

In your signup and login flows, one call:

await op.identify(user.id);

With the script tag, it’s window.openpartner.identify(user.id).

This links “anonymous visitor who clicked partner X’s link” to “customer #123”. Use the same user ID your backend will report events with — it’s the join key for everything.

Selling only through Stripe Checkout or Payment Links, with no accounts on your site? Skip this step: the Stripe checkout carries the referral instead (step 3).

3. Record revenue

Bill with Stripe? Connect it

On the hosted plan, Admin → Integrations → Connect Stripe installs the OpenPartner Stripe App (beta) on your own Stripe account. Your Checkout and Payment Link purchases, invoices, renewals, refunds and disputes are then recorded from Stripe, with nothing forwarded from your server. The app can read your payments but never moves money; its only write access is to coupons and promotion codes, which it uses to create your partners’ customer-discount codes.

What’s left is getting the partner click into Stripe once. Integrations asks how your customers pay and shows the one step that fits:

How customers payWhat you do
A partner link goes straight to a Stripe Payment LinkNothing to install: put ?client_reference_id={click_id} on the program’s destination URL (Programs → Edit).
Payment Links, a Pricing Table or a Buy Button on your siteThe script tag from step 1, in your <head>.
Your app creates the Checkout SessionThe script tag, plus client_reference_id: req.cookies.op_ref where you create the session.
Partner promo codes at checkoutNothing, when the program offers a customer discount.

Details for each are on the Stripe App page. Self-hosting? Your instance reads your Stripe webhooks directly: see Stripe Billing.

Everything else: report it from your backend

For revenue that isn’t a Stripe payment, such as a payment taken on another billing system, a deal closed in your CRM, or a charge your backend makes directly with a PaymentIntent, your server reports one event, authenticated with an API key you mint under Admin → Integrations:

import { OpenPartnerServer } from '@openpartner/sdk/server';
const op = new OpenPartnerServer({
apiUrl: process.env.OPENPARTNER_API_URL!,
apiKey: process.env.OPENPARTNER_API_KEY!,
});
await op.trackEvent({
userId: user.id,
type: 'invoice_paid',
value: 49.0, // major units — dollars, not cents
currency: 'USD',
externalEventId: order.id, // makes retries safe
});

Always pass externalEventId, your own stable id for that one payment. A retried call with the same id records nothing new, so a webhook or queue that retries can’t pay a commission twice. See Tracking events.

(Or raw HTTP: POST /attribution/events.) Also worth sending signup and trial_started events even though they carry no revenue; they power the funnel view.

With Stripe connected, don’t report Stripe payments here too: one sent under its Stripe invoice or Checkout Session id is refused with 409 recorded_from_stripe, and one sent under your own order id would count twice.

Running a referral program inside your app

To run a customer “Refer & Earn” program on a page inside your own product, with no OpenPartner login for your customers, download the Refer & Earn starter kit. It has a working page and backend, a setup script, and the full integration guide.

Common questions

Do I need to give OpenPartner access to my database? No — nothing ever connects to your database. Data flows one way, through the snippet, the events API and, if you connect it, your Stripe account. You can export your program data from your dashboard at any time.

Do I need to point a Stripe webhook at OpenPartner? No. On the hosted plan you connect Stripe instead: the OpenPartner Stripe App receives your Stripe events for you, so there’s nothing to add under Stripe’s webhook settings and nothing to forward from your server. A self-hosted install points a webhook in your Stripe account at its own /webhooks/stripe endpoint (Stripe Billing).

What if I don’t bill with Stripe? Report payments with trackEvent, as in step 3. It works the same with any billing provider.

Can OpenPartner notify my systems? Yes — that’s separate, and optional: outbound webhooks with HMAC signatures fire on commission events, so your CRM or Slack can react to partner activity.

Test the loop end to end

Before inviting real partners:

  1. Create a test partner in Admin → Partners and grant them your program.
  2. Open the partner’s referral link in a private browser window — you should land on your site with ?cref=… in the URL (or, with a Payment Link destination, on Stripe’s checkout).
  3. Sign up as a fake customer in that window — this fires identify().
  4. Pay in that window. With Stripe connected, pay through your Stripe checkout: Integrations should then show a recent “last event”. Otherwise, trigger a test payment or call trackEvent by hand with the fake user’s ID.
  5. Watch the dashboard: the event should appear attributed to your test partner, with a commission accrued under Admin → Partners → [partner] → Commissions.

To test without real money, connect a Stripe test-mode account if Integrations offers Connect a test-mode account, and pay with a Stripe test card.

If the event comes back no_identity, identify() never ran for that user; if no_click, the browser session didn’t carry a referral token (make sure you landed via the partner link in the same browser profile). The events response tells you which.

Once one test partner works, the integration is done — invite real partners, or share your public application page (/join on your portal, configurable under Settings → Partner signups).