Skip to content
KKODETRA

Payments

How to Add Stripe (or PayPal) Billing to Your SaaS

May 16, 2026 · 8 min read

Adding subscription billing to a SaaS sounds like “drop in a checkout button,” but the button is the easy 20%. The other 80% — the part that decides whether customers are charged correctly and whether your app knows who is actually subscribed — is webhooks and a single source of truth. Get those right and billing is boring and reliable. Get them wrong and you spend nights reconciling money. Here is the path we use, whether you go with Stripe or PayPal.

First, model your plans

Before touching any API, write down your pricing exactly: the plans, their prices, the billing interval, any free trial, and whether you charge per seat or by usage. A flat monthly plan is simple. Seats, usage metering, proration on upgrades, and coupons each add real work. Decide this first, because it drives every choice that follows — and it is the biggest factor in whether Stripe or PayPal fits, which we compare in our Stripe vs PayPal guide.

The checkout flow

The recommended flow for both gateways is to let the provider host the sensitive part so you never touch raw card data:

  • Create a customer record in the gateway tied to your user, so future charges and the billing portal have a home.
  • Start a checkout session(Stripe Checkout) or create a subscription (PayPal) for the chosen plan and redirect or render the gateway’s flow.
  • Send the user back to a success page — but do not trust that redirect as proof of payment. It only means they finished the form, not that money cleared.

Webhooks are the source of truth

This is the single most important thing to understand: payments are asynchronous. The customer clicks pay, and the truthof whether they are subscribed arrives later as a webhook event from the gateway. Your app must treat the webhook — not the success redirect — as the authority on subscription state. When the gateway sends “subscription active,” you mark the user active. When it sends “payment failed” or “subscription canceled,” you downgrade. Almost every billing bug we are hired to fix is a system that trusted the redirect instead of the webhook.

Idempotency and out-of-order events

Webhooks can arrive more than once, out of order, or be retried by the gateway after a timeout. Your handler must be idempotent: processing the same event twice must not double-charge, double-provision, or corrupt state. Record the event ID you have already processed and skip duplicates. Verify the webhook signature so you only act on events that genuinely came from the gateway. And handle the unhappy events explicitly — failed renewals, refunds, disputes, downgrades — because those are where revenue quietly leaks.

One internal model of “is this customer subscribed?”

Your application code should never scatter gateway-specific checks everywhere. Keep one internal subscription record — plan, status, current period end — that your features read to decide what a user can access. The gateway and its webhooks update that record; the rest of your app just reads it. This also makes supporting both Stripe and PayPal sane: both gateways feed the same internal model, and your feature gates do not care which one charged the customer. Our own products Linq List and Thumbnail Art Studio run real PayPal subscriptions on exactly this pattern.

Don’t forget the billing portal and proration

Customers will want to update their card, see invoices, upgrade, downgrade, and cancel. Both Stripe and PayPal can host a customer portal so you do not build all of that yourself. Upgrades and downgrades mid-cycle raise proration questions — does the customer get credited or charged the difference now? Decide your policy and let the gateway do the math; rolling your own proration is a classic way to introduce money bugs.

Common mistakes to avoid

  • Trusting the success redirect. It is not proof of payment. The webhook is.
  • Non-idempotent webhook handlers. Duplicate events will happen; design for them from day one.
  • No handling for failed renewals. Cards expire and payments fail; without retry and dunning logic you lose revenue silently.
  • Scattering gateway logic across the app instead of one subscription record as the source of truth.

Billing is one of those areas where “it works in the demo” and “it works with real customers’ money” are very different bars. If you want subscription billing wired in correctly — webhooks, idempotency, and a clean source of truth — with Stripe, PayPal, or both, tell us about your plans and your buyers at info@kodetra.com and we will scope it as part of your SaaS build.

Start a conversation

Have a project like this in mind?

Tell us the goal and we'll map it to a plan, timeline, and fixed price — usually within one business day.