Agent skill
whop
Whop platform expert for digital products, memberships, and community monetization. Covers memberships API, payments, courses, forums, webhooks, OAuth apps, and checkout integration. Build SaaS, course platforms, and gated communities. Triggers on Whop, memberships, digital products, course platform, community monetization, Whop API, license keys.
Install this agent skill to your Project
npx add-skill https://github.com/raintree-technology/claude-starter/tree/main/skills/whop
Metadata
Additional technical details for this skill
- author
- raintree
- version
- 1.0
SKILL.md
Whop Platform Expert
Whop is a platform for selling digital products, memberships, courses, and community access.
When to Use
- Building membership/subscription products
- Integrating Whop checkout and payments
- Managing courses and educational content
- Gating content by membership status
- Handling webhooks for payment events
- Building Whop apps with OAuth
Quick Start
Authentication
const headers = {
Authorization: `Bearer ${process.env.WHOP_API_KEY}`,
"Content-Type": "application/json",
};
const response = await fetch("https://api.whop.com/api/v5/me", { headers });
API Key Types:
- Company API Keys - Your own company data (Dashboard → Settings → API Keys)
- App API Keys - Multi-tenant apps (Dashboard → Developer → Your App)
Core Operations
Create Product
const product = await fetch("https://api.whop.com/api/v5/products", {
method: "POST",
headers,
body: JSON.stringify({
title: "Premium Membership",
description: "Access to all content",
visibility: "visible",
}),
});
Create Plan
const plan = await fetch("https://api.whop.com/api/v5/plans", {
method: "POST",
headers,
body: JSON.stringify({
product_id: "prod_xxx",
billing_period: 1,
billing_period_unit: "month",
price: 2999, // $29.99 in cents
currency: "usd",
}),
});
Create Checkout
const checkout = await fetch(
"https://api.whop.com/api/v5/checkout-configurations",
{
method: "POST",
headers,
body: JSON.stringify({
plan_id: "plan_xxx",
success_url: "https://yourapp.com/success",
cancel_url: "https://yourapp.com/cancel",
metadata: { user_id: "123" },
}),
}
);
const { url } = await checkout.json();
// Redirect user to url
Membership Management
List Memberships
const response = await fetch(
"https://api.whop.com/api/v5/memberships?valid=true",
{ headers }
);
const { data: memberships } = await response.json();
Check User Access
async function checkAccess(userId: string, productId: string): Promise<boolean> {
const response = await fetch(
`https://api.whop.com/api/v5/memberships?user_id=${userId}&product_id=${productId}&valid=true`,
{ headers }
);
const { data } = await response.json();
return data.length > 0;
}
Validate License Key
async function validateLicense(licenseKey: string): Promise<boolean> {
const response = await fetch(
`https://api.whop.com/api/v5/memberships?license_key=${licenseKey}`,
{ headers }
);
const { data } = await response.json();
return data.length > 0 && data[0].valid;
}
Cancel Membership
await fetch(
`https://api.whop.com/api/v5/memberships/${membershipId}/cancel`,
{
method: "POST",
headers,
}
);
Payments
Get Payment
const payment = await fetch(
`https://api.whop.com/api/v5/payments/${paymentId}`,
{ headers }
);
Refund Payment
await fetch(`https://api.whop.com/api/v5/payments/${paymentId}/refund`, {
method: "POST",
headers,
body: JSON.stringify({
amount: 1000, // Optional: partial refund in cents
}),
});
Courses
Create Course
const course = await fetch("https://api.whop.com/api/v5/courses", {
method: "POST",
headers,
body: JSON.stringify({
product_id: "prod_xxx",
title: "Complete Web Development",
description: "Learn fullstack from scratch",
visibility: "visible",
}),
});
Create Chapter
const chapter = await fetch("https://api.whop.com/api/v5/course-chapters", {
method: "POST",
headers,
body: JSON.stringify({
course_id: "course_xxx",
title: "Introduction to JavaScript",
order: 1,
}),
});
Create Lesson
const lesson = await fetch("https://api.whop.com/api/v5/course-lessons", {
method: "POST",
headers,
body: JSON.stringify({
chapter_id: "chapter_xxx",
title: "Variables and Data Types",
content: "Lesson content in markdown...",
type: "video", // or 'text', 'quiz', 'assignment'
video_url: "https://youtube.com/watch?v=...",
order: 1,
}),
});
Mark Lesson Complete
await fetch(
`https://api.whop.com/api/v5/course-lessons/${lessonId}/mark-as-completed`,
{
method: "POST",
headers: {
Authorization: `Bearer ${userAccessToken}`,
},
}
);
Webhooks
Setup Endpoint
import crypto from "crypto";
export async function POST(req: Request) {
const body = await req.text();
const signature = req.headers.get("x-whop-signature");
// Verify signature
const hash = crypto
.createHmac("sha256", process.env.WHOP_WEBHOOK_SECRET!)
.update(body)
.digest("hex");
if (hash !== signature) {
return new Response("Invalid signature", { status: 401 });
}
const event = JSON.parse(body);
switch (event.action) {
case "payment.succeeded":
await handlePaymentSuccess(event.data);
break;
case "membership.activated":
await grantAccess(event.data);
break;
case "membership.deactivated":
await revokeAccess(event.data);
break;
case "dispute.created":
await handleDispute(event.data);
break;
}
return Response.json({ received: true });
}
Key webhook events:
| Event | Trigger |
|---|---|
payment.succeeded |
Payment completed |
payment.failed |
Payment failed |
membership.activated |
Membership started |
membership.deactivated |
Membership ended |
invoice.paid |
Recurring payment succeeded |
dispute.created |
Chargeback initiated |
OAuth Apps
Redirect to Whop OAuth
const authUrl = new URL("https://whop.com/oauth");
authUrl.searchParams.set("client_id", process.env.WHOP_CLIENT_ID!);
authUrl.searchParams.set("redirect_uri", "https://yourapp.com/callback");
authUrl.searchParams.set("scope", "memberships:read payments:read");
// Redirect user
window.location.href = authUrl.toString();
Handle Callback
export async function GET(req: Request) {
const url = new URL(req.url);
const code = url.searchParams.get("code");
const response = await fetch("https://api.whop.com/api/v5/oauth/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
client_id: process.env.WHOP_CLIENT_ID!,
client_secret: process.env.WHOP_CLIENT_SECRET!,
code,
grant_type: "authorization_code",
redirect_uri: "https://yourapp.com/callback",
}),
});
const { access_token, refresh_token } = await response.json();
// Store tokens securely
}
Middleware (Access Control)
// middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export async function middleware(request: NextRequest) {
const token = request.cookies.get("whop_user_token")?.value;
if (!token) {
return NextResponse.redirect(new URL("/login", request.url));
}
const response = await fetch("https://api.whop.com/api/v5/me/memberships", {
headers: { Authorization: `Bearer ${token}` },
});
const { data } = await response.json();
const hasAccess = data.some((m: any) => m.status === "active" && m.valid);
if (!hasAccess) {
return NextResponse.redirect(new URL("/subscribe", request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ["/dashboard/:path*", "/premium/:path*"],
};
TypeScript Types
interface WhopMembership {
id: string;
user_id: string;
product_id: string;
plan_id: string;
status: "active" | "paused" | "canceled" | "expired";
valid: boolean;
license_key: string;
renews_at: string | null;
expires_at: string | null;
cancel_at_period_end: boolean;
}
interface WhopPayment {
id: string;
amount: number;
currency: string;
status: "succeeded" | "pending" | "failed";
user_id: string;
product_id: string;
}
Error Handling
async function safeWhopRequest(url: string, options: RequestInit) {
const response = await fetch(url, options);
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || "Whop API error");
}
return response.json();
}
| Error | Meaning |
|---|---|
401 Unauthorized |
Invalid API key |
403 Forbidden |
Insufficient permissions |
404 Not Found |
Resource doesn't exist |
429 Too Many Requests |
Rate limited |
Security Best Practices
DO:
- Verify webhook signatures
- Store tokens encrypted
- Check membership status server-side
- Use HTTPS everywhere
DON'T:
- Expose API keys client-side
- Trust client-sent membership data
- Skip webhook verification
- Log sensitive data
Implementation Checklist
- Create Whop account and company
- Get API keys from Dashboard
- Set environment variables
- Create products and plans
- Implement checkout flow
- Add membership access checking
- Set up webhook endpoint
- Handle payment events
- Test end-to-end flow
Resources
- Dashboard: https://whop.com/dashboard
- API Docs: https://docs.whop.com
- API Base: https://api.whop.com/api/v5
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
claude-mcp-expert
Model Context Protocol (MCP) expert for Claude Code. Install, configure, and troubleshoot MCP servers. Covers HTTP, SSE, and stdio transports, authentication, popular integrations (Sentry, GitHub, Jira, Notion, databases). Triggers on MCP, Model Context Protocol, MCP server, installing MCP, connecting tools, webhooks, remote server.
claude-skill-builder
Interactive skill creator for Claude Code and Agent Skills ecosystem. Build SKILL.md files with proper frontmatter, triggers, and structure. Triggers on creating skills, building skills, skill templates, skill frontmatter, allowed-tools, npx add-skill, agent skills.
move-prover
Move Prover formal verification expert for Aptos smart contracts. Write specifications (MSL), preconditions (requires), postconditions (ensures), invariants, abort conditions (aborts_if), quantifiers, schemas, and pragmas. Debug verification failures. Triggers on Move Prover, formal verification, spec, invariant, ensures, requires, aborts_if, precondition, postcondition.
helius
Helius Solana RPC and API expert. High-performance infrastructure for Solana including RPC nodes, DAS API for NFTs/tokens, LaserStream real-time streaming, webhooks, Priority Fee API, Enhanced Transactions, and ZK Compression. Triggers on Helius, Solana RPC, DAS API, Digital Asset Standard, NFT metadata, Solana webhooks, priority fees, LaserStream, ZK compression.
toon-formatter
Token-Oriented Object Notation (TOON) format expert for 30-60% token savings on structured data. Auto-applies to arrays with 5+ items, tables, logs, API responses, database results. Supports tabular, inline, and expanded formats with comma/tab/pipe delimiters. Triggers on large JSON, data optimization, token reduction, structured data, arrays, tables, logs, metrics, TOON.
aptos
Aptos blockchain and Move language expert. Covers Move programming (abilities, generics, resources), Aptos framework modules, smart contract development, token standards (Coin, Fungible Asset, Digital Asset), object model, gas optimization, and dApp integration. Triggers on Aptos, Move language, Move smart contract, Aptos blockchain, abilities, generics, resources, fungible asset, digital asset.
Didn't find tool you were looking for?