### Navigate to App Directory Source: https://github.com/whopio/developer-documentation/blob/main/apps/create-an-app.mdx Change into your newly created application's directory to proceed with further setup. ```bash cd my-new-app ``` -------------------------------- ### Install Whop Dev Proxy with NPM Source: https://github.com/whopio/developer-documentation/blob/main/sdk/proxy.mdx Install the @whop-apps/dev-proxy package using NPM. ```bash npm install @whop-apps/dev-proxy ``` -------------------------------- ### Direct SDK Usage Examples Source: https://github.com/whopio/developer-documentation/blob/main/what-to-build/web-apps.mdx Examples demonstrating direct usage of the Whop API SDK for common operations like fetching user profiles, listing experiences, and sending messages. ```APIDOC ## SDK Methods ### PublicUser #### Description Retrieves the profile information for a specific user. ### ListExperiences #### Description Lists available experiences, with options for filtering and pagination. - `companyId` (string) - Required - The ID of the company. - `first` (number) - Optional - The number of results to return. - `after` (string) - Optional - A cursor for pagination. - `accessPassId` (string) - Optional - Filter experiences by access pass ID. - `appId` (string) - Optional - Filter experiences by app ID. - `onAccessPass` (boolean) - Optional - Whether to only show experiences on an access pass. ### SendDmMessage #### Description Sends a direct message to another user. - `toUserId` (string) - Required - The ID of the recipient user. - `message` (string) - Required - The content of the message. ### SendChatMessage #### Description Sends a message to an experience's chat. - `experienceId` (string) - Required - The ID of the experience. - `message` (string) - Required - The content of the message. ### SendFeedMessage #### Description Sends a message to an experience's feed. - `experienceId` (string) - Required - The ID of the experience. - `message` (string) - Required - The content of the message. ``` -------------------------------- ### App Mode Usage Example Source: https://github.com/whopio/developer-documentation/blob/main/sdk/api.mdx Example of fetching company information using the App mode. Ensure the SDK is imported and the API key is configured. ```typescript import { WhopAPI } from "@whop-apps/sdk"; export default async function Home() { const companyInformation = await WhopAPI.app().GET("/app/companies/{id}", { params: { path: { id: "biz_XXX" } }, }); } ``` -------------------------------- ### Install Whop Dev Proxy with PNPM Source: https://github.com/whopio/developer-documentation/blob/main/sdk/proxy.mdx Install the @whop-apps/dev-proxy package using PNPM. ```bash pnpm add @whop-apps/dev-proxy ``` -------------------------------- ### Install Whop Dev Proxy with Yarn Source: https://github.com/whopio/developer-documentation/blob/main/sdk/proxy.mdx Install the @whop-apps/dev-proxy package using Yarn. ```bash yarn add @whop-apps/dev-proxy ``` -------------------------------- ### Install Whop API and Dev Proxy Dependencies Source: https://github.com/whopio/developer-documentation/blob/main/what-to-build/web-apps.mdx Install the necessary packages for interacting with the Whop API and for local development with the dev proxy. ```bash pnpm add @whop/api @whop-apps/dev-proxy ``` -------------------------------- ### Example Callback URL Source: https://github.com/whopio/developer-documentation/blob/main/oauth.mdx This is the URL your users will be redirected to after authorizing your application. It includes a 'code' parameter. ```bash https://your-site.xyz/callback/whop?code=xxxxxxxx ``` -------------------------------- ### Example .env.local file Source: https://github.com/whopio/developer-documentation/blob/main/apps/create-an-app.mdx Configure your environment variables by adding these to your .env.local file. WHOP_API_KEY is for authentication, and NEXT_PUBLIC_WHOP_APP_ID is your application's identifier. ```env WHOP_API_KEY=YOUR_API_KEY NEXT_PUBLIC_WHOP_APP_ID=YOUR_APP_ID ``` -------------------------------- ### Company Mode Usage Example Source: https://github.com/whopio/developer-documentation/blob/main/sdk/api.mdx Example of fetching user information using the Company mode. Ensure the SDK is imported and the API key is configured. ```typescript import { WhopAPI } from "@whop-apps/sdk"; export default async function Home() { const userInformation = await WhopAPI.company().GET("/company/users/{id}", { params: { path: { id: "user_XXX" } }, }); } ``` -------------------------------- ### Install Whop SDK with pnpm Source: https://github.com/whopio/developer-documentation/blob/main/sdk/installation.mdx Use this command to add the Whop SDK to your project if you are using pnpm as your package manager. ```bash pnpm add @whop-apps/sdk ``` -------------------------------- ### Install Whop SDK with npm Source: https://github.com/whopio/developer-documentation/blob/main/sdk/installation.mdx Use this command to add the Whop SDK to your project if you are using npm as your package manager. ```bash npm install @whop-apps/sdk ``` -------------------------------- ### Install Whop SDK with Yarn Source: https://github.com/whopio/developer-documentation/blob/main/sdk/installation.mdx Use this command to add the Whop SDK to your project if you are using Yarn as your package manager. ```bash yarn add @whop-apps/sdk ``` -------------------------------- ### Me Mode Usage with Token Source: https://github.com/whopio/developer-documentation/blob/main/sdk/api.mdx Example of fetching the current user's information using Me mode with a manually provided access token. ```javascript const currentUser = await WhopAPI.me({ token: "" }).GET("/me", {}); ``` -------------------------------- ### Next.js Client Layout Source: https://github.com/whopio/developer-documentation/blob/main/sdk/iframe-setup.mdx This client component imports the SDK setup file. Ensure the "use client" directive is present. ```tsx "use client"; // this line is important import { FC, PropsWithChildren } from "react"; import "@/lib/iframe"; export const ClientLayout: FC = ({ children }) => { return <>{children}; }; ``` -------------------------------- ### Me Mode Usage with Headers Source: https://github.com/whopio/developer-documentation/blob/main/sdk/api.mdx Example of fetching the current user's information using Me mode with headers. This is typically used in server components where headers are available. ```javascript import { headers } from "next/headers"; const currentUser = await WhopAPI.me({ headers }).GET("/me", {}); ``` -------------------------------- ### Payment Received Webhook Setup Source: https://github.com/whopio/developer-documentation/blob/main/what-to-build/web-apps.mdx Provides instructions and code for setting up a webhook endpoint to receive and process payment success and failure events from Whop. ```APIDOC ## Webhook Handler for Payments ### Description Sets up an API route to receive and validate webhook events from Whop, specifically for payment-related actions. ### Method POST ### Endpoint `/api/webhooks/whop/route.ts` ### Parameters #### Request Body - **request** (NextRequest) - Required - The incoming webhook request. ### Webhook Events Handled #### `payment.succeeded` - **id** (string) - The ID of the payment. - **final_amount** (number) - The total amount charged after fees. - **amount_after_fees** (number) - The amount received after fees. - **currency** (string) - The currency of the payment. - **user_id** (string) - The ID of the user who made the payment. #### `payment.failed` - **user_id** (string) - The ID of the user whose payment failed. - **error** (any) - Details about the payment failure. ### Response - **200 OK** - Indicates the webhook was received and processed successfully. - **400 Bad Request** - Indicates webhook validation failed. ``` -------------------------------- ### Initiate Whop OAuth Authentication Source: https://github.com/whopio/developer-documentation/blob/main/what-to-build/oauth-guide.mdx Redirect users to this URL to start the OAuth authentication process. Ensure you replace `[YOUR_CLIENT_ID]` and `[YOUR_REDIRECT_URL]` with your actual credentials. ```bash https://whop.com/oauth/?scope=openid+user&response_type=code&client_id=[YOUR_CLIENT_ID]&redirect_uri=[YOUR_REDIRECT_URL] ``` -------------------------------- ### Fetch User Information Source: https://github.com/whopio/developer-documentation/blob/main/oauth.mdx Use your authorization token to make a GET request to the /v5/me endpoint to retrieve details about the authenticated user. ```APIDOC ## GET /v5/me ### Description Fetches information about the currently authenticated user using an access token. ### Method GET ### Endpoint /v5/me ### Parameters #### Headers - **Authorization** (string) - Required - Bearer token for authentication. Example: `Bearer YOUR_ACCESS_TOKEN` ### Request Example ```json { "Authorization": "Bearer YOUR_ACCESS_TOKEN" } ``` ### Response #### Success Response (200) - **user_data** (object) - Contains details about the user. #### Response Example ```json { "id": "user_id_123", "username": "example_user", "email": "user@example.com" } ``` ### Error Handling - **400**: Invalid or expired authorization grant. - **401**: Invalid or malformed access token. - **404**: The requested route was not found. ``` -------------------------------- ### Fetch DMs using Python requests Source: https://github.com/whopio/developer-documentation/blob/main/api-reference/graphql/examples.mdx Example of fetching direct messages using the Python 'requests' library. Ensure you replace placeholder API keys and IDs. ```python import requests headers = { "Authorization": "Bearer YOUR_API_KEY", "x-on-behalf-of": "user_123", "x-company-id": "biz_123", "Content-Type": "application/json" } # Example: Fetching DMs full_query = """query DmsFeedData($feedId: ID!, $postsLimit: Int!) { dmsFeedData(feedId: $feedId, postsLimit: $postsLimit) { posts { content user { username id } } } }""" payload = { "query": full_query, "variables": { "feedId": "your_feed_id", "postsLimit": 1 } } response = requests.post( "https://api.whop.com/public-graphql", headers=headers, json=payload ) response_json = response.json() ``` -------------------------------- ### Example `curl` Request to Whop API Source: https://github.com/whopio/developer-documentation/blob/main/instructions/make-a-call.mdx This `curl` command demonstrates how to make a POST request to the Whop GraphQL API, including authentication and query parameters. Replace placeholders with your actual credentials and desired query. ```bash curl -X POST https://api.whop.com/public-graphql \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "x-on-behalf-of: user_123" \ -H "x-company-id: biz_123" \ -H "Content-Type: application/json" \ -d '{ "query": "query { user { id name email } }"}' ``` -------------------------------- ### Fetch Current User using Swift Apollo iOS Source: https://github.com/whopio/developer-documentation/blob/main/api-reference/graphql/examples.mdx Example of fetching current user data using the Apollo iOS SDK. This includes configuring the Apollo client with necessary headers. ```swift import Apollo // Configure Apollo Client let url = URL(string: "https://api.whop.com/public-graphql")! let store = ApolloStore() let transport = RequestChainNetworkTransport( interceptorProvider: DefaultInterceptorProvider(store: store), endpointURL: url, additionalHeaders: [ "Authorization": "Bearer YOUR_API_KEY", "x-on-behalf-of": "user_123", "x-company-id": "biz_123" ] ) let client = ApolloClient(networkTransport: transport, store: store) // Example: Get Current User let getCurrentUser = """ query myCurrentUser { viewer { user { id username name email } } } """ client.fetch(query: getCurrentUser) { result in switch result { case .success(let graphQLResult): print("Success! Result: \(graphQLResult)") case .failure(let error): print("Failure! Error: \(error)") } } ``` -------------------------------- ### Initialize Whop API Client Source: https://github.com/whopio/developer-documentation/blob/main/api-reference/graphql/authentication.mdx Initialize the Whop API client with your application's API key and optionally specify the user or agent user to act on behalf of, along with a company ID if applicable. This setup is required before making any API calls. ```javascript export const whopApi = WhopApi({ appApiKey: process.env.WHOP_API_KEY ?? "fallback", onBehalfOfUserId: 'YOUR_USER_OR_AN_AGENT_USER', companyId: undefined, }); // fetch another user await whopApi.FetchPublicUser({ userId: winningUser }) ``` -------------------------------- ### GraphQL API Call Example Source: https://github.com/whopio/developer-documentation/blob/main/instructions/make-a-call.mdx This snippet demonstrates how to make a GraphQL API call to the Whop API using `curl`. It includes the necessary endpoint, headers for authentication and context, and a sample query. ```APIDOC ## POST https://api.whop.com/public-graphql ### Description This endpoint allows you to interact with the Whop API using GraphQL queries and mutations. You must authenticate using your App API key and provide context with `x-on-behalf-of` and `x-company-id` headers. ### Method POST ### Endpoint https://api.whop.com/public-graphql ### Headers - **Authorization** (string) - Required - Bearer YOUR_API_KEY - **x-on-behalf-of** (string) - Required - The User ID of the account you are using to make requests. - **x-company-id** (string) - Required - The Company ID to target when making requests that involve managing a creator's whops. - **Content-Type** (string) - Required - application/json ### Request Body - **query** (string) - Required - The GraphQL query or mutation to execute. ### Request Example ```json { "query": "query { user { id name email } }" } ``` ### Response #### Success Response (200) - **data** (object) - Contains the data returned by the GraphQL query. - **errors** (array) - Contains any errors encountered during the GraphQL execution. #### Response Example ```json { "data": { "user": { "id": "user_123", "name": "John Doe", "email": "john.doe@example.com" } } } ``` ``` -------------------------------- ### Get current user information (GraphQL) Source: https://github.com/whopio/developer-documentation/blob/main/api-reference/graphql/examples.mdx Retrieve details about the currently authenticated user, including their ID, username, name, and email. ```graphql query myCurrentUser { viewer { user { id username name email } } } ``` -------------------------------- ### Authenticate Users with Whop Token Verifier Source: https://github.com/whopio/developer-documentation/blob/main/what-to-build/web-apps.mdx Verify user tokens in a server component to authenticate requests. This example shows how to retrieve headers and use the verifyUserToken function to check token validity. ```typescript // app/components/SomeComponentThatNeedsAuthVerified.tsx import { verifyUserToken } from "@/lib/whop-api"; import { headers } from "next/headers"; export async function Page() { const requestHeaders = await headers(); const userTokenData = await verifyUserToken(requestHeaders); if (!userTokenData) { return (

Authentication Error

Invalid or missing user token

); } return (

Authentication Successful

Authenticated as:{" "} {userTokenData.userId}

); } ``` -------------------------------- ### Get whops from discover (GraphQL) Source: https://github.com/whopio/developer-documentation/blob/main/api-reference/graphql/examples.mdx Query the discovery endpoint to find available access passes. This includes details like title, route, headline, and logo. ```graphql query DiscoverySearch($query: String!) { discoverySearch(query: $query) { accessPasses { title route headline logo { sourceUrl } } } } ``` -------------------------------- ### Generate AI Response with OpenAI Source: https://github.com/whopio/developer-documentation/blob/main/what-to-build/chat-bots.mdx Uses the OpenAI library to generate a text response based on user input. Ensure you have installed the 'openai' library and set your OPENAI_API_KEY environment variable. ```bash pip install openai ``` ```bash export OPENAI_API_KEY="sk-proj-..." ``` ```python from openai import OpenAI client = OpenAI() completion = client.chat.completions.create( model="gpt-4.1", messages=[ { "role": "user", "content": message_content } ] ) response = completion.choices[0].message.content print(response) ``` -------------------------------- ### App Mode Usage Source: https://github.com/whopio/developer-documentation/blob/main/sdk/api.mdx Demonstrates how to use the App Mode of the Whop API SDK to make a GET request to the /app/companies/{id} endpoint. This mode uses the app's API key. ```APIDOC ## App Mode When you are using one of the **App** endpoints, you need to use this mode. This will use the app's API key to make requests, which can either be set in the environment variables, as `WHOP_API_KEY`, or passed in manually. ### Usage ```typescript import { WhopAPI } from "@whop-apps/sdk"; export default async function Home() { const companyInformation = await WhopAPI.app().GET("/app/companies/{id}", { params: { path: { id: "biz_XXX" } }, }); } ``` ``` -------------------------------- ### Making API Requests with Whop SDK Source: https://github.com/whopio/developer-documentation/blob/main/what-to-build/web-apps.mdx Use the Whop SDK to make various API requests such as getting user profiles, listing experiences, and sending different types of messages. Ensure you have the SDK initialized. ```typescript // Get user profile const userProfile = await whopApi.PublicUser({ userId: "user_id_here", }); // List experiences const experiences = await whopApi.ListExperiences({ companyId: "company_id_here", first: 10, // Optional: limit results after: "cursor_here", // Optional: pagination accessPassId: "access_pass_id_here", // Optional: filter by access pass appId: "app_id_here", // Optional: filter by app onAccessPass: true, // Optional: only show experiences on access pass }); // Send messages // Direct message await whopApi.SendDmMessage({ toUserId: "target_user_id", message: "Hello!", }); // Chat message await whopApi.SendChatMessage({ experienceId: "target_experience_id", message: "Hello everyone!", }); // Feed message await whopApi.SendFeedMessage({ experienceId: "target_experience_id", message: "New announcement!", }); ``` -------------------------------- ### Fetch Company Information using Whop API Source: https://github.com/whopio/developer-documentation/blob/main/apps/seller-page.mdx Use the WhopAPI function to make a GET request to retrieve company information. Pass the company ID from path parameters to the request. ```javascript const companyInformation = await WhopAPI.app().GET("/app/companies/{id}", { params: { path: { id: params.companyId } }, }); ``` -------------------------------- ### Retrieve User Profile Details with Access Token Source: https://github.com/whopio/developer-documentation/blob/main/what-to-build/oauth-guide.mdx This asynchronous JavaScript function makes a GET request to the Whop API's `/me` endpoint to fetch user profile information using an `accessToken`. The token must be included in the `Authorization` header as a Bearer token. ```javascript const checkAccess = async (accessToken) => { const response = await fetch("https://api.whop.com/v5/me", { headers: { Authorization: `Bearer ${accessToken}`, }, }); return response.json(); }; ``` -------------------------------- ### Initialize Whop App SDK Source: https://github.com/whopio/developer-documentation/blob/main/sdk/iframe-setup.mdx Initialize the SDK by calling `createAppIframeSDK` and exporting the instance. This should be done in a separate file for easy import. ```typescript import { createAppIframeSDK } from "@whop-apps/sdk"; export const WhopApp = createAppIframeSDK({ onMessage: {}, }); ``` -------------------------------- ### Create User Page Directory and File Source: https://github.com/whopio/developer-documentation/blob/main/apps/customer-page.mdx Use this bash command to create the necessary directory structure and file for your user page. ```bash mkdir app/user && mkdir "app/user/[experienceId]" && touch "app/user/[experienceId]/page.tsx" ``` -------------------------------- ### Initialize App Mode SDK Source: https://github.com/whopio/developer-documentation/blob/main/sdk/api.mdx Use this to make requests using the app's API key. The key can be set via environment variables or passed manually. ```javascript await WhopAPI.app({apiKey: ""})... ``` -------------------------------- ### Initialize Company Mode SDK Source: https://github.com/whopio/developer-documentation/blob/main/sdk/api.mdx Use this to make requests using the company's API key. The key can be set via environment variables or passed manually. ```javascript await WhopAPI.company({apiKey: ""})... ``` -------------------------------- ### Create Next.js App with npm Source: https://github.com/whopio/developer-documentation/blob/main/apps/create-an-app.mdx Use this command to create a new Next.js application. Follow the prompts to name your app and configure its settings. ```bash npx create-next-app@latest ``` -------------------------------- ### Create Next.js App with pnpm Source: https://github.com/whopio/developer-documentation/blob/main/apps/create-an-app.mdx Use this command to create a new Next.js application. Follow the prompts to name your app and configure its settings. ```bash pnpm create next-app ``` -------------------------------- ### Get messages from a direct message feed (GraphQL) Source: https://github.com/whopio/developer-documentation/blob/main/api-reference/graphql/examples.mdx Use this query to retrieve posts from a direct message feed. Specify the feed ID and the desired number of posts. ```graphql query DmsFeedData($feedId: ID!, $postsLimit: Int!) { dmsFeedData(feedId: $feedId, postsLimit: $postsLimit) { posts { content user { username id } } } } ``` -------------------------------- ### Get User Token from Headers Source: https://github.com/whopio/developer-documentation/blob/main/sdk/fetch-token.mdx Use this function to retrieve the user's Whop token from the request headers. Ensure you pass the `headers` object from your framework (e.g., Next.js). ```typescript import { getToken } from "@whop-apps/sdk"; import { headers } from "next/headers"; export default async function Home() { const token = await getToken({ headers }); } ``` -------------------------------- ### Create Next.js App with TypeScript and Tailwind CSS Source: https://github.com/whopio/developer-documentation/blob/main/what-to-build/web-apps.mdx Use this command to scaffold a new Next.js project with TypeScript and Tailwind CSS. Navigate into the created directory afterwards. ```bash pnpm create next-app my-whop-app --typescript --tailwind --eslint cd my-whop-app ``` -------------------------------- ### Perform Discovery Search using Next.js Apollo Client Source: https://github.com/whopio/developer-documentation/blob/main/api-reference/graphql/examples.mdx Demonstrates how to perform a discovery search using Apollo Client in a Next.js application. Includes setting up the client with authentication headers. ```typescript import { ApolloClient, InMemoryCache, createHttpLink } from "@apollo/client"; import { setContext } from "@apollo/client/link/context"; import { gql } from "@apollo/client"; // Create HTTP link const httpLink = createHttpLink({ uri: "https://api.whop.com/public-graphql", }); // Add auth headers const authLink = setContext((_, { headers }) => { return { headers: { ...headers, authorization: `Bearer YOUR_API_KEY`, "x-on-behalf-of": "user_123", "x-company-id": "biz_123", }, }; }); // Create Apollo Client const client = new ApolloClient({ link: authLink.concat(httpLink), cache: new InMemoryCache(), }); // Example: Discovery Search const DISCOVERY_SEARCH = gql` query DiscoverySearch($query: String!) { discoverySearch(query: $query) { accessPasses { title route headline logo { sourceUrl } } } } `; // Usage client .query({ query: DISCOVERY_SEARCH, variables: { query: "search_term" }, }) .then((result) => console.log(result)); ``` -------------------------------- ### Create Seller Page Directory Structure Source: https://github.com/whopio/developer-documentation/blob/main/apps/seller-page.mdx Use this bash command to create the necessary directory structure and the page.tsx file for your seller page. ```bash mkdir app/seller && mkdir "app/seller/[companyId]" && mkdir "app/seller/[companyId]/[experienceId]" && touch "app/seller/[companyId]/[experienceId]/page.tsx" ``` -------------------------------- ### Setting Up Payment Received Webhook Source: https://github.com/whopio/developer-documentation/blob/main/what-to-build/web-apps.mdx Create an API route to handle incoming webhooks from Whop. This involves initializing a webhook validator with your secret, validating the signature, and processing different event actions like 'payment.succeeded' or 'payment.failed'. Use `waitUntil` for asynchronous handling of events. ```typescript import { waitUntil } from "@vercel/functions"; import { makeWebhookValidator } from "@whop/api"; import type { NextRequest } from "next/server"; // Initialize webhook validator with your webhook secret const validateWebhook = makeWebhookValidator({ webhookSecret: process.env.WHOP_WEBHOOK_SECRET ?? "fallback", }); // Handle webhook events export async function POST(request: NextRequest): Promise { try { // Validate the webhook signature const webhookData = await validateWebhook(request); // Handle different webhook events switch (webhookData.action) { case "payment.succeeded": const { id, final_amount, amount_after_fees, currency, user_id } = webhookData.data; // Process the successful payment waitUntil( handlePaymentSuccess( user_id, final_amount, currency, amount_after_fees ) ); break; case "payment.failed": const { error, user_id: failedUserId } = webhookData.data; waitUntil(handlePaymentFailure(failedUserId, error)); break; // Add more webhook event handlers as needed } return new Response("OK", { status: 200 }); } catch (error) { console.error("Webhook processing failed:", error); return new Response("Webhook validation failed", { status: 400 }); } } // Handle successful payments async function handlePaymentSuccess( userId: string, amount: number, currency: string, amountAfterFees: number ) { try { // Update your database // Grant access to premium features // Send confirmation email // etc. } catch (error) { console.error("Failed to process successful payment:", error); } } // Handle failed payments async function handlePaymentFailure(userId: string, error: any) { try { // Update your database // Notify the user // etc. } catch (error) { console.error("Failed to process payment failure:", error); } } ``` -------------------------------- ### Run Whop Proxy with NPM Source: https://github.com/whopio/developer-documentation/blob/main/sdk/proxy.mdx Execute the Whop Proxy using NPM. Ensure you have configured your package.json with the 'whop-proxy' script. ```bash npm run whop-proxy ``` -------------------------------- ### Display User Information Source: https://github.com/whopio/developer-documentation/blob/main/apps/customer-page.mdx Extract and display the username and email from the fetched user data. This snippet shows how to present a welcome message. ```javascript const { username, email } = user.data; return

Hey {username}, welcome to your new Whop App!

; ``` -------------------------------- ### Configure Whop Integration Environment Variables Source: https://github.com/whopio/developer-documentation/blob/main/what-to-build/web-apps.mdx Set up your .env.local file with essential API credentials and identifiers for your Whop application. Ensure these are kept secure. ```env WHOP_API_KEY=your_api_key_here WHOP_APP_ID=your_app_id_here WHOP_AGENT_USER_ID=your_agent_user_id WHOP_WEBHOOK_SECRET=your_webhook_secret ``` -------------------------------- ### Create Next.js App with Yarn Source: https://github.com/whopio/developer-documentation/blob/main/apps/create-an-app.mdx Use this command to create a new Next.js application. Follow the prompts to name your app and configure its settings. ```bash yarn create next-app ``` -------------------------------- ### Initialize Whop API Client and Token Verifier Source: https://github.com/whopio/developer-documentation/blob/main/what-to-build/web-apps.mdx Set up the Whop API client and a user token verifier in a server-side file. This client is used for making API calls, and the verifier for authenticating requests from the Whop iframe. ```typescript "use server" import { WhopApi, makeUserTokenVerifier } from "@whop/api"; export const whopApi = WhopApi({ appApiKey: process.env.WHOP_API_KEY ?? "fallback", onBehalfOfUserId: process.env.WHOP_AGENT_USER_ID, }); export const verifyUserToken = makeUserTokenVerifier({ appId: process.env.WHOP_APP_ID ?? "fallback", dontThrow: true, }); ``` -------------------------------- ### Handle No Product Access Source: https://github.com/whopio/developer-documentation/blob/main/apps/customer-page.mdx If `hasAccess` returns false, display a message indicating the user does not own the necessary product. ```javascript if (!access) { return (

You do not have access to view this page as you do not own the correct product

); } ``` -------------------------------- ### Run Whop Proxy with PNPM Source: https://github.com/whopio/developer-documentation/blob/main/sdk/proxy.mdx Execute the Whop Proxy using PNPM. ```bash pnpm whop-proxy ``` -------------------------------- ### Create a forum post (GraphQL) Source: https://github.com/whopio/developer-documentation/blob/main/api-reference/graphql/examples.mdx Use this mutation to create a new forum post. You can specify return fields within the input if needed. ```graphql mutation CreateForumPost($input: CreateForumPostInput!) { createForumPost(input: $input) { # You can specify return fields here if needed } } ``` -------------------------------- ### Import hasAccess and headers Source: https://github.com/whopio/developer-documentation/blob/main/sdk/has-access.mdx Import the necessary functions from the SDK and Next.js headers module at the top of your page. ```javascript import { hasAccess } from "@whop-apps/sdk"; import { headers } from "next/headers"; ``` -------------------------------- ### Whop Proxy Configuration Options Source: https://github.com/whopio/developer-documentation/blob/main/sdk/proxy.mdx Command line options for configuring the Whop Proxy. Defaults are provided for port and command execution. ```bash Usage: yarn whop-proxy [options] Options: --proxyPort The port the proxy should listen on (3000 by default) --upstreamPort The port the upstream server is listening on (set automatically by default) --npmCommand The npm command to run to start the upstream server (dev by default) --command The command to run to start the upstream server (npm run dev by default) ``` -------------------------------- ### Check User Product Access with Whop SDK Source: https://github.com/whopio/developer-documentation/blob/main/apps/customer-page.mdx Use the `hasAccess` function to verify if a user owns the required product. Pass the experience ID and request headers. ```javascript const access = await hasAccess({ to: params.experienceId, headers }); ``` -------------------------------- ### Add Whop Sign-in Button Source: https://github.com/whopio/developer-documentation/blob/main/oauth/sign-in-button.mdx Use this link to redirect users to the Whop OAuth portal. Ensure your CLIENT_ID and REDIRECT_URI environment variables are set. ```javascript ``` -------------------------------- ### Configure Dev Proxy Script in package.json Source: https://github.com/whopio/developer-documentation/blob/main/what-to-build/web-apps.mdx Add the 'whop-proxy' script to your package.json to facilitate local development. This script typically runs your Next.js dev server with a custom port. ```json { "scripts": { "dev": "next dev", "whop-proxy": "whop-proxy" } } ``` -------------------------------- ### Next.js Root Layout Source: https://github.com/whopio/developer-documentation/blob/main/sdk/iframe-setup.mdx The root layout must include a client component to ensure the SDK is initialized on the client side. ```tsx import { ClientLayout } from "./layout.client"; export default function RootLayout({ children, }: { children: React.ReactNode, }) { return ( {children} ); } ``` -------------------------------- ### Run Whop Proxy with Yarn Source: https://github.com/whopio/developer-documentation/blob/main/sdk/proxy.mdx Execute the Whop Proxy using Yarn. Ensure you have configured your package.json if using NPM. ```bash yarn whop-proxy ``` -------------------------------- ### Import Whop SDK for Authentication Source: https://github.com/whopio/developer-documentation/blob/main/apps/customer-page.mdx Add these imports to the top of your page to use the Whop SDK for user authentication. ```javascript import { headers } from "next/headers"; import { validateToken } from "@whop-apps/sdk"; ``` -------------------------------- ### Connect to Whop WebSocket for Live DMs Source: https://github.com/whopio/developer-documentation/blob/main/what-to-build/chat-bots.mdx Establishes a WebSocket connection to receive real-time messages from Whop. This code snippet requires the 'websockets' and 'json' libraries. It continuously listens for incoming messages and prints them. ```python import asyncio import websockets import json async def connect_to_websocket(): uri = "wss://ws-prod.whop.com/ws/developer" try: async with websockets.connect(uri, additional_headers=headers) as websocket: print(f"Successfully connected to {uri}") # Keep the connection alive and listen for messages while True: try: message = await websocket.recv() formatted_message = json.loads(message) print(f"Received: {formatted_message}") except websockets.exceptions.ConnectionClosed: print("Connection closed") break except Exception as e: print(f"Failed to connect or error during communication: {e}") if __name__ == "__main__": asyncio.run(connect_to_websocket()) ``` -------------------------------- ### Me Mode Usage with Token Source: https://github.com/whopio/developer-documentation/blob/main/sdk/api.mdx Demonstrates using the Me Mode of the Whop API SDK by manually providing a token to access the /me endpoint and retrieve current user information. ```APIDOC ### Token Usage ```javascript const currentUser = await WhopAPI.me({ token: "" }).GET("/me", {}); ``` ``` -------------------------------- ### Fetch User Information with Access Token Source: https://github.com/whopio/developer-documentation/blob/main/oauth.mdx Use this function to retrieve details about the authenticated user by sending their access token in the Authorization header. Ensure the token is valid and correctly formatted. ```JavaScript import axios from "axios"; const checkAccess = async (accessToken) => { try { const response = await axios.get(`https://api.whop.com/v5/me`, { headers: { Authorization: `Bearer ${accessToken}`, }, }); return response.data; } catch (error) { throw error; } }; export default checkAccess; ``` ```Python import requests def check_access(access_token): headers = { "Authorization": f"Bearer {access_token}" } response = requests.get('https://api.whop.com/v5/me', headers=headers) return response.json() ``` ```Ruby require 'net/http' require 'uri' require 'json' def check_access(access_token) uri = URI.parse("https://api.whop.com/v5/me") request = Net::HTTP::Get.new(uri) request["Authorization"] = "Bearer #{access_token}" req_options = { use_ssl: uri.scheme == "https", } response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http| http.request(request) end JSON.parse(response.body) end ``` -------------------------------- ### Check Product Access with hasAccess Source: https://github.com/whopio/developer-documentation/blob/main/sdk/has-access.mdx Use the hasAccess function with an access string and the headers object to verify if a user owns a specific product. The function returns a boolean indicating access. ```javascript const access = await hasAccess({ to: "prod_XXXX", headers }); ``` -------------------------------- ### Import Whop SDK Functions Source: https://github.com/whopio/developer-documentation/blob/main/apps/customer-page.mdx Import necessary functions from the Whop SDK for token validation, access checks, and API interactions. ```javascript import { validateToken, hasAccess, WhopAPI } from "@whop-apps/sdk"; ``` -------------------------------- ### Me Mode Usage with Headers Source: https://github.com/whopio/developer-documentation/blob/main/sdk/api.mdx Shows how to use the Me Mode of the Whop API SDK with headers to retrieve current user information from the /me endpoint. This mode uses a user's access token. ```APIDOC ## Me Mode When you are using one of the **Me** endpoints, you need to use this mode. This will use a user's access token. This can be retrieved by using the [/token](/api-reference/v5/me/token) endpoint, or if you are building an app, it can be retrieved from the `whop_user_token` cookie. ### Headers Usage ```javascript import { headers } from "next/headers"; const currentUser = await WhopAPI.me({ headers }).GET("/me", {}); ``` ``` -------------------------------- ### Authorization Header Format Source: https://github.com/whopio/developer-documentation/blob/main/api-reference/v5/authentication.mdx All API requests require an `Authorization` header. Use `Bearer {TOKEN}` where `{TOKEN}` is your API key or OAuth access token. ```bash Authorization: Bearer {TOKEN} ``` -------------------------------- ### Handle Unauthorized Access Source: https://github.com/whopio/developer-documentation/blob/main/apps/seller-page.mdx Implement logic to handle cases where the user does not have access to the company. If `access` is false, display an appropriate message to the user. ```javascript if (!access) { return

You do not have access to view this company

; } ``` -------------------------------- ### GraphQL API Headers Source: https://github.com/whopio/developer-documentation/blob/main/instructions/make-a-call.mdx Include these headers to authenticate and target your API requests. Ensure `YOUR_API_KEY` is replaced with your actual App API key, and `user_123` and `biz_123` are replaced with the appropriate User ID and Company ID. ```plaintext Authorization: Bearer YOUR_API_KEY x-on-behalf-of: user_123 x-company-id: biz_123 Content-Type: application/json ``` -------------------------------- ### Charging a User with Whop API Source: https://github.com/whopio/developer-documentation/blob/main/what-to-build/web-apps.mdx Implement a payment processing flow to charge users custom amounts. This function requires payment options including user ID, amount, currency, and optional metadata or redirect URLs. It returns a purchase URL if a checkout session is created, otherwise null. ```typescript // app/lib/payments.ts import { whopApi } from "./whop-api"; export async function chargeUser(options: PaymentOptions): string | null { try { const chargeResult = await whopApi.ChargeUser({ input: { userId: options.userId, amount: options.amount, currency: options.currency, description: options.description, // Show a custom message to the user at checkout. metadata: options.metadata, // pass any Record. This data will be sent in the payment redirectUrl: options.redirectUrl, // optional, redirect the user to a custom url AFTER checkout affiliateCode: options.affiliateCode, // attribute this purchase to a custom username / user_id }, }); if (!chargeResult.chargeUser) { throw Error("Failed to charge user."); } // If we get back a checkout session, we need to return the `purchaseUrl` to the client application. // The client should redirect or open this URL. if (chargeResult.checkoutSession) { return chargeResult.chargeUser.checkoutSession.purchaseUrl; } // Otherwise the checkout processing succeeded, and the payment webhook will be received soon. return null; } catch (error) { console.error("Payment processing failed:", error); throw new Error("Failed to process payment"); } } ``` -------------------------------- ### Generate Company Authorization Access String Source: https://github.com/whopio/developer-documentation/blob/main/sdk/has-access.mdx Use the authorizedUserOn helper function to create the correct access string for checking company authorization. Pass the company ID to the function. ```javascript authorizedUserOn("biz_XXXX"); ``` -------------------------------- ### Request Authorization Token (Python) Source: https://github.com/whopio/developer-documentation/blob/main/oauth.mdx Uses the requests library to POST the authorization code and credentials to the Whop API for an access token. The 'redirect_uri' must match the one registered. ```python import requests def get_auth_token(code, client_id, client_secret, redirect_uri): data = { "code": code, "client_id": client_id, "client_secret": client_secret, "redirect_uri": redirect_uri } response = requests.post('https://api.whop.com/v5/oauth/token', data=data) return response.json() ``` -------------------------------- ### Open External URL in iFrame Source: https://github.com/whopio/developer-documentation/blob/main/sdk/external-url.mdx Use `openExternalUrl` to close the app and navigate to a specified URL. Ensure the iFrame SDK is initialized before use. ```javascript "use client"; import { useCallback } from "react"; import { WhopApp } from "@/lib/iframe"; export default function Home() { const openLink = useCallback(async () => { await WhopApp.openExternalUrl({ url: "https://google.com" }); }, []); return ; } ``` -------------------------------- ### Customize Whop Dev Proxy Behavior Source: https://github.com/whopio/developer-documentation/blob/main/what-to-build/web-apps.mdx Override default proxy settings like ports or the npm command using command-line flags. This allows for more flexible development configurations. ```bash pnpm whop-proxy --proxyPort=3000 --upstreamPort=3001 --command='echo "Hello from the proxy running on $PORT!"' ``` -------------------------------- ### Request Authorization Token (Ruby) Source: https://github.com/whopio/developer-documentation/blob/main/oauth.mdx Employs Net::HTTP to send a POST request with the authorization code and necessary credentials to the Whop API. The response is parsed as JSON. ```ruby require 'net/http' require 'uri' require 'json' def get_auth_token(code, client_id, client_secret, redirect_uri) uri = URI.parse('https://api.whop.com/v5/oauth/token') request = Net::HTTP::Post.new(uri) request.content_type = 'application/json' request.body = { code: code, client_id: client_id, client_secret: client_secret, redirect_uri: redirect_uri }.to_json req_options = { use_ssl: uri.scheme == 'https', } response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http| http.request(request) end JSON.parse(response.body) end ``` -------------------------------- ### Java Placeholder for Whop API Source: https://github.com/whopio/developer-documentation/blob/main/api-reference/graphql/authentication.mdx A placeholder for future Java integration with the Whop API. ```java class HelloWorld { public static void main(String[] args) { System.out.println("Coming soon"); } } ``` -------------------------------- ### Handle Access Denied Message Source: https://github.com/whopio/developer-documentation/blob/main/sdk/has-access.mdx Conditionally render a message to the user if they do not have the required access. This is typically done within a React component. ```javascript if (!access) { return

You do not have access to view this page

; } ``` -------------------------------- ### Python Flask Callback Handler Source: https://github.com/whopio/developer-documentation/blob/main/oauth.mdx A basic Flask route to capture the authorization code from incoming requests. ```python from flask import Flask, request, redirect app = Flask(__name__) @app.route('/callback') def callback(): code = request.args.get('code') ``` -------------------------------- ### Display Experience ID on User Page Source: https://github.com/whopio/developer-documentation/blob/main/apps/customer-page.mdx Add this JavaScript code to your user page file to read and display the experience ID passed as a path parameter. ```javascript export default async function UserPage({ params, }: { params: { experienceId: string }, }) { const experienceId = params.experienceId; return

The ID of the product the user is viewing is {experienceId}

; } ``` -------------------------------- ### Request Authorization Token (JavaScript) Source: https://github.com/whopio/developer-documentation/blob/main/oauth.mdx Uses axios to send a POST request to the Whop API to exchange an authorization code for an access token. Ensure 'clientId', 'clientSecret', and 'redirect_uri' are correctly provided. ```javascript import axios from 'axios'; const getAuthToken = async (code, clientId, clientSecret, redirect_uri) => { try { const response = await axios.post('https://api.whop.com/v5/oauth/token', { code, client_id: clientId, client_secret: clientSecret, redirect_uri: redirect_uri }); return response.data; } catch (error) { throw error; } }; export default getAuthToken; ``` -------------------------------- ### Send Response Back to Whop via GraphQL Source: https://github.com/whopio/developer-documentation/blob/main/what-to-build/chat-bots.mdx Sends a generated response back to a user on Whop using the public GraphQL API. This requires the 'requests' library and the 'headers' dictionary previously defined. Ensure 'feed_id', 'response' are available in the current scope. ```bash pip install requests ``` ```python full_query = """ mutation sendMessage($input: SendMessageInput!) { sendMessage(input: $input) } """ payload = { "query": full_query, "variables": { "input": { "feedId": feed_id, "feedType": "dms_feed", "message": response } }, } response = requests.post( "https://api.whop.com/public-graphql", headers=headers, # use the same headers as before json=payload ) ``` -------------------------------- ### Send chat message (GraphQL) Source: https://github.com/whopio/developer-documentation/blob/main/api-reference/graphql/examples.mdx This mutation is used to send a chat message. It requires a SendMessageInput object containing the necessary details. ```graphql mutation SendMessage($input: SendMessageInput!) { sendMessage(input: $input) } ``` -------------------------------- ### Fetch User Data Source: https://github.com/whopio/developer-documentation/blob/main/apps/customer-page.mdx Use the WhopAPI.me function to retrieve information about the current user. Ensure you have the necessary headers configured. ```javascript const user = await WhopAPI.me({ headers }).GET("/me", {}); ``` -------------------------------- ### Set Request Headers for Whop API Source: https://github.com/whopio/developer-documentation/blob/main/what-to-build/chat-bots.mdx Configure the necessary headers for API requests, including authentication and specifying the user ID for on-behalf-of operations. Ensure your WHOP_APP_API_KEY and WHOP_AGENT_USER_ID are set as environment variables. ```python headers = { "Content-Type": "application/json", "Authorization": f"Bearer {WHOP_APP_API_KEY}", "x-on-behalf-of": WHOP_AGENT_USER_ID } ``` -------------------------------- ### getToken Source: https://github.com/whopio/developer-documentation/blob/main/sdk/fetch-token.mdx Fetch the user's authentication token. This function retrieves the token from the request headers and requires the `headers` object to be passed. ```APIDOC ## getToken ### Description Fetch the user's authentication token. This function retrieves the token from the request headers and requires the `headers` object to be passed. ### Method Function Call ### Parameters #### Arguments - **headers** (object) - Required - The headers object from the request. ### Request Example ```typescript import { getToken } from "@whop-apps/sdk"; import { headers } from "next/headers"; export default async function Home() { const token = await getToken({ headers }); } ``` ### Response #### Success Response - **token** (string) - The user's authentication token. ``` -------------------------------- ### Python Placeholder for Whop API Source: https://github.com/whopio/developer-documentation/blob/main/api-reference/graphql/authentication.mdx A placeholder for future Python integration with the Whop API. ```python print('Coming soon') ``` -------------------------------- ### Generate a Redirect URL Source: https://github.com/whopio/developer-documentation/blob/main/sdk/redirect-url.mdx Use this client component function to generate a URL that redirects users to a specific path within your embedded Whop app. Ensure the iFrame SDK is initialized before calling this function. ```javascript "use client"; import { useCallback, useState } from "react"; import { WhopApp } from "@/lib/iframe"; export default function Home() { const [redirectUrl, setRedirectUrl] = useState(""); const fetchURL = useCallback(async () => { const redirectUrl = await WhopApp.getRedirectUrl({ path: "/relative/path/on/my/domain", }); setRedirectUrl(redirectUrl.url); }, []); return (
{redirectUrl &&

Redirect URL: {redirectUrl}

}
); } ``` -------------------------------- ### Company Mode Usage Source: https://github.com/whopio/developer-documentation/blob/main/sdk/api.mdx Illustrates how to use the Company Mode of the Whop API SDK to fetch user information from the /company/users/{id} endpoint. This mode utilizes the company's API key. ```APIDOC ## Company Mode When you are using one of the **Company** endpoints, you need to use this mode. This will use the company's API key to make requests, which can either be set in the environment variables, as `WHOP_API_KEY`, or passed in manually. ### Usage ```typescript import { WhopAPI } from "@whop-apps/sdk"; export default async function Home() { const userInformation = await WhopAPI.company().GET("/company/users/{id}", { params: { path: { id: "user_XXX" } }, }); } ``` ```