docs
  1. SCAYLE Resource Center
  2. Developer Guides
  3. Checkout
  4. Integrate Checkout

Integrate Checkout

Follow these steps to start your checkout integration:

  1. Access to the SCAYLE Panel
  2. Shop Data & Configuration
  3. Shop backend middleware layer
  4. Auth Service integration
  5. Baskets
  6. Endpoint URLs
  7. CORS Settings.

Refer to the Checkout integration for mobile app for details on how to set up Checkout on mobile devices.

Access to the SCAYLE Panel

To start integrating the Checkout, ensure you have access to your SCAYLE Panel in the desired environment, to get a valid shop ID (same as appId).

A SCAYLE Account Manager must activate your Checkout. You can access Checkout on a test environment and on public/internal domains where the shop is hosted (see Endpoint URLs).

Depending on your setup, we need to add the IP addresses of selected users involved in migration to our allow-list. Alternatively, we can add your company VPN to an allowed network. Please contact your SCAYLE Account Manager and provide the IP addresses that require access.

For most Checkout interactions, you'll need appId parameter (same as shopId)

Get shop ID in the SCAYLE Panel

  1. Go to Shops and select your shop.

Shop ID in the SCAYLE Panel

Shop Data & Configuration

Before the checkout systems can be used, you need to have shops and products in your environment. For further information, see the getting started guide.

For most Checkout interactions, you'll need:

  • appId parameter (same as shopId)

To sign tokens, you'll need:

  • shopToken and shopSecret

Never expose shop tokens/secrets via frontend code, git repositories, or other public places that may pose a security risk.

You can customize Checkout for your shops via the SCAYLE Panel. For details, see the Checkout Settings section of the User Guide or follow the Configuration & Customization section of this guide.

Checkout settings in the SCAYLE Panel

Shop backend middleware layer

Before integrating the Checkout in your shop frontend, you'll need to add a backend middleware layer within the same origin as your shop. This middleware should then handle all interactions with the Checkout APIs, validate signatures with the shopSecret, etc.

  • To avoid CORS issues it's recommended that the middleware (e.g. /api/checkout/ ) is served from the same domain as the main shop.
  • When using multiple shops, e.g. for different locales, keep in mind that you have to either pass the information (shopId) via API or deploy a shop-specific middleware instance which is aware of the config.
  • Never expose secrets or access tokens to your frontend

Auth Service integration

Make sure to have your integration with our Authentication API ready, because you will need to authenticate Customers and pass the accessToken later to the checkout Webcomponent.

Refer to the Checkout Authentication API reference for further insights.

Baskets

To proceed with the Checkout integration, you need to have a basket integrated.

Endpoint URLs

Below, we provide the URL to load our frontend JavaScript bundle for the Checkout. For backend-to-backend server requests, you will use a dedicated API hostname.

Frontend Bundle URL

https://{{tenant-space}}.checkout.api.scayle.cloud/frontend/checkout-wc/js?appId={{shop}}

API URL: https://{{tenant-space}}.checkout.api.scayle.cloud

Your SCAYLE Account Manager will provide you with the exact hostnames for your environments. How to use these is described in the corresponding sections of this manual.

CORS Settings

In order to allow requests from the embedded Webcomponent to the Checkout API, your shop hostnames will need to be added to the list of allowed CORS hosts.

See hosts configuration for more detailed information.

Frontend / Webcomponent

How to integrate the Checkout Webcomponent into your shop frontend

Loading the JavaScript bundle

Begin by either creating a static page or modifying the existing start page of your shop application. Then, insert the following JavaScript snippet into the head element to load the Checkout bundle.

<script
  src="https://${tenant-space}.checkout.api.scayle.cloud/frontend/checkout-wc/js?appId=${shopId}"
  defer
></script>

This script registers the Webcomponent with the browser and loads necessary assets (CSS, images).

Initialize the Webcomponent

To initialize and display the Webcomponent, add the <scayle-checkout> tag at a desired place where the content needs to appear. Any additional element like a header or footer must be defined in the root document.

Example code how to set up the Webcomponent:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <title>Your shop title</title>
  <script
    src="https://${tenant-space}.checkout.api.scayle.cloud/frontend/checkout-wc/js?appId=${shopId}"
    defer>
  </script>
</head>
<body>
<div id="header">...</div>
...
<scayle-checkout jwt="${jwt}" access-token="${accessToken}" origin="web" header-element="#header"></scayle-checkout>
...
</body>
</html>

Attributes

jwtContains basketId, etc. as encoded and signed parameter. Find out how to generate the token here. More details about the JWT .required
access-tokenThe access token you receive after successful user authentication. Find out how to generate the token here.required
originDefines where the user is coming from, can be app or web. Passing the correct value is mandatory, otherwise users might encounter problems with e.g. payment processing.required
header-elementCSS selector pointing to the header element of the site (e.g. #header), used to display Checkout notifications with the correct top offset (under the header)required
has-cookie-consentContains the value of the user's cookie consent. Only enabled when the value resolves to 'true'. It unlocks in-depth error tracking, A/B testing, etc. We strongly recommend adding it to the Webcomponent and passing in the correct cookie consent value.required

All these attributes need to be set on the Webcomponent from the very start. If you mount the component first and then set e.g. the basket-id attribute afterward, it will not be considered and not work correctly.

JWT attribute

To ensure integrity, you need to provide the jwt attribute containing an encoded JSON payload. The value of the jwt attribute has to be a common JWT (JSON web token) string. The payload of the JWT contains the properties likes basketId to initialize the checkout. The JWT is then signed with the shopSecret. Find the example here.

NameDescriptionType
issIdentifies the principal that issued the token. It is typically a unique identifier or URL of the service responsible for generating the token. The recipient of the token can use this field to verify the authenticity of the issuer. See example.optional
audIntended recipients of the token. It is used to ensure that the token is only accepted by the services or users that are authorized. The value is typically a unique identifier or URI representing the audience. See example.optional
iatissued at / current unix timestamprequired
nbfnot-valid-before unix timestampoptional
expexpiry unix timestamprequired
basketIdsets the current basket id of the active sessionrequired
rBasketIdsalted hash of basketId for rate-limiting purposesoptional
customDatasets order-level custom data, must be a JSON stringoptional
carriersets preferred carrier group. See docsoptional
campaignKeyset an active campaign, so that corresponding price-reductions are displayed in the checkout cartoptional
preferredCollectionPointsets preferred collection point data as objectoptional
preferredCollectionPoint.idcollection point idoptional
preferredCollectionPoint.typecollection point type. e.g. dhl_packstationoptional
vouchersets an pre-applied voucher codeoptional

If you require a more advanced configuration of your JWT parameters, please view the documentation.

Tracking

Tracking events will be sent to the same Google Tag Manager (GTM) instance as the frontend application and the events will be attached to the same data layer object (window.dataLayer).

This section is important for the customers hosting their own storefront. For all other clients, this step is done by SCAYLE.

Your shop frontend is responsible for implementing the connection with the GTM (Google Tag Manager) and the corresponding data layer. It's crucial to ensure the correct data layer setup. To achieve this, insert the given code segment at the top of the page, just before initializing the checkout.

<script>
  window.dataLayer = window.dataLayer || [];
</script>

Add the following into your code to forwarding the events:

import { find } from 'lodash-es';

window.addEventListener('message', function receiveMessage(message) {
  const event = message.data.event;
  // avoid duplicate tracking of events
  if (message.data.type === 'tracking' && !find(window.dataLayer, event)) {
    // forward CHECKOUT tracking events to GTM
    window.dataLayer.push(event);
  }
}, false);

For more details and available events see the tracking overview.

Loading Indicator

You can optionally improve the UX for customers with slow internet connection by implementing a custom loading indication on the page that renders the checkout application, within the <body> tag.

We do not provide a custom loading animation, so it's up to you to design the loading-indicator. Below we only show how a sample implementation could look like.

Example HTML Code:

<!DOCTYPE html>
<html>
 <head>
  <!--  all the resources your checkout rendering page needs -->
 </head>
 <body>
  <header id="sampleHeader"> <!-- A header id we pass to the 'header' attribute of scayle-checkout with # sign, in order to properly position notifications and modals -->
   <a href="#">Sample link</a>
  </header>
  <div class="sample-checkout-wrapper"> <!--Just an example container -->
   <!-- Your custom loading animation goes here -->
   <div class="loading-indicator" id="loading-indicator">...</div> <!-- Your custom loading indicator, you may want to add some css to showcase some animations -->
    <!-- Your custom loading animation ends here -->
   <scayle-checkout jwt="${jwt}" origin="web" header="#sampleHeader" style="display: none;"></scayle-checkout>
 </div>
 </body>
</html>

Example JS Code

The code below does two things:

  1. It listens for the load event emitted by the checkout application upon successful initialization, while also monitoring for the error event in case anything goes wrong during app bootstrap.
  2. It sets the display CSS property of both <scayle-checkout> and #loading-indicator elements to show the checkout and hide custom loading indicator.

The script below can be added at the bottom of your body tag:

<!DOCTYPE html>
<html>
 <head>
 
 </head>
 <body>
   <!--- All the HTHL described above, <scayle-checkout>, loading-indicator etc -->
   
   <!--- Start of the script -->
   <script>
    const loadingIndicator = document.getElementById('loading-indicator');
    const checkoutWebComponent = document.getElementsByTagName('scayle-checkout')[0];
    const onLoad = () => {
      loadingIndicator.style.display = 'none';
      checkoutWebComponent.style.display = 'block';
    };
    checkoutWebComponent.addEventListener('load', onLoad);
    checkoutWebComponent.addEventListener('error', () => {
      console.error('Checkout web  component is experiencing difficulties...');
      onLoad();
    });
   </script>
   <!--- End of the script -->
 </body>
</html>

Webcomponent methods

The Checkout Webcomponent provides a method to update the used basket ID (string) via setBasketId:

const checkoutWebComponent = document.getElementsByTagName('scayle-checkout')[0];
// Update the basket ID of the current Webcomponent instance
checkoutWebComponent.setBasketId('${newBasketId}');

Webcomponent events

The Checkout Webcomponent can notify the parent shop frontend about specific events or user actions. Your application can subscribe to these events by adding a listener, as shown in the below example:

const checkoutWebComponent = document.getElementsByTagName('scayle-checkout')[0];

checkoutWebComponent.addEventListener('authenticate', e => {
  // evt.detail property contains payload data
  // Use it to provide feedback to users, update app state
...
});

The event listener needs to be added within the page where you load your Checkout bundle.

You can find the event details in the table below. The list of event types may be extended in the future.

Event NameDescriptionTrigger
loadCheckout has loaded all data for initial render; use this if you want to show your own loading indicator until the component is readyCheckout has loaded all data for initial render
errorCheckout has loaded all data for initial render, but there was an unrecoverable issue. An error state will be rendered by the Webcomponent. The load event will not be triggered in this caseCheckout has loaded all data for initial render, but there was an unrecoverable error
intentConfirmationCustomer has made the decision to buy / intents to confirm the orderCustomer clicks the "Pay Now" button
authenticateDeprecated This event is fired to inform the shop frontend that a user has logged in or registered during checkoutUser logs in or signs up via Checkout

The authenticate event is deprecated, we encourage you to use the token-based authentication approach.

Order Success Page

Order Success Page (OSP) is the last step in the process of the purchase. When an order is completed, the customer reaches the Order Success Page with the order details if the cbd token is valid.

By default the OSP is valid for 3 minutes after completing the checkout process. After expiration of time the OSP will display an error which will also prevent any further purchase events.

See Order hierarchy and states for details on how to handle orders.

Order Success Page (OSP) flow

Retrieve order from the Checkout to render the Order Success Page

  1. After an order is placed, the Checkout Frontend calls the configured OSP Page in the frontend and attaches the cbd token.
  2. Once the shop received and validated the cbd token, it can use the AdminApi getOrder endpoint to fetch all data and render an overview page for the customer.
  3. The function first checks, if the GET parameter cbd is provided.
    If not, an exception is thrown and the process stops.
  4. The signature of the CBD token is validated:
    For the validation the FE Backend needs to know the so called secret. By using the secret the Frontend Backend can compare the delivered signature in the CBD with the generated one. If they match it is valid, if not, an exception is thrown.
  5. If the validation of the token passed successfully, the orderID, which was provided in the first part of the cbd is used, to retrieve the order information from checkout.
    The order information are returned in the end to the Frontend.
  6. Based on the retrieved order information, the purchase event on the OSP Page is enriched and pushed to the data layer.

OSP structure

The shop frontend needs to have an Order Success Page (OSP) in place.
Defaults to /order/success but can be changed.\

Check Routes configuration for details how to update default routes.

When the user enters the Checkout (e.g. /checkout ) to make a payment and successfully places the order, they will be redirected to the order success page with a cbd token attached as query parameter to the URL (https://<shopName.domain>/order/success?cbd=<base64EncodedToken>).

Example/default
Checkout/checkout
Order Success Page (OSP)/order/success
Example URLhttps://<shopName.domain>/order/success?cbd=<base64EncodedToken>

cbd token

The cbd token is generated after completing the checkout process.

Before the shop renders the OSP page, it should decode the cbd token on its backend and validate that the given signature is correct.

  • If the cbd token is invalid, then the shop shouldn't display user data, but instead redirect to a 404 error page or show a relevant message on the OSP for this case.
  • If the cbd token is valid, the shop can proceed, parse the payload and use the included information to render the page.

The Frontend Backend needs authorization to Checkout API and know the Secret which is used to encrypt the CBD.

The CBD token is provided by Checkout and consists of two parts separated by .

The cbd token is encoded in base64 needs to be split into two parts according to its format:
${payload}.${signature}.

Example cbd token in encoded format

eyJzdGF0dXMiOiJvcmRlcl9jcmVhdGVkIiwiY2FsbGJhY2tfdHlwZSI6ImNoZWNrb3V0X2ZpbmlzaCIsIm9yZGVyX2lkIjo5NjMwMzgxOCwiY3VzdG9tZXJfaWQiOjUyMTk2LCJjdXN0b21lcl9uYW1lIjoiVGVzdGJlc3RlbGx1bmciLCJjdXN0b21lcl9zYWx1dGF0aW9uIjoibSIsImlzc3VlZF9hdCI6MTYxNTI3NzM3N30%3D.MTBjMmI1ZTcyMGViNDRjZjFlYzg1NmFmNWY2MzdmNDkwYzljYjMwYTViZmVmYTcwODU4ODQ0Y2ZiNDYwM2M2MA%3D%3D&pmm=b2b

Example decoded payload:

{
  "status": "order_created",
  "callback_type": "checkout_finish",
  "order_id": 123456789,
  "customer_id": 987654321,
  "customer_name": "firstName",
  "customer_salutation": "m",
  "issued_at": 585439200
}

To verify the signature you need to generate a hash (sha256) of the $payload with the shopSecret.

Learn more about decoding and verifying the cbd token.

Customer account area

SCAYLE gives you the flexibility to build the account area according to your requirements.

Depending on your needs you can combine different APIs by e.g. fetching an orderId from the Customer Account API and using the same id to fetch the full order via the Admin API.

In the account area, customers can manage their personal, payment and order details.

Use Customer Account API endpoints to:

Access Customer profile via Checkout Authentication API

You need to have a valid accessToken for the current user to load the customer profile.
See the Authentication API guide for detailed information.

To use the /api/oauth/me endpoint within your shop backend integration, the accessToken must be used as Authorization bearer token for calls to the Checkout API.

curl --location --request GET 'https://{{tenant-space}}.checkout.api.scayle.cloud/api/oauth/me' \
  --header 'Content-Type: application/json' \
  --header 'X-Shop-Id: {{shopId}}' \
  --header 'Authorization: Bearer {{accessToken}}'

Display a list of past orders

To display a list of past orders, you need to fetch the /api/oauth/me endpoint as well and parse the orderSummary property of the response. For each order in that list you can then use one of the availableAPI endpoints to fetch the order details:

  • Admin API - using the application access token
  • Customer Account API - using the Authentication API access token, scoped to the current customer

Change Password

Within the account section, it's typical to include a "change password" feature. To implement the Account API endpoint, set up a form that prompts users for their current and new passwords.

Check Password reset.

Use Checkout Authentication API endpoints to: