Skip to main content

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​

  1. A buyer starts checkout on a partner or merchant storefront.
  2. An AppDirect access token is obtained using the client credentials grant.
  3. The createHostedCheckoutSession GraphQL mutation is called with the buyer and the items to purchase.
  4. AppDirect returns a hostedCheckoutUrl.
  5. The buyer's browser is redirected to that URL.
  6. The buyer reviews the cart and completes the purchase on AppDirect checkout.
  7. 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:

  1. 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 a purchaseId query 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.
  2. 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.
  3. 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_PARTNER scope. 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.id and user.accountId. Both values are required to create sessions for returning buyers.

Quick checklist​

  1. Enable Hosted Checkout and set both redirection links: one for a successful purchase and one for cancellation or exit.
  2. Set the purchase restriction to All company employees can buy.
  3. Create an API client with ROLE_PARTNER.
  4. Ensure that the products to sell are published with active pricing plans, and retrieve the pricing plan IDs.
  5. Provide an HTTPS return URL for expired or reused checkout links.
  6. Plan to store each buyer's AppDirect user.id and user.accountId for 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.

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:

  1. The buyer starts checkout on the storefront.
  2. The browser sends the checkout request to the application.
  3. An AppDirect access token is obtained.
  4. A Hosted Checkout session is created.
  5. Only the hostedCheckoutUrl is returned to the browser, or an HTTP redirect to that URL is returned.
  6. The browser opens the URL immediately.
  7. 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​

FieldRequiredDescription
returnUrlYesAn HTTPS URL. AppDirect redirects the buyer here when the checkout link has expired or was already used.
currencyYesThe currency code of the marketplace, such as USD.
buyerYesnewBuyer or existingBuyer
buyer.newBuyer.emailYes, for a new buyerThe buyer's email address. It must not already be registered on the marketplace.
buyer.newBuyer.firstNameYes, for a new buyerThe buyer's first name.
buyer.newBuyer.lastNameYes, for a new buyerThe buyer's last name.
buyer.existingBuyer.accountIdYes, for an existing buyerThe buyer's company ID. Use the user.accountId stored from an earlier session.
buyer.existingBuyer.userIdYes, for an existing buyerThe buyer's user ID. Use the user.id stored from an earlier session.
itemsYes1 to 20 items.
items[].pricingPlanIdYesThe AppDirect pricing plan ID of a published product.
items[].quantityNoThe 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.id
  • user.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 have ROLE_PARTNER or 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 buyer field has both or neither of newBuyer and existingBuyer.
  • An item has no pricingPlanId, or quantity is not a whole number of 1 or more.
  • There are no items, or more than 20.
  • The currency is not the currency of the marketplace.
  • The returnUrl is not an allowed URL.
  • The email address of a new buyer is already registered. If that buyer's user.id and user.accountId are stored, use existingBuyer instead.
  • 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.

  1. Create an API client with ROLE_PARTNER on a test marketplace.
  2. Create a session for a new buyer with one pricing plan.
  3. Open the returned hostedCheckoutUrl in a browser within about 30 seconds. Confirm that the cart shows the correct item and quantity.
  4. Add payment details and complete the purchase. Confirm that the success page opens with a purchaseId.
  5. Create a second session with existingBuyer and the stored IDs. Confirm that the saved payment method and addresses appear.
  6. Open an old checkout URL a second time. Confirm that the buyer is redirected to the returnUrl.
  7. Open a new checkout URL and click Continue Shopping. Confirm that the cancellation or exit page opens.
  8. 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 the returnUrl sent in the session. Create a new session and redirect again.

  • Should a new buyer or an existing buyer be used?
    Use newBuyer the first time. Store user.id and user.accountId from the response. Use existingBuyer with those values for every later purchase. Sending an email that is already registered with newBuyer is 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 example USD.

  • How is a successful purchase confirmed?
    After a successful purchase, the buyer lands on the success redirect URL with a purchaseId. 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 GraphQL createHostedCheckoutSession mutation 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?