ContentForger

Guides

Stripe Checkout vs Payment Links: How to Take Payments in a Web App

Stripe Checkout or Payment Links? What each does, fees, and the webhook fulfilment both need, for people taking payments in their first web app.

By Thomas Lovas Lokoy — 2026-10-17, last updated 2026-10-17

Keys of an old cash register
Photo: Sub cash register by Franck BLAIS · CC BY-SA 2.0 · cropped
On this page (9)
  1. The short answer
  2. What Payment Links are
  3. What Stripe Checkout is
  4. Stripe Checkout vs Payment Links, side by side
  5. Fees
  6. The part neither one does for you: fulfilment
  7. Manual fulfilment is allowed, at first
  8. Which one to use
  9. Sources

Stripe offers two ways to take payments without building a card form: Stripe Checkout, which your code creates for each purchase, and Payment Links, which you create once in the Dashboard and share anywhere. Both send the customer to a payment page hosted by Stripe. The difference is how much your app knows about the purchase and how much code you write to get there. This guide compares the two for someone building a first web app and explains the one part neither of them does for you: fulfilment.

The short answer

Use a Payment Link if you sell a small, fixed set of things and can live with a generic flow: one product, one subscription, one donation page. Use Stripe Checkout if the purchase depends on who is signed in or what is in their cart, or if you need to tie the payment to a record in your database without extra work.

Under the hood they are closer than they look. Stripe's fulfilment guide says: "Payment Links use Checkout, so all of the information below applies to both Payment Links and Checkout unless otherwise noted." A Payment Link is a reusable, preconfigured way to start a Checkout Session.

Stripe describes Payment Links as a way to "Accept payments online without writing code." You create the link in the Dashboard, choose a product or price, and share the URL. Stripe lists three ways to share: show a QR code, copy the link into email, SMS or social media, or add an embeddable buy button to your website.

From Stripe's Payment Links page:

  • The page is Stripe-hosted, with an integration effort Stripe rates at 1 out of 5.
  • Customisation is limited to "20 preset fonts, 3 preset border radius options, and custom logo, background, and button colors."
  • A link can be reused "multiple times with multiple customers, or limit the number of purchases."
  • Customers can choose what to pay (useful for donations), edit quantities, and add optional items or upsells.
  • Payment Links support subscriptions, Stripe Tax, coupons and promotion codes.
  • Receipts and refunds work without code.

What a Payment Link does not know is anything about your app. The same URL is shared with everyone, so it cannot tell which signed-in user clicked it unless you add tracking yourself. Stripe offers URL parameters for this, and the comparison table on the Payment Links page describes reconciliation as "Simple reconciliation by using URL parameters."

What Stripe Checkout is

Stripe Checkout is built on the Checkout Sessions API. Your server creates a session for each purchase, with the exact line items, the customer, the mode (one-time payment or subscription) and the URL to return to. Then it sends the customer to the session. Stripe says you can "Accept one-time and subscription payments from more than 125 local payment methods" this way.

Checkout comes in three UI options, all on the same API:

OptionHostingComplexityCustomisation
Full page (Stripe's recommended option)Hosted or embeddedLow15 configurable settings via brand settings
Embedded formEmbeddedSome70 configurable settings via the Appearance API
ElementsEmbeddedMostFull CSS customisation via the Appearance API

The full page is the closest to a Payment Link in look and maintenance. The others move the form onto your site at the cost of more front-end work. For a first app, the full hosted page is almost always the right start.

The advantage of creating a session in code is context. Your server already knows the signed-in user, their cart and the price, so it can attach your own identifiers to the session and recognise the payment when it completes.

QuestionPayment LinksStripe Checkout
Code needed to start a paymentNoneA server route that creates a session
Price and itemsFixed when the link is madeDecided per purchase
Knows which user is payingOnly via URL parameters you addYes, set when the session is created
Payment pageStripe-hostedStripe-hosted, embedded form or Elements
SubscriptionsYesYes
After paymentConfirmation message or redirectReturn to your success URL
Fulfilment by webhookYes, same eventsYes, same events

Fees

Neither product adds a per-transaction fee on standard pricing. Stripe's pricing page says Checkout and Payment Links are "Included at no additional charge for businesses on standard payments pricing." You pay the normal card processing fees.

Those fees depend on the country of your Stripe account. Two examples, read on Stripe's own pricing pages on 17 October 2026:

  • Norway: 2.4% + 2.00 kr for European Economic Area cards; 3.25% + 2.00 kr for UK and international cards; plus 2% if currency conversion is required.
  • United States: 2.9% + 30¢ per successful transaction for domestic cards; plus 1.5% for international cards; plus 1% if currency conversion is required.

Check the pricing page for your own country before you set prices, and check it again later, because fees change.

The part neither one does for you: fulfilment

Taking the money is half the job. You also have to deliver what was paid for: unlock the account, start the subscription, send the file. Stripe calls this fulfilment, and its guide is direct about how to do it:

You can't rely on triggering fulfillment only from your checkout landing page, because it's not guaranteed customers visit that page.

Stripe's example is a customer who pays and then loses their internet connection before your success page loads. If your app only unlocks access on that page, they have paid and received nothing. The guide adds that webhooks are required if you sell subscriptions or accept payment methods with delayed confirmation.

What the guide asks for, in plain terms:

  • Listen for checkout.session.completed. Stripe sends this event when a customer pays through Checkout or a Payment Link.
  • Also listen for checkout.session.async_payment_succeeded if you accept slower methods such as bank debits. The Payment Links guide notes these "can take 2-14 days to confirm the payment."
  • Check the payment status on the session before delivering anything.
  • Fulfil once. Stripe warns that your fulfilment function "might be called multiple times, possibly concurrently, for the same Checkout Session." Record which sessions you have fulfilled and skip repeats.
  • Fulfil from the success page too. Stripe recommends running the same function when the customer lands on your success page, because "webhooks can sometimes be delayed." The webhook is the guarantee; the success page is the fast path.

Stripe's webhooks guide adds the safety rules for the endpoint itself:

  • Verify the signature on every event. "Without verification, an attacker could send fake webhook events to your endpoint to trigger actions like fulfilling orders, granting account access, or modifying records." Signature checks need the raw request body, so make sure your framework does not parse it first.
  • Return a 2xx status quickly, before any slow work, to avoid timeouts.
  • Expect duplicates and any order. "Stripe doesn't guarantee the delivery of events in the order that they're generated." Track event IDs to spot repeats.
  • Know the retry window. In live mode Stripe retries failed deliveries "for up to three days with an exponential back off."

This is the same work for both products. A Payment Link saves you the session-creation route, not the webhook.

Manual fulfilment is allowed, at first

Stripe's guide lists manual fulfilment as an option: watch the Dashboard or payment emails and deliver by hand. It says this "works for low volume or experimental ventures." If you sell ten consulting calls a month, a Payment Link plus an email notification is a legitimate setup. Automate once you would miss a payment by doing it by hand.

Which one to use

Pick a Payment Link if:

  • You have one to a handful of fixed products or plans.
  • You want to sell before your app has user accounts.
  • You are happy to fulfil by hand, or with a small webhook handler that reads URL parameters.

Pick Stripe Checkout if:

  • Prices or items depend on the user or their cart.
  • Payment must unlock something in your app for a specific signed-in user.
  • You expect to add tax, trials or saved payment methods later through the API.

Many apps start with a Payment Link to test demand, then move to Checkout when payments need to be tied to accounts. That move is small, because the fulfilment code stays the same.

For a step-by-step build, see how to add Stripe to a generated app in 20 minutes. If payments unlock accounts, sort out sign-in first with the guide to web app authentication options, and test the paid path end to end before launch using the pre-launch checklist.

Sources

ShareXLinkedInFacebook

Was this article helpful?

New guides in your inbox

One short email when we publish something useful — tutorials, comparisons and launch checklists. Unsubscribe in one click.

Related articles