Skip to content
Gaurav TiwariDocs

Sell Through Polar as Merchant of Record

Updated October 17, 2026

Selling digital products worldwide means collecting and filing sales tax and VAT in places you’ve never been. Most small stores either ignore it and hope, or pay an accountant more than the sales are worth.

Polar is a merchant of record: it sells to the buyer, works out the tax and remits it. The Polar module connects it to WooCommerce. Buyers pay on Polar’s hosted checkout, and the order, renewals, refunds and cancellations stay in step with WooCommerce through signed webhooks.

Turn On the Gateway

  1. Switch on the Polar module under Stackless → Dashboard.
  2. Go to WooCommerce → Settings → Payments → Polar (Stackless).
  3. Tick Enable (Accept payments with Polar).

Stackless → Settings → Polar only shows a link to that screen and your webhook URL.

Add Your Access Tokens

Create an organization access token in Polar → Settings → General → Developers with these scopes:

products:read, products:write, checkouts:read, checkouts:write, orders:read, refunds:read, refunds:write, subscriptions:read, subscriptions:write, organizations:read

Then fill in:

  • Sandbox: on by default. No real money moves. Sandbox tokens come from sandbox.polar.sh with the same scopes.
  • Live access token and Live webhook secret
  • Sandbox access token and Sandbox webhook secret

When you save, Stackless looks up the organization for each token and shows “Connected to [organization].” If you switch a token to a different organization, the Polar products remembered for that environment are cleared.

You can also set these as wp-config.php constants, which win over saved settings: STACKLESS_POLAR_LIVE_ACCESS_TOKEN, STACKLESS_POLAR_LIVE_WEBHOOK_SECRET, STACKLESS_POLAR_SANDBOX_ACCESS_TOKEN and STACKLESS_POLAR_SANDBOX_WEBHOOK_SECRET.

Connect the Webhook

In Polar, live and sandbox, open Settings → Webhooks and add an endpoint with the Raw format and this URL: https://yoursite.com/wp-json/stackless/v1/polar/webhook. The settings screen shows your exact URL. Select these events:

order.paid
order.updated
order.refunded
refund.created
refund.updated
subscription.created
subscription.updated
subscription.active
subscription.canceled
subscription.uncanceled
subscription.revoked
subscription.past_due

Copy the endpoint secret into the matching webhook secret field. Webhooks confirm payments when a buyer closes the tab before coming back, record renewals, and bring refunds and cancellations made in Polar into WooCommerce. Each delivery is signature-checked and applied once.

Set How Tax Works

Prices and tax has three options:

  • Follow the buyer’s country (Polar default)
  • Add tax on top of my prices
  • My prices already include tax

Polar calculates sales tax and VAT itself. Turn off WooCommerce tax for products you sell through Polar, or buyers get taxed twice.

What Buyers See

At checkout, Polar shows with the title “Card, Apple Pay or Google Pay (Polar)”. Placing the order sends the buyer to Polar’s checkout to pay. After paying, they come back to your order received page. In sandbox mode, checkout shows a notice that no real payment will be taken.

Prices always come from WooCommerce. Polar charges the amount WooCommerce sends for each checkout.

Each product and variation gets Polar product (live) and Polar product (sandbox) fields, with a Create in Polar button and a Polar billing choice: One-time, Daily, Weekly, Monthly, Every 3 months, Every 6 months or Yearly.

You can leave them empty. Polar products are then created on the first sale and remembered per environment. A product you link by hand must use the same billing schedule as the WooCommerce product.

Subscriptions on Polar

Polar runs the renewal schedule for subscriptions it bills:

  • Free trials work. The trial length is passed to Polar in days.
  • When Polar charges a renewal, a paid WooCommerce renewal order is created.
  • The next payment date follows Polar’s current period.
  • Polar statuses map to Stackless ones: past due becomes On hold, canceled becomes Cancelled, unpaid becomes Expired, and “cancel at period end” becomes Pending cancellation.

Cancelling from WooCommerce or My Account cancels at Polar too, either at the end of the paid period or straight away. If Polar doesn’t confirm, the cancellation is refused with a message to try again or cancel in Polar.

A subscription set to Manual only isn’t billed by Polar. Its first order goes through Polar as a one-time payment, and each renewal can be paid the same way.

Refunds

Refund from the WooCommerce order screen and the refund is made in Polar. Refunds made in the Polar dashboard are recorded on the WooCommerce order through the webhook.

Limits

  • Polar takes one subscription per checkout, with no other items in the cart. Carts with only one-time items can be any size, and show in Polar as one store order.
  • Polar charges the same amount every cycle, so a subscription with a signup fee or a discounted first payment can’t use Polar.
  • Polar isn’t offered for carts it can’t take, or for currencies it doesn’t support.
  • Polar doesn’t save cards in WooCommerce. Customers can’t renew early, resume a pending cancellation, toggle auto-renew or change the payment method from My Account, and you can’t change the next payment date.
  • Turn on Debug log to write Polar activity to WooCommerce → Status → Logs (stackless-polar_gateway). Tokens are never logged.
Share

Was this helpful?

Still stuck? Open a support ticket