Polar payments, in v1.1.0
The first feature after v1 is out. SaaS Stack can now take payments with Polar as well as Stripe. It is tagged v1.1.0.
Why Polar
Polar is a merchant of record: it sells to your customers on your behalf. It charges the sales tax and VAT, files it, and sends the receipts. With Stripe that is your job, and selling to customers in other countries means registering for their taxes. With Polar it is handled for you.
What you get
- One setting:
BILLING_PROVIDER=polar. Stripe stays the default, and nothing changes if you keep it. - The same plans: still declared once in code.
bun run billing:synccreates them in Polar, flat or per seat, monthly and yearly. - Checkout and the customer portal through Polar, from the same billing page.
- Webhooks that are verified and safe to receive twice, writing the same subscription records as Stripe’s.
- Plan-gated features unchanged: the API, the web app and the mobile app don’t know which provider took the payment.
- A fake Polar for tests, with the same guarantees as Stripe’s: 212 API tests, and Polar has been run end to end against the real service.
Billing now goes through one PaymentProvider interface, so the rest of the code never calls a provider directly. See Polar to set it up, and Billing for how it works.
Upgrading
Merge v1.1.0 and run bun run db:migrate. The migration makes the subscriptions table provider-neutral and copies your Stripe data across, so nothing changes for anyone already paying. UPGRADING.md has the full list, and your coding agent can apply it with the upgrade-kit skill.
Next
Usage-based billing: metered prices with an allowance, reported to Stripe or Polar, with the AI assistant metered per message as the example. The roadmap has the order after that.
Get the next one by email
Only project updates. Unsubscribe with one click.