Last updated

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:

AreaEndpoints
LoyaltyPOST /loyalty/{orderId}/set
PromotionsGET /promotions/{orderId}, POST /promotions/{orderId}/{promotionId}/apply, POST /promotions/{orderId}/{promotionId}/remove
Reward vouchersGET /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.id to be set by POST /api/v1/loyalty/{orderId}/set first. Otherwise the adapter returns loyalty-id-missing.
  • Reward vouchers require rewardVoucherLevels to be configured. An applied voucher whose amount does not match any configured level is rejected with configuration-error.
  • Promotions without an externalId and without a usable ECOM redemption channel value are rejected on apply with promotion-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

FieldDescriptionExample Value
adapter.internalUrlInternal URL of the Voyado Loyalty Adapter, used by other Norce services.https://voyado-adapter.checkout.playground.internal.norce.tech
adapter.publicUrlPublic 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.apiUrlBase URL of the Voyado Engage API. Use the staging URL in test and the production URL in live.https://yourclient.voyado.com
apiSettings.apiKeyVoyado 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.

FieldDescription
rewardVoucherLevels[].maxAmountUpper bound (inclusive) of the voucher amount for this level.
rewardVoucherLevels[].externalIdNorce 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).
  • StatusActive.
  • RequirementIf the external discount code is <externalCode>, where <externalCode> is exactly one of:
    • A Voyado promotion externalId.
    • The value of the Voyado promotion's ECOM redemption channel (when externalId is empty).
    • A rewardVoucherLevels[].externalId value from the adapter configuration (for example VOYADO_VOUCHER_100, RewardVoucher-600).
  • Effect — the discount that should be applied (for example THEN Discount all in basket with 600,00 SEK incl. VAT for 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:

Norce Commerce Admin Promotion with Requirement 'IF External discount code is RewardVoucher-600' and Effect '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 %:

Norce Commerce Admin Promotion with Requirement 'IF External discount code is NEWCUSTOMER' and Effect '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.id to the provided voyadoId.
  • Sets order.customer.loyalty.provider to "Voyado".
  • Returns a ContactDetailsResponse with the Voyado contact, the contact's active promotions, and their available reward vouchers.
Required after set loyalty

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:

  1. If the Voyado promotion's externalId is non-empty, it is used.
  2. Otherwise, the value of the redemption channel whose type is ECOM (case-insensitive) is used. Both string and numeric value types are supported.
  3. 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:

  1. Rejects the call with voucher-invalid if the voucher is already redeemed.
  2. Resolves an externalCode from the configured rewardVoucherLevels (the first level where voucher.value.amount <= maxAmount wins).
  3. Writes a LoyaltyRewardVoucher entry to order.customer.loyalty.rewardVouchers[] containing the Voyado id, voucherNumber, name, and resolved externalCode.

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.apiUrl points to the correct Voyado environment (https://{client}.staging.voyado.com for test, https://{client}.voyado.com for production).
  • Check that apiSettings.apiKey is valid and has access to api/v3/contacts/{id}, api/v3/promotion-assignments, and api/v3/reward-vouchers/available.
  • Check that order.customer.loyalty.id is set before calling promotion or reward-voucher endpoints.
  • Check that each Voyado promotion intended for ECOM has either an externalId or a non-empty ECOM redemption channel value.
  • Check that every voucher amount your Voyado tenant issues is covered by a rewardVoucherLevel.
  • Check that every externalCode the adapter writes has a matching Promotion in Norce Commerce Admin whose requirement is If 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 CodeDescription
voyado-contact-not-foundThe Voyado contact id used on the request does not exist in the configured Voyado tenant.
voyado-promotion-not-foundThe promotion id on an apply call is not in the list returned by Voyado for this contact.
voyado-voucher-not-foundThe voucher id on an apply call is not in the list returned by Voyado for this contact.
loyalty-id-missingThe order does not have customer.loyalty.id set. Call POST /api/v1/loyalty/{orderId}/set first.
promotion-external-id-missingThe promotion has no externalId and no usable ECOM redemption channel value, so no Norce discount code can be resolved.
promotion-not-appliedWriting the promotion to the order failed validation on the order service.
voucher-invalidThe reward voucher is already redeemed.
voucher-not-appliedWriting the reward voucher to the order failed validation on the order service.
configuration-errorThe adapter configuration is missing or the voucher amount does not match any configured rewardVoucherLevel.
voyado-bad-requestThe promotion or reward voucher is already applied to the order, or is already redeemed in Voyado.