Skip to main content
Accept one-time and recurring payments using checkout links or an embedded checkout component. To initiate a checkout you need a plan, and optionally a checkout configuration. Plans specify the price shown at checkout and type of purchase (either one_time or renewal) as well as many other configurable options. Plans can be created manually in the dashboard or via the API. A checkout configuration allows you to attach custom metadata and redirect URLs to one or more checkouts created from it. These can only be created via the API. 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);
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

Use the embedded checkout component to render the payment form on the client:
import { WhopCheckoutEmbed } from "@whop/checkout/react";

export function Checkout({ sessionId }: { sessionId: string }) {
  return (
    <WhopCheckoutEmbed
      sessionId={sessionId}
      onComplete={(paymentId) => {
        console.log("Payment complete:", paymentId);
      }}
    />
  );
}
Pass the checkoutConfig.id from step 1 as the sessionId prop.

Handle payment webhooks

Listen for the payment.succeeded webhook to fulfill orders on your server:
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";

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);
}

API Reference

Create Checkout Configuration API

See the full API reference for creating checkout configurations