Pick your save flow
Two paths, depending on whether the user is also paying right now.
The rest of this page covers setup mode end-to-end, then shows how to charge a saved method later.
Save a payment method with the payment elements
Build the save form on the payment elements inmode: "setup". The element offers only methods that can be saved, shows the buyer the future-use consent the save requires, and hands you a confirmation token. You turn that token into a setup intent from your server, and the setup intent’s client_secret finishes any step the buyer still owes.
1
Mount the form in setup mode
Pass The token carries the consent the element displayed. A token collected from a payment-mode form is refused by the setup intent, so mount in
mode="setup" and the currency the saved method will be used with. There is no amount, so amount limits don’t apply. Set returnUrl to a page you host over https. Bank enrollments and some 3D Secure flows bring the buyer back there.mode="setup" when the buyer isn’t paying.2
Create the setup intent on your server
Create a setup intent with the confirmation token. Whop resolves the buyer from the token’s email and answers
201 Created with the setup intent. It carries the status, a client_secret for any step the buyer still owes, and once it has succeeded, the saved method as payment_method_id. Attach metadata to tie the saved method to a customer in your system. It comes back on the webhook. Send an Idempotency-Key so a retried request never saves the method twice.3
Finish any pending step
A setup intent that comes back
succeeded has the method on file. requires_action means the buyer still has a step like 3D Secure or a bank enrollment. Pass the client_secret to handleNextAction, the same call the payment flow uses. It runs an inline step in a dialog or sends the buyer to your returnUrl. Branch on the status it returns: succeeded saved the method, processing is still deciding, and anything else needs another try. A dismissed dialog leaves the setup at requires_action with no error, and lastPaymentError carries the reason when the attempt fails. processing means the processor is still deciding, so show a pending state and let the webhook below confirm the save. canceled means the buyer abandoned the step or the provider refused the method: last_setup_error carries the provider’s reason, and stays null when the buyer walked away. To read the state from your server instead, retrieve the setup intent and branch on the same status, or poll the lighter Retrieve setup status while a step is pending.4
Handle completion
Listen for the The payment method is now saved and authorized for this member. Charge it with the steps in Charge a saved payment method.
setup_intent.succeeded webhook to get the payment method ID and your metadata back. It’s the only signal that survives a closed tab, and the same handler serves the hosted flow below. The setup intent also carries payment_instrument for display: a name, the standard icon set, and for a card its brand, last four, and expiry. You can show the saved method without another request. Webhooks pinned before API version 2026-09-22-1 carry the saved method as payment_method.id instead.Save a payment method with a hosted checkout
1
Create a checkout configuration in setup mode
Create a checkout configuration without a variant to collect payment details without charging. Add metadata to be able to link the member and payment method to a customer in your system.
2
Direct the user to checkout
Mount the Checkout element or redirect the user to save their payment method.A setup-mode configuration mounts the same element as a payment-method
save: nothing is charged, and the finished checkout redirects to
- Embedded
- Redirect
returnUrl with setup_intent_id in the query string. Confirm the save
from the setup_intent.succeeded webhook rather than from the redirect.3
Handle completion
Listen for the The payment method is now saved and authorized for this member.
setup_intent.succeeded webhook to get the payment method ID. The setup intent carries checkout_configuration_id and the configuration’s metadata, which you can use to link the member and payment method to a customer in your system.Confirm the save from the webhook rather than from the buyer arriving at your
redirect_url. It’s the only signal that survives a closed tab.Charge a saved payment method
1
Get the payment method
List saved payment methods for a member, or use the
payment_method_id from the setup intent in the previous step.2
Create an off-session payment
Charge the payment method without customer interaction. The create payment endpoint returns a payment object immediately and processes the charge asynchronously.
3
Handle payment events
Listen for payment webhooks to track success or failure.
Save during checkout
To save a payment method while charging the buyer, build the checkout on the payment elements and passsetupFutureUsage: "off_session" on the Payments handle. The elements show the buyer the save consent and record it on the confirmation token, and the payment vaults the method only when that consent is attested.
The Elements property for selecting a variant remains named plan for compatibility.
1
Mount the form with save consent
createConfirmationToken, and handleNextAction.2
Create the payment with the confirmation token
The create response is the payment as opened, not its outcome. The saved method’s
payment_method_id arrives on the payment.succeeded webhook once the charge completes.3
Charge it later
payment_method_id is the payt_ method to use in Charge a saved payment method. It stays null when nothing was saved. The payment.succeeded webhook carries the same field, and it’s the path that survives a closed tab.Next steps
Accept payments
One-time and subscription checkouts to pair with your save flow.
Checkout element
Mount Whop checkout on your own site with Whop Elements.
Listen to webhooks
Track
setup_intent.succeeded, payment.succeeded, and payment.failed.Billing portal
Let customers manage and remove their saved payment methods.

