Loyalty Integration Guide
Introduction
Loyalty features in the checkout process are essential for customer retention. By rewarding repeat purchases, they make the experience more personal and enhance customer satisfaction, encouraging long-term loyalty.
SCAYLE supports several loyalty-related features within the checkout, allowing customers to:
- Register for the loyalty program.
- Attach an existing loyalty card number to their profile.
- Earn loyalty points on their purchases.
- Pay for orders using loyalty points.
These features are designed to work with external loyalty systems. The SCAYLE Checkout sends generic API requests to a custom loyalty adapter, which then connects to your specific loyalty provider.
This guide walks you through integrating an external loyalty system with the SCAYLE Checkout, outlining the required API endpoints, SCAYLE Panel configurations, and the resulting customer experience.
Reference Architecture
SCAYLE's loyalty features are designed to work with various external loyalty systems. However, the SCAYLE Checkout does not support direct, native integration with specific loyalty providers. For this reason, a custom adapter, often referred to as loyalty middleware, is required. This adapter receives generic requests from the SCAYLE Checkout and translates them into the specific format required by your loyalty provider.
The middleware must implement a specific set of API endpoints to handle customer actions. These endpoints are modular; you only need to implement those required for the specific actions you wish to support, such as registration at checkout or paying with loyalty points. For the specification of each possible endpoint, see Requirements for the Custom Adapter.
Requirements for the Custom Adapter
This section outlines the API contract that your loyalty middleware must fulfill. The implementation is modular; you only need to develop the endpoints for the features you intend to support. For example, if you do not want to offer loyalty program registration during checkout, you do not need to implement the Registration endpoint.
Overview of API Endpoints
| Type | Endpoint | Purpose |
|---|---|---|
| POST | Registration | Allows new customers to sign up for the loyalty program during checkout. |
| POST | Validation | Verifies a customer's loyalty card number and retrieves their current balance. |
| GET | Conversion rate | Calculates the monetary value of loyalty points when used as a payment method. |
| PUT | Capture | Finalizes the deduction of loyalty points once an order is successfully placed. |
| POST | Refund | Returns loyalty points to a customer if an order is cancelled or fails post-payment before the order delegation. |
Specification of Endpoints
Endpoint Naming
The specific URL paths for your endpoints are entirely flexible. You configure the full URL for each implemented endpoint in the SCAYLE Panel. For setup details, see Configure Endpoints in the SCAYLE Panel.
Authentication
Every request sent by the SCAYLE Checkout includes an Authorization header, which you configure in the SCAYLE Panel. For setup details, see Configure Endpoints in the SCAYLE Panel. To ensure the security of user data, properly manage and rotate Bearer tokens.
Registration Endpoint
Description
This endpoint is called when a customer signs up for the loyalty program directly within the checkout process. Implementing this feature is optional. While SCAYLE sends the relevant customer data to this endpoint, your loyalty middleware must handle all registration logic within the external system. A successful response must return the newly generated loyalty card number, which SCAYLE then associates with the customer's profile.
Alternatively, you can assign a loyalty card to a customer in advance via the SCAYLE Admin API with the POST /shops/{shopKey}/countries/{countryCode}/customers/{customerIdentifier}/memberships endpoint (see Create a new customer membership). If a membership is created this way, the customer is already recognized as a loyalty member and does not need to register manually during the checkout process.
Request
HTTP method: POST
Headers:
X-Shop-Idinteger – Country-shop identifier.Content-Typestring – Must be set toapplication/json.Authorizationstring – The Bearer token configured in the SCAYLE Panel.
Example request body:
Response
Once the registration is completed, the response must use the following format:
cardNumberstring – Unique customer's loyalty identifier.providerstring – The identifier of the loyalty program.
Status Codes
| Code | Description |
|---|---|
201 | A new loyalty card has been successfully created for the customer. |
400 | Bad request – invalid syntax. |
422 | Unprocessable Content – mandatory data is not provided. |
500 | Internal Server Error. |
Validation Endpoint
Description
This endpoint is triggered by customer actions during the checkout process. Its primary purpose is to verify the validity of a submitted loyalty card against your external service. The response must indicate whether the card is valid and must return the customer's current loyalty point balance.
Request
HTTP method: POST
Headers:
X-Shop-Idinteger – Country-shop identifier.Content-Typestring – Must be set toapplication/json.Authorizationstring – The Bearer token configured in the SCAYLE Panel.
Request body:
cardKeystring – Unique customer's loyalty identifier.typestring – The identifier of the loyalty program.emailstring – Customer's email.
Response
Your loyalty middleware must provide the validation status and the balance in the following format:
cardKeystring – Unique customer's loyalty identifier.typestring – The identifier of the loyalty program.emailstring – Customer's email.validbool –trueif the provided loyalty card is valid.loyaltyPoints.balanceinteger – Customer's loyalty balance in cents.
Status Codes
| Code | Description |
|---|---|
| 200 | The loyalty card has been checked. valid can be true or false; balance can be zero or positive. |
| 400 | Bad request – invalid syntax. |
| 422 | Unprocessable Content – mandatory data is not provided. |
| 500 | Internal Server Error. |
Conversion Rate Endpoint
Description
The purpose of this endpoint is to provide SCAYLE with the conversion factor used to transform a customer's loyalty point balance into a monetary value for a specific currency.
Because SCAYLE does not support the configuration of a static default value for the conversion rate in the SCAYLE Panel, implementing this endpoint is a prerequisite for enabling point redemption logic.
Request
HTTP method: GET
Headers:
X-Shop-Idinteger – Country-shop identifier.Content-Typestring – Must be set toapplication/json.Authorizationstring – The Bearer token configured in the SCAYLE Panel.
Query parameters:
currencystring – Currency code (for example,EUR).typestring – The identifier of the loyalty program (for example,your_loyalty_program).
Response
Your loyalty middleware must provide the conversion rate value in the following format:
conversionFactorfloat – Conversion rate for loyalty point burns.
Status Codes
| Code | Description |
|---|---|
| 200 | The conversion rate is returned. |
| 400 | Bad request – invalid syntax. |
| 422 | Unprocessable Content – mandatory data is not provided. |
| 500 | Internal Server Error. |
Capture Endpoint
Description
A capture request is sent for every confirmed order that is at least partially paid for with loyalty points. These requests are queued and automatically retried to ensure the points are successfully deducted from the external loyalty system.
If a capture operation fails, SCAYLE retries the request every 60 minutes for up to 100 attempts (approximately 4 days). If all retry attempts fail, the order is automatically cancelled.
Request
HTTP method: PUT
Headers:
X-Shop-Idinteger – Country-shop identifier.Content-Typestring – Must be set toapplication/json.Authorizationstring – The Bearer token configured in the SCAYLE Panel.
Request body:
amountinteger – Amount of burned points in cents.cardKeystring – Unique customer's loyalty identifier.typestring – The identifier of the loyalty program.currencyCodestring – Currency code of the transaction.orderIdinteger – ID of the order in which the loyalty points are burned.emailstring – Customer's email.transactionKeystring – Transaction ID for the loyalty burn.appIdinteger – Country-shop identifier (the same asX-Shop-Id).
Response
Once the loyalty adapter captures the burned loyalty amount, it must return a confirmation in the following format. If the response status code is different from 200, the capture request is retried.
amountinteger – Amount of burned points in cents.cardobjectcardKeystring – Unique customer's loyalty identifier.typestring – The identifier of the loyalty program.currencyCodestring – Currency code of the transaction.statusobjectbalanceinteger – New balance after capturing the loyalty points.capturedAmountinteger – Amount of captured points.initialAmountinteger – Old balance before capturing the loyalty points.refundedAmountinteger (optional) – Amount of refunded points.
orderIdinteger – ID of the order in which the loyalty points are burned.transactionKeystring – Transaction ID for the loyalty burn.
Status Codes
| Code | Description |
|---|---|
| 200 | The loyalty points have been successfully captured. |
| 400 | Bad request – invalid syntax. |
| 404 | Customer not found. |
| 406 | The capture amount exceeds the available balance. You can decide whether you want to support negative balances. |
| 409 | Conflict – a capture operation with the same transactionKey exists. |
| 422 | Unprocessable Content – mandatory data is not provided. |
| 500 | Internal Server Error. |
Refund Endpoint
Description
This endpoint is triggered by SCAYLE to refund loyalty points when a confirmed order fails before it has been successfully delegated. This typically occurs when all order delegation attempts fail, requiring a full refund of all captured loyalty points for the entire order.
This endpoint is not called for standard post-delegation events, such as customer-initiated returns or cancellations after an order has been processed. Your system is responsible for managing loyalty logic in these cases:
- Revoking earned points: If a customer returns an item, any points earned from that purchase must be deducted from their balance.
- Refunding spent points: If a customer cancels or returns an order paid for with points, those points must be manually credited back to their balance via your internal logic.
Request
HTTP method: POST
Headers:
X-Shop-Idinteger – Country-shop identifier.Content-Typestring – Must be set toapplication/json.Authorizationstring – The Bearer token configured in the SCAYLE Panel.
Request body:
amountinteger – Amount of loyalty points that must be refunded.cardKeystring – Unique customer's loyalty identifier.typestring – The identifier of the loyalty program.currencyCodestring – Currency code of the transaction.orderIdinteger – ID of the order in which the loyalty points were burned.emailstring – Customer's email.transactionKeystring – Transaction ID for the loyalty refund.appIdinteger – Country-shop identifier (the same asX-Shop-Id).
Response
Once the loyalty adapter refunds the loyalty amount, it must return a confirmation in the following format:
amountinteger – Amount of refunded points in cents.cardobjectcardKeystring – Unique customer's loyalty identifier.typestring – The identifier of the loyalty program.currencyCodestring – Currency code of the transaction.statusobjectbalanceinteger – New balance after refunding the loyalty points.capturedAmountinteger (optional) – Amount of captured points.initialAmountinteger – Old balance before refunding the loyalty points.refundedAmountinteger – Amount of refunded points.
orderIdinteger – ID of the order in which the loyalty points were burned.transactionKeystring – Transaction ID for the loyalty refund.
Status Codes
| Code | Description |
|---|---|
| 200 | The loyalty points have been successfully refunded. |
| 400 | Bad request – invalid syntax. |
| 404 | Customer not found. |
| 409 | Conflict – a refund operation with the same transactionKey exists. |
| 422 | Unprocessable Content – mandatory data is not provided. |
| 500 | Internal Server Error. |
Configure Endpoints in the SCAYLE Panel
After implementing the API endpoints in your middleware, you must set them up in the SCAYLE Panel. This configuration directs SCAYLE to the correct URLs for each loyalty action, such as card validation or point capture.
To set up the URLs and authentication tokens for your loyalty program:
- Navigate to Loyalty Programs. In the SCAYLE Panel, go to Settings ➜ Loyalty Programs. You can either create a new loyalty program or select an existing one to edit.
- Set up your loyalty program.
| Configuration | Description |
|---|---|
| Name | Readable name of your loyalty program. Displayed only in the SCAYLE Panel. |
| Key | Enter a unique identifier for your program (for example, your_loyalty_program). This Key must exactly match the type value you specify in the Checkout Customization section. |
| Calculation factor and Rounding | Determines how many points are earned per currency unit. For example, a factor of 0.1 awards 1 point for every 10 EUR spent. You can also define how earnable points are rounded (for example, round up or round down to the nearest integer). |
| Endpoints configuration | Enter the full URL and the specific Bearer Token for each implemented feature. |
- Save your configuration. After entering the required endpoint details and tokens, save your changes. The SCAYLE Checkout begins using these URLs to communicate with your external loyalty service.
Checkout Frontend Configuration
Once you have configured the backend endpoints, you can activate and customize the loyalty features for the customer-facing Checkout. These settings control the appearance, validation rules, and specific behaviors of the loyalty widgets.
To configure these settings, in the SCAYLE Panel, go to Settings ➜ Checkout ➜ Customization ➜ Payment Step ➜ Payments ➜ Loyalty Program.
| Setting | Description |
|---|---|
| General Settings | |
| Disable Removal | Prevents a customer from removing a loyalty card once it has been successfully applied to the order. |
| Enabled | The master switch to activate or deactivate the loyalty program features in the Checkout. |
| Format | A regular expression used to validate the loyalty card number format on the frontend. |
| Min – Max Length | Sets the character limits for the loyalty card field. |
| Required | When enabled, makes the loyalty card number a mandatory field for completing the checkout. |
| Type | A unique identifier for the loyalty program (for example, your_loyalty_program). This value is critical, as it must exactly match the Key configured in the endpoint specification to link the frontend widget to the correct API endpoints. |
| Illegal Terms | A list of specific strings that are blocked from the input field. |
| Format On Blur | |
| Input – Output | Defines how the input is reformatted (Input → Output) when the customer clicks away from the field (for example, adding hyphens). |
| Redeemable Points | |
| Enabled | Activates the "Redeem Loyalty Program Points" widget, allowing customers to use their balance to reduce the order total. |
| Registration | |
| Disable for guest | Hides the registration option for guest users. |
| Enabled | Displays the registration widget for customers who do not yet have a loyalty card associated with their profile. |
| Tool Tip | |
| Enabled | Displays an informational icon and tooltip next to the loyalty field. |
Customer Actions and System Interactions in Checkout
This section describes how customer interactions within the Checkout trigger communication between SCAYLE and your loyalty middleware.
Attach a Loyalty Card to a Customer's Account
There are three ways a loyalty card can be linked to a customer's account.
1. Automated attachment via Admin API
Loyalty cards can be attached to profiles programmatically. A common use case is automatically enrolling customers upon account registration. In this scenario, your service would:
- Listen for
customer-createdwebhooks from SCAYLE. - Generate a new loyalty card in your loyalty system.
- Use the SCAYLE Admin API endpoint
POST /shops/{shopKey}/countries/{countryCode}/customers/{customerIdentifier}/membershipsto attach the card to the customer profile. For details, see Create a new customer membership.
2. Manual attachment of an existing card
Customers can manually enter an existing loyalty card number during the checkout process. This is ideal for users with physical cards. When a number is submitted:
- SCAYLE sends a request to the Validation endpoint.
- If the service confirms the card is valid, it is attached to both the customer's profile and the current order.
3. Manual registration at Checkout
Customers without a card can sign up directly in the Checkout widget.
- When the form is submitted, SCAYLE calls your Registration endpoint.
- Your service handles the account creation and returns the new card number.
- SCAYLE then applies this number to the checkout session and the customer profile.
If you use automated association (Option 1), you may want to disable the registration widget in the Checkout to avoid confusion. You can manage this in the SCAYLE Panel under Settings ➜ Checkout ➜ Customization ➜ Payment Step ➜ Loyalty Program, where you can define:
- Whether manual registration is enabled.
- Whether guest customers are allowed to register.
Customer Earns Loyalty Points
For customers with a valid loyalty card attached, the Checkout displays the estimated points they earn for their purchase. This amount is automatically recalculated whenever the basket changes (for example, adjusting item quantities or applying a discount code).
How Earnable Points Are Calculated
The calculation logic is defined in the Loyalty Programs section of the SCAYLE Panel. The Calculation Factor is applied to the order total to determine the number of points.
The calculation is based on the order total after any promotions, vouchers, gift cards, or loyalty point reductions are applied, but before shipping costs are added. A rounding rule (up or down) is applied to the final amount, as only whole numbers are supported for earnable points.
Products can be excluded from the loyalty program. For more information, see Exclude Products from the Loyalty Program.
System Interaction and Responsibilities
While SCAYLE calculates the points, your external loyalty service is responsible for managing the customer's total balance. SCAYLE facilitates this by providing the points data once an order is finalized.
- After an order is successfully placed, SCAYLE includes the earned points in the order data (Order Delegation payload, webhooks, and Admin API get-order payload). This information is transmitted within the
loyaltyCardobject:
- Your loyalty service must extract the points value and credit it to the customer's balance. The operation must be idempotent to prevent duplicate credits for the same order. Use the SCAYLE
order_idor thereference_keyas a reference to prevent crediting points multiple times for the same transaction in the event of retried webhooks.
The amount of earned loyalty points on an order is displayed on the order's detail page in the SCAYLE Panel.
Customer Pays with Loyalty Points
You can enable customers to use their accumulated points as a payment method to reduce their order total. This process involves a series of interactions between the SCAYLE Checkout and your loyalty middleware.
Products can be excluded from the loyalty program. For more information, see Exclude Products from the Loyalty Program.
How Redeemable Points Are Calculated
To display the redeemable amount, SCAYLE performs the following:
- Calls the Validation endpoint to fetch the current point balance.
- Calls your Conversion Rate endpoint to retrieve the factor for converting points into the local currency.
- The Checkout widget displays the balance and its monetary equivalent.
Customers have a binary choice to either redeem the full calculated amount (up to the order total) or nothing. Partial redemption (for example, choosing to use only 50 points when 100 are available) is not supported.
Order Processing
Once an order is placed, the following sequence occurs:
- If applicable, the primary payment method (for example, credit card) is authorized or captured first.
- If applicable, the voucher and promotion usage count increases.
- Once the primary payment is successful, SCAYLE sends a request to your Capture endpoint.
Capture requests are processed via an asynchronous background job. If Capture requests are not reaching your middleware for confirmed orders, the corresponding worker may be inactive. Contact your SCAYLE Account Manager to ensure the worker is enabled.
The burned points data is included in the membershipDiscount object:
membershipCardIdinteger – The SCAYLE internal identifier of the loyalty card number.pointsUsedinteger – The number of points that were redeemed.reductionValueinteger – The corresponding reduction value (in cents) in the specific currency.taxinteger – The tax associated with this reduction.
If a Capture request fails, the checkout retries every 60 minutes for 100 attempts. If all retries also fail, the order is cancelled, and SCAYLE triggers a refund of the payment with the regular payment method.
Handling Insufficient Balances
If a customer attempts to spend more points than they have (for example, through simultaneous orders), you can handle the Capture request in one of two ways:
- Do not modify the balance and respond with the status code
406. SCAYLE retries the capture request. If unsuccessful, the order is cancelled, and the primary payment is refunded. - Deduct the points even if it results in a negative balance and respond with the status code
200. The order is confirmed and delegated immediately.
Exclude Products from the Loyalty Program
To maintain flexibility in your business strategy, you can exclude specific products, such as gift cards, from participating in the loyalty program. When a product is excluded, customers neither earn points on its purchase price nor are able to apply loyalty points to pay for that specific item.
How to Set Up Exclusions
Exclusions are managed via product attributes. To exclude items, follow these steps:
- Create a new, simple, non-translatable attribute group specifically for this purpose, named
loyaltyCardExclusion. - Within this group, add an attribute whose name corresponds exactly to the key (the identifier) of your loyalty program (for example,
your_loyalty_program). - Assign this attribute to every product that must be excluded from the loyalty program.
Customer Experience
The Checkout frontend dynamically adjusts based on the contents of the customer's basket:
- If the basket contains only excluded products, the loyalty component (widgets for registration or point redemption) is not displayed at all.
- If the basket contains both eligible and excluded products, the loyalty component remains visible. However, the system excludes the value of the restricted items when calculating the estimated earnable points and the maximum points available for redemption. For mixed baskets, the
reductionValueandearnedPointscalculations only reflect the eligible portions of the order total.
Post-Purchase: Enriching Customer Communication
Adding Loyalty Data to Transactional Emails
You can enhance your transactional emails (such as order confirmations) by including details about the loyalty points a customer earned or redeemed. When a loyalty card is associated with an order, all relevant information is accessible in your email templates via the data.order.membershipDiscount object.
The following JSON snippet illustrates the data structure available for your templates:
cardNumberstring – Unique customer's loyalty identifier.earnedPointsinteger – The number of points the customer earned from this order.membershipCardIdinteger – The SCAYLE internal identifier of the loyalty card number.pointsUsedinteger – The number of points that were redeemed.reductionValueinteger – The corresponding reduction value (in cents) in the specific currency.taxinteger – The tax associated with this reduction.