Skip to main content
Accept one-time and recurring payments using checkout links or an embedded checkout component. Whop supports 100+ payment methods across 195 countries, and the right ones appear automatically based on the buyer’s location. See all payment methods.
Building an iOS app? The Whop iOS Checkout SDK handles checkout natively with lower fees (2.7% + $0.30 vs Apple’s 15–30%). The SDK uses a scoped iap:read API key that’s safe to embed in your app.

Choose your integration

Checkout linkEmbedded checkout
EffortLowMedium
CustomizationLimitedFull control
Best forSharing links, quick setupCustom UX, dynamic pricing
Server code requiredNo (Dashboard) / Yes (API)Yes
Checkout links are the simplest way to accept payments. Create a plan to get a shareable checkout URL.
  1. Go to your Dashboard > Checkout links
  2. Click + Create checkout link
  3. Select a product and configure your pricing (free, one-time, or recurring)
  4. Click Create checkout link
The generated link can be shared directly with customers or embedded on your website.

Option 2: Embedded checkout

For a custom checkout experience, use the embedded checkout component with a checkout configuration.

Step 1: Create a checkout configuration

Create a checkout configuration on your server with an inline plan:
import Whop from "@whop/sdk";

const client = new Whop({
  apiKey: "Company API Key",
});

const checkoutConfig = await client.checkoutConfigurations.create({
  company_id: "biz_xxxxxxxxxxxxx",
  plan: {
    initial_price: 10.0,
    plan_type: "one_time",
  },
  metadata: {
    order_id: "order_12345",
  },
});

console.log(checkoutConfig.id); // ch_xxxxxxxxxxxxx (session ID)
console.log(checkoutConfig.plan?.id); // plan_xxxxxxxxxxxxx (plan ID)
In this example:
  • company_id is your company ID
  • plan.initial_price is the payment amount
  • plan.plan_type is either one_time or renewal for subscriptions
  • metadata stores custom data for your reference

Step 2: Render the checkout

import { WhopCheckoutEmbed } from "@whop/checkout/react";

export function Checkout({ sessionId }: { sessionId: string }) {
  return (
    <WhopCheckoutEmbed
      sessionId={sessionId}
      returnUrl="https://yoursite.com/checkout/complete"
      onComplete={(paymentId) => {
        console.log("Payment complete:", paymentId);
      }}
    />
  );
}
Pass the checkoutConfig.id from step 1 as the sessionId prop.
The returnUrl is required to handle redirects from external payment providers. When redirected, check the status query parameter:
  • success: The payment succeeded. Use the receipt information to render a success page.
  • error: The payment failed or was canceled. Remount the checkout so your customer can try again.

Step 3: Customize the checkout

You can customize the checkout appearance and behavior:
Prop (React)Attribute (HTML)Description
themedata-whop-checkout-theme"light", "dark", or "system" (default)
hidePricedata-whop-checkout-hide-priceHide the price display
themeOptions.accentColordata-whop-checkout-theme-accent-colorCustom accent color
For the full list of customization options, see the Embedded checkout reference.

Handle payment webhooks

Listen for webhooks to fulfill orders on your server. This example uses Next.js on Vercel, but the whopsdk.webhooks.unwrap pattern works with any framework:
import { waitUntil } from "@vercel/functions";
import type { Payment } from "@whop/sdk/resources.js";
import type { NextRequest } from "next/server";
import { whopsdk } from "@/lib/whop-sdk"; // your Whop SDK instance

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 === "payment.succeeded") {
    waitUntil(handlePaymentSucceeded(webhookData.data));
  }

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

async function handlePaymentSucceeded(payment: Payment) {
  console.log("Payment succeeded:", payment.id);
}
Other useful webhook events: membership.went_valid (access granted), payment.failed (payment failed).

Next steps

Webhooks

Handle payment events in real-time

Save payment methods

Save and charge payment methods

iOS payments

Accept payments in your iOS app with lower fees

Payment methods

100+ payment methods across 195 countries