iCodeLTD

Adding Payments to Your SaaS or Web App: What Founders Should Decide Before the Build

Umar Farooq NadeemFounder of iCodeLTD
10 min read

Overview

Adding payments is not a checkout form bolted onto a finished product. It is a set of decisions about what you charge for, what access follows from each arrangement, what happens when a payment fails, and who carries the compliance work. Settling them first can narrow the integration, without guaranteeing a cheaper build.

Key Points

  • Decide what customers pay for, and what each arrangement entitles them to, before choosing a provider.
  • The collection route — hosted redirect, embedded provider-hosted fields, or direct handling — drives PCI scope; SAQ A must be confirmed, not assumed.
  • Base access on verified server-side provider state and your agreed entitlement policy, not on a success page.
  • Plan for failed renewals, refunds and cancellations as normal product behaviour, not as support exceptions.
  • Confirm the PCI route with your acquirer, and test authentication, failures and duplicates before launch.

Start with what you are charging for

The first decision is not which provider to use. It is what the customer is buying, and what that purchase changes inside your product. A one-off payment usually buys a single item, a licence period, or a defined amount of credit. A subscription usually buys access for a period or up to a limit.

Write the answer in one paragraph before code is discussed. Who pays, what the arrangement unlocks — the whole product, one workspace, a number of seats, a quantity of usage — when access starts and stops, and what happens to stored data when it stops. A hypothetical example: a team tool charging per workspace, seats included, extra seats priced separately.

Choose a billing model that matches how value is used

Stripe's recurring pricing models documentation describes four patterns. Flat rate charges one price for a tier. Per-seat charges for each user needing access. Tiered changes unit cost as quantity or usage grows. Usage-based charges for actual consumption: fixed fee plus overage, pay as you go, or credits that burn down.

None is right in general. The test is whether price moves with the value received, and whether the next bill is predictable. Decide mid-period upgrades, downgrades, added seats and pauses too: immediate or from the next period, and is unused time credited?

Three ways to take a card payment, three compliance positions

First, a hosted redirect: the customer leaves your site for a provider-run payment page, such as Stripe Checkout, pays there, and returns. Second, embedded provider-hosted fields: the customer stays on your pages, but the card fields are iframes served from the provider domain, as with Stripe Elements; the page can look fully customised, yet card numbers go directly to the provider. Third, direct handling: card data passes through your own systems to the provider API — the only route where you directly handle card numbers.

The distinction matters because of PCI DSS: all businesses accepting card payments must comply, and validation depends on volume and integration type. Stripe's PCI compliance guide maps Checkout and Elements to SAQ A, the shortest questionnaire. Treat that as a mapping to test, not eligibility conferred by product choice: SAQ A is potentially applicable only where all eligibility criteria are met. The older Stripe.js v2 approach maps to SAQ A-EP; passing card data directly to the API maps to SAQ D. A customised interface does not by itself change your questionnaire. Stripe describes itself as a PCI Level 1 service provider; that covers Stripe systems, not your business. Never store card numbers, expiry dates or security codes in your own database; use provider tokens instead.

PCI SSC FAQ 1588 clarifies a commonly misunderstood criterion. The SAQ A criterion that a merchant site is not susceptible to script attacks affecting the payment flow applies to pages embedding a provider form in iframes. A merchant can confirm it through protective techniques, or provider confirmation that the embedded solution includes them when implemented according to the provider's instructions. The criterion does not apply to a redirect — but a redirect does not remove other obligations. Your acquirer or compliance-accepting entity confirms the right SAQ and your eligibility.

Payment confirmation is not the same as an access decision

A completed checkout is not proof of payment: a customer can finish checkout while payment is still pending, particularly with methods that confirm later. Stripe's SaaS subscriptions guide makes the same point for subscriptions — before provisioning access, wait for a confirmed event such as invoice paid and verify the subscription or payment status. A browser success page alone proves nothing; it can be bookmarked or faked.

Access should follow two things together: provider state your server has verified, and the entitlement policy agreed with the customer. Verification need not arrive by webhook: your server can also retrieve current payment, invoice or subscription state from the provider directly.

The policy then decides what each state means, and it differs by arrangement. A paid purchase normally grants access once payment is confirmed. A free trial grants access before payment, for the trial period. A zero-payment arrangement may have no charge due, but the server must still verify the authorised entitlement before granting access. An agreed grace period keeps access running for a stated time after a payment problem. Where payment is required and unconfirmed, delayed payments stay pending and paid access stays withheld. Keep subscription events distinct from one-off confirmation in your records.

Authentication: scope depends on more than serving Europe

Strong Customer Authentication, or SCA, is often summarised as a European rule, but serving someone in Europe does not settle whether it applies. Stripe's SCA readiness guidance frames it around business location in the European Economic Area (or EEA-based connected accounts), customers served in the EEA, and card acceptance. Locations and transaction type all matter; check UK and EEA regimes separately. Where SCA applies, banks may decline payments that should have been authenticated but were not.

Not every payment that looks in scope is challenged. Stripe's SCA exemptions documentation (applicability: EEA, Switzerland and UK) describes exemptions such as low-value payments and transaction risk analysis, and explains that payments using saved cards off-session may qualify as merchant-initiated transactions, outside SCA scope. Neither position is guaranteed: an issuer can still request authentication. When saving a card, record the agreement — permission to initiate payments, the anticipated frequency, and how the amount is determined — and build a recovery path that brings the customer back to authenticate when an issuer asks during a later charge.

A new Stripe subscription whose first payment is incomplete or awaiting action, such as authentication, sits in subscription status incomplete. A renewal problem differs: payment failing on a later, finalised invoice typically moves the subscription to past_due, depending on configuration. Neither is a PaymentIntent status: the PaymentIntent has its own status, such as requires_action or processing. Stripe's subscription webhook documentation defines each status separately.

Failed payments, refunds and disputes are product features

A failed renewal is not an edge case. Cards expire, balances run short, banks ask for re-authentication, and customers change cards without telling you. Stripe treats a failed invoice payment as a normal event: notify the customer and direct them to a self-service portal to update the payment method.

Decide the grace rules in writing: how long access continues after failure, and what happens to stored data if the subscription ends. Treat it as a trade-off, not a lever with a guaranteed result: a longer grace period may be more forgiving for customers who would otherwise leave, but carries more unpaid use; stopping at once may limit unpaid use, but can cut off customers over a temporary card problem. Refunds need the same treatment: who can issue a full or partial refund, what evidence is kept, and how a refund changes access. In the direct-selling model discussed here, those decisions sit with your business, subject to applicable law and provider terms.

Treat payment notifications as unreliable messages

Stripe's webhook documentation warns that delivery can be retried for up to three days in live mode and that events are not guaranteed to arrive in order. First, the same event can be delivered more than once; log processed event identifiers and skip repeats. Second, two separate event objects, with different identifiers, can refer to the same business action; Stripe advises spotting those via the object identifier in the event data, with the event type — so event-identifier deduplication alone does not cover every duplicate action. Third, events arrive out of order, so check current state before applying a change, and retrieve current state where needed, rather than letting a late event overwrite newer state.

Processing should be idempotent: handling the same business action twice must leave the same result as handling it once, so a duplicate cannot grant access or refund twice. Verify first: for Stripe, use the official library with the unchanged raw body, the signature header and the endpoint secret, keeping the timestamp check in place, which defends against replayed deliveries; any change to the raw body breaks verification. Respond quickly but safely: return success promptly once the event is safely accepted and persisted for processing, then process asynchronously. Ensure failed handling can be recovered, through retries or reconciliation, never silently dropped.

What to test before launch

  • A successful one-off payment and subscription signup, each granting access per its policy.
  • A trial starting and ending, a zero-payment arrangement, and a renewal succeeding and failing, with its message and grace rule.
  • Initial and renewal authentication separately, succeeding and failing, distinguishing initial subscription incomplete status, renewal past_due status where applicable, and PaymentIntent states.
  • A refund, a mid-period plan change, and a cancellation ending access as stated.
  • The same event twice, two events for one action, events out of order, and a forged event that changes nothing.

Practical next steps

Start from the decisions in this guide, not from a provider setup screen. Write down what is sold, what access each arrangement buys, the billing model, the grace and refund rules, the events your product must handle, and the currency, tax and payout questions for your adviser. Ask your development partner to show each working in a test environment. The earlier guide to SaaS development planning covers the wider decisions, and the guide to SaaS data security basics covers the surrounding controls. For scope and timeline, the project cost calculator estimates cost and timeline from scope and complexity, and iCodeLTD's SaaS development service includes subscription and billing integration support. Discuss your payment decisions through the contact page.

Frequently asked questions

Do we need to store card numbers ourselves?

No. Use provider-hosted fields or checkout so card details go to the provider, and store only its customer, subscription and payment references. Storing raw card data brings a far heavier burden.

Can we start with one-off payments and add subscriptions later?

Yes, but plan for the change. One-off and subscription purchases differ in how access is granted, renewed, cancelled and refunded, so adding subscriptions later means adding that state logic and the customer portal. Deciding the future model early reduces rebuild risk, but cannot rule one out.

Who owns refunds and disputes?

In the model discussed here, where you sell directly, both have a part, subject to applicable law and provider terms. The provider processes the movement of money and records the transaction, but your business sets the refund policy, issues refunds, keeps dispute evidence, and answers the customer.

Sources

PCI Security Standards Council — FAQ 1588: SAQ A eligibility criteria for scripts (February 2025; accessed 28 October 2026).

Stripe — What is PCI DSS compliance? (accessed 28 October 2026).

Stripe — Recurring pricing models (accessed 28 October 2026).

Stripe — Strong Customer Authentication readiness (accessed 28 October 2026).

Stripe — Strong Customer Authentication (SCA) exemptions (accessed 28 October 2026).

Stripe — Receive Stripe events in your webhook endpoint (accessed 28 October 2026).

Stripe — Using webhooks with subscriptions (accessed 28 October 2026).

Stripe — Sell subscriptions as a SaaS startup (accessed 28 October 2026).

Share this post

More insights

Product Delivery

Should You Test Before You Build? A Founder's Guide to Prototypes, Proofs of Concept and Pilots

Prototypes, proofs of concept, pilots and first releases each settle a different unknown. Learn which test your build decision actually needs, and what to agree before it starts.

Read more

Product Delivery

Who Owns the Software You Paid For? A Founder's Guide to IP, Escrow and Handover

You paid for the build — but do you own the software? A founder's guide to IP assignment, source-code escrow, third-party licences and the practical handover.

Read more

Product Delivery

Rewrite or Refactor? A Founder’s Guide to Deciding What to Do With Ageing Software

Should you rewrite your ageing software or refactor it? A founder’s guide to the three paths, the evidence to gather first, and when a full rebuild is the honest answer.

Read more

Discuss your project

Ready to review scope for AI, SaaS, web, mobile, or automation work?

Book a Free Strategy Call