Money and messages
Stripe
Payments and subscription billing, used for checkout, plan tiers, the customer portal and webhook-driven entitlements.
Stripe is the payments layer: hosted checkout, subscriptions, a customer portal for card and plan changes, and a webhook stream telling your application what happened. You do not touch card numbers, which removes most of the compliance problem. In exchange you take on a percentage of every transaction and an integration whose hard part is not the payment at all, but keeping your own idea of who has paid in step with theirs.
How we use it
Objectify bills four tiers in sterling, monthly or annually, from a free plan through to a business plan at ninety-nine pounds a month, with a launch discount applied automatically and both prices rendered on the pricing page. Checkout, the customer portal and the webhook handler are all wired up, and plan limits, tenant counts, record counts, storage, AI and realtime access, are enforced in the application rather than read back from Stripe on each request.
DMARC Engine does the same for a longer ladder of plans and adds two things worth noting. One is a single one-off purchase alongside the subscriptions, the done-for-you enforcement service that takes a domain from p=none to p=reject, sold as a product rather than a plan. The other is that entitlements do not all come from Stripe: lifetime deal codes are redeemed and revoked independently, so the code that answers "can this organisation add another domain" reads one table and does not care which route the entitlement arrived by. That separation is the design we would repeat.
What it costs you
The webhook is the integration. Events arrive out of order, arrive twice, and arrive while your Worker is mid-deploy, so the handler must verify the signature, be idempotent, and treat every event as a fact to reconcile rather than an instruction to execute. Test and live keys diverge, and price IDs come from environment variables in both of these builds, which is flexible and also means a wrong value in production produces a checkout page that fails at the last step rather than a loud error at deploy time. That path needs an actual test purchase after every environment change.
Beyond the plumbing: fees are a real percentage of revenue at small scale, tax is your problem unless you buy Stripe Tax, proration on plan changes will produce invoices a customer queries, and disputes cost more than the transaction. Anchor pricing and discounts multiply the states the pricing page can be in, and each one needs to be right, because a wrong price displayed is a refund conversation.
When we would choose something else
If the answer is a handful of invoices to clients you already know, we would not integrate anything. A payment link and an entitlement flag in SQLite is the whole system, and it is the shape DMARC Engine already uses for its lifetime codes. Stripe earns its fee when sign-up is self-serve and nobody is available to chase an invoice.
Stripe also does not serve every market well. For a product whose payers are somewhere its coverage is thin, local rails matter more than a tidy API, and we would build against those instead. Either way, the webhook consumer belongs on a queue rather than in the request path, so a slow downstream write never turns into a retry storm.
Where we have used it
Every build below lists this in its stack, so the claim is checkable.