Run a Polar affiliate program from Polar webhooks
Polar at a glance
Does Polar have a built-in affiliate program?
We found no built-in affiliate program in Polar's docs as of November 2026. Its docs describe an integration with Affonso, a separate affiliate tool. Any tool that reads Polar webhooks and checkout metadata can run your program and OpenPromoter is one of them.
Polar's Affonso guide uses the same pattern. A webhook endpoint in Polar and a referral id passed as checkout metadata.
Polar is a merchant of record and takes on international sales tax for you. Source: Polar merchant of record (November 2026). OpenPromoter's commission base excludes that tax.
How Polar affiliate tracking works with metadata
Polar copies checkout metadata to the order and the subscription it creates. OpenPromoter reads op_click from the order's metadata and from the customer's metadata on each order.paid event. Your server sets the value from window.openpromoter.clickId when it creates the checkout session.
Polar creates a new order for every renewal and every billing cycle. Source: Polar orders (November 2026). Each paid order inside the commission window books its own commission.
Checkout Links
Polar Checkout Links copy only listed query parameters into metadata, such as reference_id and UTM values. An op_click parameter on the link is not one of them. Source: Polar Checkout Links (November 2026).
With Checkout Links, record the buyer's email with openpromoter.signup() before checkout. A partner discount code also works.
The Next.js adapter
Polar's Next.js checkout handler takes a metadata query parameter as URL-encoded JSON. Put op_click in that object when you build the checkout URL. Source: Polar Next.js adapter (November 2026).
When the click id is missing
OpenPromoter falls back to the partner's discount code and then to the signup email. Call openpromoter.signup() with the buyer's email before checkout. A Polar customer created with that email is then credited to the partner.
Discount codes as partner codes
A discount code on the order counts as the partner's coupon code. A sale with that code is credited with or without a click.
const checkout = await polar.checkouts.create({
products: ["prod_123"],
metadata: { op_click: clickId }, // window.openpromoter.clickId from the browser
});Set up a Polar affiliate program in four steps
A Polar affiliate program needs one webhook endpoint and one metadata field in your checkout code. You add the endpoint in Polar, select seven events and paste the secret into OpenPromoter. Then your server passes the click id when it creates the checkout.
- 1
Add an endpoint
In Polar, go to Settings > Webhooks and add /api/webhooks/polar/<workspaceId> in Raw format.
- 2
Select seven events
Tick every event in the table below and save the endpoint.
- 3
Paste the secret
Copy the endpoint secret into Settings > Integrations.
- 4
Pass the click id
Add op_click to the checkout metadata on your server.
OpenPromoter checks the webhook-id, webhook-timestamp and webhook-signature headers on every request. Anything older than five minutes is rejected.
Polar retries a failed delivery up to 10 times and times out after 10 seconds. It disables an endpoint after 10 failures in a row. Source: Polar webhook delivery (November 2026).
Polar webhook events and what each one does
OpenPromoter reads seven Polar webhook events. One links the customer, one books the commission, one handles refunds and four follow the subscription status. The order.paid event books the commission on the net amount of each order after discounts and without tax.
| Event | What OpenPromoter does |
|---|---|
| customer.created | Links the customer to a partner from metadata or the lead email |
| order.paid | Books the commission on the paid order |
| order.refunded | Reduces or reverses the commission |
| subscription.created | Tracks the subscription and its status |
| subscription.updated | Updates trialing, active and past due status |
| subscription.canceled | Stops recurring commissions |
| subscription.revoked | Stops recurring commissions at once |
order.created is not read. Select order.paid so only orders that were paid earn a commission.
The billing providers docs list the URL and events with copy-ready values.
How Polar refunds and cancellations change commissions
A partial refund reduces the commission in proportion and a full refund reverses it. A refund after payout becomes a clawback on the partner's next payout. Polar can also refund an order on its own to head off a chargeback, and those refunds adjust commissions the same way.
Polar can refund for you
Polar may refund an order within 60 days of purchase to prevent a chargeback. Source: Polar refunds (November 2026). Set the hold period to 60 days to cover that window.
Disputes
OpenPromoter reads no Polar dispute event today. A refund that Polar issues to prevent a chargeback still arrives as order.refunded.
Canceled and revoked subscriptions
subscription.canceled and subscription.revoked both stop recurring commissions. A revoked subscription is marked canceled at once.
Test with the Polar sandbox
The Polar sandbox is a separate server with its own account, organization and access tokens. Stripe's test card 4242 4242 4242 4242 works there. Turn on Sandbox when you connect it and OpenPromoter tags its events as Test.
Sign up at sandbox.polar.sh and add the same OpenPromoter webhook URL there. Delete test data before you connect production with Sandbox off. Source: Polar sandbox (November 2026).
The Polar CLI forwards webhooks to your machine with polar webhook listen. That works well with a self-hosted copy on your laptop.
Common Polar affiliate setup mistakes
Most Polar setup problems come from a click id that never reaches the order. Checkout Links are the usual cause because they drop query parameters they do not know. A hold period shorter than Polar's 60-day refund window is the other common one.
op_click on a Checkout Link
Checkout Links do not copy it to metadata. Create the checkout through the API instead.
order.created only
OpenPromoter books on order.paid. Select it on the endpoint.
A 30-day hold
Polar can refund for 60 days. Set the hold period to match.
A disabled endpoint
Polar turns an endpoint off after 10 failures in a row. Turn it back on in Polar.
Sandbox tokens in production
Sandbox and production use separate accounts and tokens. Match the Sandbox switch to the account you connect.
Pay Polar affiliates and handle tax
Polar pays you and OpenPromoter pays your partners. Partners choose Stripe Connect, PayPal, Wise or manual payment in their portal and you approve each batch before it goes out. Each rail charges its own fee and OpenPromoter takes 0% of payouts on every plan.
Stripe Connect needs a Stripe account of your own as the platform. PayPal and Wise payouts need no Stripe account. The payouts page compares the rails.
Partners paid by PayPal, Wise or by hand submit a W-9 or a W-8BEN in the portal. EU VAT ids are checked against the VIES service. Every payout gets a self-billed invoice with a sequential number.
US partners need a W-9 before their payouts for the year pass the 1099-NEC threshold. That threshold is $2,000 for payments made in 2026. The 1099 guide for affiliates covers the filing.
Questions
Which Polar events does OpenPromoter need?
Do Polar renewals earn recurring commissions?
Do Polar discount codes count?
Can I self-host OpenPromoter for Polar?
Can the click id go in a Polar custom field?
Is OpenPromoter open source like Polar?
Related

[ openpromoter ]
Try it with your own Stripe account
Free on Cloud up to $1k a month in partner revenue or free forever on your own server.