How to Add Order Bumps and One-Click Upsells to Stripe

TL;DR

An order bump is a second line item toggled before payment — one PaymentIntent, recalculated server-side. A one-click upsell is a separate charge on the card saved during the first payment: setup_future_usage: 'off_session' on the first PaymentIntent, then a second PaymentIntent confirmed with the saved payment method. You can build this on Stripe's APIs in a week or two, configure it in a cart platform in an afternoon, or say one sentence to your AI agent in gocushy and have both live in minutes on your own Stripe.

Ask any direct-response marketer where the cheapest revenue in their business is and you'll get the same answer: the buyer who is already checking out. Order bumps and one-click upsells exist for exactly that moment, and together they routinely add 20–40% to average order value without a single extra visitor.

Stripe gives you world-class payments infrastructure, but neither mechanic ships out of the box — a payment link is one product at one price (we cover that gap in Stripe Payment Links vs a real funnel). This guide explains how both mechanics actually work at the API level, the four pitfalls that quietly break DIY builds, and your three realistic options for getting them live.

The mechanics, precisely

An order bump is a second line item, toggled before payment

On the checkout page, a bump looks like a checkbox: "Add the workbook — $17." Under the hood it is a second line item added to the same payment before the buyer confirms. One PaymentIntent, one charge, one receipt. When the buyer ticks the box, your server updates the PaymentIntent's amount and the order's line items, and the Payment Element charges the new total.

The one detail that separates a safe implementation from a vulnerable one: the total must be recalculated server-side. If your front-end computes the new amount and posts it back, anyone with DevTools open can buy your $49 course for $0.49. The client sends bump: true; the server does the arithmetic.

A one-click upsell is a second charge, after payment

The upsell happens after the first payment succeeds. The thank-you page offers a second product — "Add the template pack for $97?" — and clicking yes charges the card the buyer just used, with nothing re-entered. That takes three Stripe pieces working together.

First, save the card during the initial payment:

// 1. First charge — flag the card for reuse
const paymentIntent = await stripe.paymentIntents.create({
  amount: 4900,
  currency: 'usd',
  customer: customerId,
  setup_future_usage: 'off_session',
});

Second, when the payment succeeds, Stripe attaches the PaymentMethod to the Customer — grab its ID from the succeeded PaymentIntent in your webhook handler. Third, when the buyer clicks yes on the upsell, create and confirm a second PaymentIntent against the saved card:

// 2. The one-click upsell — a separate PaymentIntent
const upsell = await stripe.paymentIntents.create({
  amount: 9700,
  currency: 'usd',
  customer: customerId,
  payment_method: savedPaymentMethodId,
  off_session: true,
  confirm: true,
});

Two payments means two charges on the buyer's statement — which is exactly why the pitfalls below exist.

The four pitfalls that break DIY builds

1. SCA and 3DS on the second charge

Strong Customer Authentication — mandatory for most European cards and spreading elsewhere — means the buyer's bank can demand a 3D Secure challenge on any charge, including your upsell. A pure off-session confirm returns an authentication_required decline when that happens. The saving grace of post-purchase upsells is that the buyer is still sitting on your thank-you page: a well-built flow catches the decline, surfaces the 3DS challenge on-session while they're present, and completes the payment. Skip that handling and you silently lose a meaningful slice of EU and UK upsell revenue.

2. Refunds now span two payments

"Refund my order" can now mean refunding two PaymentIntents. Your support tooling, your accounting export, and your refund endpoint all need to treat the pair as one order — otherwise you strand upsell charges when the main product is refunded, and your affiliate or bookkeeping numbers drift.

3. Receipts and invoices

The buyer made one buying decision but has two charges. Stripe will happily email two disconnected receipts. If you operate anywhere that requires proper invoices — VAT in the EU and UK, GST in New Zealand and Australia — each charge needs correct invoice lines under your sequential numbering, and the upsell can't just vanish from the paper trail.

4. Tax on the upsell

The second PaymentIntent is a separate taxable transaction. If you calculate tax on the first charge — with Stripe Tax or anything else — you must run the same calculation on the upsell amount, with the same buyer-location and tax-ID treatment, including reverse charge for EU B2B buyers. DIY builds skip this constantly, and it surfaces later as under-collected VAT or GST. (None of this is tax or legal advice — your registrations and obligations are between you and your accountant.)

Option A: build it yourself on Stripe's APIs

If checkout is core to your product, or your flow is genuinely unusual, building on the raw APIs is legitimate. Here's the full parts list:

A competent developer gets the happy path working in a week or two. The edge cases — 3DS recovery, partial refunds, invoice correctness across jurisdictions — are where the second month goes. It's the right call when you need something nobody sells.

Option B: use a cart platform

Cart platforms like ThriveCart and SamCart have offered order bumps and one-click upsells for years, and both are mature at it: visual funnel builders, template libraries, affiliate centers, and a long track record of processed volume. As of this writing, ThriveCart is best known for a pay-once lifetime-license model while SamCart sells monthly subscription tiers — check their current pricing pages, because these things change.

An honest note: if you want a visual editor a human drives, an established template ecosystem, and a tool your VA already knows, a mature cart platform is a genuinely good choice — plenty of serious funnels run on them, and that isn't going to stop. Their limitation is the axis this post lives on: they're dashboard-first. As of this writing, there's no meaningful way for an AI agent to build or operate a funnel in them — every bump and upsell is configured by a person clicking through screens. We've written full comparisons if you're weighing them up: the ThriveCart alternative guide and the SamCart alternative guide.

Option C: one sentence to your agent

gocushy is the checkout machinery from Option A, pre-built, with an interface designed for AI agents instead of dashboards. You connect your own Stripe account once — money settles in your Stripe; gocushy never holds funds — and then, in Claude, ChatGPT, Cursor, or anything else that speaks MCP, you type:

you → your agent"Set up a checkout for my $49 course. Add the $17 workbook as an order bump and offer the $97 template pack as a one-click upsell."

The agent calls create_offer and get_checkout_link, and the checkout is live — hosted, mobile-first, loading in under a second. Every one-time offer supports a bump and a post-purchase one-click upsell by default, and the four pitfalls above are already handled:

If you'd rather integrate than converse, the same machinery is exposed as a REST API — see the developer docs — and the quickstart covers setup for Claude, ChatGPT, and Cursor. You can create an account here. For the bigger picture of why checkout is becoming something agents operate, read What is an MCP checkout?

Which route should you take?

DIY on Stripe APIsCart platformgocushy
Time to first upsell live1–2 weeks, plus edge casesAn afternoon of configuringMinutes — one sentence to your agent
Order bumpYou build itBuilt inBuilt in, on every one-time offer
SCA / 3DS on the upsellYou handle authentication_requiredHandled by the platformHandled
Tax on the upsellYou wire itVaries by platform and planStripe Tax on your registrations, incl. reverse charge
InvoicesYou build the numberingVariesSequential, compliant, covers both charges
Whose Stripe accountYoursTypically connects to your gatewayYours — funds never touch gocushy
Agent-operableOnly what you codeNo, as of this writingNative — 22 MCP tools

The short version: if checkout is your product, build it. If you want a human-clicked dashboard with templates, buy a cart. If you want bumps and one-click upsells live this afternoon without leaving your AI tool — with the money staying in your own Stripe — that's what gocushy is for.

Founding member: $299/yr, 0% platform fees for life

Limited to 200 seats

gocushy is opening soon. The first 200 founding members lock in zero platform fees forever — you pay only Stripe's standard processing on your own account.

Claim a founding seat

FAQ

Are one-click upsells allowed on Stripe?

Yes. Charging a saved payment method off-session is a standard, documented Stripe flow. You need the buyer's consent to save the card — that's what setup_future_usage represents — and you should disclose that it may be used for a follow-up purchase. The buyer's bank still has the final say and can require authentication on the second charge.

Why do my off-session upsell charges fail with authentication_required?

That's Strong Customer Authentication: the buyer's bank is demanding a 3D Secure challenge, which can't be completed without the buyer present. Because the buyer is usually still on your thank-you page, the fix is to surface the 3DS challenge on-session and confirm the payment there. Builds that skip this handling silently lose a slice of EU and UK upsell revenue.

Does the buyer get one receipt or two?

There are two charges, so by default Stripe issues two disconnected receipts, which confuses buyers and bookkeepers. A correct implementation presents them as one order with invoicing that covers both charges. gocushy issues sequential, compliant invoices that include upsell line items and links them from every receipt.

Do I have to charge tax on the upsell?

In most VAT and GST jurisdictions the upsell is a separate taxable sale, so the calculation that ran on the first charge has to run again with the same buyer-location and tax-ID treatment. gocushy runs Stripe Tax on upsells automatically, on your own registrations. This isn't tax or legal advice — confirm your obligations with your accountant.

What's the fastest way to add a bump and upsell to products already in my Stripe account?

Import your existing Stripe catalog into gocushy with one command, then ask your agent to create an offer with a bump and a one-click upsell attached. The hosted checkout link works anywhere, or a one-line embed script opens it over any existing page.

Sam Bakker is the founder of gocushy. He's spent a decade building funnel software for creators, and is based in New Zealand.