Hosted Checkout
Hosted Checkout lets partners and merchants that run a headless or custom storefront use AppDirect for cart, billing, and payment without requiring buyers to sign in to the marketplace first.
Use the createHostedCheckoutSession mutation to create a short-lived checkout session. AppDirect returns a checkout URL that can be used to redirect the buyer to an AppDirect-hosted checkout page. After checkout is completed or abandoned, AppDirect redirects the buyer back to the configured return URL.
For an overview of the capability, see the release notes for Introducing Hosted Checkout.
π Note: The checkout GraphQL APIs mentioned in this guide are currently in Preview:
https://marketplace-url/api/graphql/preview
How it worksβ
- A buyer starts checkout on a partner or merchant storefront.
- An AppDirect access token is obtained using the client credentials grant.
- The
createHostedCheckoutSessionGraphQL mutation is called with the buyer and the items to purchase. - AppDirect returns a
hostedCheckoutUrl. - The buyer's browser is redirected to that URL.
- The buyer reviews the cart and completes the purchase on AppDirect checkout.
- AppDirect redirects the buyer to the configured website URL.
Prerequisitesβ
Before you can use Hosted Checkout, ensure that the following prerequisites are in place.
Marketplace settingsβ
Configure the following marketplace settings:
- Hosted Checkout settings (Marketplace settings > Checkout > Hosted Checkout):
- Select Enable Hosted Checkout.
- Set Redirection link on successful purchase to the order confirmation page on the partner or merchant website, for example
https://merchant.example.com/order/confirm. After a successful purchase, AppDirect redirects the buyer to this URL and adds apurchaseIdquery parameter. - Set Redirection link on cancellation or exit to the page where a buyer should land when leaving checkout, for example
https://merchant.example.com/cart. The settings page labels this field optional, but this integration requires it. When a buyer clicks Continue Shopping, AppDirect redirects to this URL. If it is empty, the buyer lands on the marketplace home page. - Click Save.
- Purchase restrictions (Marketplace settings > Purchase Restrictions):
- Set Default Purchase Behavior to All company employees can buy.
- Leave Allow company admins to decide default purchase behavior in their company unchecked if this setting must apply to every company.
- If Only company and billing admins can buy is selected, an existing buyer who is not a company admin or billing admin sees an unauthorized error at checkout.
- Branding (optional): Use Theme Manager to set colors and the logo so the checkout pages match the storefront.
Productsβ
Each item in a session must be a product that is already published on the marketplace, with an active pricing plan. The pricing plan ID is sent for every item. See Find pricing plan IDs.
API accessβ
Ensure that the following API access requirements are in place:
- An AppDirect OAuth client ID and client secret with the
ROLE_PARTNERscope. Create an API client or ask the marketplace operator to create one. See Getting started with Checkout APIs. - The base URL of the marketplace, such as
https://marketplace-url.
Integration requirementsβ
Ensure that the following integration requirements are in place:
- A secure server-side integration that can call AppDirect APIs. Do not call these APIs from browser code.
- An HTTPS return URL. AppDirect redirects the buyer to this URL when the checkout link has expired or was already used.
- Storage for each buyer's AppDirect
user.idanduser.accountId. Both values are required to create sessions for returning buyers.
Quick checklistβ
- Enable Hosted Checkout and set both redirection links: one for a successful purchase and one for cancellation or exit.
- Set the purchase restriction to All company employees can buy.
- Create an API client with
ROLE_PARTNER. - Ensure that the products to sell are published with active pricing plans, and retrieve the pricing plan IDs.
- Provide an HTTPS return URL for expired or reused checkout links.
- Plan to store each buyer's AppDirect
user.idanduser.accountIdfor returning-buyer sessions.
Next steps: Build the API call and redirect described in this guide, then run a test purchase end to end. See Test your integration.
Find pricing plan IDsβ
When you create a Hosted Checkout session, each item must include the pricing plan ID of a published product. Use the AppDirect GraphQL Preview endpoint to retrieve those IDs:
https://marketplace-url/api/graphql/preview
Pass the product's productRefId as the id. The version must be PUBLISHED so that the query returns pricing plans from the published version of the product.
Query:
query productPricingPlans {
product(
id: "3c19a7ab-d256-4c39-b732-63197a707329"
version: "PUBLISHED"
) {
editions {
pricing {
pricingPlans {
id
}
}
}
}
}
Sample output:
{
"data": {
"product": {
"editions": [
{
"pricing": {
"pricingPlans": [
{
"id": "d268fff1-dd2d-40e7-ac6f-b61a5690865a"
}
]
}
}
]
}
}
}
The response includes the pricing plans for each edition of the product. Select the pricing plan for the edition the buyer is purchasing, then send its id as the item's pricingPlanId.
Recommended integrationβ
After the prerequisites are in place and you have the pricing plan IDs, integrate Hosted Checkout using the following server-side pattern. Call the OAuth and Hosted Checkout APIs from a secure server. Do not request access tokens or call the session API from browser code. Doing so would expose the OAuth client secret or access token.
The recommended flow is:
- The buyer starts checkout on the storefront.
- The browser sends the checkout request to the application.
- An AppDirect access token is obtained.
- A Hosted Checkout session is created.
- Only the
hostedCheckoutUrlis returned to the browser, or an HTTP redirect to that URL is returned. - The browser opens the URL immediately.
- AppDirect displays the checkout experience and redirects the buyer back when the purchase is complete.
The checkout URL is short-lived and intended for one buyer and one checkout attempt. Do not store it for later use, reuse it, or expose it in logs.
Authenticate with client credentialsβ
Every Hosted Checkout session request must be authorized. Obtain an access token so that your application can call the session API securely.
Use the OAuth 2.0 client credentials grant to obtain an access token. ROLE_PARTNER is required to create Hosted Checkout sessions.
For detailed steps, see Getting started with Checkout APIs and Client credentials grant.
Send a request to:
https://marketplace-url/oauth2/token
Query parameters:
grant_type:client_credentials
client_id:<client_id>
client_secret:<client_secret>
scope:ROLE_PARTNER
Response:
{
"access_token": "oGbdEBNJ6vKQip5RTQ0mgXGj48kvxjTMWNRPc6r-kRfYig",
"token_type": "bearer",
"expires_in": 43199,
"scope": "ROLE_PARTNER"
}
Keep the access token server-side. Reuse it until it approaches the lifetime reported by expires_in, then request another token.
Include the access token in the header of each Hosted Checkout request:
Authorization: Bearer <access_token>
Content-Type: application/json
Create a sessionβ
After authentication, create a Hosted Checkout session that includes the buyer and the items to purchase.
Use the createHostedCheckoutSession mutation to create a Hosted Checkout session for a new or existing buyer. The buyer type is selected with the buyer field. Send the mutation to the preview GraphQL endpoint:
https://marketplace-url/api/graphql/preview
Mutation:
mutation CreateHostedCheckoutSession($input: CreateHostedCheckoutSessionInput!) {
createHostedCheckoutSession(input: $input) {
session {
cartId
transactionId
hostedCheckoutUrl
expiresOn
user {
id
accountId
}
}
userErrors {
message
path
errorCode
}
}
}
Input fieldsβ
| Field | Required | Description |
|---|---|---|
returnUrl | Yes | An HTTPS URL. AppDirect redirects the buyer here when the checkout link has expired or was already used. |
currency | Yes | The currency code of the marketplace, such as USD. |
buyer | Yes | newBuyer or existingBuyer |
buyer.newBuyer.email | Yes, for a new buyer | The buyer's email address. It must not already be registered on the marketplace. |
buyer.newBuyer.firstName | Yes, for a new buyer | The buyer's first name. |
buyer.newBuyer.lastName | Yes, for a new buyer | The buyer's last name. |
buyer.existingBuyer.accountId | Yes, for an existing buyer | The buyer's company ID. Use the user.accountId stored from an earlier session. |
buyer.existingBuyer.userId | Yes, for an existing buyer | The buyer's user ID. Use the user.id stored from an earlier session. |
items | Yes | 1 to 20 items. |
items[].pricingPlanId | Yes | The AppDirect pricing plan ID of a published product. |
items[].quantity | No | The starting quantity. A whole number of 1 or more. The default is 1. |
Create a session for a new buyerβ
Use this flow for a buyer's first purchase, when the buyer does not yet have an AppDirect user and company. AppDirect creates both as part of session creation.
Sample arguments:
{
"input": {
"returnUrl": "https://merchant.example.com/checkout/return",
"currency": "USD",
"buyer": {
"newBuyer": {
"email": "buyer@example.com",
"firstName": "New",
"lastName": "Buyer"
}
},
"items": [
{
"pricingPlanId": "d268fff1-dd2d-40e7-ac6f-b61a5690865a",
"quantity": 1
}
]
}
}
You can include more than one item. Add one entry to items for each pricing plan:
"items": [
{
"pricingPlanId": "d268fff1-dd2d-40e7-ac6f-b61a5690865a",
"quantity": 1
},
{
"pricingPlanId": "ae1acd7c-e161-4dc1-8b35-1865138874ce",
"quantity": 2
}
]
Session responseβ
A successful session response includes the hostedCheckoutUrl, expiresOn, and buyer identifiers.
Sample output:
{
"data": {
"createHostedCheckoutSession": {
"session": {
"cartId": "643d307d312f6e1ffbb17efd",
"transactionId": "25f7dcee-325c-40f9-98ee-019b7d4bc985",
"hostedCheckoutUrl": "https://marketplace-url/hostedcheckout/25f7dcee-325c-40f9-98ee-019b7d4bc985?token=TOKEN",
"expiresOn": "2026-10-22T12:01:39Z",
"user": {
"id": "95cce1ea-37fb-431d-9f5a-7df387b7e8e4",
"accountId": "9faf88c2-9e58-4f5b-a009-5dc9094fe2a0"
}
},
"userErrors": []
}
}
}
Treat the hostedCheckoutUrl as opaque. Do not change its path or query parameters.
expiresOn indicates when the short-lived checkout URL expires. Open the URL immediately after the session is created.
Store the buyer identifiersβ
To support returning buyers, persist the AppDirect user and company identifiers returned in the session response. After a session is created for a new buyer, store the following values with the customer record:
user.iduser.accountId
Both values are required to create sessions for this buyer on later purchases.
Do not use cartId, transactionId, hostedCheckoutUrl, or expiresOn as permanent customer identifiers. They belong only to that checkout attempt.
Create a session for an existing buyerβ
For later purchases, create a session with the stored buyer identifiers so AppDirect can reuse the existing user and company. Use the stored IDs in buyer.existingBuyer.
Sample arguments:
{
"input": {
"returnUrl": "https://merchant.example.com/checkout/return",
"currency": "USD",
"buyer": {
"existingBuyer": {
"accountId": "9faf88c2-9e58-4f5b-a009-5dc9094fe2a0",
"userId": "95cce1ea-37fb-431d-9f5a-7df387b7e8e4"
}
},
"items": [
{
"pricingPlanId": "d268fff1-dd2d-40e7-ac6f-b61a5690865a",
"quantity": 1
}
]
}
}
The user must belong to the company specified in accountId. Otherwise, AppDirect rejects the request.
Creating a new session for a buyer replaces that buyer's previous Hosted Checkout cart. It does not change the buyer's regular marketplace cart.
Redirect the buyerβ
After the session is created, redirect the buyer's browser to the hostedCheckoutUrl before it expires.
Server redirectβ
The checkout-start endpoint can return an HTTP redirect:
HTTP/1.1 302 Found
Location: <hostedCheckoutUrl>
Browser redirectβ
If the checkout URL is returned as JSON, expose only that URL to browser code:
window.location.assign(response.hostedCheckoutUrl);
Do not send the OAuth access token, client ID, or client secret to the browser.
What the buyer seesβ
After the redirect, the buyer completes checkout on the AppDirect-hosted page. The following points describe the buyer experience:
- The buyer lands on the checkout cart page without signing in. The cart shows the items and quantities included in the session.
- The buyer can change the quantity of an item or remove it before paying.
- A new buyer adds a payment method, and billing and shipping details, before completing the purchase. For a physical product, the shipping address form starts empty.
- An existing buyer sees the saved payment method and addresses.
- The buyer pays on the AppDirect checkout page. Payment details are not handled by the partner or merchant website.
- The checkout pages use the marketplace theme and logo.
Handle the return to the applicationβ
When checkout finishes, is abandoned, or the checkout link can no longer be used, AppDirect redirects the buyer back to your application. Handle that return so you can show the right page and confirm purchase status.
After a successful purchase, AppDirect redirects the buyer to the Redirection link on successful purchase from the Hosted Checkout settings and adds the purchase identifier:
https://merchant.example.com/order/confirm?purchaseId=25f7dcee-325c-40f9-98ee-019b7d4bc985
If the checkout link has expired or was already used, AppDirect redirects the buyer to the returnUrl sent when the session was created.
If the buyer clicks Continue Shopping in checkout, AppDirect redirects the buyer to the Redirection link on cancellation or exit from the Hosted Checkout settings.
Treat the browser return as a navigation event, not as authoritative proof that a purchase succeeded.
When the buyer returns:
- Show an appropriate confirmation or status page.
- Use the existing AppDirect integration or event processing to confirm the final purchase status.
- Avoid putting secrets or sensitive customer data in the return URL.
Error handlingβ
Session creation can fail because of authentication problems or invalid input. Handle these errors in your application so that failed checkout attempts can be corrected or retried.
In addition to the common errors that result from requests with invalid data or headers, this mutation can also result in specific user errors when there is a failure in one of the business rules.
HTTP errors:
401 Unauthorized: The access token is missing, invalid, or expired.403 Forbidden: The OAuth client does not haveROLE_PARTNERor is not allowed to access the marketplace.
Validation errors: The request can still return HTTP 200 when validation fails. In that case, session is null and the userErrors array describes the problem. Each error includes a message, the path of the affected field, and an errorCode. Common causes include:
- A required field is missing or has an invalid value.
- The
buyerfield has both or neither ofnewBuyerandexistingBuyer. - An item has no
pricingPlanId, orquantityis not a whole number of 1 or more. - There are no items, or more than 20.
- The
currencyis not the currency of the marketplace. - The
returnUrlis not an allowed URL. - The email address of a new buyer is already registered. If that buyer's
user.idanduser.accountIdare stored, useexistingBuyerinstead. - The user does not belong to the company in
existingBuyer.
Log the errorCode and path with the request ID. Do not log access tokens or complete checkout URLs.
If a checkout URL expires or was already used, create a new session. Do not retry the old URL.
For more information on common GraphQL errors, refer to the section on general GraphQL Error handling.
Test your integrationβ
Before you go live, verify the full Hosted Checkout flow for new and returning buyers, including success, expired-link, and cancellation paths.
- Create an API client with
ROLE_PARTNERon a test marketplace. - Create a session for a new buyer with one pricing plan.
- Open the returned
hostedCheckoutUrlin a browser within about 30 seconds. Confirm that the cart shows the correct item and quantity. - Add payment details and complete the purchase. Confirm that the success page opens with a
purchaseId. - Create a second session with
existingBuyerand the stored IDs. Confirm that the saved payment method and addresses appear. - Open an old checkout URL a second time. Confirm that the buyer is redirected to the
returnUrl. - Open a new checkout URL and click Continue Shopping. Confirm that the cancellation or exit page opens.
- Confirm that the regular marketplace cart for the same buyer is unchanged.
Security recommendationsβ
Hosted Checkout depends on short-lived checkout URLs and server-side credentials. Follow these recommendations to protect tokens, checkout links, and buyer data:
- Keep the OAuth client secret and access token server-side.
- Use HTTPS for API calls, browser redirects, and return URLs.
- Redirect to the returned checkout URL immediately.
- Treat the checkout URL as sensitive because it contains a short-lived token.
- Do not log access tokens or complete checkout URLs.
- Validate that redirect URLs returned to the browser use the expected AppDirect marketplace host.
- Store AppDirect user and company IDs with the customer record for future checkouts.
FAQβ
The following questions and answers cover common Hosted Checkout integration scenarios.
-
Does the buyer need an AppDirect account or to sign in?
No. The checkout link signs the buyer in for that checkout only. For a new buyer, AppDirect creates the user and company when the session is created. -
How long is the checkout link valid?
About 30 seconds, and it works once. Create the session when the buyer starts checkout and redirect immediately. -
What happens if the link expires or the buyer opens it twice?
AppDirect redirects the buyer to thereturnUrlsent in the session. Create a new session and redirect again. -
Should a new buyer or an existing buyer be used?
UsenewBuyerthe first time. Storeuser.idanduser.accountIdfrom the response. UseexistingBuyerwith those values for every later purchase. Sending an email that is already registered withnewBuyeris rejected. -
Does a new session change the buyer's marketplace cart?
No. A Hosted Checkout cart is separate from the regular marketplace cart. A new session replaces only the buyer's previous Hosted Checkout cart. -
Can products that are not in the AppDirect catalog be sold?
Not yet. Each item must use the pricing plan ID of a published product on the marketplace. -
Can several items be sent?
Yes, 1 to 20 items per session. Each item can have its own quantity. -
Can the buyer change the quantity or remove an item?
Yes. The quantity sent in the session is the starting value. -
Which currency should be sent?
The currency of the marketplace, for exampleUSD. -
How is a successful purchase confirmed?
After a successful purchase, the buyer lands on the success redirect URL with apurchaseId. Confirm the final status through the existing AppDirect integration or event processing before fulfilling the order. -
The buyer lands on the site but there is no
purchaseId. Why?
Confirm that Enable Hosted Checkout is selected and that Redirection link on successful purchase is set in the Hosted Checkout settings. If several teams share a marketplace, confirm that the success URL was not changed. If the issue continues, contact your AppDirect technical representative. -
The buyer sees an unauthorized error at checkout. Why?
The marketplace is set to Only company and billing admins can buy, and the buyer is not an admin. Change Default Purchase Behavior to All company employees can buy in Purchase Restrictions. -
Is there a way for the buyer to cancel and return to the site?
Yes. Set Redirection link on cancellation or exit in the Hosted Checkout settings. When the buyer clicks Continue Shopping, AppDirect redirects to that URL. The checkout page has no separate cancel button, so Continue Shopping is how a buyer leaves checkout. If the link is empty, the buyer lands on the marketplace home page. -
The buyer clicks Continue Shopping and lands on the marketplace home page instead of the site. Why?
Redirection link on cancellation or exit is empty in the Hosted Checkout settings. Set it and save. If several teams share a marketplace, confirm that the link was not changed or cleared. -
Can checkout match the storefront brand?
Yes. Use Theme Manager in Marketplace Manager to set colors and the logo. -
Does the website handle card details?
No. The buyer enters payment details on the AppDirect checkout page. -
What has changed from the earlier REST session endpoints?
The GraphQLcreateHostedCheckoutSessionmutation replaces them. Use it for all new integrations.
Demo for Hosted Checkoutβ
Use the following demo storefront and videos to see Hosted Checkout in action from a merchant perspective before you build your own integration.
A demo storefront is available at https://web-production-7eeda.up.railway.app/sessions.
The following videos show the journey first for a new buyer and then for a returning buyer.
New buyer
Returning buyer
Referencesβ
Was this page helpful?
Tell us moreβ¦
Help us improve our content. Responses are anonymous.
Thanks
We appreciate your feedback!