codexmachina
Component

Every verified stack that runs on Polar.

Polar billing: recurring subscriptions synced via a verified, idempotent webhook.

0 verified stacksHow we verify →

0 verified stacks

No verified stacks published yet.

What Polar gives you

Polar ships a webhook and no schema. `billingWebhook` emits two files: the record core at `lib/billing/record.ts`, and a route in whatever shape the framework actually uses — an App Router `POST` handler at `app/api/webhooks/polar/route.ts` on Next.js, an `action` in the resource route `app/routes/webhooks.polar.ts` on React Router, a `defineEventHandler` reading `readRawBody`/`getHeaders` at `server/api/webhooks/polar.post.ts` on Nuxt. All three do the same three things: return 500 if `POLAR_WEBHOOK_SECRET` is unset, run `validateEvent(raw, headers, secret)` from `@polar-sh/sdk/webhooks` and return 403 on `WebhookVerificationError` (every other error is rethrown, so Polar retries rather than seeing a false 200), then hand the six `subscription.*` types in `SUBSCRIPTION_EVENTS` to `recordPolarEvent`. The record core carries the guarantees, and it touches exactly one table: `subscriptions`.

`STATUS_MAP` folds Polar's vocabulary onto the four values that table's status CHECK allows — `unpaid` becomes `past_due`, `revoked` becomes `canceled` — and an unmapped status returns `{ changed: false }` instead of defaulting to something plausible. The write is an UPDATE whose WHERE carries both the match on `provider_sub_id` and the staleness comparison (`provider_event_at` IS NULL, or older than this event's `modifiedAt`), so the ordering decision is made under the row lock: a late-arriving older delivery matches no row, and concurrent retries serialize instead of racing. There is no read-then-write window to lose. If nothing advanced, a SELECT separates the two reasons — the row exists and our event was stale (ignore it) or the row is new (insert it).

The insert closes the last race with the UNIQUE `provider_sub_id`: `onConflictDoNothing` on Postgres, a caught `ER_DUP_ENTRY` on MySQL, which also supplies `crypto.randomUUID()` for the id and reads `affectedRows` because MySQL has no RETURNING. `changed` comes back true only on a real advance, so a caller can hang side effects like receipt mail off it without sending one per duplicate delivery.

Built for

Reject a forged or unsigned delivery

Each route branch calls `validateEvent(raw, headers, secret)` before the database is touched at all; a `WebhookVerificationError` answers 403, an unset `POLAR_WEBHOOK_SECRET` answers 500, and anything else is rethrown so the delivery is retried rather than silently acknowledged.

Absorb duplicate deliveries

`recordPolarEvent`'s insert leans on the UNIQUE `subscriptions.provider_sub_id` rather than a query-then-insert: `onConflictDoNothing({ target: subscriptions.providerSubId })` on Postgres, a caught `ER_DUP_ENTRY` on MySQL. Both report `changed: false`.

Apply events that arrive out of order

The guarded UPDATE pairs `eq(providerSubId, sub.id)` with `isNull(providerEventAt) OR lt(providerEventAt, eventAt)` in the WHERE, so a canceled event delivered after the renewal that followed it updates no row and cannot roll newer state backwards.

Map a provider's status vocabulary onto the app's

`STATUS_MAP` is the whole translation layer: six Polar statuses collapse to the four the `subscriptions.status` CHECK constraint permits, and an unrecognized one returns early instead of writing a value the constraint would reject.

Fire side effects once per real change

`recordPolarEvent` returns `{ changed }`, true only when a row genuinely advanced or was inserted. Callers gate emails, provisioning, and analytics on it, which is what makes retry-heavy delivery safe end to end rather than only at the database.

Why Polar, specifically

note

Idempotency is a DB UNIQUE constraint on subscriptions.provider_sub_id (+ onConflictDoNothing) — not a query-then-insert; that's what survives Polar's duplicate/concurrent webhook retries.

note

A staleness guard (subscriptions.provider_event_at) means a late-arriving older event can't overwrite newer subscription state — the out-of-order case naive handlers get wrong.

note

These columns live on the SaaS app-type's subscriptions table (a generic provider-sync contract); this fragment maps Polar's events onto them rather than declaring its own schema.

What Polar pulls in

bun add @polar-sh/sdk
POLAR_ACCESS_TOKENPolar API token (server-side)
POLAR_WEBHOOK_SECRETvalidates the webhook HMAC signature