PAYMENTS / LESSON 07
Whop in Your App.
API keys, checkout from code, access checks and webhooks with the Whop SDK

Loading the lesson…
Loading activities…
PAYMENTS / LESSON 07
API keys, checkout from code, access checks and webhooks with the Whop SDK

Loading the lesson…
Loading activities…
Whop works fine without code, but it also has an API for developers. This lesson covers the four things you'll touch the MOST. API keys, creating a checkout from code, checking who has access, and receiving webhooks. Deep breath... we'll take them one at a time.
Here's how a Whop sale usually flows when you've got your own app.
Your server asks Whop for a checkout page and gets back a URL.
The buyer opens that URL and pays. Card details go to Whop and never touch your server.
Whop sends your server a message saying the payment succeeded.
Your server marks the order paid and lets the buyer in. Later on, your app can ask Whop whether someone still has access.
Sound like the Stripe flow? Yep, pretty much. The difference is that Whop also stores memberships, so it can answer the "does this person have access?" question for you.
An API key is a secret password that lets your server talk to Whop's API. Whop has a few kinds of credentials, and most projects start with an Account API key, which lets your server act for your own business.
To make one, open your Whop dashboard and head to the developer section. Under Account API Keys, select Create, give the key a name you'll recognize, and pick its permissions. Copy the key when Whop shows it and save it in your .env file.
Whop also suggests the Admin role for your first test only. Once you know which endpoints you actually use, switch the key to a narrower custom set of permissions.
An SDK is a library that wraps the API, so you call functions instead of building web requests by hand. Whop's TypeScript SDK is the @whop/sdk package.
Whop also publishes SDKs for Python (whop-sdk) and Ruby (whop_sdk).
Now make your first call. This one asks Whop "which business does this key belong to?" If it prints an ID starting with biz_, your key works. Easy win.
Save that as first-call.mts (the .mts ending lets you use await at the top of the file) and run it with npx tsx --env-file=.env first-call.mts. The --env-file part loads your key from .env.
Last lesson you made a checkout link by clicking around the dashboard. Your server can do the same thing with ONE call. It hands back a purchase_url, which is a live payment page.
This example creates a new one-time price on the fly. Already made a plan in the dashboard? Pass its ID as plan_id instead of the plan object. You can't send both.
Send the buyer to purchase_url with a link or a redirect. Whop takes the payment page from there.
Sandbox keys only work against the sandbox, so you have to tell the SDK which one you mean. The SDK exports WhopEnvironment, and you pass environment: WhopEnvironment.Sandbox next to token when you create the client.
Whop also has ways to put checkout right on your own page instead of linking out. Its Accept Payments guide compares them. A shared checkout link is still the simplest place to start.
Here's where Whop saves you a pile of work. When someone pays, Whop creates a membership for them. Your app can just ask Whop whether a user has access to something, instead of tracking it all in your own database.
The method is users.checkAccess. You pass in a user ID (starts with user_) and the ID of the thing you're checking.
The resource_id can point at three kinds of things.
| ID starts with | Checks access to |
|---|---|
biz_ | Your whole business |
prod_ | One product |
exp_ | One experience, like a course or chat |
The answer comes back as has_access (true or false) plus an access_level.
| Access level | Meaning |
|---|---|
customer | The user has a valid membership |
admin | The user is on the business's team |
no_access | The user has no access |
There's one catch... you need the user's Whop ID in the first place. Apps that run inside Whop get it from a token Whop sends with each request. Apps that run on their own site can use "Sign in with Whop", which is Whop's OAuth flow. Both get covered in Whop's Authentication and Auth and API Keys guides.
A webhook is a message Whop sends to your server when something happens, like payment.succeeded or membership.activated. Same deal as Stripe, this is how you find out what really happened.
To set one up, open the developer section of your dashboard and select Create webhook. Paste your server's HTTPS address, keep the API version on v1, and pick the events you want. Whop gives you a signing secret that starts with ws_. Store it EXACTLY as given.
Here's the Next.js example from Whop's Webhooks guide, with one small tweak. It checks the signature, reads the event type and answers fast. Put it in app/api/webhooks/whop/route.ts and install the helper it uses with npm install @vercel/functions.
The tweak is that <WhopEvent> part. It tells TypeScript what an event looks like. Leave it off and TypeScript can't tell that event.data is an object, so the build fails with a type error.
A few rules from Whop's docs are worth tattooing somewhere.
unwrapWebhook throws if the signature is wrong, so fake requests never reach your code.waitUntil does on Vercel.webhook-id header and skip the ones you've already handled.localhost, so use a tunnel like ngrok while developing.@whop/sdk, and client.accounts.me() is a good first testclient.checkoutConfigurations.create() returns a purchase_url buyers can pay atclient.users.checkAccess() asks Whop whether a user has access to a business, product or experiencepayment.succeeded tell your server what really happened, so give access thereTry the whole loop in the sandbox. Create a key, make a checkout, pay with the test card and watch your webhook fire. That first webhook landing is a weirdly great feeling...