How to Add Order Bumps and One-Click Upsells to Stripe
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 checkout page on the Payment Element, backed by an endpoint that creates the PaymentIntent with a Customer and
setup_future_usage: 'off_session' - A bump-toggle endpoint that recalculates the amount server-side
- A webhook consumer for
payment_intent.succeededthat writes the order and captures the saved payment method - A signed thank-you URL, so the upsell page can't be forged or replayed
- An upsell endpoint that creates and confirms the second PaymentIntent, with an on-session 3DS fallback for
authentication_required - Tax calculation on both charges, invoice generation with sequential numbering, and receipt emails that read as one order
- Refund tooling that spans both PaymentIntents
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:
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:
- Pricing is server-side, so neither an agent nor a buyer can ship or exploit a mispriced checkout
- Upsells charge the saved payment method while the buyer is still present, with SCA handled
- Stripe Tax runs on the upsell too — on your registrations, with buyer country, business tax-ID capture, and EU B2B reverse charge
- Invoices are sequential and compliant across both charges, and refunds work at the order level
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 APIs | Cart platform | gocushy | |
|---|---|---|---|
| Time to first upsell live | 1–2 weeks, plus edge cases | An afternoon of configuring | Minutes — one sentence to your agent |
| Order bump | You build it | Built in | Built in, on every one-time offer |
| SCA / 3DS on the upsell | You handle authentication_required | Handled by the platform | Handled |
| Tax on the upsell | You wire it | Varies by platform and plan | Stripe Tax on your registrations, incl. reverse charge |
| Invoices | You build the numbering | Varies | Sequential, compliant, covers both charges |
| Whose Stripe account | Yours | Typically connects to your gateway | Yours — funds never touch gocushy |
| Agent-operable | Only what you code | No, as of this writing | Native — 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 seatsgocushy 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 seatFAQ
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.