Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.whop.com/llms.txt

Use this file to discover all available pages before exploring further.

Use saved payment methods to charge customers automatically for subscriptions, renewals, or usage-based billing. The customer saves their card once using a Whop hosted or embedded flow, and you can charge it any time after.
Pair this guide with webhooks: listen for setup_intent.succeeded to confirm the save, then for payment.succeeded / payment.failed to track future charges.

Pick your save flow

Two paths, depending on whether the user is also paying right now.
Setup mode (collect-only)Save during checkout
Charges the user now?NoYes
Use caseFree trial signup, on-file card before usage-based billingSubscription that renews after the first paid checkout
APICreate checkout configuration with mode: "setup"Pass setupFutureUsage: "off_session" on WhopCheckoutEmbed
Webhook to listen forsetup_intent.succeededpayment.succeeded (the payment_method is on the result)
The rest of this page covers setup mode end-to-end, then shows how to charge a saved method later.

Save a payment method

1

Create a checkout configuration in setup mode

Create a checkout configuration without a plan to collect payment details without charging. Add metadata to be able to link the member and payment method to a customer in your system.
const checkoutConfiguration = await whopsdk.checkoutConfigurations.create({
  company_id: "biz_XXXXXX",
  mode: "setup",
  redirect_url: "https://mywebsite.com/return_location",
  metadata: { customer_id: "my_internal_user_id" },
});
2

Direct the user to checkout

Use embedded checkout or redirect the user to save their payment method.
import { WhopCheckoutEmbed } from "@whop/checkout/react";

export default function SavePayment() {
  return (
    <WhopCheckoutEmbed
      sessionId={checkoutConfiguration.id}
      returnUrl="https://yoursite.com/setup/complete"
      onComplete={(id) => {
        console.log("Payment method saved");
      }}
    />
  );
}
3

Handle completion

Listen for the setup_intent.succeeded webhook to get the payment method ID. The CheckoutConfiguration and its metadata will be included on the SetupIntent, which you can use to link the member and payment method to a customer in your system.
The example uses waitUntil from @vercel/functions to run the handler after responding 200. On other runtimes (Bun, Cloudflare Workers, Fastify, Hono) swap it for your framework’s equivalent background-task primitive or a job queue. See the webhooks guide for Python and Ruby handler equivalents.
import { waitUntil } from "@vercel/functions";
import type { NextRequest } from "next/server";
import { whopsdk } from "@/lib/whop-sdk";

export async function POST(request: NextRequest): Promise<Response> {
  const requestBodyText = await request.text();
  const headers = Object.fromEntries(request.headers);
  const webhookData = whopsdk.webhooks.unwrap(requestBodyText, { headers });

  if (webhookData.type === "setup_intent.succeeded") {
    waitUntil(handleSetupSucceeded(webhookData.data));
  }

  return new Response("OK", { status: 200 });
}

async function handleSetupSucceeded(setupIntent) {
  console.log("Payment method ID:", setupIntent.payment_method.id);
  console.log("Member ID:", setupIntent.member.id);
  console.log("Metadata:", setupIntent.metadata);
}
The payment method is now saved and authorized for this member.

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.
const payment_methods = await whopsdk.paymentMethods.list({
  member_id: "mber_XXXXXXXX",
});

const payment_method = payment_methods.data[0];
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.
const payment = await whopsdk.payments.create({
  plan: { initial_price: 40.00, currency: "usd", plan_type: "one_time" },
  company_id: "biz_XXXXXXXX",
  member_id: "mber_XXXXXXXX",
  payment_method_id: "payt_XXXXXXXXX",
});

console.log("Payment:", payment.id);
3

Handle payment events

Listen for payment webhooks to track success or failure.
if (webhookData.type === "payment.succeeded") {
  await fulfillOrder(webhookData.data);
}

if (webhookData.type === "payment.failed") {
  await notifyCustomer(webhookData.data.member.email, webhookData.data.failure_message);
}

Save during checkout

To save a payment method while processing a payment, add setupFutureUsage: "off_session" to the embedded checkout.
<WhopCheckoutEmbed
	planId="plan_XXXXXXXX"
	returnUrl="https://yoursite.com/checkout/complete"
	setupFutureUsage="off_session"
/>
The payment method will be saved after successful payment.

Next steps

Accept payments

One-time and subscription checkouts to pair with your save flow.

Embedded checkout

Drop checkout into your own site without redirects.

Listen to webhooks

Track setup_intent.succeeded, payment.succeeded, and payment.failed.

Billing portal

Let customers manage and remove their saved payment methods.