Payments
Payment integration powered by Polar.sh via the Better Auth Polar plugin. Sell digital products, subscriptions, or one-time purchases. Checkout, customer portal, and webhooks are wired through Better Auth’s /api/auth endpoints.
Key features
- One-time payments and subscriptions
- Automatic role assignment on purchase
- Email notifications for access changes
- Ready-to-use checkout button component
- Webhook handling via
@polar-sh/better-auth
-
Create a Polar account - sign up at polar.sh
-
Create products - set up your products in the Polar dashboard
-
Create an Organization Access Token - generate a Polar access token and add it as a secret:
Terminal window bunx wrangler secret put POLAR_ACCESS_TOKEN --env=previewTerminal window bunx wrangler secret put POLAR_ACCESS_TOKEN --env=production -
Configure webhooks - create a webhook endpoint pointing to
/api/auth/polar/webhooksand enable these events:order.paid,order.refunded,subscription.active,subscription.revoked -
Add the webhook secret - add
POLAR_WEBHOOK_SECRETas a secret in Cloudflare for preview and production environments:Terminal window bunx wrangler secret put POLAR_WEBHOOK_SECRET --env=previewTerminal window bunx wrangler secret put POLAR_WEBHOOK_SECRET --env=production -
Configure your products - add them to
packages/config/index.ts:payments: {products: {premium: {name: "Premium",userRoleToGrant: "premium",polarProductId: {preview: "your-preview-product-id",production: "your-production-product-id",},},},}
Each product maps to a user role via userRoleToGrant. When a customer completes payment, they’re automatically granted the corresponding role (see permissions). The role is automatically revoked on refund or subscription cancellation.
CheckoutButton
Section titled “CheckoutButton”A styled button that starts Polar checkout through the Better Auth client. Uses the product config slug.
import { CheckoutButton } from "@/payments/components/checkout-button"
;<CheckoutButton productId="premium">Get Premium Access</CheckoutButton>The productId must match a key in your payments.products config.
Purchase Flow
Section titled “Purchase Flow”- User clicks a
CheckoutButton - Better Auth Polar checkout opens Polar’s hosted checkout
- After payment, Polar sends a webhook to
/api/auth/polar/webhooks - The webhook handler grants the user role and sends a confirmation email
- User is redirected to
/payments/success
Webhook events handled:
| Event | Action |
|---|---|
order.paid | Grant role, send access granted email |
subscription.active | Grant role, send access granted email |
order.refunded | Revoke role, send access revoked email |
subscription.revoked | Revoke role, send access revoked email |