Build your checkout page
As well as consumer and business-facing apps, you can also create ones that get displayed during the checkout process. When the user goes to checkout a product, they can be shown the app beforehand. This can be used to collect additional information about the user, check they are eligible for the product, or display a message.
Examples
- Form Collection App
- NFT Gating App
- Calendar Booking App
What you’ll learn
In this tutorial, you’ll learn how to do the following tasks:
- Enable the checkout page on specific products
- Build a page that is shown before the checkout page.
- Use the iFrame SDK to communicate with the checkout page.
- Prevent or allow the user to continue to the billing section.
Prerequisites
- To view the checkout iFrame, you need to have added the app to a product. From here you can simulate going through the checkout process.
- You will need to have set up the iFrame SDK
1. Add your app to a product
You will need to specify which products you want your app to be added to, this is only for checkout apps.
To do this, you will either need to use the SDK or a standard HTTP request.
In this example, we will use the SDK.
await WhopAPI.app().POST("/app/app_connections", {
body: {
resource_id: "prod_XXX",
resource_type: "product",
view_type: "customer_before_checkout_view",
},
});
You need to pass in the productId
that you want to add the app to.
2. Create your checkout page
We will start by creating the checkout page.
The checkout page will be displayed to customers before they reach the billing section. They will need to perform any actions required by the app before they can continue to the billing section, where they will be able to complete their purchase
- Create a page to match this URL
checkout/$companyId/$checkoutSessionId
. To do this, create this file:app/checkout/[companyId]/[checkoutSessionId]/page.tsx
.
mkdir app/checkout && mkdir "app/checkout/[companyId]" && mkdir "app/checkout/[companyId]/[checkoutSessionId]" && touch "app/checkout/[companyId]/[checkoutSessionId]/page.tsx"
To know which company the app belongs to, Whop will pass the ID as a path parameter. These are defined in the URL of the app settings page, which we will do later.
These are all the options that you can use for the Checkout Page, but for now, we will only use companyId
and checkoutSessionId
.
Parameter | Description |
---|---|
companyId | The ID of the company |
checkoutSessionId | The ID of the checkout session |
productId | The ID of the product |
planId | The ID of the plan |
- Add the following code to the
page.tsx
file, it will read and display thecompanyId
andcheckoutSessionId
path parameters.
export default async function CheckoutView({
params,
}: {
params: { companyId: string, checkoutSessionId: string },
}) {
const companyId = params.companyId;
const checkoutSessionId = params.checkoutSessionId;
return (
<div>
<p>The company ID is: {companyId}</p>
<p>The checkout session ID is: {checkoutSessionId}</p>
</div>
);
}
- Update the Checkout Path in your app configuration to be
/checkout/$companyId/$checkoutSessionId
.

3. Authenticate the session
To ensure that the checkout session is valid, we will need to authenticate it.
- Add two imports to the top of your page
import { validateCheckoutSession } from "@whop-apps/sdk";
import { headers } from "next/headers";
- Use the
validateCheckoutSession
function from the Whop SDK to obtain the user’s ID.
const { userId } = await validateCheckoutSession({
headers,
checkoutSessionId: params.checkoutSessionId,
});
userId
may be undefined if the user is not logged in.4. Setup the iFrame SDK
For the app to know when the user has tried to continue to the billing section, we will need to use the iFrame SDK to setup Post Messages.
If you are using our Next.js template, this will be already setup.
If you are not, follow this guide to setup the iFrame SDK.
Once completed, head to the lib/iframe.ts
file and add the following code:
import { createAppIframeSDK } from "@whop-apps/sdk";
export const WhopApp = createAppIframeSDK({
onMessage: {
onCheckoutRequirementComplete: async (data) => {
const { checkoutSessionId, planId, productId, companyId } = data;
return {
shouldContinue: false,
error: "This is an error message",
};
},
},
});
This will set up the SDK to list for the onCheckoutRequirementComplete
message. We can then either allow the user to continue to the billing section or display an error message and prevent them from continuing.
- Setting
shouldContinue
totrue
will allow the user to continue to the billing section. - Setting
shouldContinue
tofalse
will prevent the user from continuing to the billing section. You can also make use of theerror
value to display an error message to the user. This will be in the form of a Toast.
Next steps
- Deploy your app to production
Was this page helpful?