Voyado Loyalty Adapter
Overview Document: Loyalty Adapters Overview
Overview and Unique Capabilities
The Voyado Loyalty Adapter integrates Voyado Engage with Norce Checkout. It links a Voyado contact to a Norce Checkout order and exposes the Voyado promotions and reward vouchers available to that contact. When a promotion or reward voucher is applied, the adapter writes it to order.customer.loyalty so that the Norce Adapter can translate it into a discount line item in Norce Commerce.
The adapter id used in order.customer.loyalty.provider is Voyado. The adapter itself is identified in Norce Checkout Admin as voyado_checkout_adapter.
Supported operations
The Voyado Loyalty Adapter exposes three sets of endpoints under /api/v1:
| Area | Endpoints |
|---|---|
| Loyalty | POST /loyalty/{orderId}/set |
| Promotions | GET /promotions/{orderId}, POST /promotions/{orderId}/{promotionId}/apply, POST /promotions/{orderId}/{promotionId}/remove |
| Reward vouchers | GET /rewardvouchers/{orderId}, POST /rewardvouchers/{orderId}/{voucherId}/apply, POST /rewardvouchers/{orderId}/{voucherId}/remove |
Limitations
- The Voyado Loyalty Adapter does not register receipts or transactions in Voyado. No purchase data is pushed to Voyado by this adapter. If you need receipt/transaction synchronization with Voyado, it is currently handled by third-party integration partners such as Nexer Group's Commerce Integration Platform, not by this adapter.
- All promotion and reward-voucher endpoints require
order.customer.loyalty.idto be set byPOST /api/v1/loyalty/{orderId}/setfirst. Otherwise the adapter returnsloyalty-id-missing. - Reward vouchers require
rewardVoucherLevelsto be configured. An applied voucher whose amount does not match any configured level is rejected withconfiguration-error. - Promotions without an
externalIdand without a usableECOMredemption channel value are rejected on apply withpromotion-external-id-missing.
Configuration in Norce Admin
The Voyado Loyalty Adapter is configured per merchant/channel in Norce Checkout Admin. The configuration is validated against the voyado_adapter JSON schema published by the adapter.
Required configuration
| Field | Description | Example Value |
|---|---|---|
adapter.internalUrl | Internal URL of the Voyado Loyalty Adapter, used by other Norce services. | https://voyado-adapter.checkout.playground.internal.norce.tech |
adapter.publicUrl | Public URL of the Voyado Loyalty Adapter, used by the storefront. Must contain your slug. | https://{slug}.api-se.playground.norce.tech/checkout/voyado-adapter |
apiSettings.apiUrl | Base URL of the Voyado Engage API. Use the staging URL in test and the production URL in live. | https://yourclient.voyado.com |
apiSettings.apiKey | Voyado Engage API key. Sent as the apikey header on every outgoing call to Voyado. | *** |
Reward voucher levels
rewardVoucherLevels maps Voyado reward vouchers to Norce discount externalId values based on the voucher amount.
| Field | Description |
|---|---|
rewardVoucherLevels[].maxAmount | Upper bound (inclusive) of the voucher amount for this level. |
rewardVoucherLevels[].externalId | Norce discount externalId written to the order when a voucher of this level is applied. |
Levels are evaluated in ascending maxAmount order. The first level whose maxAmount is greater than or equal to the voucher amount wins. If no level matches, applying the voucher fails with configuration-error.
Example configuration:
{
"$schema": "https://{slug}.api-se.playground.norce.tech/checkout/voyado-adapter/openapi/v1/schemas/voyado_adapter.json",
"id": "voyado_adapter",
"active": true,
"adapter": {
"internalUrl": "https://voyado-adapter.checkout.playground.internal.norce.tech",
"publicUrl": "https://{slug}.api-se.playground.norce.tech/checkout/voyado-adapter"
},
"apiSettings": {
"apiUrl": "https://yourclient.voyado.com",
"apiKey": "***"
},
"rewardVoucherLevels": [
{ "maxAmount": 100, "externalId": "VOYADO_VOUCHER_100" },
{ "maxAmount": 250, "externalId": "VOYADO_VOUCHER_250" },
{ "maxAmount": 500, "externalId": "VOYADO_VOUCHER_500" }
]
}Matching Voyado promotions and reward vouchers to Norce Commerce promotions
Every externalCode that the Voyado Loyalty Adapter writes to the order (from a Voyado promotion or from a rewardVoucherLevels[].externalId) must exist as a Promotion in Norce Commerce Admin. Without a matching Promotion, the order will contain the loyalty entry but no corresponding discount line in Norce Commerce.
For each expected externalCode, create a Promotion in Norce Commerce Admin with:
- Code — a unique code for the promotion (free-form).
- Status —
Active. - Requirement —
If the external discount code is <externalCode>, where<externalCode>is exactly one of:- A Voyado promotion
externalId. - The
valueof the Voyado promotion'sECOMredemption channel (whenexternalIdis empty). - A
rewardVoucherLevels[].externalIdvalue from the adapter configuration (for exampleVOYADO_VOUCHER_100,RewardVoucher-600).
- A Voyado promotion
- Effect — the discount that should be applied (for example
THEN Discount all in basket with 600,00 SEK incl. VATfor a 600 SEK reward voucher, or a percentage discount for a promotion).
When a Voyado promotion or reward voucher is applied through the adapter, the Norce Adapter looks for a Norce Commerce Promotion whose external discount code requirement matches the externalCode on the order and adds the corresponding discount line item to the cart. If no matching Promotion exists, no discount is applied.
Example: Norce Commerce Promotion for a Voyado reward voucher
A Voyado reward voucher of 600 SEK, mapped by rewardVoucherLevels to externalId = "RewardVoucher-600", requires a Norce Commerce Promotion whose Requirement is IF External discount code is RewardVoucher-600 and whose Effect is THEN Discount all in basket with 600,00 SEK incl. VAT:

Example: Norce Commerce Promotion for a Voyado promotion
A Voyado promotion whose externalCode resolves to NEWCUSTOMER (either directly from the Voyado externalId or from the ECOM redemption channel value) requires a Norce Commerce Promotion whose Requirement is IF External discount code is NEWCUSTOMER and whose Effect is, for example, THEN Discount all in basket with 10,00 %:

Setting the Voyado Contact on the Order
Use POST /api/v1/loyalty/{orderId}/set to link a Voyado contact to a Norce Checkout order. The adapter validates the contact against Voyado, stores it on the order, and returns the contact together with the promotions and reward vouchers the contact is entitled to.
POST /api/v1/loyalty/{order_id}/set
Host: {slug}.api-se.stage.norce.tech
x-merchant: {merchant}
x-channel: {channel}
Authorization: Bearer {token}
Content-Type: application/json
{
"voyadoId": "a7f3c1b2-....."
}On success the adapter:
- Sets
order.customer.loyalty.idto the providedvoyadoId. - Sets
order.customer.loyalty.providerto"Voyado". - Returns a
ContactDetailsResponsewith the Voyado contact, the contact's active promotions, and their available reward vouchers.
All other Voyado Loyalty Adapter endpoints read order.customer.loyalty.id. Call POST /api/v1/loyalty/{orderId}/set before calling GET, apply, or remove for promotions or reward vouchers. If order.customer.loyalty.id is missing, the adapter returns loyalty-id-missing.
Working with Voyado Promotions
Listing promotions
GET /api/v1/promotions/{order_id}
Host: {slug}.api-se.stage.norce.tech
x-merchant: {merchant}
x-channel: {channel}
Authorization: Bearer {token}The adapter calls Voyado's GET api/v3/promotion-assignments?contactId={loyaltyId} and returns the promotions for the contact stored on the order.
Applying a promotion
POST /api/v1/promotions/{order_id}/{promotion_id}/apply
Host: {slug}.api-se.stage.norce.tech
x-merchant: {merchant}
x-channel: {channel}
Authorization: Bearer {token}On apply, the adapter resolves an externalCode for the promotion and writes it to order.customer.loyalty.promotions[].
The externalCode is resolved in this order:
- If the Voyado promotion's
externalIdis non-empty, it is used. - Otherwise, the
valueof the redemption channel whosetypeisECOM(case-insensitive) is used. Both string and numericvaluetypes are supported. - If neither is available, the call fails with
promotion-external-id-missing.
Applying a promotion that has already been redeemed in Voyado, or that is already on order.customer.loyalty.promotions[], fails with voyado-bad-request.
Removing a promotion
POST /api/v1/promotions/{order_id}/{promotion_id}/remove
Host: {slug}.api-se.stage.norce.tech
x-merchant: {merchant}
x-channel: {channel}
Authorization: Bearer {token}The adapter removes the promotion from order.customer.loyalty.promotions[] by matching either id or externalCode.
Working with Voyado Reward Vouchers
Listing reward vouchers
GET /api/v1/rewardvouchers/{order_id}
Host: {slug}.api-se.stage.norce.tech
x-merchant: {merchant}
x-channel: {channel}
Authorization: Bearer {token}The adapter calls Voyado's GET api/v3/reward-vouchers/available?contactId={loyaltyId} and returns the available reward vouchers for the contact stored on the order.
Applying a reward voucher
POST /api/v1/rewardvouchers/{order_id}/{voucher_id}/apply
Host: {slug}.api-se.stage.norce.tech
x-merchant: {merchant}
x-channel: {channel}
Authorization: Bearer {token}On apply, the adapter:
- Rejects the call with
voucher-invalidif the voucher is already redeemed. - Resolves an
externalCodefrom the configuredrewardVoucherLevels(the first level wherevoucher.value.amount <= maxAmountwins). - Writes a
LoyaltyRewardVoucherentry toorder.customer.loyalty.rewardVouchers[]containing the Voyadoid,voucherNumber,name, and resolvedexternalCode.
Applying a voucher that is already on order.customer.loyalty.rewardVouchers[] fails with voyado-bad-request. Applying a voucher whose amount does not match any configured level fails with configuration-error.
Removing a reward voucher
POST /api/v1/rewardvouchers/{order_id}/{voucher_id}/remove
Host: {slug}.api-se.stage.norce.tech
x-merchant: {merchant}
x-channel: {channel}
Authorization: Bearer {token}The adapter removes the voucher from order.customer.loyalty.rewardVouchers[] by matching either id or voucherNumber.
Troubleshooting (Voyado Specific)
In addition to the generic troubleshooting steps:
- Check that
apiSettings.apiUrlpoints to the correct Voyado environment (https://{client}.staging.voyado.comfor test,https://{client}.voyado.comfor production). - Check that
apiSettings.apiKeyis valid and has access toapi/v3/contacts/{id},api/v3/promotion-assignments, andapi/v3/reward-vouchers/available. - Check that
order.customer.loyalty.idis set before calling promotion or reward-voucher endpoints. - Check that each Voyado promotion intended for ECOM has either an
externalIdor a non-emptyECOMredemption channelvalue. - Check that every voucher amount your Voyado tenant issues is covered by a
rewardVoucherLevel. - Check that every
externalCodethe adapter writes has a matching Promotion in Norce Commerce Admin whose requirement isIf the external discount code is <externalCode>. Without it, no discount line item is added to the cart even though the loyalty entry is on the order.
Error Codes
| Error Code | Description |
|---|---|
voyado-contact-not-found | The Voyado contact id used on the request does not exist in the configured Voyado tenant. |
voyado-promotion-not-found | The promotion id on an apply call is not in the list returned by Voyado for this contact. |
voyado-voucher-not-found | The voucher id on an apply call is not in the list returned by Voyado for this contact. |
loyalty-id-missing | The order does not have customer.loyalty.id set. Call POST /api/v1/loyalty/{orderId}/set first. |
promotion-external-id-missing | The promotion has no externalId and no usable ECOM redemption channel value, so no Norce discount code can be resolved. |
promotion-not-applied | Writing the promotion to the order failed validation on the order service. |
voucher-invalid | The reward voucher is already redeemed. |
voucher-not-applied | Writing the reward voucher to the order failed validation on the order service. |
configuration-error | The adapter configuration is missing or the voucher amount does not match any configured rewardVoucherLevel. |
voyado-bad-request | The promotion or reward voucher is already applied to the order, or is already redeemed in Voyado. |
Links and References
- Voyado Engage (contact Voyado for API documentation)