# Crobox
Source: https://partner-integrations.voyado.com/docs/data-enrichment/crobox/crobox
This integration enables the enrichment of contact profiles in Voyado Engage. The enrichment is based on the customer's interactions with a product finder that is provided by Crobox. The integration allows for:
* seamless syncing of user responses
* creation or updating of contacts
* personalization of follow-up communication.
Contact your account manager at Voyado to activate this integration with Crobox. You will need to have Incentives as part of your license model to use the feature.
You will need to contact Crobox too if you haven't already signed with them yet sicne most of the setup is done in their tool.
## Setup and configuration in Engage
Here are the configuration steps:
Contact your Voyado AM to enable interactions and to be assigned a representative who will help you with the implementation.
Define which datapoints you wish to use in Engage through the Crobox integration. This will be discussed together with Crobox and Voyado, to create a setup tailored to your needs.
An Engage API key is needed for this integration. Create this yourself via Config Hub:
You will need to be in permissions group "Configurator" to be able to create API keys.
Now you'll need to send your Engage client ID to Crobox. It's the *tenantname* part of the URL:
```http theme={null}
http://[tenantname].voyado.com
```
## Setup and configuration in Crobox
Contact Crobox if you have any questions related to the setup.
A standard webhook integration exists for any client to use. Here the interaction schema ID from your Engage environment can be set, together with the `Client_id` and `Api_key` values.
Here is what the interface looks like in Crobox:
In the finder setup, you can map questions, product properties and other custom properties to the Voyado interaction schema's fields. Your contact will be enriched with the answers given in the finder, which products were suggested (URL, images, benefits, or any other product property), and in what language the visitor was engaging.
## Personalized content
In order to add content from the product finder to a send-out in Engage, use the schema ID like this:
```bash theme={null}
[[croboxproductfinder.XYZ]]
```
Where you have replaced XYZ with the value saved in `Property Key` in Crobox.
More Personalization examples can be found here:
# Playable
Source: https://partner-integrations.voyado.com/docs/data-enrichment/playable/playable
Playable's gamification system allows marketers to create, tailor and deploy marketing gamification campaigns and competitions to deliver results at every touch-point. Here you can learn about the Playable integration with Voyado Engage.
The integration offers the following features:
* **Signing up Playable customers to Engage**\
Once a customer enter a competition and sign up for it, Playable will check if the customer already exists as a contact in Engage. If not, Playable creates them there. If the customer already exists in Engage, Playable will just update the contact with data from the competition.
* **Enriching a customer's profile from Playable**\
You can ask customers for custom attributes such as interests, favorites and so on in Playable and send this data to Engage to be saved for the contact there.
* **Using custom triggers in Engage**\
You can trigger automation flows in Engage from Playable, including with personalization, once a customer has completed a campaign / competition. An Engage custom trigger will need to be created for each one (or you can even have several triggers each one). The trigger IDs used needs to be communicated to Playable.
* **Automations for game outcomes via interactions**\
You can build automation flows around certain specific games or outcomes of a game you have enrolled in, or maybe award customers with points dependent on how many games they have played.
Custom triggers can set up in the Config Hub:
## 1 - Create contact if needed
If the customer does not exist in Engage, they can first be created using this endpoint:
```http theme={null}
POST /api/v2/contacts
```
Using a payload like this:
```json theme={null}
{
"firstName": "John",
"email": "john.doe@voyado.com",
"mobilePhone": "4237",
"campaignSource": "Playable",
"country": "Danmark",
"source": "Playable",
"storeExternalId": "1",
"contactType": "Member",
"preferences": {
"acceptsEmail": true,
"acceptsSms": true
}
```
This request will return the `contactId` value that uniquely identifies this contact.
Read more about `contactId` and how to work with it here:
This integration uses v2 of the Engage API.
## 2 - Update the contact
An update to the contacts information (enrichment) can now be made to Engage like this:
```http theme={null}
POST /api/v2/contacts/{contactId}
```
With this kind of payload:
```json theme={null}
{
"firstName": "John",
"email": "john.doe@voyado.com",
"mobilePhone": "345",
"acceptsEmail": true,
"acceptsSms": true,
"campaignSource": "Playable",
"country": "Danmark",
"source": "Playable",
"storeExternalId": "1"
}
```
Note the difference in how preferences such as `acceptsEmail` and `acceptsSms` are handled in the update payload compared to creation payload shown above.
The Custom trigger (called "proPlayable" in this case) used when the competition is completed for a particular contact is triggered like this:
```http theme={null}
POST api/v2/automation/customTriggers/proPlayable/triggerByContactId/{{contactId}}
```
No payload body is needed in this request.
## Playable's documentation
Read more about the Engage integration with Playable on their site.
# Tik Tok Leads - BETA
Source: https://partner-integrations.voyado.com/docs/data-enrichment/tik-tok-leads/tik-tok-leads
This feature is currently in BETA and Voyado is actively seeking user feedback to improve its performance and function. As a beta feature, it may undergo frequent updates and enhancements. Check for updates regularly to take advantage of the latest improvements. While beta features have been rigorously tested, they could contain issues, bugs, or glitches. Be prepared for occasional disruptions, and report any issues you find.
To gain access to TikTok leads, Engage users should contact their Voyado account manager.
## Configuring TikTok Leads
Follow the step to complete the configuration.
To track what form the customer has arrived from, you'll need to first go to **Config Hub** and create a custom attribute called `customSource` of type "string".
Do it like this:
The same custom contact attribute is used for TikTok and Meta, so if this has already been set up for Meta, skip this step.
Now log into Onsite Manager:
Or go to **Config Hub** again where you can configure Lead Ads.
If you don't see Lead Ads in Config Hub, contact Voyado's support:
In Onsite Manager go to: **Accelerator Configuration → Accelerators for lead ads**
If this section is missing, contact Voyado's support;
Use your existing site in OSM. Currently, you can only connect to **one** site in OSM.
In Onsite Manager press **Actions → Edit**.
In the **TikTok** section, connect to your TikTok Page.
Select **Connect** then add the account you want to connect to:
Press **Confirm** and you should be authenticated to TikTok.
Once connected, Engage will pull in your TikTok Lead Forms.
If no forms are visible, ensure one has been created for your campaign.
Choose the form you want and then map its fields to Engage.
The **Get forms** button will fetch all the forms on your page that you can connect to Voyado Engage.
Once you've done that, you will get a list of forms under **TikTok forms**.
Press on the form that you want to connect to Engage and then press the button **Get fields**. This will retrive all the fields on that specific form.
Do the mapping of fields as shown in the image and then press **Save**.
## Testing
After setting up your TikTok Lead Ads integration in Engage, you'll want to check that your setup works as expected. You can use TikTok's built-in Lead Ads Testing Tool to create test submissions that simulate a real lead. This is especially useful before running a live campaign.
Before you begin, make sure that:
* Your TikTok Page and Lead Form are already created
* The TikTok Lead Ads integration is active in Engage
* You've selected the correct Page and Form in the integration setup
* Your TikTok user has the right permissions
Then follow this procedure:
### 1. Open the testing tool
Visit TikTok's Lead Ads Testing Tool, here:
### 2. Select your TikTok Lead Form
From the dropdowns:
* Choose the TikTok account running your lead ad
* Select the form you want to test
### 3. Create a test lead
Select **Create Lead** to simulate a new lead submission.
This lead will not appear in your Ads Manager or Page Inbox, only through the API integration.
### 4. Verify the lead in Engage
Once created, go back to Voyado Engage to verify the lead exists. You can do this in two ways:
* Searching directly for the contact in Engage
* Or looking for them via segmentations using either:
* customSource: \[\[name of form]]
* source: TikTok
### 5. Troubleshooting
If the lead doesn't appear:
* Ensure your TikTok user has Leads Access to the account
* Recheck that the correct TikTok account and Form are selected in Engage
* Check if the lead was already created; duplicate test submissions might be ignored if your form doesn't allow them
To remove test data, delete the test contact directly in Engage after verification.
# Benefits flow
Source: https://partner-integrations.voyado.com/docs/data-enrichment/vipps/benefits-flow
The Vipps Benefits (Fordeler) app allows customers to:
* Become a member of a loyalty club directly in the app
* See available promotions and vouchers for all their loyalty clubs
* Create their account directly in the app
## Adding a new loyalty club
Here's how a customer adds a new loyalty club in the app:
This is how the customer's existing loyalty clubs are presented:
## If contact already exists
If the contact already exists in Engage, loyalty data is fetched from Engage to the Vipps app like this:
The full contact data is then fetched from Engage with:
```http Fetch contact data theme={null}
GET api/v2/contacts/{contactId}
```
The contact's promotions are fetched using:
```http Fetch promotions theme={null}
GET /api/v2/contacts/{contactId}/promotions
```
And the available vouchers (bonus checks) are fetched with:
```http Fetch vouchers theme={null}
GET /api/v2/contacts/{contactId}/bonuschecks/available
```
## Creating a contact
If the customer in the Vipps app does not exist in Engage, they will be created there.
The creation flow looks like this:
*CIBA = Client Initiated Backchannel Authentication*
## Onboarding automation flow
The automation in Engage (triggered by a middle layer using an iPaas) is built up like this:
1. Create an automation with the trigger "Vipps CIBA from Vipps Benefits".
2. Press the "+" button to add an Activity called "Vipps CIBA".
This automation will now be triggered by the middle layer when a customer is created from Vipps Benefits.
# Best practice
Source: https://partner-integrations.voyado.com/docs/data-enrichment/vipps/best-practice
Here are some best practices when working with Vipps and Engage.
## 1 - Creating account online
Follow these steps:
* Send a reset password email from Voyado
* Use a custom activity to create a customer in the e-com
## 2 - Welcome flow
The welcome automation flow looks like this:
## 3 - Promotions
Create an automation in Engage that triggers when the consent `VippsFordeler` is set to true.
When a contact enters this automation, assign a promotion to them. This ensures that new sign-ups will always see a promotion in the app as soon as they give their consent to Vipps Benefits.
## 4 - Segmentations
Contacts who have consented to Vipps Benefits:
Contacts who have the approved Vipps CIBA flow:
Created from the POS:
Created from the Vipps app:
## 5 - Sign-ups before and after go-live
You can segment for the number of sign-ups you had before going live, and compare that to afterwards.
Before go-live:
After go-live:
This way you can compare if you receive more consents from your customers, and also if the data looks better, when they start using Vipps versus before they uses it.
## 6 - Redeeming vouchers and promotions
You can examine the redemption of vouchers and promotions and compare the contacts who have Vipps Benefits activated to those who don't.
For those contacts who have Vipps Benefits:
And for those who don't:
## 7 - Handling non-Vipps users
For non-Vipps users you need to create a new automation and choose **Trigger a SMS-flow for non-Vipps users**.
Select the trigger and create an SMS as the first step.
# Custom flow
Source: https://partner-integrations.voyado.com/docs/data-enrichment/vipps/custom-flow
Custom Flow for Login is a Vipps feature that allows you to set up custom screens that will be shown during the Login flow. You can use these screens to collect consents and share important information such as terms and conditions. The information can be presented in form of text, links and checkboxes.
Custom Flow is configured in Vipps. You can freely choose text and links that you want to be shown. For detailed setup instructions, see here:
To be able to save your changes, make sure you have created custom screens in at least two languages: English and Norwegian.
For the integration with Engage to work correctly, the Checkbox ID in Vipps must match your consent ID in Engage. In many setups, the consent ID is "memberTerms". However, this can vary depending on your configuration.
Check the consent ID with your Voyado contact to complete the setup.
# Introduction
Source: https://partner-integrations.voyado.com/docs/data-enrichment/vipps/introduction
Vipps is a mobile payment solution. Customers can connect their payment card to Vipps and then use the app to pay merchants both offline and online. Users can easily identify themselves through the app, and can be onboarded through verified personal data.
Vipps also permits users to transfer money to other Vipps users.
This integration between Engage and Vipps consists of:
* The Vipps Login product
* The Vipps Benefits (fordeler) product
**Login** provides an easy way to identify, register and onboard a customer in physical stores, through the Vipps app on their phone. Technically, this is done through CIBA (Client Initiated Backchannel Authentication).
**Benefits** is a channel for retailers to engage with customers. It primarily acts as a way to display loyalty data from Engage in the Vipps app, but also as a way to onboard new customers and allow them to sign up for each of their chosen loyalty clubs.
## Integration overview
| Partner. | Vipps. |
| :--------------- | :-------------------------------------------------------------- |
| Product | Vipps CIBA + Vipps Benefits |
| Category | Onboarding + Benefits |
| Integration type | Connector |
| Hosted by | Voyado (Login and CIBA) and Vipps (Benefits/Fordeler) |
| Implementation | Installed and configured by the customer |
| Prerequisites | Active Vipps license, Active Engage and/or Omni/Loyalty license |
# Login flow
Source: https://partner-integrations.voyado.com/docs/data-enrichment/vipps/login-flow
This article covers the flow for the Vipps Login product.
The minimum age to use Vipps is 15, but it is possible that in your Engage configuration a higher minimum age has been set. In this case, be aware that data coming in from Vipps won't be saved in Engage.
To be able to use Vipps with Engage, the customer first need to sign up.
This is done through what is technically known as a CIBA (Client Initiated Backchannel Authentication) and this process starts when the customer displays the identifying QR-code on the Vipps app on their phone in-store.
Once the QR-code is scanned by the POS, the customer's mobile number is fetched and displayed. The customer will then be created as a contact in Engage through the integration between the POS and Engage.
Vipps will never create the customer in Engage; that is done by the POS.
Once the customer is created in Engage, a custom activity will trigger the onboarding flow that's been set up in Engage's automation tool:
Engage then triggers an app push to Vipps to ask the customer to share data with the merchant:
If the customer proceeds, they choose which consents (if any) they want to give.
This customer has accepted to be contacted by email:
When the customer selects "Continue" their consents and data are synced to Engage:
This following video showing the connection between Vipps and Engage:
## Summary of flow
The whole flow looks like this:
*CIBA = Client Initiated Backchannel Authentication*
# Loyyo
Source: https://partner-integrations.voyado.com/docs/digital-wallet/loyyo/loyyo
Loyyo is a middlewear solution allowing quick and easy identification of customers / contacts in a store environment. It can take time to spell out a name, mobile number or email address, and mistakes are easily made. Loyyo's unique NFC passes for Apple and Google solve this by allowing merchants an easier way to turn every non-cash payment into loyalty transactions, member identification and valuable insights.
Loyyo creates a tailored API per partner, making sure that all their partners can interconnect. This way, a payment partner can easily connect to any loyalty partner, while loyalty or POS partners are not forced to connect to several payment partners or methods, since Loyyo acts as the bridge.
Loyyo also offers their SaaS product as a white label allowing partners to use it for their own clients.
## What Loyyo offers for Engage
An Engage integration with Loyyo allows existing Engage clients to streamline the sign-up and identification of their customers. Loyyo allows one-step sign-up of loyalty members and, after that, instant identification using just the customer's mobile phone.
The customer will automatically earn points and their full profile can be fetched from Engage and displayed on the POS, including all promotions and offers available.
The Loyyo digital wallet integration with Engage enables merchants to offer customers a digital loyalty pass that can be stored in their Apple Wallet or Google Wallet. This pass can be used for identification in physical stores through NFC readers or, alternatively, via QR codes or barcodes.
The integration also supports real-time updates of loyalty information and push notifications triggered by location, points updates, or manual campaigns.
## 1 - Digital wallet creation
This is how the digital wallet is created.
When a customer joins the loyalty program, a personalized digital wallet pass is generated.
The merchant now sends a link enabling the customer to access the digital wallet, via:
* Email, using the existing Engage email modules
* SMS, by a direct download link
The customers can now download the pass to their Apple Wallet or Google Wallet and access personalized loyalty content from Engage.
## 2 - In-store Identification
There are two ways customers can identify themselves using their digital wallet.
* Customers hold their phone near an NFC reader
* The reader retrieves the customer's identifier from the wallet pass
* The POS uses this to fetch the customer profile from Engage and access loyalty details and rewards
If a merchant does not have NFC readers, the pass can display:
* A QR code (on the front or back of the card)
* A barcode for scanning at the POS
## 3 - Points and profile updates
Loyyo listens to Voyado's `points/update` webhook. When a customer's loyalty points change, the pass is updated in real-time.
## 4 - Push notifications
Merchants can send notifications that are:
1. **Geolocation-based**: These are triggered when the customer is near a store (can add up to 10 stores)
2. **Points update-based**: These are triggered by the Voyado webhook
3. **Manual**: These are sent to all pass holders (this is done from Loyyo's platform)
Push notifications can:
* Increase engagement rates
* Drive in-store visits
* Promote sales events
## 5 - Summary
The Loyyo digital wallet integration with Engage:
* Enables frictionless **customer identification** in-store
* Supports both **NFC** and **QR/barcode** methods
* Allows **personalized loyalty experiences**
* Enables **real-time pass updates** to keep customers informed
* Allows **push notifications** to increase in-store traffic and conversion rates
# Configuration guide
Source: https://partner-integrations.voyado.com/docs/ecom/adobe-commerce/back-in-stock
**BETA Disclaimer**
This feature is currently in beta and is continuously being improved based on user feedback. While we aim to provide a stable and high-quality experience, you may encounter limitations, incomplete functionality, or unexpected behavior.
The feature may be updated frequently, which could result in changes to functionality, performance, or user experience. We recommend using this feature with this in mind and avoiding reliance on it for business-critical workflows.
Your feedback is highly valuable and will help us refine and enhance the feature moving forward.
This extension connects an **online store powered by Adobe Commerce (Magento)** with **Voyado Engage**, which is Voyado's customer loyalty and marketing platform. Think of it as a bridge that keeps your webshop and your customer engagement tools in sync. Two major new capabilities have recently been added:
## Back in stock subscriptions
**The problem it solves:** A shopper visits your online store and finds a product they want, but it's currently out of stock. Previously, they'd just leave — and you'd lose that potential sale.
**What it does now:**
* When a product goes out of stock, the system automatically takes note of it behind the scenes.
* Shoppers can **sign up to be notified** when that product comes back. Their request gets sent to Voyado Engage, where it's recorded against their customer profile.
* If the shopper doesn't already exist in Voyado, the system **automatically creates a customer record** for them so nothing falls through the cracks.
* A scheduled job runs every day (by default at 8:15 AM) that checks which previously out-of-stock products now have inventory again.
* When stock arrives, Voyado Engage is notified — and it can then **automatically send an email or message** to all the customers who were waiting for that product.
**In short:** Customers can say "tell me when this is available again," and the system handles the rest — automatically.
***
## Inventory changes
**The problem it solves:** Voyado Engage needs to know how much stock you have for each product so it can make smart decisions — like not promoting a product that's about to sell out, or triggering those "back in stock" notifications at the right time.
**What it does now:**
* The system can **send stock levels from Magento to Voyado**, either one product at a time or **in bulk (batches)** for efficiency.
* The batch capability (the most recent addition from March 2026) means that instead of sending hundreds of individual updates, the store can send them all at once — which is **much faster and more reliable** when you have a large product catalog.
**In short:** Your online store keeps Voyado up to date on what's in stock and what isn't, so marketing campaigns and notifications stay accurate.
***
## **How it all fits together**
The extension is built in **three layers**:
| Layer | What it does |
| :------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **API layer** (`/api`) | A PHP library that knows how to talk to Voyado's web services (generated from Voyado's official API specifications). |
| **SDK layer** (`/sdk`) | A friendlier wrapper around the API — it handles things like finding or creating customer records and managing "back in stock" subscriptions. |
| **Magento module** (`/magento2`) | The actual Magento extension that store owners install. It hooks into Magento's product catalog, inventory system, and customer management to trigger all the syncing automatically. |
The extension also handles many other things (syncing orders/receipts, promotions, vouchers, newsletter subscriptions, customer data, etc.), but the **back in stock notifications** and **batch stock level sync** are the headline new features.
## **Prerequisites**
* **Correct version of the extension** -`10.6.0 and higher` or `8.6.0` depending on Adobe Commerce version. *See more details [here](https://partner-integrations.voyado.com/docs/ecom/adobe-commerce/introduction#prerequisites)*.
* **Product feed connected and active** - Your Shopify product feed must be imported into Engage and updating regularly.
* **Back in stock module enabled** - The Back-in-Stock feature must be activated in the Engage tenant.
* **Back in stock email/SMS template ready** - There is at least one template (usually email) that can be used for the notification.
* **All relevant products exist in the feed** - If a product isn’t in the feed, Voyado can’t send Back-in-Stock notifications for it.
If any of these are missing, it's vital that you fix them first (this is usually done together with your Voyado CSM or implementation team).
## **Configure Back in stock**
Still in the Magento Admin under **Stores → Configuration → Voyado Engage**:
**1a.** Scroll to the **Back in stock** section:
| Field | Value | Notes |
| :----------------------- | :----- | :----------------------------------------------------- |
| **Enable** | Yes | Turns on the subscription form and the stock sync |
| **Ask for phone number** | Yes/No | Optional — adds phone + SMS consent fields to the form |
**1b.** Save the configuration.
This is a **critical** Magento catalog setting that the indexers depend on.
Navigate to:
> **Stores → Configuration → Catalog → Inventory → Stock Options**
Set `Display Out of Stock Products` (`cataloginventory/options/show_out_of_stock`) based on your Magento version:
| Magento Version | Setting |
| :------------------- | :------ |
| **2.4.6 and lower** | **No** |
| **2.4.7 and higher** | **Yes** |
Getting this wrong means the indexers won't correctly detect stock transitions, and the back-in-stock flow will silently fail.
The two Voyado indexers **must** run in scheduled (MView) mode, not "Update on Save". Run:
```bash bash theme={null}
bin/magento indexer:set-mode schedule voyado_backinstock
bin/magento indexer:set-mode schedule voyado_backinstock_msi
```
Verify they are set correctly:
```bash bash theme={null}
bin/magento indexer:show-mode voyado_backinstock
bin/magento indexer:show-mode voyado_backinstock_msi
```
Both should report "Update by Schedule".
The extension publishes all Voyado API calls to a RabbitMQ topic called `voyado.api`. A consumer processes them asynchronously.
* Confirm RabbitMQ is running and Magento is connected to it (check `app/etc/env.php` for the `queue` → `amqp` connection).
* Ensure the Voyado message queue consumer is running. In production you would typically use `supervisord` or a similar process manager:
```bash bash theme={null}
bin/magento queue:consumers:start voyado.api.consumer
```
Without the consumer running, subscription messages and stock level updates will pile up in the queue and never reach Voyado Engage.
The back-in-stock cron is defined to run **daily at 08:15** server time:
```text theme={null}
voyado/adobe-commerce-extension-copy/magento2/src/etc/crontab.xml
```
```text theme={null}
\
15 8 * * *\
```
Verify your Magento cron is running properly:
```bash bash theme={null}
bin/magento cron:run
```
Check the schedule is registered:
```bash bash theme={null}
bin/magento cron:status
```
If you need the stock check to run more frequently (e.g., every hour), you can override the cron schedule in your Magento configuration, but the default is once per day.
Test the subscription flow:
1. Go to a product detail page in your storefront.
2. If the product is in stock and Back in Stock is enabled, you should see a **"Notify me when available"** form with an email field (and optionally phone).
3. Select a product variant that's out of stock, fill in your email, and click **"Notify me"**.
4. Confirm the message was queued: check the `queue_message` table in the database or your RabbitMQ management console for a message with event `back_in_stock_subscription`.
5. Confirm the consumer processed it: check Magento logs (`var/log/`) for Voyado API call records.
Test the inventory change flow:
1. Set a product to out-of-stock in the Magento admin (or set quantity to 0).
2. Wait for the indexer to run (or trigger it manually: `bin/magento indexer:reindex voyado_backinstock voyado_backinstock_msi`).
3. Verify a record appears in the `voyado_backinstock_index` table.
4. Set the product back to in-stock (increase quantity).
5. Either wait for the 08:15 cron, or trigger it manually: `bin/magento cron:run --group=default`.
6. Verify the record has been removed from `voyado_backinstock_index` (meaning it was processed).
7. Check logs to confirm a `back_in_stock_update_stock_levels` message was sent to Voyado Engage.
# Configuration
Source: https://partner-integrations.voyado.com/docs/ecom/adobe-commerce/configuration
When the extension has been successfully installed, you can start configuring it.
## Enabling the extension
In Adobe Commerce admin, navigate to **Stores > Configuration > Integrations** and select the "Voyado" tab.
Inside this configuration space, you'll be able to enable or disable the functionality supported by the extension.
Start by enabling the extension under “General” settings as seen in this video:
## Websites
You can connect your Voyado Engage environment/s to all your websites.
In the top left corner, change the website under “Scope”. You can choose to have a default setup for all websites, connected to one Voyado Engage environment (recommended), or configure websites separately, connecting each one to a separate instance.
## Establish your connection settings
Next, you'll need to input the credentials for your Engage environment.
**Base URL:** Input the Base URL of your Engage environment
```http Example of a base URL theme={null}
https://mytenantid.staging.voyado.com
```
**API key**: Input your Engage API key (for example: ).
```text Example of an Engage API key theme={null}
00000000-0000-0000-0000-000000000000
```
**Source:** Input the source of contact registration to use as a filter when triggering marketing automation acquisition journeys in Engage. For example: "ecom-eu".
**StoreExternalId:** Input the external ID of the Engage store that you want to connect your customers and orders to.
## Configure the contact sync
This integration with Engage supports the sync of customers, guests and newsletter subscribers. These different types of customers are each stored in Voyado Engage as separate contact types.
All contact types must be created in Engage by the Voyado team before contact exports are enabled.
To allow syncing of the Customer entity you will have to:
1. Enable the customer export, found under **Export > Enable customer export**.
2. Go to the “Customer Specific Settings” section and enable “Create Voyado contact as member”.
If you want to sync your guest customers and store them in Engage, follow these steps:
1. Enable the customer export which can be found under **Export > Enable customer export**.
2. Go to the “Customer Specific Settings” section and enable **Create Voyado contact also from Guest Customer**.
If you want to store your newsletter subscriptions in Engage:
1. Enable the newsletter subscriber export under **Export > Enable newsletter subscriber export**.
## Sync all contacts to Engage as type "Member"
With this setting you can choose to save ALL contacts - customers, guests and newsletter subscribers - as contact type "Member" in Engage.
The benefit of doing this is to minimize confusion and make for a cleaner integration. By only having the contact type "Member" it also means fewer calls to the Engage API. Voyado recommends this approach.
Using three different contact types might be useful if you want to separate different customers from each other in Engage. If you have a loyalty program, for example, and want that only account holders should be part of it, then it might be easier to have three types. However, this can also be done by making every customer have the contact type Member and using a `HasAccount` consent to tell them apart.
## Phone number validation
Voyado Engage requires a phone number to have a country calling code. If no validation for this is done in the front-end, and a phone number without a country calling code is input in checkout, the extension will validate that phone number based on the code of the country chosen in checkout.
For example:
* A customer chooses country “Sweden” and gives the phone number “0701234567” in checkout.
* The extension validates to check if the number is a valid Swedish number.
* If it is, we add a country calling code and format the number to “+46701234567” before we send it to Engage.
* If not, we just exclude the phone number from the request sent to Engage.
## Enable Engage to update customers
In the configuration area you have the option of activating a two-way sync, allowing Engage to update customers in Adobe Commerce. The two-way sync is connected to the login event, meaning that data is fetched from Engage and used to update the customer whenever they login to their account.
You can sync any or all of the name and address data or the newsletter subscription flag from Engage.
Two-way sync is only applicable if you have the “Require Email Confirmation” setting enabled in Adobe Commerce. This can be found in **Stores > Configuration > Customer Configuration**.
Voyado recommends that you at least enable the “Sync newsletter subscription” setting connected to the two-way sync. This is so that both platforms are in sync and so that there is no mismatch in the newsletter subscription field.
Follow these steps to enable to two-way sync:
1. Enable the “Sync after login” setting which can be found under **Customer specific settings > Sync after login**.
2. Enable “Sync name and address” if you want Engage to update this information in Adobe Commerce.
3. Enable “Sync newsletter subscription” if you want Engage to update this information in Adobe Commerce (recommended).
## Contact data model
Here are the fields in the contact model:
**Contact:**
* First name
* Last name
* Street
* City
* Zip code
* Country code
* Gender
* Recruited in store (the store where the contact signed up)
**Preferences:**
* Accepts email marketing
The contact data model can be extended by developing a custom patch.
## Configure syncing of purchases and returns
To sync purchases (known as "invoices" in Adobe Commerce) and returns ("credit memos" in Adobe Commerce) you must enable two separate exports. Activating these will allow you to create segments based on the contact's order history in Voyado Engage.
You can enable the invoice export at **Export > Enable invoice export**.
You can enable the credit memo export at **Export > Enable credit memo export**.
The order will only be stored for segmentation in Engage after it has been set to "invoiced" in Adobe Commerce Admin.
### Payload examples
```json theme={null}
{
"contact": {
"contactType": "member",
"matchKey": "f0352103-7143-4a44-a20d-af3300c58d7f",
"matchKeyType": "ContactId"
},
"createdDate": "2022-11-08T12:49:43+00:00",
"createdDateForXml": "2022-11-08T12:49:43+00:00",
"currency": "EUR",
"items": [
{
"articleName": "Joust Duffle Bag",
"articleNumber": "24-MB01",
"awardsPoints": true,
"extraData": [],
"grossPaidPrice": 85,
"quantity": 2,
"sku": "24-MB01",
"taxAmount": "17.0000",
"taxPercent": "25.0000",
"type": "PURCHASE"
}
],
"paymentMethods": [
{
"description": "Payment for: 000000034",
"type": "checkmo",
"value": 85
}
],
"receiptNumber": "000000034",
"storeExternalId": "opensource_demostore",
"taxDetails": {
"description": "TAX",
"percent": "25.0000",
"totalExcludingTax": 68,
"totalIncludingTax": 85,
"value": "19.5000"
},
"totalGrossPrice": 170,
"uniqueReceiptId": "000000034"
}
```
```json theme={null}
{
"contact": {
"contactType": "member",
"matchKey": "f0352103-7143-4a44-a20d-af3300c58d7f",
"matchKeyType": "ContactId"
},
"createdDate": "2022-11-08T12:49:43+00:00",
"createdDateForXml": "2022-11-08T12:49:43+00:00",
"currency": "EUR",
"items": [
{
"articleName": "Joust Duffle Bag",
"articleNumber": "24-MB01",
"awardsPoints ": true,
"extraData": [],
"grossPaidPrice": 42.5,
"quantity": -1,
"sku": "24-MB01",
"taxAmount": "8.5000",
"taxPercent": "25.0000",
"type": "RETURN"
}
],
"paymentMethods": [
{
"description": "Refund payment for: 000000034",
"type": "Refund",
"value": -42.5
}
],
"receiptNumber": "000000034",
"storeExternalId": "opensource_demostore",
"taxDetails": {
"description": "TAX",
"totalExcludingTax": 34,
"totalIncludingTax": 42.5,
"value": "8.5000"
},
"totalGrossPrice": -42.5,
"uniqueReceiptId": "34-20"
}
```
## Configure Order Notifications
The Voyado module can automatically notify Voyado Engage when an order reaches a specific status. This is how Engage knows when to trigger post-purchase automations, loyalty point awards, and transactional communications.
### **Enabling order notifications**
1. Go to **Stores → Configuration → Voyado Engage → Order notifications**
2. Set **Enable Order notifications** to **Yes**
3. In **Send notification on order statuses**, select every status that should trigger a notification to Engage
4. Click **Save Config**
### **Choosing the right statuses**
You can select one or more statuses. A notification is sent to Engage each time an order is saved with one of the selected statuses.
**Common configurations:**
| Goal | Status |
| ---------------------------------------- | ---------- |
| Notify Engage when an order is confirmed | Pending |
| Notify Engage when an order is shipped | Processing |
| Notify Engage when an order is fulfilled | Complete |
| Notify Engage when an order is cancelled | Cancelled |
Select only the statuses that are meaningful for your Engage automations. Selecting too many can result in duplicate or premature notifications.
If you select **Closed**, be aware that Magento may save an order with this status multiple times (e.g. after a partial refund), which can result in multiple API calls being sent to Engage for the same order.
If you want to trigger “**Order returned notifications**”, you must enable the credit memo export (see the previous section).
### **Custom order statuses**
Custom order statuses — added by your theme, a third-party module, or your own Magento configuration — are fully supported. They appear in the status list automatically alongside the native Magento statuses. No additional setup or code changes are required to use them.
If a custom status such as **Packing** or **Shipped** is relevant to your Engage workflows, simply select it in the list and save.
Make sure that these custom order statuses are also configured on Voyado Engage side.
### Where to manage order statuses in Magento
If you need to create or modify order statuses, go to:\
**Stores → Order Status**
Any status created there will immediately become available in the Voyado notification settings.
### Order data model
Below are the "out of the box" data points included in transactional emails:
**Contact:**
* MatchKey (contactId)
* MatchKeyType (GUID)
**Order header:**
* Currency
* Created date
* Freight fee
* Freight fee VAT
* Language
* Order number
* Order status
* Payment methods
* Shipping method
* Payment status
* Total discounts
* Total gross price|
* Total VAT
* Total original price
* Total net price
* Total items price|
* Total discounts
**Customer information**
* First name
* Last name
* Middle name
* Phone
* Billing city
* Billing country
* Billing company
* Billing street
* Billing zip code
* Shipping first name
* Shipping last name
* Shipping middle name
* Shipping phone
* Shipping city
* Shipping company
* Shipping country
* Shipping street
* Shipping zip code
**Order items:**
* Description
* Price
* Quantity
* SKU
* Image URL
* Image target URL
* VAT amount
* VAT percent
* Type (PURCHASE or RETURN)
If you want to extend the order payload with the additional product attributes in Adobe Commerce, follow the instructions in the README.md file in Gitlab under the section "Extending".
If you don't have access to the file on Gitlab, try this article.
## Shipment settings
Add the Adobe Commerce tracking URL at **Shipment settings > Add the Adobe Commerce tracking URL also shown in the admin**.
Setting this to “Yes” will add the default tracking link provided by Adobe Commerce which is available in admin.
Setting this option to “No” will allow you to add your transporter's tracking URL. When the transactional email is sent, the first tracking number found will be added to the URL and sent in the payload.
## Soft identification
When you send a newsletter or email with a link to your customers in Engage, the links are encrypted with a contact identifier (contactId). This functionality can be used for various actions, such as triggering abandoned carts or product views through Engage's tracking script, or to personalize the experience on-site since Engage lets Adobe Commerce know who the visitor is.
To enable soft identification:
1. Navigate to **Soft Login > Enable** and select “Yes”.
2. Input your decryption key.
The Decryption Key, 32 characters long, is configured in the Engage back-office. AES is the encryption method used. Ask your Voyado team about this.
When a customer arrives on the site via a soft identification link, the Voyado Engage extension decrypts the link and identifies the customer. If the **Soft identification** setting is enabled, the extension will automatically push the contact identifier (contactId) to the Google Tag Manager (dataLayer) for further use in personalization.
In addition, if you set the **Display in front-end** setting to "Yes" the extension will also display the response payload directly in the storefront. This is useful for debugging purposes, as it lets you easily verify that the correct contact information is being retrieved and handled.
### DataLayer Event: softLogin
Once the customer is identified, the extension triggers a softLogin event in the dataLayer. This event contains the customer's **Contact ID** under the `contactId` property.
Soft identification only facilitates web-activity tracking and personalization on-site. It is not something that is supported out-of-the-box, since it is tightly coupled to front-end components.
## Web activity tracking
Enabling this feature in the extension will allow you to act on cart abandonment and abandoned browse (beta). Engage will also calculate and store the ten top products of interest which can be used in segmentation as well as when generating content in emails.
Web activity tracking is only applicable if using the Adobe Commerce native front-end. If you are running a headless front-end then you'll need to implement this yourself. See the following link.
The prerequisites for using web activity tracking are the following:
* Adobe Commerce native front-end
* The Voyado/magento2 project version 4.2.0
* Web activity tracking enabled in Voyado Engage (talk to your Voyado account manager)
Follow these steps to enable web activity tracking:
In the Adobe Commerce config area, scroll down to the bottom of the page. Select the "Enable" drop-down and choose the option "Yes".
Input the "Script path" which depends on your environment:
* In production: [https://assets.voyado.com/jsfiles/analytics\_0.1.7.min.js](https://assets.voyado.com/jsfiles/analytics_0.1.7.min.js)
* In staging: [https://assets.voyado.com/jsfiles/analytics\_0.1.7.staging.min.js](https://assets.voyado.com/jsfiles/analytics_0.1.7.staging.min.js)
Input the tenant ID of your Voyado Engage environment. This string is your unique client (tenant) ID and is the same in production and staging. It is usually the subdomain name in `*.voyado.com`
For example, the tenant ID for "supershop.voyado.com" would be "supershop". Contact your Voyado team if you are unsure about this.
Enable "Product" tracking and "Cart" tracking.
Select "Save Config" in the top right corner of the page.
Go to **System** and then **Cache Management** in the left menu and refresh "Configuration" and "Page cache".
Here is a video showing the configuration:
# Custom attributes
Source: https://partner-integrations.voyado.com/docs/ecom/adobe-commerce/custom-attributes
When adding custom functionality to this extension, make sure to create your own plugin. Otherwise, you may interfere with the existing code and risk breaking it.
## How to add custom attributes to the Contact
To store custom attributes for a contact in Engage, these plugins can be used:
```xml theme={null}
```
```php theme={null}
'MarriedExtraPropertyDummyValue',
'region' => 'RegionExtraPropertyDummyValue',
];
return array_merge($result, $extraData);
}
}
```
***
## How to add custom data to the Order
This guide walks you through adding custom key-value pairs to the `extra_data` field in the `api/v2/orders` payload sent to Voyado. You do this with a Magento after-plugin — no modification to the Voyado extension source is needed.
### Before you start
* You need a working Voyado Adobe Commerce integration.
* All customizations must live in a **separate Adobe Commerce module** that depends on `Voyado_Magento2`. Do not edit the extension's files directly — your changes would be overwritten on the next Composer update.
### How extra data works
Every order exported to `api/v2/orders` includes an `extra_data` object. This is a **flat string-to-string map** — both keys and values must be strings. The extension populates it by default with shipping, billing, and payment details.
The extension calls `getExtraDataForOrder()` in `Voyado\Magento2\Helper\VoyadoHelper` to build this map. You extend it with an `afterGetExtraDataForOrder` plugin that receives the existing array and returns it with your additions.
The Voyado API model types `extra_data` as `map[string,string]`. All values must be strings. If you pass a nested array or object, the serializer will cast it to the string `"Array"`, which is not what you want. To include structured data, **JSON-encode it into a string value** as shown below.
### How to create the module
Create `app/code/VendorName/ExtendedVoyado/registration.php`:
```php theme={null}
Create `app/code/VendorName/ExtendedVoyado/etc/module.xml`:
```xml theme={null}
```
Create `app/code/VendorName/ExtendedVoyado/etc/di.xml`:
```xml theme={null}
```
Create `app/code/VendorName/ExtendedVoyado/Plugin/AddExtraOrderData.php`.
The plugin receives the existing `extra_data` array in `$result` — which already contains all the default fields like shipping address, billing address, and payment method. You add your field to this array and return it. Nothing else in the payload is affected.
In this example, we read a custom order field called `discount_code` and add it as `discountCode` in the `extraData` object:
```php theme={null}
getData('discount_code');
if (!empty($discountCode)) {
$result['discountCode'] = (string) $discountCode;
}
return $result;
}
}
```
After this plugin runs, the `extraData` object in the `api/v2/orders` payload will contain your new field alongside all the existing fields:
```json theme={null}
{
"extraData": {
"shipping_method": "DHL",
"shipping_amount": "49.00",
"customer_firstname": "John",
"customer_lastname": "Doe",
"billing_street": "Example Avenue 12",
"billing_zipcode": "123 45",
"billing_city": "Examplecity",
"billing_country": "SE",
"payment_method": "Kort",
"discountCode": "WELCOME10"
}
}
```
The `$result` parameter contains the full existing `extra_data` array built by the extension. By adding a key and returning the array, your field is merged into the same object. You are not creating a new object — you are extending the one that already exists.
All values in `extra_data` must be strings. The Voyado API model types this field as `map[string,string]`. If you pass a non-string value (e.g. an integer or array), cast it with `(string)` or use `json_encode()` for complex types.
Run the standard Magento setup commands:
```bash theme={null}
bin/magento module:enable VendorName_ExtendedVoyado
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush
```
Then place a test order and check the `voyado_magento2_status` table. Look at the **request** column for the order export — your new fields should appear in the `extraData` object of the JSON body.
The extension populates these fields by default. Your plugin adds to this — it does not replace it.
| Key | Source |
| :------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------- |
| `website_code` | Store ID |
| `shipping_method` | Order shipping description |
| `shipping_description` | Order shipping description |
| `shipping_amount` | Base shipping amount including tax |
| `customer_firstname`, `customer_middlename`, `customer_lastname` | Billing address |
| `customer_telephonenumber` | Billing address telephone |
| `billing_company`, `billing_street`, `billing_zipcode`, `billing_city`, `billing_country` | Billing address |
| `shipping_firstname`, `shipping_middlename`, `shipping_lastname` | Shipping address |
| `shipping_telephonenumber`, `shipping_company`, `shipping_street`, `shipping_zipcode`, `shipping_city`, `shipping_country` | Shipping address |
| `payment_method` | Payment method config value |
| `shipping_track` or `shipping_track_number` + `shipping_track_url` | Shipment tracking (depending on config) |
Do not overwrite any of these default keys unless you specifically intend to replace their values. Your plugin receives the full existing array in `$result` — add to it, do not reassign it.
## Common mistakes
| Mistake | What happens | Fix |
| ----------------------------------------------- | ------------------------------------------------------- | --------------------------------------------------------------------- |
| Passing an array as a value instead of a string | The value is serialized as `"Array"` in the API request | Use `json_encode()` to convert the array to a string |
| Reassigning `$result` to a new array | All default extra\_data fields are lost | Always add keys to the existing `$result` and return it |
| Forgetting `(string)` cast on non-string data | Integer or float values may cause type mismatches | Cast all values to `string`, or use `json_encode()` for complex types |
| Editing the Voyado extension source directly | Changes are lost on the next `composer update` | Always use a separate module with a plugin as shown above |
# Installation
Source: https://partner-integrations.voyado.com/docs/ecom/adobe-commerce/installation
The Magento 2 extension for Engage is developed in PHP. These are the steps to install it.
## Installation
Add this repository to your composer:
```bash theme={null}
composer config repositories.voyado composer
https://gitlab.com/api/v4/group/11993948/-/packages/composer/
```
Then add this to use the magento2 module:
```bash theme={null}
composer require voyado/magento2
```
## Development
The module has quality assurance scripts in place. To activate them, run:
```bash theme={null}
composer install
```
Use composer 2 and PHP 7.4.
You'll be asked for Magento credentials. It's best to use those for Magento Enterprise. Don't store them as they are needed just once.
You'll also need a GitLab token. Create an "auth.json" file with it as follows:
```json theme={null}
{
"gitlab-token": {
"gitlab.com": "generate-this-in-your-gitlab-account"
}
}
```
When changes are committed, GrumPHP will now perform some checks.
## Flows
See PlantUML flows in src/doc.
## Extending
The module can be extended to, for example, allow more data to be sent to Engage in the order receipt. To do this, replace "\[Vendor]" in the four examples below with your own vendor name and add these files to the paths shown:
```php theme={null}
```xml theme={null}
```
```xml theme={null}
```
```php theme={null}
getProduct() !== null) {
if ($orderItem->getProduct()->getTypeId() === 'simple') {
if ($orderItem->getProduct()->getAttributeText('my_own_attribute') !== false) {
$result['my_own_attribute'] = $orderItem->getProduct()->getAttributeText('my_own_attribute');
}
} elseif ($orderItem->getProduct()->getTypeId() === 'configurable') {
$options = $orderItem->getProductOptions();
if (isset($options['attributes_info'])) {
foreach ($options['attributes_info'] as $option) {
if ($option['label'] === 'My Own Attribute Label') {
$result['my_own_attribute'] = $option['value'];
break;
}
}
}
}
}
return $result;
}
/**
* @param VoyadoHelper $object
* @param array $result
* @param mixed $orderItem
* @return array
*/
public function afterGetExtraDataForReceiptItem(VoyadoHelper $object, $result, $orderItem)
{
if ($orderItem->getProduct() !== null) {
if ($orderItem->getProduct()->getTypeId() === 'simple') {
if ($orderItem->getProduct()->getAttributeText('my_own_attribute') !== false) {
$result = [
[
'name' => 'my_own_attribute',
'value' => $orderItem->getProduct()->getAttributeText('my_own_attribute')
]
];
}
} elseif ($orderItem->getProduct()->getTypeId() === 'configurable') {
$options = $orderItem->getProductOptions();
if (isset($options['attributes_info'])) {
foreach ($options['attributes_info'] as $option) {
if ($option['label'] === 'My Own Attribute Label') {
$result = [
[
'name' => 'my_own_attribute',
'value' => $option['value']
]
];
break;
}
}
}
}
}
return $result;
}
}
```
When adding custom functionality to this extension, make sure to create your own plugin. Otherwise, you may interfere with the existing code and risk breaking it.
## Consents
Add consents for contacts by creating two plugins:
* `afterGetConsents` for class "Voyado\Magento2\Helper\ContactAttributesHelper"
* `afterGetConsents` for class "Voyado\Magento2\Helper\OrderBodyHelper"
For `addOrder` and `creditMemo`, the function will receive "true" for the argument fromOrder.
The method `getConsents` can be found in the class "Voyado\Magento2\Helper\VoyadoHelper" and only returns an empty array.
Per index, an array should be added with these keys (the values are examples):
```cs theme={null}
[
"id" => "consentGeneralTerms",
"value" => true,
"date" => "2021-03-15T16:32:42+01:00",
"source" => "string",
"comment" => "string"
]
```
# Introduction
Source: https://partner-integrations.voyado.com/docs/ecom/adobe-commerce/introduction
The Adobe Commerce (Magento 2) extension for Engage allows Adobe Commerce clients to leverage Engage as their customer experience platform, enabling a more personalized experience for their end-users. As a user of this extension, you can even adapt it to personalize your customer's journey beyond what is shown here with the help of your development team or agency.
This Voyado Engage extension has been developed to work with a default Adobe Commerce (Magento 2) installation. If your implementation has had custom development, Voyado can't guarantee that the extension will work as intended, nor will Voyado be able to support you technically if any issues arise because of this.
## Prerequisites
Here are the versions you'll need to run a specific version of Adobe Commerce:
| Adobe Commerce | PHP | voyado/api | voyado/sdk | voyado/magento2 |
| -------------- | ------------- | ---------- | ---------- | --------------- |
| 2.4.9 | 8.4 | 4.1.0 | 7.1.0 | 10.6.1 |
| 2.4.8 | 8.4 | 4.1.0 | 7.1.0 | 10.6.1 |
| 2.4.7 | 8.1, 8.2, 8.3 | 2.1.0 | 5.1.0 | 8.6.1 |
| 2.4.6 | 8.1, 8.2, 8.3 | 2.1.0 | 5.1.0 | 8.6.1 |
| 2.4.5 | 8.1, 8.2, 8.3 | 2.1.0 | 5.1.0 | 8.6.1 |
If you are running voyado/magento2 8.1.0 and want back-in-stock functionality, you need to upgrade directly to 10.x, skipping version 9 entirely.
### Voyado Engage
You'll need an active Voyado Engage license, plus an API key to access the Engage API from Adobe Commerce.
### Adobe Commerce
You'll need an active license for Adobe Commerce 2.4.6 or higher. Earlier versions (2.4.4 and 2.4.5) may still be supported and functional, but we can't guarantee full compatibility. If the extension does not work as expected on those versions, the merchant will need to apply their own patches to ensure functionality.
### RabbitMQ
Click [here](https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/system-requirements.html) to see the supported versions.
### Extension and SDK
You'll need an agreement with Voyado giving you the right to use the Magento Extension and SDK. When that is in place, you will receive access to download the extension and the SDK.
## Integration overview
Here's an overview of what the integration offers:
* Synchronize customers, invoices and credit memos across stores to one or several Voyado Engage environments.
* Enable a two-way synchronization to update customer data in Adobe Commerce upon login.
* Send order notifications through Voyado Engage to streamline and personalize your send-outs and improve your deliverability.
* Assign and target personal coupon codes in Adobe Commerce with Engage's segmenting tool.
* Convert reward points into vouchers in Voyado Engage and enable them in your store as a personal coupon code.
* Use shopping behavior and product views onsite to target your communication and offer products your customer likes or is most likely to buy next.
* Leverage onsite behavior to act upon cart and browse abandonment and send a friendly reminder to your customers.
## Release notes
```text theme={null}
4.1.0, 2024-08-02
-----------------
- Ticket #172300: always update contact information in Engage.
4.0.0, 2024-03-13
-----------------
- Ticket #171054# Working towards one contact type in Engage - ContactType 'Member';
3.1.2, 2024-02-21
-----------------
- No ticket. Update composer.json - add monolog v3
3.1.1, 2023-11-29
-----------------
- Ticket #164822: improve getting requested type when creating an account.
3.1.0, 2023-11-23
-----------------
- Ticket #164822: Properly promote to member when creating an account.
3.0.0, 2023-11-01
-----------------
- Ticket #149066: support AES as decryption method for soft login.
- Ticket #150467: clear client history before trying a new call.
- Ticket #164235: improve finding contact by removing contactType from receipts body.
2.2.0, 2023-02-07
-----------------
- Ticket #147317: make handlers plugable in Magento.
2.1.1, 2022-11-30
-----------------
- No ticket. Use correct value to set decryption mode.
2.1.0, 2022-07-12
-----------------
- Ticket #138658: support Magento 2.4.4 and PHP 8.1
2.0.0, 2022-03-03
-----------------
- Ticket #125852: support Engage Voyado promotions.
- Ticket #126019: support Engage Voyado vouchers.
- Ticket #130181: remove setting consents, must be done in client modules.
1.0.0, 2021-08-25
-----------------
- Ticket #118857: initial version.
```
```text theme={null}
6.0.0, 2024-03-13
-----------------
- Refactored configuration sections. Sections in the configuration are now more clear. Renamed some config settings and changed their position.
- Set phone number validation as default validation in the code.
- Working towards one contact type in Engage - 'Member'. Added the option to work towards one contact type instead of three.
5.1.0, 2023-11-23
-----------------
- Ticket #164822: Properly promote to member when creating an account and if street, gender or phone number is empty, do not send it to Voyado.
5.0.1, 2023-11-07
-----------------
- Ticket #165108: wait a little while to make sure new or updated objects are ready for processing.
5.0.0, 2023-11-01
-----------------
- Ticket #149066: support AES as decryption method for soft login.
- Ticket #150467: improve search performance in Voyado admin by adding indexes.
- Ticket #150467: clear client history before trying a new call to prevent getting wrong history.
- Ticket #164235: improve lookup hits by removing contactType from receipts.
- Ticket #144831: clean up records in table voyado_magento2_status
- Ticket #162636: observe shipments to send partial shipments to Voyado.
4.2.0, 2023-10-10
-----------------
- Ticket #156112: [BETA feature] Web activity tracking on contacts, products and cart, all are configurable.
4.1.2, 2023-11-07
-----------------
- Ticket #165108: wait a little while to make sure new or updated objects are ready for processing.
4.1.1, 2023-09-26
-----------------
- Ticket #162683: added check on whether the customer model is present before we request a value from it when creating a new customer.
4.1.0, 2023-09-06
-----------------
- Ticket #159194: explain that Soft Login display message on frontend is for debugging purposes.
- Ticket #148453: reflect shipping costs on invoice receipt.
- Ticket #149761: get customer Voyado ID from Voyado if it's not stored in Magento.
4.0.3, 2023-06-13
-----------------
- Ticket #157726:set fallback values if the first and last name are empty.
4.0.2, 2023-05-26
-----------------
- Ticket #155596: improve logic to update/set custom attributes on customer.
4.0.1, 2023-05-23
-----------------
- Ticket #155596: set fallback values if the street and housnumber are empty.
4.0.0, 2023-05-02
-----------------
- Ticket #152167: export formatted phone number, but only if it's a valid one.
- Ticket #150526: sync customer and address data from Voyado back into Magento.
- Ticket #153915: sync newsletter subscription from Voyado to Magento.
- Ticket #151380: prevent error when loading promotions/vouchers without a customer id.
- No ticket. Improve performance loading status log in Magento admin.
- Ticket #150355: export language as default contact property.
3.4.1, 2023-02-13
-----------------
- Noticket: enforce correct type of $storeId
3.4.0, 2023-02-07
-----------------
- Ticket #146493: check order hash to prevent sending duplicates to Voyado.
- Ticket #149402: to avoid using cached data, load the customer always from the database.
- Ticket #147317: upgrade to minimum voyado/sdk 2.2.0 which makes handlers plugable in Magento.
3.3.1, 2023-01-11
-----------------
- Ticket #149066: prevent an error during the soft login resulting in a non-working shop.
3.3.0, 2022-12-19
-----------------
- Ticket #146957: load product for specific store to have the correct URLs generated.
- Ticket #146950: export complete address in order contact attributes.
- Ticket #147243: don't let an empty default tracking url break the code.
- Ticket #146987: set store ID in promotion / voucher message to redeem in correct Voyado account.
- Ticket #138806: default to an empty string instead of 'f' when gender in Magento is empty.
- Ticket #147245: for the credit receipt, take the created date from the credit memo.
- Ticket #146720: only send accepts email, others are handled by Voyado internally.
- Ticket #146864: reset cached subscriber if another one must be loaded.
3.2.1, 2022-11-15
-----------------
- Ticket #145753: add shipping costs incl. tax to the order header.
3.2.0, 2022-11-09
-----------------
- Ticket #145753: add refunded shipping tax to the total_tax and improve logic to detemine refunded quantity.
3.1.0, 2022-11-02
-----------------
- Ticket #144186: use a delay before sending create customer calls to Voyado.
- Ticket #143416: load customer from quote if it isn't in the session (for use with GraphQL).
- Ticket #145317: take the freigth fee from the credit memo as refunding it is optional and add refunded freight fee in credit memo receipt.
- Ticket #143417: add URL to Magento Shipping Track page with configurable tracking information in the order body.
- Ticket #145692: always load orders and creditmemos from database to prevent using cached data (as happens with get() ).
3.0.1, 2022-09-20
-----------------
- Ticket #143105: show contact attributes in log entry as normal array.
3.0.0, 2022-08-25
-----------------
- Ticket #132642: only send cart rule to Voyado if it has been changed.
- Ticket #140836: support per store view API endpoint. Each queue message holds the store ID to be used.
- Ticket #140654: fix deletion of customers in Voyado and always set contact type for customers to a member.
- Ticket #130611: support multiple voucher codes using module amasty/coupons.
2.3.0, 2022-07-26
-----------------
- Ticket #138807: Send the export receipt at all times regardless of whether the order can be exported.
2.2.0, 2022-07-12
-----------------
- Ticket #138099: load customer with email and for it's own store to check subscription.
- Ticket #140192: cast order store ID to int to avoid strict errors.
- Ticket #138658: support Magento 2.4.4 and PHP 8.1
2.1.0, 2022-06-03
-----------------
- Ticket #137498: add configuration to redeem after invoicing or after placing the order.
- Ticket #137573: support extra_data for customers which is extendable with an after plugin.
2.0.1, 2022-03-09
-----------------
- No ticket. Cast customer ID to required type int.
2.0.0, 2022-03-03
-----------------
- Ticket #125852: support Voyado promotions.
- Ticket #126019: support Voyado vouchers.
- Ticket #127419: export company and shipping customer name to Voyado.
- Ticket #128392: keep current contactType when subscribing a customer to a newsletter.
- Ticket #129665: support Magento commerce feature 'Giftwrap'.
- Ticket #130181: set optional consents in the contact attributes.
- Ticket #132775: Avoid duplicate api calls to Voyado.
1.0.2, 2021-09-15
-----------------
- Ticket #125197: product ID could be a string, remove strict type.
1.0.1, 2021-08-27
-----------------
- Ticket #11857: fix typo in module registration.
1.0.0, 2021-08-25
-----------------
- Ticket #118857: initial version.
```
```text theme={null}
1.3.4, 2024-04-22
-----------------
- Ticket #175145: use correct name for attribute SocialSecurityNumber.
1.3.3, 2023-11-23
-----------------
- Ticket #163698: allow any main property on a contact.
1.3.2, 2023-06-23
-----------------
- Ticket #137932: replace customer specific URL with a generic one.
1.3.1, 2023-05-02
-----------------
- Ticket #150355: export language as default contact property.
1.3.0, 2022-09-20
-----------------
- Ticket #143477: support Guzzle/Psr7 2.0.0
- Ticket #144186: drop support for PHP 7.x .
1.2.1, 2022-10-13
-----------------
- Ticket #144186: make 1.2.x compatible again with PHP 7.x.
1.2.0, 2022-07-12
-----------------
- Ticket #138658: support Magento 2.4.4 and PHP 8.1
1.1.0, 2022-06-03
-----------------
- Ticket #137573: support extra_data for customers.
1.0.1, 2021-08-27
-----------------
- No ticket. Update README.
1.0.0, 2021-08-25
-----------------
- Ticket #118857: initial version.
```
# Promotions and vouchers
Source: https://partner-integrations.voyado.com/docs/ecom/adobe-commerce/promotions-and-vouchers
Here you'll find information about using promotions and vouchers in the Adobe Commerce extension for Engage.
## Promotions
When the extension is implemented you'll be able to assign promotions (personal discounts) in Engage and enable the checkout staff to apply them for customers at the checkout. Once the discount has been applied and the purchase made, the extension will automatically redeem the promotion in Engage so that it can't be used again.
Adobe Commerce is the master of price logic, which means that discounts should always be created first in the Adobe Commerce admin under the section **Cart price rule**. Once created with the correct settings (explained below), a promotion will automatically be created as a draft in Engage with the correct reference code already inserted.
### Promotion cart price rule
This example demonstrates how to create a 20% off welcome offer.
1. Navigate to **Marketing > Cart price rules** in Adobe Commerce admin.
2. Select **Add new rule**.
3. Name the price rule in the field **Rule name** and set it as active.
4. Choose which websites your price rule is valid on.
5. Choose your customer groups (several or all of them can be chosen).
6. Choose the coupon to be a Specific coupon and enter the coupon code. The coupon code is the key reference between the promotion that was created in Engage and the Cart price rule in Adobe Commerce. This coupon code is what is sent to the customers by email or SMS.
7. Assuming the extension is implemented, a dropdown appears called "Voyado type". Here, choose **Promotion**.
8. Set the rules for the discount. A promotion in Engage can be connected to the four different rules below:
* Percent of product price discount
* Fixed amount discount
* Fixed amount discount for whole cart
* Buy X get Y for free (discount amount is Y)
9. After setting up the rules, hit **Save** and the promotion will be created in Engage as a draft. From there you can choose to assign the discount to your customer segment either manually or through Engage's marketing automation platform.
### Online and offline promotions
A promotion is automatically created in Engage when creating a cart price rule in Adobe Commerce, and such a promotion can also be set to be valid in-store (POS).
Follow the steps below to enable a promotion to be used *in-store*:
1. In Engage, navigate to the promotion that was created by Adobe Commerce.
2. Tick the box "Can be used in store".
3. Choose the type of promotion: Monetary discount, Discount in percent, or External promotion code.
4. Enter the value of the discount.
This requires you to have an integration with the POS that supports multichannel promotion assignment in Engage. Note that the type of promotion may vary depending on your integration with the POS.
### Using promotion at checkout
The extension has out-of-the-box support for manually inputting the customer's promotion code, which they received by email or SMS, into the discount code field in checkout. This will automatically apply the discount to the customer's basket.
If you want to present all available promotions to the customer, allowing them to choose the one to use at checkout, this will require additional front-end development.
When the purchase in finalized, the extension will redeem the voucher in Engage so that it cannot be used again in other channels.
### Redeeming a promotion
This setting allows you to decide at what stage in a purchase the promotion is redeemed in Engage.
There are two different options:
* Redeem when the order has been fulfilled (**Invoice**)
* Redeem at the order confirmation stage (**Order**)
If the order is not initially booked as an invoice in the Adobe Commerce admin view, you should select the option **Order** as in the image above. This will redeem the promotion as soon as the order has been submitted.
## Reward vouchers
As well as promotions, the extension also allows a customer to use a reward voucher as a discount at checkout.
A reward voucher is a monetary discount of a fixed amount that was created from points that were earned by the customer.
Reward vouchers are also connected to a cart price rule in Adobe Commerce but of a different type than promotions.
You need to create ONE master template to be connected to the vouchers in Engage. Once the extension has identified that specific customer in Engage, it will automatically enable the usage of their available vouchers.
### Voucher cart price rule
You need only create this cart price rule once and then have it active as a master template. The extension handles the rest.
Here's how you do it:
1. Navigate to **Marketing** and then **Cart price rules** in the Adobe Commerce admin view.
2. Choose **Add new rule**.
3. Name the price rule in the **Rule name** field and set it as “Active”.
4. Set the coupon to be a **Specific coupon** and tick the box **Use Auto Generation**.
5. Set "Uses per coupon" to “1”.
6. Set "Voyado type" to **Voucher**.
7. Under "Actions" select "Apply to Voyado voucher" and save the cart price rule.
### Using voucher at checkout
The extension supports manually inputting the voucher number, which has been communicated to the customer by email or SMS, into the discount code field at checkout. This will automatically apply the monetary voucher value as a discount to their basket.
Once the purchase in finalized, the extension will redeem the voucher in Engage so that it can't be used in other channels.
As for promotions, if you want to present all available reward vouchers to the customer, allowing them to choose the one to use at checkout, you will need additional front-end development.
### Redeeming reward vouchers
This setting allows you to decide at what stage in a purchase a promotion or reward voucher is redeemed in Engage.
The options are:
* Redeem when the order has been fulfilled ("Invoice")
* Redeem at the order confirmation stage ("Order")
If the order is not initially booked as an invoice in Adobe Commerce admin, you should choose the option “Order” as in the image. This will redeem the promotion or reward voucher as soon as the order has been submitted.
# Release notes
Source: https://partner-integrations.voyado.com/docs/ecom/adobe-commerce/release-notes
Updates will be posted here.
# Good to know
Source: https://partner-integrations.voyado.com/docs/ecom/big-commerce/good-to-know
## Order status deduplication
BigCommerce fires both `store/order/refund/created` and `store/order/statusUpdated` when a refund is processed. The connector intentionally ignores `statusUpdated` events where the new status is Refunded (4) or Partially Refunded (14). The `refund/created` event is the authoritative source for refund processing. If your webhook logs show `statusUpdated` being silently dropped for refunds, this is expected.
## Order processing is asynchronous
Orders are not sent to Engage the moment the webhook arrives. The connector stages the order and processes it asynchronously. This means there is a small delay between a BigCommerce order event and the order appearing in Engage. If processing fails, the event is retried automatically up to 10 times. If all retries are exhausted, the order record is marked as failed and requires manual investigation.
## Product tracking retries
If the Collect API returns a 5xx error when receiving a product view event, the connector retries the request up to 3 times. If all retries fail, the event is dropped. Cart tracking does not use the same retry mechanism — check your internal error logs if cart events are not appearing in Engage.
## Multi-channel configuration is required
If a BigCommerce store uses multiple sales channels, each channel must have its own configuration and site record. A webhook that cannot be matched to a specific channel is dropped. For `store/customer/created` events that don't carry a `channel_id`, the connector fetches the customer from BigCommerce to resolve the channel — this adds one extra API call per event.
## Phone number validation
Phone numbers are validated against the customer's country code. Numbers that fail validation are stored as `null` rather than saved in an invalid format. If a customer has no address on record, the country code is unknown and the phone number is omitted.
## Category name limit for product tracking
When resolving category names for a product view event, the connector uses the last 5 category IDs from the product's category list (most specific). The resulting joined string is capped at 255 characters. If the product has no categories in BigCommerce, the connector falls back to extracting a category name from the product URL path.
## Cart and product tracking with anonymous visitors
The storefront tracking payloads accept a `contactId` field. If the visitor is anonymous (no `contactId`), the event is still forwarded to Engage — Engage handles anonymous session tracking on its end. The `store/cart/converted` webhook is used to retroactively link an anonymous cart to a contact when the customer completes checkout.
## Webhook self-healing does not recover missed events
The webhook health job re-activates inactive webhooks every five minutes, but it does not replay events that were missed while a webhook was inactive.
# Running headless
Source: https://partner-integrations.voyado.com/docs/ecom/big-commerce/headless
Running headless BigCommerce with Engage comes with a few considerations:
1. **Abandoned cart** will not work, since it is tied to the BigCommerce front-end. To use abandoned cart, the tracking script must be manually implemented by whoever builds your custom front-end.
2. The **Engage widgets within the app** can't be used for merchants running the headless version since this is tied to the front-end. The information displayed -- vouchers, promotions, points and member levels -- can all be accessed through the Engage `/contacts` API.
3. The **syncing and creation of vouchers and assignment of promotions** in BigCommerce when customer log in is NOT available for merchants running the headless version.
4. **Soft identification** is tied to the front-end and is not available if running as headless.
# Introduction
Source: https://partner-integrations.voyado.com/docs/ecom/big-commerce/introduction
Connect your BigCommerce store to Voyado Engage for contact sync, order tracking, and behavioral data collection.
The BigCommerce connector links your BigCommerce store to Voyado Engage. It keeps contacts and orders in sync in real time via webhooks and feeds cart and product browsing behavior into Engage's automation and personalization layer.
The Engage connector for BigCommerce is currently in BETA. This means that updates and enhancements could happen at any time until the full release. Voyado encourages you to check for updates regularly. While we have conducted rigorous testing, features in beta could contain issues or bugs. Be prepared for occasional disruptions, and report any issues to help us at Voyado to refine the app.
## What this does
* **Contact sync** — Keeps Engage contacts in sync with BigCommerce customers. Supports real-time webhook-driven updates.
* **Order sync** — Subscribes to BigCommerce order webhooks and translates order status changes into Voyado order actions (confirmed, shipped, completed, cancelled, refunded).
* **Cart tracking** — Forwards cart activity from the storefront to Engage so abandoned cart automations can trigger.
* **Product tracking** — Forwards product page views from the storefront to Engage to power product-view automations and recommendations.
## How it works at a high level
BigCommerce sends events to the connector via webhooks. The connector validates each request's signature and processes the event asynchronously.
For frontend behavioral signals — cart activity and product page views — a JavaScript integration on the storefront posts directly to the connector's REST endpoints.
Some functions, such as tracking, will not work if you plan to run BigCommerce headless, since they require the BigCommerce frontend. Check with your Voyado account manager about this.
# Prerequisites
Source: https://partner-integrations.voyado.com/docs/ecom/big-commerce/prerequisites
## Required products and access
* An active Voyado Engage licence with the BigCommerce connector enabled
* Access to the BigCommerce admin panel with Store-level API accounts permissions
* A product feed connected to Engage for each market locale (for example, `sv-SE`)
* Engage email templates configured for abandoned cart automations
## Customer responsibilities
* Provide BigCommerce API credentials with sufficient permissions to read and/or write customers, orders, and products.
* Ensure the storefront JavaScript snippet is installed if cart tracking or product tracking is required.
## Before you continue
Verify that:
* The BigCommerce store hash and API authentication token are available.
* The Engage tenant domain and API key are available.
* The BigCommerce connector is configures and reachable from BigCommerce's webhook delivery infrastructure. Please advice with your Voyado team.
# Assign promotions
Source: https://partner-integrations.voyado.com/docs/ecom/big-commerce/promotions
Since **General Settings**, **Cart and Order Conditions**, and **Discount Rules** are managed within BigCommerce, you must first create your promotion in BigCommerce before syncing it to Engage and assigning it to customers.
Once the promotion is assigned to one or more customers, they must log into their account to access the discount. During login, the app assigns the promotion by linking the customer to a Rule using their **externalId** in Engage, which corresponds to their **Customer ID** in BigCommerce.
If you plan to run a promotion campaign that can be reused, it is *strongly recommended* to create the assignment directly in BigCommerce.
If a customer creates accounts in two Sales Channels with the same email address, and both are connected to the same Engage environment, the promotion will only be linked to the externalId of the first account created.
If a personal promotion has been assigned in BigCommerce and redeemed through a third-party system (POS), it will remain active in BigCommerce.
Here are the steps to create and sync promotions:
1. Log into your BigCommerce store.
2. Navigate to **Marketing > Promotions**.
3. Click on **Coupon**.
4. Click **Create.**
1. **Promotion Name:** Enter a name for the promotion.
2. **Display name (optional):** Enter a suitable display name.
1. Choose which storefront channels the promotion will be eligible for.
2. Enter your **Coupon Code.**
1. **Currency is:** Here you choose the currency of the promotion.
Do NOT set any other Customer targeting rules. Engage will manage these when assigning the promotion.
1. Select **Add rule.**
2. Choose and apply your template.
3. Input the rules of the coupon.
4. Select **Add rule to promotion.**
1. **Limit total usage of this promotion**: Choose "No limit" for total usage of promotion.
2. **Limit usage for individual customers:** Set value to 1 (Set this value for extra validation).
3. **Create promotion.**
1. Navigate to **Apps >** **Voyado.**
2. Click on the **Promotion Sync-up** tab.
3. In the **Sales Channel List**, select the Sales Channel linked to the promotion.
4. Mark the promotions you want to sync to Engage.
5. Select **Sync Promotions**.
The promotion will now be created in Engage as a Draft Promotion. It can then be activated and assigned manually or via the Automation tool.
Once it is assigned in Engage, eligible customers will be able to use the promotion when they log into their account by applying the code in the discount code field.
# Configuration
Source: https://partner-integrations.voyado.com/docs/ecom/big-commerce/setting-up
Follow these steps to integrate your Engage account with your BigCommerce store using the Voyado Engage connector for BigCommerce.
## Setting up the connector
Log into BigCommerce admin and access your BigCommerce admin panel.
* Navigate to **Settings > Store-level API accounts**
* Create an API account and choose the following:
* Token type: V2/V3 Token
* Name: Voyado Engage connector
* Choose the following OAuth scopes:
* Click **Save**
* Download the file and/or copy the credentials (Client ID, Client Secret, Access token) and store them securely.
* Click **Done**
* Share the credentials in a secure way with your Voyado team together with the **Store hash** of your BigCommerce store.
The **Store Hash** can be found in your BigCommerce admin URL:
`https://store-{storeHash}.mybigcommerce.com/manage/dashboard`
BigCommerce does not validate phone numbers in the same way as Voyado Engage. To ensure compatibility, you must add validation to all phone number fields in customer registration forms. We recommend using the [Google libphonenumber library](https://github.com/google/libphonenumber?tab=readme-ov-file) for accurate validation.
# Technical Details
Source: https://partner-integrations.voyado.com/docs/ecom/big-commerce/technical-details
Architecture, webhook events, status mapping, data flow, and sync behavior for the BigCommerce connector.
This article covers the integration architecture, data flows, and processing behavior for implementers.
## Architecture overview
The connector runs as an ASP.NET Core application on AWS Lambda. Incoming BigCommerce webhooks are validated synchronously for signature integrity, then handed off asynchronously via SQS. A separate Lambda function polls the SQS queue and processes events in parallel batches.
```mermaid theme={null}
flowchart TD
A[BigCommerce webhook] --> B[Connector]
B --> C{Validate HMAC signature}
C -- Invalid --> D[Return 401]
C -- Valid --> E[Publish to SQS]
E --> F[Event processor Lambda]
F --> G{Route by event type}
G --> H[Customer webhook handler]
G --> I[Order webhook handler]
G --> J[Cart-converted handler]
K[Storefront JS] --> L[Connector]
K --> M[POST Tracking event]
L --> N[Voyado Collect API]
M --> N
```
## Webhook authentication
Every incoming webhook from BigCommerce is verified before processing:
1. The connector extracts the store hash from the `producer` field of the payload.
2. It looks up the client secret for that store from the secrets store.
3. It computes an HMAC-SHA256 digest of the raw request body using the client secret.
4. The result is compared against the `X-BC-Signature` request header.
If the signature doesn't match, the request is rejected with `401 Unauthorized`. If validation passes, the payload is queued for asynchronous processing.
## Contact sync
### Real-time webhook flow
The following BigCommerce webhook scopes trigger contact upserts in Engage:
| Scope | Action |
| -------------------------------- | ------------------------------------------------------ |
| `store/customer/created` | Create or update contact |
| `store/customer/updated` | Create or update contact |
| `store/customer/address/updated` | Re-fetch customer by ID, then create or update contact |
| `store/customer/deleted` | Delete contact in Engage |
| `store/subscriber/created` | Newsletter opt-in — create or update contact |
| `store/subscriber/updated` | Newsletter opt-in — create or update contact |
When a `created` or `updated` event arrives, the connector:
1. Fetches full customer data from BigCommerce v3 (`customers?id:in={id}&include=addresses`).
2. Extracts the `origin_channel_id` to resolve which sales channel the customer belongs to.
3. Checks whether a contact with that email already exists in Engage.
4. Creates a new contact or updates the existing one.
### Contact field mapping
| BigCommerce field | Voyado contact field |
| ---------------------------------------- | ------------------------------------------------------------ |
| `first_name` | `firstName` |
| `last_name` | `lastName` |
| `email` | `email` |
| `birthday` | `birthDay` |
| `id` | `externalId` |
| `date_created` | `registrationDate` (ISO 8601 with offset) |
| `phone` (from address, E.164 normalised) | `mobilePhone` |
| Country from first address | Used to resolve registration store ID and phone country code |
| `addresses[0].*` | Address fields (street, city, zip, country) |
Phone numbers are validated and normalised to E.164 format using the libphonenumber library. Invalid numbers are omitted rather than stored in a broken format
## Order sync
### Webhook events
| BigCommerce scope | Trigger |
| ---------------------------- | -------------------------------- |
| `store/order/created` | New order placed |
| `store/order/statusUpdated` | Any order status transition |
| `store/order/refund/created` | Refund or partial refund created |
When `store/order/statusUpdated` fires for a refund status (status ID 4 or 14), the connector skips it. The authoritative event for refunds is `store/order/refund/created`.
### Two-phase processing
1. **Stage** — When a webhook arrives, the connector fetches order and line item data from BigCommerce and writes a `Pending` record with the full payload.
2. **Process** — The event processor picks up pending records and sends the order to Engage.
If processing fails, the event is retried automatically up to 10 times. Records that exhaust all retries are marked as failed.
### Order status mapping
| BigCommerce status | Status ID | Voyado order type | Voyado order status | Voyado order action |
| -------------------- | --------- | ----------------- | ------------------- | ------------------- |
| Awaiting Fulfillment | 11 | PURCHASE | InProgress | ConfirmOrder |
| Partially Shipped | 3 | PURCHASE | InProgress | ConfirmShipment |
| Shipped | 2 | PURCHASE | InProgress | ConfirmShipment |
| Awaiting Pickup | 8 | PURCHASE | InProgress | ConfirmCompletion |
| Completed | 10 | PURCHASE | Completed | ConfirmCompletion |
| Cancelled | 5 | PURCHASE | Cancelled | ConfirmCancellation |
| Refunded | 4 | RETURN | Completed | ConfirmOrder |
| Partially Refunded | 14 | RETURN | Completed | ConfirmOrder |
The following statuses are skipped — no action is taken in Engage:
* Awaiting Payment (7)
* Awaiting Shipment (9)
* Manual Verification Required (12)
* Declined (6)
* Any unrecognised status ID
When `status_id` is 2 (Shipped) and a product has `quantity_shipped > 0`, the connector generates shipment-level line items in addition to the order-level items.
### Line items and promotions
For each order, the connector:
* Maps each line item to a Voyado line item (SKU, quantity, price, discount) using `v2/orders/{id}/products`.
* Fetches payment methods from BigCommerce and attaches them to the order payload.
* Looks up any coupon code applied to the order and redeems the matching Engage promotion if found.
### Return orders
When `store/order/refund/created` fires:
1. The `refund_id` is extracted from the payload.
2. The connector fetches the parent order data.
3. A pending record is written with the return type and `refund_id` as a sub-identifier.
4. The event processor processes it as a RETURN order using the status mapping table above.
## Cart tracking
The storefront posts cart data to the connector. The connector:
1. Resolves the store and channel from `hash` and `saleschannelUrl`.
2. Checks that **Cart tracking** is enabled.
3. Fetches the store locale from BigCommerce (`v3/settings/store/locale`).
4. Builds a cart payload and posts it to Voyado's Collect API.
The cart payload includes: cart ID, line items with SKU and quantity, session ID, contact ID, URL, locale, and UTM tags.
### Cart-converted webhook
When BigCommerce fires `store/cart/converted`, the connector:
1. Extracts the `orderId` from the payload.
2. Fetches the order from BigCommerce to get the `channel_id` and `billing_address.email`.
3. Looks up the Engage contact ID for that email.
4. Posts a cart event to the Collect API with the resolved contact ID, linking an empty cart session to the identified contact.
## Product tracking
The storefront posts product view data to the connector. The connector:
1. Resolves the store and channel from `hash` and `saleschannelUrl`.
2. Checks that **Product tracking** is enabled.
3. Fetches the product from BigCommerce by SKU (`v3/catalog/products?sku={sku}`).
4. Resolves up to 5 category names from the product's category IDs (most specific categories). Category names are joined with `/` and capped at 255 characters.
5. Fetches the store locale.
6. Builds a `productview` payload and posts it to the Collect API.
If the product SKU category is not found in BigCommerce, the category is extracted from the product URL path as a fallback.
If the BigCommerce API returns a 5xx error, the connector retries the request up to 3 times before dropping the event.
## Multi-channel support
A single BigCommerce store can have multiple sales channels, each with its own configuration and site record. The connector resolves the correct configuration by matching store hash and sales channel ID. For webhook scopes that don't include a `channel_id`, the connector fetches the customer or order from BigCommerce to discover the channel before routing.
## Webhook health and self-healing
A background job periodically checks all registered BigCommerce webhooks. It:
* Re-activates inactive webhooks via a PUT to BigCommerce's `v3/hooks/{id}`.
* Detects missing webhook scopes and registers them.
This keeps the connector operational after periods of inactivity or after BigCommerce automatically deactivates low-volume webhooks. The job does not replay events missed while a webhook was inactive.
# What's new?
Source: https://partner-integrations.voyado.com/docs/ecom/big-commerce/whats-new
Here you'll find the changes and updates to the Voyado Engage connector for BigCommerce.
There is an RSS feed for this page allowing you to subscribe to changes as they are published.
## Bug fixes
* Fixed incorrect tax amounts on refunded and discounted orders. Tax percentages are now validated to stay within a valid range, preventing invalid values from reaching Voyado Engage.
## Bug fixes
* Orders and refunds that had already been completed or accepted by Voyado Engage are no longer retried unnecessarily, reducing duplicate processing and delays.
## Improvements
* The promotions selection screen now supports paging, making it easier to browse and select promotions for stores with large catalogs.
## Bug fixes
* Orders and refunds with line items taxed at different VAT rates now calculate tax correctly per line, instead of applying a single rate to the whole order.
## Improvements
* Orders and refunds that could not be fully processed on the first attempt are now automatically retried with fresh data, and will fail clearly after repeated attempts instead of being retried indefinitely.
* Outbound API calls now enforce a 10-second timeout, preventing slow responses from delaying order processing.
## Improvements
* Contact and order event processing now runs fully asynchronously, improving throughput and reducing the risk of timeouts under high load.
## Bug fixes
* Fixed an issue where a customer's email marketing preference could be incorrectly synced from BigCommerce. The value is now read directly from the API response, ensuring opt-in/opt-out status is always accurate in Voyado Engage.
## Improvements
* Contact syncing is now more resilient to temporary rate limits from Voyado Engage — requests that encounter a rate limit are handled gracefully rather than failing and accumulating in the retry queue.
## Improvements
* More reliable syncing of orders and customers. Resolved HTTP timeouts and improved parallel batch processing so individual event failures no longer block others in the same batch.
## Improvements
* Order addresses with a missing postal code on either the shipping or billing address now fall back to the value from the other address, so orders sync with more complete address details.
* Contacts synced from BigCommerce are now classified correct as either a member or a regular contact in Engage, based on your store's configuration.
# Back in stock
Source: https://partner-integrations.voyado.com/docs/ecom/centra/back-in-stock
The back-in-stock feature allows retailers using Voyado Engage to inform customers automatically when an out-of-stock product becomes available. This functionality integrates with Centra to enhance customer experience by keeping them updated on their favorite items.
This feature is ideal for retailers looking to boost customer engagement, reduce missed sales opportunities, and foster loyalty.
## Prerequisites
Before starting the back in stock configuration for Centra, ensure the following:
* **Engage configuration**: The integration must first be configured on the Voyado side before testing can begin. Contact your Voyado account manager or project team to ensure your Engage environment is correctly set up.
* **Product Feeds**: Product feeds must be connected to Engage for each locale (Ex: sv-SE).
* **Event System in Centra**: The event system must be enabled in Centra. Contact your Centra Customer Success Manager for validation.
* **Back in Stock email module**: A "Back in Stock" module must be added to your Engage email templates.
* **API Credentials**: API credentials must be set up in Centra and Engage.
* **Subscription form in front-end**: A back-in-stock subscription form must be available on the product page and connected to Engage's Subscription API.
* **Marketing automation**: A back-in-stock marketing automation flow must be set up in Engage.
See below for more on the Subscription API.
## Configuring API token in Centra
Follow these steps:
The Integration should have a relevant name, for example "Engage integration".
Choosing an existing name can cause conflicts with other integrations.
Write permissions:
* Event
Read permissions:
* Allocation rule
* Event
* Market
* Product
* Product Size
* Product Variant
* Stock Change
* Store
* Warehouse
* Orders
* Returns
## Using multiple brands
If your Centra environment includes multiple brands connected to separate Voyado Engage tenants, you *must* create a unique API token and Integration name for each brand.
This is important for the following reason:
When the same token and integration name are reused across multiple brands, Centra will mark processed events (such as stock changes) as "Processed" for all integrations sharing that configuration. As a result, when Brand X processes its stock events, Brand Y will no longer receive the same event data in its subsequent stock-level queries. This leads to missing updates and prevents the back-in-stock automation from triggering correctly for Brand Y. Best practice tp prevent this is therefore:
* Create one token per brand
* Assign each token a distinct Integration name (such as "Voyado\_Integration\_BrandX", "Voyado\_Integration\_BrandY")
* Ensure each token is only shared with its corresponding Engage tenant
## Subscription API for Centra
The subscription flow is not supported “out of the box” and requires front-end development.
To enhance security and prevent abuse of the Back-in-Stock Subscription API, it is strongly recommended to use a Captcha system. Since the API is open and has no authorization, it is vulnerable to automated scripts and fraudulent activities. Adding a Captcha will help verify that requests originate from legitimate users and protect against bots manipulating the system, ensuring a secure and reliable user experience.
These are the steps in building a subscription flow:
Build a **subscription form** that is visible when the end user enters a product variant page that is considered to be out-of-stock.
**Register the subscriptions** in Voyado Engage, using the Subscription API for Centra.
Ensure that the **locale field** aligns with the locales associated with the product feeds in Engage (for example: “en-US”).
```http The subscription endpoint theme={null}
POST https://accelerator.voyado.com/api/v1/centra/back-in-stock/subscribe
```
```json theme={null}
{
"email": "john.doe@voyado.com",
"sku": "1234-1",
"acceptemail": true,
"store": "voyado.centraqa",
"locale": "en-US",
"externalId":"4"
}
```
The email address of the user. Must be a valid email format.
Example: "[john-doe@voyado.com](mailto:john-doe@voyado.com)"
The productSize.SKU value in Centra.
Example: "1234SIZEM"
If user accepts general newsletters or not.
Example: true
Unique identifier for your Centra environment.
Example: "voyadotenant-1"
Locale matching Engage product feeds.
Example: "sv-SE"
The Market ID connected to the user. Must match the Market ID in the stock change.
Example: "4"
```json theme={null}
{
"email": "john.doe@voyado.com",
"acceptsEmail": true,
"lang": "en",
"countryCode":"US"
}
```
```json theme={null}
{
"ContactId": "0fbfa450-35a6-4d0b-bcd3-b22f00f1ee47",
"sku": "1234-1",
"locale": "en-US",
"externalId":"4"
}
```
### Store field format
The `store` field used above must be a unique string based on your client's setup.
When you have **a single Engage environment for all stores** just use the `tenantId` value as the store field. For example: "mytenant".
When you have multiple Engage stores (one per Centra store) combine the `tenantId` and `CentraStoreID` to a single string. For example "mytenant-124".
Doing this ensures each connection is **uniquely identified** in Engage.
## Stock changes
Engage receives the current Free to Allocate (FTA) quantity for a product at the time of the stock change event. It does not calculate or use the delta (the change in quantity). This means the quantity value in the payload always reflects *the latest available stock level*, and not how much it has changed since the last update.
| **Field name Engage** | **Field name Centra** | **Type** | **Description** | Example |
| :-------------------- | :--------------------- | :------- | :------------------------------------ | -------- |
| sku\* | productSize.SKU | string | The productSize.SKU in Centra. | "1234-1" |
| quantity\* | Free to allocate (FTA) | int | Available stock quantity. | 125 |
| externalId\* | Market ID | string | Market ID matching subscription data. | "4" |
## Workflow
Here is the entire workflow as an image:
## Testing the Integration
Here are some ways to test the integration.
* Subscribe to a back-in-stock notification for a test product.
* Validate that the subscription has been registered on the user in Engage.
* Update stock levels in Centra for a test product SKU.
* Validate that the automation has been triggered and a notification email is sent upon stock update.
* Check Engage Administration > Integration log to confirm stock changes and email triggers are processed correctly.
# Introduction
Source: https://partner-integrations.voyado.com/docs/ecom/centra/introduction
Centra is a headless e-commerce platform that empowers DTC brands to serve advanced e-commerce globally. This section looks at the off-the-shelf integration with Voyado Engage, which is a plugin available in Centra.
## Connecting your markets to Engage
When setting up the Engage plugin in your store configuration, you can choose to map the **Markets** in Centra to **Stores** in Engage. This will help you see from which market you customers were recruited and also the market where the sales were made.
By adding “market” to the External store ID field in the configuration, the extension will personalize and use the market name defined per each market as the store.externalId in Engage.
Adjust the spelling of the market name to not have any space characters.
## Sync of contacts
In Centra you have some configuration options for how to sync your customers to Engage:
Choosing this will sync all the customers stored in Centra to the contact type "Member" in Engage.
This option will only sync customers that were created in Centra with the registered flag set to true. Customers will be registered as "Member" in Engage.
All non-registered contacts will be created in Engage as a “Transactional contact” in order to send transactional emails.
This option will only sync the customers created in Centra with a contactId from Engage.
All the customers without a contactId will be created in Engage as a “Transactional contact” in order to send transactional emails.
Toggling this to "Yes" will sync all newsletter subscribers to the contact type "Contact" in Engage.
## Sync of purchases and returns
Sales are only registered to those customers created as contact type "Member" in Engage.
**Purchases:** A receipt of type "Purchase" is sent to Engage once the order is completed in Centra and ready to be shipped.
**Returns:** A receipt of type "Return" is sent to Engage when a refund has been registered in Centra. This is only applicable if the refund is registered in Centra. If not, then you'll have to build an integration to the system that holds this information (e.g. ERP)
## Transactional emails
Out of the box, Centra can trigger four different transactional emails through Engage. All the order and payment states below are configured in Engage and can be filtered in Engage's marketing automation platform.
If a customer already exists in Engage, the transactional email will be triggered to the already existing contact. If not, then Centra will create a Transactional contact and trigger the email send-out.
Purchases and returns are *not* stored for the contact type "Transactional contact".
These are the transactional emails that are triggered:
* Order confirmation
* Order has been shipped
* Order has been returned
* Order has been canceled
## Multichannel promotions
After some front-end development, you'll be able to assign personal promotions through Engage and connect them to a voucher in Centra.
These steps need to be implemented in order to make this work:
1. The **front-end asks Engage** if the customer has any active promotions. If so, the front-end takes the external promotion code it got from Engage and checks with Centra what the price rule is for that promotion.
2. If the customer wants to use one of those promotions then **the front-end applies the discount** to the purchase (it already knows which price-rule to use).
3. Once the purchase is completed then **the front-end needs to send the promotionId** in the purchase payload to Centra.
4. After interpreting the promotionId **Centra redeems the promotion** in Engage through a separate API-call once the order is shipped.
Centra will redeem the promotion from Engage if and only if the payment has been successful.
## Technical documentation
# What's new?
Source: https://partner-integrations.voyado.com/docs/ecom/centra/whats-new
Here you'll find the changes and updates to the Voyado Engage app for Centra.
There is an RSS feed for this page allowing you to subscribe to changes as they are published.
**Bug fixes**
* Back-in-Stock notifications are now only created for contacts that match the configured sales channel. Previously, notification sign-ups could be recorded without a sales channel association, causing sync failures with Voyado Engage.
**New features**
* Back-in-Stock notifications now support a configurable SKU option, giving you control over which product variant triggers a notification.
**Improvements**
* Events are now processed more reliably in batches — if one event fails, the remaining events in the same batch continue to process independently rather than failing together.
# Integrating your e-com
Source: https://partner-integrations.voyado.com/docs/ecom/integrating-your-ecom
This guide walks you through integrating your e-commerce platform with Voyado Engage to unlock powerful loyalty, communication, and personalization capabilities.
In Engage, customers are called **contacts**. This includes members, subscribers, and prospects.
## 1. The prerequisites
To start building an integration with Engage, here's what you need:
* **An Engage tenant**: This is the instance/environment connected to your Engage account
* **API key**: You must generate this in Engage and use it in all API interactions
* **Base URL**: You must know your base URL of the form `https://[tenant].voyado.com`
* **Contact types**: At least one contact type (such as "Member") should be configured
* **Stores**: At least one store, represented by `storeExternalId` should be defined for test data
Additional data (custom attributes, more stores, etc.) can be added later as needed.
Start by aligning with your Voyado contact (e.g. project manager or partner lead) to ensure:
* You have access to the correct API credentials
* There's a plan for data structure: contacts, transactions, consents
* Configuration is being handled in parallel if not yet complete
## 2. The Engage API
Syncing customer data, transactions and other data between your systems and Engage is done via the Engage API. You will need to know how to work with the API and what security considerations and best practices exist.
### 2.1 Required parameters
All integrations with Engage require a secure API connection. For that, the following parameters must always be configured and stored safely in your integration layer:
* **Base URL** - Your Engage environment endpoint
* **API Key** - Your authentication key generated in Engage
* **Source** - A string identifying the system or integration sending the data (such as “ECOM”)
* **StoreExternalId** - A unique identifier per store, site, or market
These parameters are used in all API calls when creating contacts, submitting orders, sending receipts, or triggering transactional emails.
### 2.2 Integration approaches
Integration can be done through:
* Using a **custom build** which you code for your specific client setup
* Developing a **reusable connector** (if you are using multiple clients)
For single-client, bespoke solutions, configure the parameters directly in your application or middleware.\
This setup is suitable when only one client environment needs to be connected to Engage.
For multi-client or partner solutions, you should build a configurable onboarding interface or settings panel. Each client should be able to enter and manage their own connection details, ensuring secure, isolated, and scalable integrations across environments.
## 3. Working with customer data
When handling customers in your e-com, you always start by checking if they exist as a contact in Engage.
If they don't exist you'll need to create them there before proceeding.
Engage allows custom fields in the customer data model. Your e-com should also support a **dynamic customer model** to let clients decide what values to display and edit for each customer on-site.
### 3.1 Identifying a customer
The default unique identifier for contacts in Engage is **email** but other options exist such as:
* Mobile phone number
* Member number
* Personal identity number
See here how to find a specific contact in Engage:
### 3.2 Registering a customer
If no match is found, you will need to create a new Engage contact for the customer using available data (name, email, address, etc.).
It is recommended to manage all contacts under the **Member** contact type while using **consents** or **custom attributes** to differentiate between them. This provides greater flexibility and control over communication flows, keeps all contact data centralized, enables a unified data structure, and makes segmentation, automation, and reporting in Engage both easier and more powerful.
Include the following in your creation payload:
* **Source**: For example "ECOM"
* **StoreExternalId**: Reflects the customer's market/shipping country
* **Country**: Set from address, site geo-location, or store settings
* **Language**: Based on site language or customer choice (ISO 639-1)
### 3.3 Displaying customer info
The `/contactoverview` endpoint is used fetch the customer's full data profile in Engage (known as the enriched profile).
Useful data points from the enriched profile are:
* First name
* Last name
* Address
* Gender
* Birthday
* Communication preferences
* Loyalty level
* Points
* Available vouchers
* Available promotions
* Consents
Use this data, for example, to display loyalty data on “My Pages” and in checkout.
Multi-channel promotions set up in Engage and can be triggered via an **external code** at checkout. No manual input is needed.
Points are converted to vouchers which give discounts. Vouchers support **multi-currency** and are shown in local currency defined for that market.
### 3.4 Updating customer info
When a customer updates their data (for example name or address), you'll need to push that update to Engage.
Never include fields with empty values in your update payload. All values given in an update payload will overwrite the existing data stored in Engage, even if the values given are empty.
## 4. Working with receipts
Engage uses receipts (the total data of a customer's transaction) to enable personalized experiences and analytics.
### 4.1 Sending receipts
You should sync the receipt to Engage when the order is *completed* (delivered). This ensures that point calculations are based only on what the customer has actually received.
Since orders can be partially fulfilled or have items cancelled along the way, syncing too early could result in inaccurate points being awarded for products that were never delivered.
### 4.2 Receipt details
Here are some important details to consider about receipts:
Discount values should be distributed across all items in a purchase. Include `promotionId` or `checknumber` if a promotion or voucher was used.
Include the **local currency** and **conversion rate** if different from the client's group currency.
Don't include freight in the receipt if the client doesn't want to award points on shipping.
### 4.3 Handing returns
When a return is made, you must send a return receipt containing the details of the returned products.
## 5. Working with orders
Engage supports the tracking of the entire order journey, and can also send communications related to order updates and changes.
Order updates can be sent for:
* Pending orders
* Cancellations
* Shipments
* Deliveries
* Returns
### 5.1 Order communication
When the state of orders change, marketing automation flows in Engage can be triggered.
## 6. Promotions and vouchers
Use Engage's segmentation and automation tools to assign individual promotions or vouchers, such as “10% off for Gold members” or “€10 Voucher“.
Some important points about promotions and vouchers:
* Promotions are created in Engage and referenced in the e-com by an external ID
* It is the e-com that handles pricing rules and redemption logic
* It is Engage that handles personal assignments of the discount
## 7. Web activity tracking
User behaviour on-site can be traced with either:
* Tracking script (client-side)
* REST API (server-side)
The client-side tracking script is the recommended approach.
You can track:
* Product page views
* Cart events
## 8. Soft Identification
Soft identification connects a contact to a session (for example, by an email link) without requiring any login. Engage decrypts an encrypted JSON in the URL query string to perform the identification,
Each client has a unique shared key for decoding the identification token.
## 9. Data migration before go-live
Before go-live, we recommend importing your historical data into Engage to ensure continuity in customer insights and personalization.
Common data that should be migrated incudes:
* **Contacts** (members, newsletter sign-ups)
* **Transactions** (purchases, returns, receipts)
### 9.1 Migrating contacts
This can be done in several ways:
* **Contacts API**: Used for real-time or low-volume imports of contact data
* **Batch contacts API**: Best option for importing large volumes of contact data
* **CSV upload**: Suitable for smaller one-time imports via the Engage UI
* **XML upload via FTP**: For scheduled or high-volume contact imports
### 9.1 Migrating transactions
This can be done by:
* **Transactional API**: For full control and real-time logging of purchases and returns
* **XML via FTP**: Recommended for batch imports of large transaction volumes
The batch API is available for contacts only, not for transactions.
Always follow The Engage API rate limits to avoid throttling during migration.
# Introduction
Source: https://partner-integrations.voyado.com/docs/ecom/salesforce/introduction
Salesforce Commerce Cloud (SFCC) is a cloud-based service for unifying how businesses engage with customers over any channel or device. It enables seamless customer service and experience online or in-store by offering:
* A unified, omnichannel customer journey
* Full customer data integration
* Seamless, engaging and positive customer experiences
These articles will provide an overview of the Voyado Engage integration with SFCC.
## About the integration
The Voyado Engage integration with SFCC (called a *Cartridge* in Salesforce terminology) needs to be deployed, installed and configured in the customer's Salesforce environment. After the SDK license agreement is signed, the client will get access to the source code on Github, together with a guide on how to install the Cartridge.
This installation requires technical skill and is not as simple as just installing an app.
This integration is classed as an SDK, which means it can be extended and modified by the customer to support functionality outside of the implemented scope. However, bear this in mind:
If a Cartridge implementation has had custom development, Voyado can't guarantee the integration will work as intended, nor will Voyado be able to support you technically if any issues arise because of your custom modifications.
The Voyado Engage cartridge is also not compatible with PWA (Progressive Web App) storefronts. While some of the integration components could be used, the majority of the features have to be integrated into a PWA storefront separately, as the architecture is completely different to SFRA (Storefront Reference Architecture).
## What's included
Here is the functionality that is currently supported:
**Contact creation:** Contacts can be stored as two contact types (Member and Contact) or just one (Member).
**Contact updates:** Contacts are synced in both directions, from SFCC to Engage and also in the other direction.
**Promotions:** Promotions can be manually created in Engage and then assigned and connected to a promotion in SFCC.
**Web activity tracking:** Abandoned cart tracking/recovery and product views are supported.
**Order confirmation email:** An order confirmation email is triggered when an order is placed.
**Soft identification:** The storefront can identify customers that arrive through an email send-out.
**Country and store mapping:** The most common setup by merchants using SFCC is to connect a storefront to a specific country which means that in checkout, you are limited to shipping products within the country/countries you have set up for your site. In Engage, country and store mapping is defined by inputing a fallback store and mapping the rest of your Engage stores using a JSON structure.
The Voyado Engage cartridge also allows enrichment of the data shown in the Customer Area pages.
The only order status the integration can trigger is the order confirmation email. If you want to support other order statuses, you’ll need to develop a seperate integration between the OMS / ERP and Engage.
This integration does not support the storing of fulfilled orders or refunds for segmentation purposes in Engage. This is due to the client allowing other platforms (ERP or OMS) to be the master of record for customer data. If you want to support this then you need to develop a seperate integration between Engage and your order managment system platform.
# Working With SCC
Source: https://partner-integrations.voyado.com/docs/ecom/salesforce/working-with-scc
Below you'll find the information you need to configure and work with SCC (Salesforce Commerce Cloud), divded into:
* Contacts
* Transactional emails
* Web activity tracking
* Promotions
* Soft identification
## Contacts
Handling customers (contacts) is central to the Engage SFCC integration.
### Contact creation
An Engage contact is created through the integration in two ways:
* When a customer creates an account in SFCC
* When a guest (a customer without an account) makes a purchase
Both of these methods can be toggled ON or OFF.
### Contact updates
Updates can happen in both directions:
A contact is updated in Engage when any of the following fields are updated in SFCC:
**Personal information:**
* First name
* Last name
* Street
* Postal code
* City
* Email
* Phone number
**Preferences:**
* Accepts email
* Accepts sms
* Accepts postal
Whenever a customer logs into their account, the cartridge fetches their data from Engage and updates the fields below in SFCC:
**Personal information:**
* First name
* Last name
* Street
* Postal code
* City
* Email
* Phone number
**Loyalty information:**
* Point balance
* Member level
* Points left for upgrade
* Level expires
* Level based points
**Preferences:**
* Accepts email
* Accepts sms
* Accepts postal
If a merchant wants to sync additional fields between SFCC and Engage, that can be done by modifying the code.
### Configuration options
In the admin area of SFCC are several configuration options relating to contacts in Engage. Here you can:
1. Enable or disable the two-way contact sync from SFCC to Engage.
2. Enable the use of guest contacts (customers who place an order without an account).
3. Choose which contact type guest contacts will have, “Member“ or “Contact“.
4. Enable or disable the “Promote to Member” flow.
### Guest contacts
As mentioned, you can configure how to sync guest customers, either as “Member“ or “Contact“. This syncing is not done in real-time, but is scheduled to run every minute. If you want to make the syncing real-time, you can do this with some minor code adjustments.
To find the syncing job, navigate to **Administration / Operations / Jobs** in SFCC and find and run the job named “Voyado - Process Receipts”.
## Transactional emails
The “Order confirmation” transactional email is supported by the integration. Other order statuses are not supported because SFCC does not hold the full information for an updated order. If you want to support other order statuses you'll need to build a custom integration between Engage and the OMS / ERP platform you're using.
You can enable or disable the order confirmation email that's sent from Engage:
## Web activity tracking
This covers abandoned cart tracking and recovery, as well as product view tracking.
Web activity tracking as described below requires the SFCC native front-end. If you are a merchant using your own headless commerce solution, you'll have to implement this functionality yourself.
Tracking will only occur if the customer has consented to the “out of the box“ tracking consent requested in SFCC.
Assuming tracking is active and the customer has consented to it, as soon as they enter the site the tracking script kicks in and starts tracking cart updates and product views.
### Configuration options
In the admin area, you first need to enable tracking:
Then fill in the tracking script path and the tenant ID of your Engage environment:
### Abandoned cart
On every cart update, the following is sent via the tracking script:
* Cart reference
* Cart URL
* Locale
* SKU
* Quantity
As soon as the customer is identified, either via an email link or a login, the integration connects the cart reference to the identified contact. When the checkout is completed, the cartridge sends an empty cart to Engage to prevent sending out an email when the products are already purchased.
You can enable and disable the abandoned cart functionality via the admin interface.
### Product views
When a product is viewed, the following data for that product is sent to Engage:
* SKU
* Category name
* Contact Id
As soon as the customer is identified, either via an email link or login, the integration will connect product view data to the identified contact.
## Promotions
Personalized promotions must be configured in both Engage and Salesforce Commerce Cloud (SFCC). The SFCC promotion engine and Engage's advanced segmenting are then used to distribute these promotions to the selected audience. To make this work, the Coupon Code for the promotion in SFCC needs to match the External promotion code in Engage.
Here are the steps in setting up promotions:
In Business Manager navigate to **Merchant tools > Online marketing > Coupons**.
Open up the coupon configuration and copy the Coupon Code:
Open the promotion configuration in Engage.
Paste the Coupon Code from SFCC into the "External Promotion Code" field in the **Basic Settings** tab.
Click "Save".
Click "Save" and you're done.
SFCC will only show a promotion on the cart page if it has been marked as a Voyado promotion. To do this:
1. In Business Manager navigate to **Merchant tools > Online marketing > Promotions**.
2. Select the promotion by clicking the promotion ID in the list.
3. Tick the "Is Voyado Promotion?" checkbox in the Voyado attribute section.
After you have created the promotion, you must create a new campaign and attach it to the campaign.
When the campaign has been created, the next step is to create a coupon code and attach the campaign to that code. In order to show the products associated with the assigned promotions, the promotion ID needs to match the coupon code used when activating the promotion.
In campaign configuration, as a final step, set the coupon code as one of the required promotion qualifiers.
If the promotion name in SFCC does not match the coupon code, the promotion will still work. However then SFCC will not show products associated with the promotion in the Loyalty info page in the Account section.
Make sure that you don’t have any Customer Groups attached to the campaign. If you do, then the discount will be eligible for all users within that Customer Group.
## Soft identification
Input the soft identification (soft login) key, provided by your Voyado team, to start identifying customers who reach your storefront by an email sendout link. This functionality allow you to display active promotions, point balance and other loyalty data for the customer.
# Back in stock notifications
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/back-in-stock
The back-in-stock feature enables customers to receive alerts when out-of-stock products are restocked. This guide explains how to integrate this between Shopify and Voyado Engage.
Before setting up the back-in-stock functionality, ensure the following:
* A connected product feed is set up in the Engage environment
* The back-in-stock module is enabled in Engage
* A back-in-stock email template is available in Engage
* All products (including out-of-stock items) are present in the product feed
If a product is not in the feed, no notification can be sent for it.
Here are the steps in setting up and testing the back-in-stock integration.
## Enable inventory sync
To do this:
Open the Voyado Engage app in Shopify
Navigate to the app settings
Locate the **Inventory Sync** toggle and enable it.
Ensure inventory levels sync correctly from Shopify locations that fulfill online orders.
## Add back-in-stock theme block
To ad the back-in-stock theme block:
In Shopify Admin, go to **Online Store Themes**
Click **Customize** to open the Theme Editor.
Select **Product Templates** and find the **Default product** page template.
Add the **Back-in-Stock** theme block to your template.
Customize the form if needed.
Save the changes.
## Configure subscription form
For the subscription form to appear on the product page:
* Ensure that **Track quantity** is enabled in Shopify Admin
* Ensure that **Continue selling when out of stock** is NOT checked
## Automate notifications in Engage
* In Engage, navigate to **Automations**
* Create a new automation using the **Back-in-Stock** trigger
* Set up the automation to send email or SMS when a product is restocked
* Save and activate the automation
## Back-in-stock for Shopify headless
If you are using a Shopify headless setup, you will need to implement the subscription form manually using Voyado's API. The API allows customers to register their interest in out-of-stock products without using Shopify's built-in theme editor. See more here:
Implement back-in-stock headless like this:
1. Use the API to collect customer information and product details
2. Ensure that product IDs match those in Engage
3. Send the subscription request to the Engage back-in-Stock API endpoint
4. Handle customer confirmation and manage subscription preferences programmatically
5. Test the integration to ensure customers receive notifications when products are restocked
## Testing and troubleshooting
Test the feature by marking a product as out of stock, subscribing to notifications, and then restocking it to ensure an email/SMS is received.
If notifications are not being sent, check:
* The product feed includes the item
* The email template is correctly set up
* The automation is active in Engage
# Back in stock headless
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/back-in-stock-headless
For Engage to trigger a back-in-stock email, all products (including out of stock products) must be present in the product feed that is connected to Engage. If a product is *not* in the feed, a BIS email cannot be sent for it.
When running Shopify as *headless*, back-in-stock functionality is achieved using this endpoint:
```http theme={null}
POST https://live.voyado.eastsideapps.io/api/back-in-stock/subscribe
```
The payload sent to this endpoint to define a subscription for a particular item looks like this:
```json theme={null}
{
"shop": "store-uk.myshopify.com",
"locale": "en",
"country": "GB",
"preSelectStatus": false,
"email": "john@example.com",
"acceptsEmail": true,
"acceptsSms": false,
"hasPhone": false,
"phone": "+4671234567",
"variant": {
"id": "47695659598128",
"is_available": false,
"sku": "jersey-XS-red"
},
"product": {
"id": "8386707489072"
}
}
```
The output to Engage will then look like this for the contact creation request:
```json theme={null}
{
"language": "en",
"countryCode": "GB",
"email": "john@example.com",
"acceptsEmail": true,
"acceptsSms": false,
"mobilePhone": "+4671234567",
}
```
And like this for the create subscription request:
```json theme={null}
{
"contactId": "f5774867-1234-445f-85a4-af1200eced95",
"locale": "en-GB",
"sku": "jersey-XS-red",
"externalId": "store-uk.myshopify.com"
}
```
The fields used are:
The shop's unique identifier on Shopify. Example: "store-uk.myshopify.com".
The locale setting of the merchant. Example: "en".
The country code of the user's location. Example: "GB".
If marketing opt-in is preselected. Example: false
The email address of the user. Example: [john@example.com](mailto:john@example.com).
Indicates whether the user accepts email communication. Example: true.
Indicates whether the user accepts SMS communication. Example: false.
Indicates whether the user has provided a phone number. Example: false.
The variant's unique identifier. Example: "47695659598128".
The stock-keeping-unit associated with the variant. Example: "jersey-XS-red".
Indicates whether the variant is available for purchase. Example: false.
The product's unique identifier. Example: "8386707489072".
### More about preSelectStatus
The preSelectStatus field indicates whether the marketing opt-in checkbox is pre-selected on the back-in-stock subscription form. This boolean value is set by the merchant and determines the initial state of the marketing opt-in option for users interacting with the widget.
**true:** The marketing opt-in checkbox is now pre-selected, meaning customers will be opted into marketing communications by default unless they choose to opt out.
**false:** In this case the marketing opt-in checkbox is not pre-selected, meaning customers will need to actively opt into marketing communications.
The preSelectStatus is used to determine if an update to a customer's preferences is necessary. It ensures that any updates do not override consent previously given by the customer.
## Data flow
Here is the data flow when working with back-in-stock subscriptions:
# Basic concepts
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/basic-concepts
Here are some basic concepts to know when getting started with the app.
## Contact identification
Engage identifies each contact in its system using a unique GUID (Globally Unique Identifier). This is used as the integration key when a customer's data is created, updated or deleted.
If you are using new customer accounts, you won't be able to track who has an account or not in Engage. New customer accounts allow a merchant's customers to log in using a one-time verification code, meaning they don't have to memorize passwords. This information is *not* exposed in the Shopify API.
## Contact types
Engages uses the term "contact type" as a way to group contacts that behave in different ways. This integration uses two contact types to create a solution that works for both Shopify and Engage.
**Contact type "Member":** The contact type "Member" is the primary contact type. A member can enjoy loyalty perks such as points, vouchers and member levels. This should be the goal as these customers receive more benefits and you can collect more data on them. Shopify will use contact type Member for all account holders online.
**Contact type "Contact":** The contact type Contact is used for those who are handled differently than members. The most common use case is when a new contact signs up for a newsletter without first having signed up for membership or creating an account online. Shopify will then use contact type Contact for this person's guest purchases and newsletter registrations.
## Stores / Markets in Engage
You can use multiple markets in the Engage-Shopify integration. Shopify will set the market ID in Engage based on the configuration that is done in the app. This is configurable by the client.
## Consents
If a customer already has a Shopify account, Shopify sets the flag hasShopifyAccount in Engage to “true”.
## Syncing of customer data
The syncing of customer data currently goes in one direction, from Shopify to Engage. This means that at checkout and on account creation Shopify will not fetch any customer data from Engage, but instead use the data that's already in Shopify's customer card and then store that information in Engage. However, Shopify can fetch loyalty data -- point balance, member level, promotions and vouchers -- for a customer and display it on-site.
## Syncing of preference data
Engage is the source of truth for preference data such as the "Accepts email" and "Accepts sms" flags. At checkout, Shopify will never fetch any preference data from Engage, and Shopify will only send an updated preference to Engage if it has been set to “true”. A customer can never choose to set a preference to "false" during checkout.
# Birthday and gender data
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/birthday-gender-data
Your customer's birthdays and gender can be collected in Shopify and automatically synced to Engage.
By then setting up an Engage automation with a birthday trigger, you can send relevant offers and messages to your contacts at the right time.
## Collect birthdays in Shopify
This is how birthday data is collected.
The **Voyado Birthday** metafield is a dedicated customer metafield in Shopify.
**Settings → Metafields and metaobjects → Customers → Voyado Birthday**
You can collect birthday data in several ways:
* Enter it manually in Shopify
* Use a third-party application
* Add the field to a Shopify form to collect it automatically from customers
Choose the method that best fits your workflow.
**Contact's birthday** is a standard automation trigger in Engage:
## Collect gender in Shopify
This is how gender data is collected.
The **Voyado Gender** metafield is a dedicated customer metafield in Shopify.
**Settings → Metafields and metaobjects → Customers → Voyado Gender**
In the metafield settings, you can adjust validation rules. You can remove options from the field if needed. However, you cannot rename existing options, as they must match the values defined in the Engage platform to sync correctly.
You can collect gender data by:
* Entering it manually in Shopify
* Using a third-party application
* Adding the field to a Shopify form to collect it automatically
## The Shopify form
Here's an example of how your Shopify form can look when the birthday and gender fields are included:
In the Shopify form settings, you can edit the field's title, make a field mandatory if needed, and choose the format in which the field should be displayed.
# Configuration guide
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/configuration-guide
Here are the steps in configuring the Shopify app for Voyado Engage.
## 1 - Install the app
In Shopify Admin, go to **Apps** → **Shopify App Store**.
1. Search for **Voyado Engage**.
2. Click **Add app** and complete the installation.
You will need an Engage account to proceed. Choose the option that applies to you:
1. In the app's first screen, choose **I already have an account**.
2. Voyado might need to enable Shopify support for you. Contact your Voyado team.
3. When that is done, proceed to step 2.
1. In the app onboarding, fill in **Company name** and **Company number** (or equivalent).
2. Hit **Submit**. Voyado will now contact you to create the account.
3. Once your Engage account is ready, re-open the app and select **I already have an account**.
4. Now proceed to step 2.
You can always get back to the app configuration later via **Apps** → **Voyado Engage** → **Settings** in Shopify.
## 2 - Connect Shopify to Engage
In Shopify, open **Apps** → **Voyado Engage** → **Settings**.
### Voyado API Domain
Under **Engage account connection**, fill in **Voyado API Domain:**
* Production: `https://[tenant].voyado.com`
* Staging: `https://[tenant].staging.voyado.com`
Replacing `[tenant]` with your Engage tenant name.
### Voyado API Key
Generate this in **Config Hub** inside your Engage environment (API key for the Shopify app).
1. Click **Connect**.
2. Verify that a confirmation panel appears showing the connected Engage URL.
### Changing environment
If you need to change which Engage environment your Shopify app is connected to, you can:
1. Go to **Settings** and then **Disconnect**
2. Enter a new API Domain and API Key
3. Press **Connect** again
All app configuration (mappings, toggles, and so on) will be retained when you disconnect/reconnect
## 3 - Map countries to stores
Now you will map your countries in Shopify to stores in Engage. The store -> country mapping determines which Engage store that each Shopify customer and order belongs to. This is critical for segmentation and reporting.
To do this:
1. In Shopify, open **Voyado Engage** → **Settings** → **Voyado Store to Country Mapping**.
2. Click **Add mapping**.
3. For **Mapping type**, choose **Shipping country**.
4. For **Voyado Store**, pick the Engage store (type `ECOMM`) which will handle that shipping country.
5. For **Shipping country**, select the corresponding country from Shopify.
6. Repeat these steps for each market you sell to.
7. Set a **Rest of the world fallback store** (mandatory) for customers with unmapped or missing country.
If you have Shopify Markets (one store, many countries), you'll typically have one `ECOMM` store per country in Engage, and will map each shipping country to the right store.
## 4 - Contact synchronization
Now you will determine how customers from Shopify are created as contacts in Engage.
Open **Voyado Engage** → **Settings** → **Contact synchronization** in the app.
### Identification method
Pick **Customer identification method**:
* **Identify by email only (recommended)** - lookups only by email (this is unique in Engage).
* **Email first, then phone number** - only if you're okay with the risk of non-unique phone numbers.
* **Phone number first, then email** - the least recommended option.
Use **Identify by email only** to avoid duplicates.
### Contact type
Choose **Customer contact type**:
* **Create everyone as Member (recommended)** - Ths means all Shopify customers will be stored as Members in Engage.
* **Both Contact and Member** - Not recommended with Shopify's **New Customer Accounts**, because all new customers will effectively end up as Contacts.
With Shopify's **new customer accounts**, Voyado recommends **Create everyone as Member** so all e-com shoppers are treated as account holders in Engage.
## 5 - Orders to receipts
This determines when orders in Shopify will be sent to Engage to become transactions / receipts. Do this:
1. In the Voyado Engage app, go to **Settings** → **Receipt sync stage** (wording may vary slightly).
2. Choose when an order should be stored as a Receipt in Engage, either:
* **When Order is Unfulfilled**
* **When Order is Fulfilled**.
Once a receipt is created, it can be used for segmentation and point calculations and shown on dashboards in Engage.
Make sure **Store to Country Mapping** is in place first, otherwise receipts will fail to sync.
## 6 - Order notifications
This determines how transactional emails are sent from Engage.
1. In Engage, prepare your automation workflows and email templates for:
* Order confirmation
* Order shipped / partially shipped
* Order cancelled
* Order refunded
2. In Shopify, for Shopify Plus stores, disable Shopify's native transactional emails (where allowed) so customers don't get duplicates.
3. In the Voyado app **Settings**, enable **Order notifications** (name might vary slightly) so Shopify events trigger Engage automations with mapped order data.
## 7 - Back in stock sync
This keeps the inventory levels synced from Shopify to Engage, allowing back-in-stock functionality to work.
### Prerequisites
Before you start configuring this in Shopify, make sure the following are in place in Engage:
* **Product feed connected and active** - Your Shopify product feed must be imported into Engage and updating regularly.
* **Back in stock module enabled** - The Back-in-Stock feature must be activated in the Engage tenant.
* **Back in stock email/SMS template ready** - There is at least one template (usually email) that can be used for the notification.
* **All relevant products exist in the feed** - If a product isn't in the feed, Voyado can't send Back-in-Stock notifications for it.
If any of these are missing, it's vital that you fix them first (this is usually done together with your Voyado CSM or implementation team).
### Inventory Sync
Do this in the Shopify app:
1. In Shopify Admin, go to **Apps** → **Voyado Engage**.
2. Open the app and go to **Settings**.
3. Find the toggle for **Inventory Sync** and turn it "ON".
4. Make sure the locations that handle online orders are included in the stock levels that are synced (meaning, the same locations Shopify uses for your online store).
This step ensures that when stock levels change in Shopify, Engage is updated and knows when to trigger notifications.
## 8 - Soft ID Detect App Embed
To enable this in Shopify:
1. In Shopify Admin, go to **Apps** → **Voyado Engage**.
2. Click **View app embed**
3. In the App Embed view, enable the toggle:
* **Soft ID Detect App Embed**
4. Click **Save** in the top right corner.
This toggle must be enabled for Soft ID (and tracking features) to work at all.
## 9 - Soft ID decrypt key
Here you'll configure the soft identification decrypt key. This key is required for Shopify to decrypt the identifier coming from Engage-generated email links.
1. Login to **Voyado Engage**.
2. Go to **Administration** -> **Configure Engage**
3. Open **Soft identification** section
4. Copy the **Encryption key** (for the correct environment, usually production)
5. Go back to **Shopify admin** -> **Apps** -> **Voyado Engage**
6. Paste the key into **Soft identification decrypt key**
## 10 - Web pixel tracking
Web pixel tracking is used in abandoned cart, abandoned browse and products of interest. Before you start configuring this in Shopify, make sure the following are in place in Engage:
* Your **Product feed** must be imported into Engage and updated regularly
* The **Soft ID Detect App Embed** must be active (see step 8 above for details)
Now follow these steps:
1. In Shopify, open **Voyado Engage** → **Settings** → **Web Pixel Tracking**.
2. Enable **Enable cart tracking** for abandoned cart flows.
3. Enable **Enable identification of customers by email at checkout** (and also **Create a customer in Engage if their email is not found** if you want auto-creation to function).
4. Enable **Enable product view tracking** for products of interest / abandoned browse.
5. Confirm that the environment configured (production or staging) matches your Engage API domain.
## 11 - Loyalty & promotions
Now you will decide how loyalty and promotions are shown in the storefront by configuring theme blocks and checkout appearance.
### App theme block
1. In Shopify Admin, open **Voyado Engage** and select **Customize theme** in the app.
2. In the Theme Editor, click **Add section** → **Apps** → **Voyado**
3. Insert the **Loyalty / Promotions** block where you want it (for example, **My account**).
4. Now save the theme.
### Vouchers & promotions
In Shopify:
1. Go to **Voyado Engage** → **Settings**
2. Enable **Promotion sync** (for multichannel promotions from Engage)
3. Enable **Loyalty voucher sync** (for reward vouchers from Engage)
4. Enable **Combination options** and choose whether a voucher can be combined with:
* Product discounts
* Order discounts
* Free shipping discounts
In Engage:
1. Set up **Reward vouchers** (from points) as needed.
2. For promotions, make sure the **External promotion code** exactly matches a discount code in Shopify
### Loyalty checkout extension
If you're on Shopify Plus:
1. Go to **Settings** → **Checkout** → **Customize**.
2. Add the **Loyalty Checkout Extension** (usually near the discount code field).
3. Configure whether to require login in order to show offers.
4. Configure label overrides (optional).
5. Configure whether you show promotions, vouchers, or both (depends on which sync toggles are on).
The Checkout UI extension applies for Shopify Plus customers only.
## 12 - Data import
In this step you will be importing existing customers and orders. If you're onboarding an existing Shopify store, run these imports so that Engage starts with the full customer history.
In Shopify, open **Voyado Engage** app → **Data Import**.
### Import customers
1. Choose **Import customer data** and click **Submit**.
2. All Shopify customers (including Shopify POS) are created in Engage if they don't exist.
3. If they do exist, the app just fetches their `contactId` and stores it in Shopify for future linking.
### Import orders
1. In the same screen, choose the date range (**Start date** / **End date**) for orders you want to migrate.
2. Click **Submit** to import orders.
3. Orders are imported only when their customer already exists in Engage (hence customers first).
Be sure to temporarily disable Engage automations that trigger on "New contact registered", "Product purchase", or "New return" so you don't accidentally trigger send-outs during the import of historical data.
# Field mappings
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/field-mappings
Here are all the data mappings for the Engage - Shopify integration.
## Contact data mapping
| **Engage** | **Source data (Shopify)** | **Notes** |
| :----------------------------------------------- | :------------------------------------------------------------------- | :------------------------------------------------------------------------- |
| Contact.externalId | Customer.id | |
| Contact.contactType | "member" or "contact" | Only set on contact creation. according to "Customer contact type" setting |
| Contact.firstName | Customer.firstName | |
| Contact.lastName | Customer.lastName | |
| Contact.email | Customer.email | |
| Contact.gender | voyado.gender | Available as a customer metafield in Shopify. |
| Contact.mobilePhone | Customer.phone | |
| Contact.createdInStore | Associated Store for Customer.locale | Based on market configuration in Engage App in Shopify |
| Contact.street | Customer.defaultAddress.address1 , Customer.defaultAddress.address2 | |
| Contact.city | Customer.defaultAddress.city | |
| Contact.country | Customer.defaultAddress.country | |
| Contact.countryCode | Customer.defaultAddress.countryCodeV2 | |
| Contact.language | | |
| Contact.externalId | | Shopify internal Id |
| Contact.preferences.acceptsEmail | Customer.emailMarketingConsent.marketingState == SUBSCRIBED | Set on Contact creation and opt-in through an order |
| Contact.preferences.acceptsSms | Customer.smsMarketingConsent.marketingState == SUBSCRIBED | Set on Contact creation and opt-in through an order |
| Contact.preferences.acceptsPostal | false | Only set on Contact creation. |
| Contact.consents\[id="hasShopifyAccount"].value | Customer.state == ACTIVE | Set for all customers who have an account online |
| Contact.consents\[id="hasShopifyAccount"].source | "Shopify" | |
## Receipt data mapping
| **Engage** | **Source data (Shopify) - orders/create** | **Source data (Shopify) - refunds/create** | **Notes** |
| :---------------------------------------- | :---------------------------------------------------------------------------------- | :----------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Receipt.contact.matchKey | | Associated Contact Voyado Contact ID | |
| Receipt.contact.matchKeyType | "contactId" | | |
| Receipt.uniqueReceiptId | Order.id | Refund.order.id | |
| Receipt.receiptNumber | Order.name | Refund.order.number | |
| Receipt.createdDate | Order.createdAt | Refund.createdAt | |
| Receipt.storeExternalId | Associated Store External ID by Customer.locale retrieved from database | | Based on market configuration in Engage App in Shopify |
| Receipt.currency | Order.currencyCode | Refund.order.currencyCode | |
| Receipt.exchangeRateToGroupCurrency | | | The exchange rate between "voyado group currency" (see settings) and Order.currencyCode / Refund.order.currencyCode , retrieved from third party service (with 24-hours accuracy) |
| Receipt.totalGrossPrice | Order.totalPriceSet.shopMoney.amount | Refund.totalRefundedSet.shopMoney.amount | |
| Receipt.paymentMethods\[].type | Order.transactions\[].gateway | Refund.transactions\[].gateway | |
| Receipt.paymentMethods].description | Order.transactions\[].\[paymentProvider.name | Refund.transactions].\[paymentProvider.name | |
| Receipt.paymentMethods\[].value | Order.transactions\[].amountSet.shopMoney.amount | Refund.transactions\[].amountSet.shopMoney.amount | |
| Receipt.items\[] | Order.lineItems\[] | Refund.refundLineItems\[] | |
| Receipt.items\[].type | "PURCHASE" | "RETURN" | |
| Receipt.items\[].quantity | Order.lineItems\[].quantity | Refund.refundLineItems\[].quantity | |
| Receipt.items\[].grossPaidPrice | Order.lineItems\[].discountedTotalSet.shopMoney.amount | Refund.refundLineItems\[].priceSet.shopMoney.amount | |
| Receipt.items\[].taxAmount | Sum of Order.lineItems\[].taxLines\[\*].priceSet.shopMoney.amount | Refund.refundLineItems\[].totalTaxSet.shopMoney.amount | |
| Receipt.items\[].sku | Order.lineItems\[].sku | Refund.refundLineItems\[].lineItem.sku | |
| Receipt.items\[].articleNumber | Order.lineItems\[].sku | Refund.refundLineItems\[].lineItem.sku | |
| Receipt.items\[].discounts\[].type | Derived from type of Order.lineItems\[].discountAllocations\[].discountApplication | | See \*A1 |
| Receipt.items\[].discounts\[].description | Derived from type of Order.lineItems\[].discountAllocations\[].discountApplication | | See \*A2 |
| Receipt.items\[].discounts\[].value | Order.lineItems\[].discountAllocations\[].allocatedAmountSet.shopMoney.amount | | |
## A1 - Discount type mapping
| **DiscountApplication type** | **Engage discount description** |
| :--------------------------- | :------------------------------ |
| AutomaticDiscountApplication | 235 |
| DiscountCodeApplication | 235 |
| ManualDiscountApplication | 235 |
| ScriptDiscountApplication | 235 |
## A2 - Discount description mapping
| **DiscountApplication type** | **Engage discount description** |
| :--------------------------- | :------------------------------------------------------------ |
| AutomaticDiscountApplication | Automatic discount: `\${AutomaticDiscountApplication.code}` |
| DiscountCodeApplication | Discount code: `\${DiscountCodeApplication.code}` |
| ManualDiscountApplication | Manual discount: `\${ManualDiscountApplication.description}` |
| ScriptDiscountApplication | Script discount: `\${ScriptDiscountApplication.title}` |
## Cart abandonment
| **Engage** | **Source** |
| :-------------------- | :----------------------------------------- |
| \[].CartReference | AbandonedCheckout.cart\_id |
| \[].Time | AbandonedCheckout.updated\_at |
| \[].ContactId | Identified contact ID |
| \[].Language | AbandonedCheckout.customer\_locale |
| \[].Url | AbandonedCheckout.abandoned\_checkout\_url |
| \[].Items\[].Sku | AbandonedCheckout.line\_items\[].sku |
| \[].Items\[].Quantity | AbandonedCheckout.line\_items\[].quantity |
## Engage order notification
| **Engage** | **Source (Shopify) - orders/\*** | **Source (Shopify) - refunds/create** | **Notes** |
| :--------------------------------- | :------------------------------------------------------------------------------------ | :------------------------------------------------------------------ | :-------- |
| contact.matchKey | Order.email or Order.phone (based on *customer identification method*, see settings.) | | |
| contact.matchKeyType | "email" or "phone" (based on *customer identification method*) | | |
| orderStatus | | | See \*B3 |
| paymentStatus | | | See \*B4 |
| orderNumber | Order.name | | |
| createdDate | Order.createdAt | | |
| shippingDate | Order.fulfillments\[0]?.createdAt | | |
| statusChangedDate | Order.updatedAt | | |
| storeId | Associated store ID for Order.customerLocale (see store locale mapping.) | | |
| currency | Order.currencyCode | | |
| language | Order.customerLocale.split('-')\[0] | | |
| totalGrossPrice | Order.totalPriceSet.shopMoney.amount | | |
| freightFee.value | Order.shippingLine.discountedPriceSet.shopMoney.amount | | |
| freightFee.tax | sum(Order.shippingLine.taxLines\[].priceSet.shopMoney.amount | | |
| totalTax | Order.totalTaxSet.shopMoney.amount | | |
| taxDetails\[].description | Order.taxLines\[].title | | |
| taxDetails\[].value | Order.taxLines\[].priceSet.shopMoney.amount | | |
| extraData.CreatedDate | Order.createdAt | | |
| extraData.ShippingDate | Order.fulfillments\[0]?.createdAt | | |
| extraData.ReturnDate | Order.refunds\[0]?.createdAt | | |
| extraData.TrackingNumber | Order.fulfillments?\[0].trackingInfo.number | | |
| extraData.TrackingLinkHTML | Order.fulfillments?\[0].trackingInfo.url | | |
| extraData.ShippingMethod | Order.shippingLine.code | | |
| extraData.ShippingAddressFirstName | Order.shippingAddress.firstName | | |
| extraData.ShippingAddressLastName | Order.shippingAddress.lastName | | |
| extraData.ShippingAddressStreet | Order.shippingAddress.address1 + Order.shippingAddress.address2 | | |
| extraData.ShippingAddressZipCode | Order.shippingAddress.zip | | |
| extraData.ShippingAddressCity | Order.shippingAddress.city | | |
| extraData.ShippingAddressCountry | Order.shippingAddress.countryCodeV2 | | |
| extraData.ShippingAddressPhone | Order.shippingAddress.phone | | |
| extraData.ShippingAddressEmail | Order.email | | |
| extraData.PaymentMethod | Order.paymentGatewayNames.join(',') | | |
| extraData.BillingAddressFirstName | Order.billingAddress.firstName | | |
| extraData.BillingAddressLastName | Order.billingAddress.lastName | | |
| extraData.BillingAddressStreet | Order.billingAddress.address1 + Order.billingAddress.address2 | | |
| extraData.BillingAddressZipCode | Order.billingAddress.zip | | |
| extraData.BillingAddressCity | Order.billingAddress.city | | |
| extraData.BillingAddressCountry | Order.billingAddress.countryCodeV2 | | |
| extraData.BillingAddressPhone | Order.billingAddress.phone | | |
| extraData.BillingAddressEmail | Order.email | | |
| items\[] | Order.lineItems\[LineItem.refundableQuantity > 0] | Order.refunds\[].refundLineItems\[] | |
| items\[].type | "purchase" | "return" | |
| items\[].sku | Order.lineItems\[].sku | Order.refunds\[].refundLineItems\[].sku | |
| items\[].quantity | Order.lineItems\[].refundableQuantity | Order.refunds\[].refundLineItems\[].quantity | |
| items\[].grossPaidPrice | Order.lineItems\[].discountedTotalPriceSet.shopMoney.amount | Order.refunds\[].refundLineItems\[].priceSet.shopMoney.amount | |
| items\[].taxAmount | sum(Order.lineItems\[].taxLines\[].priceSet.shopMoney.amount) | Order.refunds\[].refundLineItems\[].totalTaxAmount.shopMoney.amount | |
| items\[].description | Order.lineItems\[].name | | |
| items\[].imageUrl | Order.lineItems\[].image.src | | |
| items\[].discounts\[].type | Order.lineItems\[].discountAllocations\[].discountApplication | | See \*B1 |
| items\[].discounts\[].description | Order.lineItems\[].discountAllocations\[].discountApplication | | See \*B2 |
| items\[].discounts\[].value | Order.lineItems\[].discountAllocations\[].allocatedAmountSet.shopMoney.amount | | |
## B1 - Discount type mapping
| **DiscountApplication type** | **Engage discount type** |
| :--------------------------- | :----------------------- |
| AutomaticDiscountApplication | 235 |
| DiscountCodeApplication | 235 |
| ManualDiscountApplication | 235 |
| ScriptDiscountApplication | 235 |
## B2 - Discount description mapping
| **DiscountApplication type** | **Engage discount description** |
| :--------------------------- | :------------------------------------------------------------ |
| AutomaticDiscountApplication | Automatic discount: `\${AutomaticDiscountApplication.code}` |
| DiscountCodeApplication | Discount code: `\${DiscountCodeApplication.code}` |
| ManualDiscountApplication | Manual discount: `\${ManualDiscountApplication.description}` |
| ScriptDiscountApplication | Script discount: `\${ScriptDiscountApplication.title}` |
## B3 - Order status mapping
| **Condition** | **Value** |
| :------------------------ | :--------------------- |
| Order.refunds | "REFUNDED" |
| Order.fulfillments | "FULFILLED" |
| Order.partialFulfillments | "PARTIALLY\_FULFILLED" |
| Order.cancellations | "CANCELLED" |
| Otherwise | "CONFIRMED" |
## B4 - Order payment status mapping
| **Condition** | **Value** |
| :-------------- | :---------------- |
| Order.fullyPaid | "PAID" |
| Order.unpaid | "UNPAID" |
| Otherwise | "PARTIALLY\_PAID" |
# Good to know
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/good-to-know
Here are some good-to-know things about the Shopify - Engage integration.
## 1 - Environment setup
To ensure a stable and implementation, the following is recommended:
Set your **Shopify Development Store** to you Engage staging environment:
```http theme={null}
{tenant}.staging.voyado.com
```
And set your **Shopify Production Store** to you Engage production environment:
```http theme={null}
{tenant}.voyado.com
```
This setup ensures:
* Clear separation between test data and live customer data
* No risk of mixing staging and production contact records
* Clean and controlled store mapping
* Safe testing of imports, automations, promotions, and vouchers
* Reduced risk of data inconsistencies
This is the preferred and most secure configuration.
### Single Shopify production store
In some cases, merchants may only have *a single Shopify production store* and may want to connect it to both their Engage staging (for testing) and then later to their Engage production environment. While technically possible, this setup requires additional care due to how the integration handles environment data.
When the Shopify store connects to Engage:
* The list of Engage stores is retrieved and stored in the app’s internal database
* This store list remains stored even if the app is later disconnected
If the same Shopify store is connected to both Engage staging and Engage production, and the store configurations differ between environments, both sets of stores may remain stored internally.
This can create confusion in store mapping if environments are switched without proper handling.
When running a customer data import:
* Each Shopify customer is linked to a specific `contactId` in the connected Engage environment
* This reference is stored internally
If customer data has been imported into Engage staging, the stored `contactId` values will point to staging contacts.
When later switching to Engage production, those references *must* be updated to point to the production contacts instead.
If they are not updated, order synchronization and automations may reference incorrect records.
If you have previously connected your Shopify store to Engage staging and are now moving to Engage production, these are the steps you *must follow*:
To change your Shopify store connection from Engage staging to Engage production:
1. Disconnect the Voyado Engage app.
2. Enter your Engage production credentials.
3. Click **Connect**.
4. Navigate to **Data Import**.
5. Run **Import customer data** again.
This ensures:
* All customers are re-synchronized
* The correct Engage production `contactId` references are stored
* Future order synchronization and automations use the correct production data
These things must be kept in mind:
* Do *not* skip the contact re-sync step when switching environments
* Avoid running order imports before re-syncing contacts
* If possible, avoid switching environments on a live production store
## 2 - Shopify plan dependencies
There are some dependancies on the Shopify plan you are using.
Displaying reward vouchers and promotions directly inside the Shopify checkout via the Loyalty Checkout Extension requires **Shopify Plus**.
Merchants not using Shopify Plus can still:
* Sync vouchers and promotions
* Allow manual entry of discount codes
However, they cannot embed the loyalty component inside the checkout.
For transactional emails (order confirmation, shipment, cancellation, etc.) to be sent from Engage instead of Shopify:
* Shopify Plus is required to disable most native Shopify emails
* “Order confirmation” must be disabled by Shopify support
Without this setup, there is a risk of duplicate email communication.
## 3 - Customer account theme limitations
There are theme limitations based on the kind of customer account.
The Loyalty app theme block:
* Works only with \*\*Shopify Classic Customer Accounts
* Is not supported for \*\*New Customer Accounts
* Cannot be placed on the checkout page
If a merchant uses New Customer Accounts, the standard loyalty block cannot be used.
The app block requires a theme that supports **Shopify OS 2.0 app blocks**.
Older or heavily customized themes may require adjustments or upgrades.
## 4 - Reward vouchers and promotions
Reward vouchers and promotions are separate features and operate differently.
Reward vouchers are synced to Shopify as discount codes. They are synced only when:
* The customer visits a page containing the Promotions & Loyalty App Block
* Or the Checkout Extension is loaded
Reward vouchers amounts are in the configured **group currency** (which should match Shopify store currency).
If a voucher has already been synced to Shopify, there is a theoretical risk that it can still be used even if redeemed in another channel before the next sync.
This is true for promotions:
* They must first be created in Shopify
* They must then be created in Engage with a matching External Promotion Code
* Promotions are language-specific in Engage and must be configured per language
* Shopify cannot handle duplicate identical external codes
* Only promotions linked to Engage are shown in the loyalty block
## 5 - Synchronization Model
Voucher and promotion synchronization is **trigger-based**, and does not run continuously.
Synchronization occurs only when:
* A page with the loyalty app block is loaded
* Or the checkout extension loads
This is important when setting expectations concerning “real-time” visibility of offers.
## 6 - Data migration constraints
These constraints exist when working with data migration.
Orders *cannot* be migrated to Engage unless the related customer already exists in Engage. Therefore, customer import must always be performed before order import.
If a customer already exists in Engage, the import process:
* Does not overwrite existing Engage data
* Only retrieves and stores the Engage contact ID in Shopify
Existing automations (e.g., “New contact registered”, “Product purchase”) may trigger during migration. This means that automations should be temporarily disabled during large data imports.
## 7 - Receipt & segmentation timing
Orders are only available for segmentation in Engage after they are stored as **receipts**.
Receipt creation depends on the configured sync stage:
* At order confirmation
* Or at fulfillment
Incorrect or missing Store-to-Country mapping (including fallback store) may affect receipt processing.
## 8 - Web tracking and identification
The web tracking features, such as abandoned cart, abandoned browse, product interest tracking, all require that:
* Web Pixel Tracking is enabled
* Soft ID Detect App Embed is enabled
* Checkout Extensibility is activated in Shopify
If a new contact is created during checkout:
* The contact is initially created with `acceptsEmail` set to "false"
* Marketing preferences are updated only after checkout is completed
## 9 - Back-in-stock constraints
These constraints exist for the back-in-stock functionality:
* Products must exist in the product feed even when out of stock
* The “Continue selling when out of stock” setting must *not* be enabled
* The theme block solution does not work in headless implementations (API implementation is required instead)
## 10 - Customer identification
These considerations exist for customer identification:
* Email-only identification is *strongly recommended*
* Phone number identification may lead to conflicts (phone number does not have to be unique in Engage)
Amd due to Shopify's New Customer Accounts structure:
* If both “Contact” and “Member” types are allowed, all customers may be created as Contacts
* To ensure loyalty functionality, “Create everyone as Member” is recommended
## 11 - Browser identifiers and consent
The Voyado Shopify app sets browser identifiers (cookies) to support visitor recognition, customer identification, and cart tracking. This article describes which identifiers are used, when they're created, and what merchants are responsible for when deploying the integration.
## Browser identifiers
The app uses three identifiers:
| Identifier | Purpose | Created when |
| :--------------------------- | :------------------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------- |
| `_va` | Stores the Voyado visitor identifier for website tracking and visitor recognition. | The visitor has granted the required consent. |
| `voyado_soft_ident_key_vtid` | Stores a temporary visitor identifier from a Voyado email campaign link to recognize the visitor during that visit. | A visitor arrives via a link in a Voyado email campaign. |
| `voyado_contact_id` | Stores the Voyado contact identifier for an authenticated customer. | A customer signs in and the required consent has been granted. |
### Consent handling
The `_va` and `voyado_contact_id` identifiers are only created after the visitor has granted the required consent. No website tracking events are sent to Engage until that consent has been granted.
The `voyado_soft_ident_key_vtid` identifier is created when a visitor arrives through a Voyado email campaign link, regardless of consent state. This behavior is built into the integration and is not configurable within the Shopify app. Merchants using Voyado email campaigns must ensure this is appropriately described in their privacy documentation.
### Merchant responsibilities
The identifier behavior described in this article is standard and cannot be changed within the Shopify app. Merchants are responsible for determining whether this implementation meets their legal, regulatory, and privacy requirements.
If the standard implementation doesn't meet your organization's requirements, you can:
* Disable the relevant functionality in the app.
* Implement your own website tracking and identification logic outside the app.
When using the built-in functionality, ensure that:
* Your privacy policy describes how browser identifiers and tracking technologies are used on your site.
* Your cookie information reflects the identifiers the app sets.
* Your Consent Management Platform (CMP) is configured to meet your legal and regulatory requirements.
* Your newsletter terms or privacy documentation covers the use of `voyado_soft_ident_key_vtid` for visitors arriving from email campaigns, where applicable.
### Compliance
Voyado provides the technical functionality described here. Voyado does not determine the legal basis for a merchant's processing of personal data or use of browser identifiers.
Each merchant is responsible for their own compliance with applicable legislation, including GDPR, the ePrivacy Directive, and local privacy regulations, and for maintaining appropriate privacy notices, consent mechanisms, and legal documentation.
If you're uncertain whether the standard implementation is suitable for your organization, consult your legal or privacy advisor before going live.
## Summary
The Shopify integration is powerful but has structural limitations. Consider:
* The use of separate Shopify environments whenever possible
* If only one Shopify production store is available, follow the structured disconnect → reconnect → re-sync process carefully when moving from staging to production
* Features can depend on your Shopify plan level (Plus vs non-Plus)
* Checkout extensibility
* Theme and account type compatibility
* Trigger-based synchronization
* Data migration dependencies
* Store mapping configuration
These constraints should be evaluated early in the project to ensure alignment with the merchant's technical setup and business goals.
##
# Identify in checkout by email
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/identify-in-checkout-by-email
This feature is only available in checkouts where Checkout Extensibility, allowing customization, is enabled.
This features enables identification of customers by their email at the checkout in Shopify. A cookie will be set in the browser to improve identification for functions such as abandoned cart and browsing behavior tracking.
If the customer's email cannot be found in Engage, it is assumed they are new and a contact is then created for them in Engage. The contact is given the source "Shopify checkout".
If needed, this can then be used to identify these contacts in an Engage automation, such as in a “New contact registered” flow, and send them for example a welcome email.
All contacts created through the checkout have `acceptsEmail` set to "false". The event sent from the checkout to the app and then on to Engage to create the contact, does not reveal email marketing preferences. If the customer completes the checkout process, their email marketing preferences will then be updated in Engage.
# Introduction
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/introduction
Shopify is a user-friendly e-commerce platform that helps small and mid-sized businesses to quickly build a modern online store. The company's software allows merchants to design, manage and sell their products across multiple sales channels.
Voyado Engage is a multichannel marketing automation platform used by hundreds of retailers. Engage enables merchants to act on their customer data, granting the insights and campaign tools they need to create extraordinary experiences across all sales and marketing channels.
This integration between Shopify and Engage gives you the power and flexibility of both platforms. It is available as an app in the Shopify app store (search there for "Voyado Engage"). In the following articles you can read about how to set up and use the app to its full advantage.
## What the integration has to offer
The Engage app for Shopify offers a range of exciting functionality, including:
* Keeping the consents (email / SMS / postal preferences) of your customers in sync between Engage and Shopify
* Enabling several types of transactional communication sent out from Engage
* Sending customer's orders to Engage to allow segmentation and BI insights
* Using a custom app theme block in Shopify showing a customer's vouchers and promotions
* Assigning vouchers and promotions in Engage that can then be used in Shopify
* Redeeming of promotions and vouchers through the Shopify-Engage connection
* Soft identification (also called Soft ID), allowing a customer to be identified in a Shopify store when they arrive there via a personalised link, for example from an Engage send-out
* Setting up abandoned cart actions in Engage to reduce lost sales
* Keeping track of a customer's products of interest (those items the customer viewed most often)
* Migrating (importing) customers and their orders into Engage from the Shopify app
* Supporting abandoned browse support out-of-the-box
## Running the app as headless
This documentation deals with configuring and using your Voyado Engage app in Shopify using the Shopify frontend. However the integration can also be run as headless, meaning you will use the Shopify APIs but replace the Shopify frontend with your own custom setup.
To learn about what running headless will entail, [go to this section](/docs/ecom/shopify/running-as-headless).
## Find out more
The Engage Shopify app uses the Engage API. You can read about that [here](https://developer.voyado.com/docs/api/the-engage-api).
The technical details of Engage can be found in the [Engage developer documentation](https://developer.voyado.com).
See the release notes for the Engage Shopify app [here](docs/ecom/shopify/whats-new).
More information and informative guides are available in the [Engage Help Centre](https://help.engage.voyado.com/hc/en-gb).
The Shopify developer docs can be found [here](https://shopify.dev/docs).
# The loyalty API
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/loyalty-api
This API has been created for merchants who wish to implement their own loyalty components in their Shopify store.
Using this API, they can seamlessly synchronize active promotions and vouchers between Shopify and Voyado Engage, as well as display a customer's loyalty data in their own front-end.
## Authorization method
The authorization method **Bearer** is used as part of a HTTPS header.
The key is generated in the app settings section called “Headless API keys“.
## Request
This is the request URL you will use:
```http theme={null}
POST https://live.voyado.eastsideapps.io/api/v1/contact-details
```
With these request headers:
* **Authorization:** Bearer \[YOUR\_AUTH\_KEY]
* **Content-Type:** application/json
* **Accept:** application/json
And one of these request body parameters:
* **shopify\_customer\_id:** This is required if none of the other parameters (voyado\_contact\_id, email) are present.
* **voyado\_contact\_id:** This is required if none of the other parameters (shopify\_customer\_id, email) are present.
* **email:** This is required if none of the other parameters (shopify\_customer\_id, voyado\_contact\_id) are present.
Explore the various payloads below:
```json theme={null}
{
"shopify_customer_id" : "7253944860994"
}
```
```json theme={null}
{
"contact": {
"shopifyCustomerId": 7253944860994,
"voyadoContactId": "d07f7b26-f6e8-4bac-bc16-b0a4008c1ba6",
"attributes": {
"firstName": "John",
"lastName": "Doe",
"street": "Street 1",
"careOf": null,
"city": "Stockholm",
"zipCode": "123 45",
"countryCode": "SE",
"country": "Sweden",
"email": "john.doe@voyado.com",
"mobilePhone": "+46123456789",
"age": null,
"birthDay": null,
"externalId": "7253944860994",
"socialSecurityNumber": null,
"gender": null,
"rfm": 79,
"discoveryKey": null,
"memberNumber": "326",
"language": "en",
"lang": null,
"annualBirthDay": null,
"isRegistrationCompleted": false,
"registrationDate": "2023-10-23T10:30:07+02:00",
"bonusPoints": 208,
"secrecyMarked": false,
"currentStore": {
"id": "c26c0876-434e-42d3-b87c-b08100e15a8c",
"name": "test",
"externalId": "43"
}
},
"bonusPoints": 208,
"memberLevel": {
"expires": "2024-10-23T00:00:00+02:00",
"levelName": "Silver",
"remainingToUpgrade": 139,
"basedOnRewardPoints": 1708,
"levelId": "silver"
},
"activeLoyaltyVouchers": [
{
"expiresOn": "2023-12-31T23:59:59+01:00",
"id": "6f0e82ce-b985-488b-a603-132607267adb",
"checkNumber": "0000000001731",
"name": "Voucher",
"value": {
"currency": "EUR",
"amount": 20
},
"localValues": [
{
"currency": "SEK",
"amount": 204.4
},
{
"currency": "GBP",
"amount": 22.68
}
],
"bonusPoints": 500,
"redeemed": false,
"redeemedOn": null
}
],
"syncFailedActiveLoyaltyVouchers": [],
"activePromotions": [
{
"id": "f0f58414-0b56-4b8a-9d83-b0a400af3145",
"promotionId": "f30a8f6e-0cfd-458d-bea6-b0a400aee0d3",
"externalId": null,
"type": "Multichannel",
"name": "20% off next order (Online discount)",
"expiresOn": null,
"heading": null,
"description": null,
"redeemed": false,
"redeemedOn": null,
"imageUrl": null,
"link": null,
"redemptionChannels": [
{
"type": "POS",
"valueType": "PERCENT",
"value": "20",
"instruction": null
},
{
"type": "ECOM",
"valueType": "EXTERNALOFFER",
"value": "RSX78CVHCX6X",
"instruction": null
}
]
}
],
"syncFailedActivePromotions": []
}
}
```
This is an example response for a failed sync of active promotions (in this case the promotion is not found as a discount in Shopify).
```json theme={null}
"syncFailedActivePromotions": [
{
"id": "323a23f6-84cd-4d23-b733-b0ac0087a168",
"promotionId": "113da8d2-3ffc-44d9-bf9f-b0ac00877ea1",
"externalId": null,
"type": "Multichannel",
"name": "Discount test",
"expiresOn": null,
"heading": null,
"description": null,
"redeemed": false,
"redeemedOn": null,
"imageUrl": null,
"link": null,
"redemptionChannels": [
{
"type": "ECOM",
"valueType": "EXTERNALOFFER",
"value": "143513531",
"instruction": null
}
],
"error": "DiscountCodeNotFoundInShopify",
"errorCode": 409,
"errorDescription": "Voyado contact ID: d07f7b26-f6e8-4bac-bc16-b0a4008c1ba6. Discount code '143513531' is not found in Shopify."
}
]
```
This is an example of a failed sync of active reward vouchers (in this case currency conversion is missing).
```json theme={null}
"syncFailedActiveLoyaltyVouchers": [
{
"expiresOn": "2023-12-31T23:59:59+01:00",
"id": "6f0e82ce-b985-488b-a603-132607267adb",
"checkNumber": "0000000001731",
"name": "Voucher",
"value": {
"currency": "EUR",
"amount": 20
},
"localValues": [
{
"currency": "SEK",
"amount": 204.4
}
],
"bonusPoints": 500,
"redeemed": false,
"redeemedOn": null,
"error": "CurrencyMissing",
"errorCode": 409,
"errorDescription": "Missing currency 'GBP' for voucher '0000000001731'. Contact ID: d07f7b26-f6e8-4bac-bc16-b0a4008c1ba6."
}
]
```
# Mapping stores to countries
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/mapping-stores-to-countries
To get Engage working with Shopify you'll need to map your Shopify markets to Engage stores.
## Markets, countries and locales
In Shopify you can create markets for your store. Each market is a way to divide up your customers into useful segments in order to target specific countries or regions, or just to group countries and regions together to simplify your expansion efforts.
Let's say, for example, you create a market and call it "BeNeLux":
* **Market:** BeNeLux:
* **Countries:** Belgium, Netherlands, Luxembourg
* **Languages:** French (fr), Dutch (nl), German (de)
If you have the language selector for your Shopify store, this means that customers in these countries can pick their language. Combining these 3 countries and 3 languages in all possible ways gives you a total of 3 x 3 = 9 locales (a locale being a combination of a language with a country) for your "BeNeLux" market.
Some of these combinations (nl-LU, fr-NL, de-NL) aren't in the standard so can't be used. Only locale names following [the .NET standard](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/a9eac961-e77d-41a6-90a5-ce1a8b0cdb9c) can be used to configure product feeds in Engage.
This shows how countries and languages combine into locales:
Now removed the invalid locales. This leaves us with:
* fr-BE
* fr-LU
* nl-BE
* nl-NL
* de-BE
* de-LU
There needs to be a **product feed** configured for each of these locales in Engage. However, since product feed is defined by language, only three product feed URLs are actually needed, since we have three languages here. So each product feed URL can be used in multiple locales when configuring them in Engage, as long as they use the same language.
For example, nl-NL and nl-BE can both use the same product feed URL.
If you don't have the language selector enabled for your e-com, the language used for a customer will just be the default one set up for their country.
In a nutshell, you'll have to send to your Voyado team the locales you will use, following the standard above. They will them use these to configure the required product feeds in Engage, for use in email send-outs etc.
With this in mind, here are two ways you can map your Engage store to a country in Shopify:
Imagine that you are a Shopify user selling to three different countries: Sweden, Netherlands and the UK. You have these shipping countries collected within the same Shopify store. When setting up the Voyado Engage app in Shopify, follow the steps below.
**First, you'll need to create the stores in Voyado Engage:**
1. Log into Voyado Engage.
2. In the left-hand menu, select "Administration" and then "Stores".
3. In the top right corner, select “New store“.
4. Input your store's details, for example:
1. **Store:** “ecom SE“
2. **Time zone:** “(+02:00) Europe/Stockholm“
3. **External Id:** “ecom-se“
4. **Store type:** “eCommerce“
5. **Active:** "Yes"
5. Select “Save” in the top right corner.
6. You've created your Sweden store. Repeat step 3-5 for the Netherlands and the UK.
**When all your stores have been created in Engage, you can start mapping them to your Shopify stores within the Voyado Engage app's configuration area.**
It's important to choose one of your stores to be “Rest of the world fallback“. Customers without a location country specified, or with a location country in Shopify that is not connected to a store in Engage, will be automatically connected to whatever Engage store is mapped as your “Rest of the world fallback“.
Errors connected to store mapping can be seen on the “Dashboard“ page.
These are the steps to follow:
1. Log into your Shopify store and access the “Voyado Engage“ app.
2. Go to “Settings“ and the section “Voyado Store to Country Mapping“.
3. Select “Add Mapping“.
4. The mapping type should be “Shipping country“.
5. In the “Voyado Store” drop-down list, choose the store you want to start mapping. In our current example, it's the first of our three countries, Sweden, so choose the “ecom SE“ store.
6. In the “Shipping Country“ list to the right, choose the country “Sweden“.
7. Select “Save“ and the mapping should appear in the list.
8. Repeat steps 3-7 for the Netherlands and the UK.
Imagine again that you sell to three different countries: Sweden, Netherlands and the UK. You have a separate Shopify store for each country. When setting up the Voyado Engage app in Shopify, follow the steps below.
**The first thing you have to do is create the stores in Voyado Engage:**
1. Log into Voyado Engage.
2. In the left-hand menu, select "Administration" and then "Stores".
3. In the top right corner, select “New store“.
4. Input your store's details, for example:
1. **Store:** “ecom SE“
2. **Time zone:** “(+02:00) Europe/Stockholm“
3. **External Id:** “ecom-se“
4. **Store type:** “eCommerce“
5. **Active:** "Yes"
5. Select “Save” in the top right corner.
6. You've created your Sweden store. Now repeat step 3-5 for the Netherlands and the UK.
**When all your stores have been created in Engage, you can start mapping them to your Shopify stores within the Voyado Engage app's configuration area.**
Customers without a location country specified or with a different location than the chosen “Shipping Country” will be connected to the Voyado store mapped as “Rest of the world fallback“. In the example above, the Shopify store will be mapped to the Engage store “ecom SE“.
Errors connected to store mapping can be seen on the “Dashboard“ page.
1. Log into your Shopify store for Sweden and access the “Voyado Engage“ app.
2. Go to “Settings“ and the section “Voyado Store to Country Mapping“.
3. Select “Add Mapping“.
4. The mapping type should be “Shipping country“.
5. In the “Voyado Store” drop-down list, choose the store you want to map. In our current example, it's the first of our three countries, Sweden, so choose the “ecom SE“ store.
6. In the “Shipping Country“ list to the right, choose the country “Sweden“.
7. Tick the box “Rest of the world fallback“.
8. Select “Save“ and the mapping should appear in the list.
9. Now repeat steps 1-8 for the Shopify stores connected to the Netherlands to the the UK.
# Multichannel promotions
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/multichannel-promotions
Here you'll learn how to integrate and manage promotions between Shopify and Voyado Engage. This allows you to synchronize promotional campaigns, enhancing customer engagement and loyalty.
Before integrating promotions, ensure the following:
* The **Voyado Engage app** should be installed and connected to your Shopify store
* An **API key** must have been generated in Engage to allow secure communication
* The **Promotions module** must be active in your Engage environment (ask your Voyado AM)
A customer's promotions are only synced when they visit a page containing the **Promotions & Loyalty App Block**. For example, if the app block is placed on the **My Account** page, promotions will only sync when the customer visits that page. To ensure proper syncing, add the app block to all necessary locations on your Shopify site wherever promotions are to be updated.
And here are some things to keep in mind:
If a customer has used a promotion and that specific promotion is assigned again, Engage will not be able to re-sync it. This happens because both the redeemed and active external codes are required in the Engage API.
If a customer has two of the same external codes (and hasn’t used either of them), Shopify will only be able to handle one, meaning both will be redeemed in Engage.
Shopify only fetches available and used promotions from Engage once the customer logs in. However, it is possible for a customer to use a promotion without being logged in. If an offer is already synced to Shopify and the offer is redeemed from another source outside Shopify, it could theoretically be reused within Shopify.
## Enabling promotions sync
To enable the syncing of promotions between the Shopify app and Engage:
* Log into your Shopify admin panel
* Navigate to **Apps** and select the **Voyado Engage** app
Within the app settings, locate and enable the **Promotion Sync** option.
## Creating discounts in Shopify
* In Shopify Admin, go to **Discounts**.
* Click **Create Discount**
* Choose discount type (Amount of products, Buy X get Y, Amount of order, Free shipping)
* Define the discount details, including value, applicability, and usage limits
* Assign a unique **Discount Code** which will link the Shopify discount to the Engage promotion
* After configuring, click **Save** to create the discount in Shopify
### Creating promotions in Engage
* Log into Engage and navigate to the **Promotions** section
* Click **Create Promotion** and enter promotion details
* Tick the **Can be used online** box
* Locate the **External Promotion Code** field
* Enter the exact Discount Code used in Shopify to ensure synchronization
* Enter a **Title** and **Description** in the **Presentation** section. These details will then appear in the checkout extension app block.
Multilingual support is not available so you'll need to create and assign separate promotions for each language.
Press "Save" and you're done.
### Assigning promotion
You will assign the promotion to customers as follows:
In Engage, activate the promotion
Assign it to selected customers, either manually or via an automation
### Redeeming promotion
Redeeming a promotion happens as follows:
Customers can enter the assigned **Discount Code** during checkout in Shopify.
Shopify validates the code, and if eligible, applies the discount to the order.
The customer completes the purchase with the applied promotion.
Purchase is completed and promotion is marked as "redeemed" in Engage.
## Testing and troubleshooting
**Testing promotions:**
* Create test promotions and conduct trial purchases to verify the integration's functionality
**Troubleshooting issues:**
If promotions aren't applying correctly then:
* Verify the *Discount Code* in Shopify matches the *External Identifier* in Engage
* Ensure the **Promotion Sync** setting is enabled in the Shopify app
* Confirm **Promotions & Loyalty App** block is placed on all necessary pages to trigger syncing
# New customer accounts
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/new-customer-accounts
Shopify is deprecating *Legacy customer accounts* and replacing them with *New customer accounts*.
With this change, Shopify will no longer expose via the API whether a customer has an account.
This means:
* The `hasShopifyAccount` flag is no longer reliable or available
* It is *not possible* to distinguish account holders from guests in Voyado Engage
* You can no longer use account status to control **contact types** or segmentation
This change is due to a platform limitation on Shopify's side, as account login is now handled via one-time codes and is not exposed externally.
## Recommended setup
To ensure consistency and maintain loyalty functionality, Voyado recommends the following setup:
Configure the app to create all customers as type "Member":
**Voyado Engage app → Settings → Customer Contact Type → “Create everyone as Member”**
This ensures all customers can be included in loyalty programs and avoids incorrect contact type classification.
Since Shopify no longer provides account status, loyalty membership needs to be defined explicitly. Voyado recommends using a *consent field in Engage* to mark when a customer joins your loyalty program. This provides several key benefits:
* **Traceability** - Track when a customer joined the loyalty program, including date and time
* **Automation** - Trigger welcome flows, onboarding journeys, and personalized communication
* **Structured data** - Store membership status in a consistent and reliable way
## Collecting loyalty membership
Since loyalty membership is defined using a consent in Engage, the next step is to decide how customers sign up. Here are the recommended options for collecting loyalty membership.
Create a **dedicated loyalty registration flow** outside of Shopify's native account system.
How it works:
* Create a custom sign-up form for loyalty membership
* Collect required fields (e.g. name, email, marketing preferences)
* Include a consent field to define loyalty membership
* Send the data directly to Engage
Benefits:
* Full control over the registration experience
* Clean and reliable data collection
* Works independently of Shopify limitations
If you are using the **Engage Onsite Messaging add-on**, you can capture loyalty members directly on-site.
How it works:
* Create pop-ups or embed minimized forms in Shopify
* Trigger them based on behavior (e.g. time on site, login to My account page)
* Collect:
* Membership data
* Consent for loyalty membership
* Automatically mark users as loyalty members in Engage
Benefits:
* No dependency on Shopify account system
* No coding required
* Contextual and dynamic targeting
If you do not need to distinguish between different customer types, the integration can be used *as is*. This applies if:
* You treat all customers equally, regardless of whether they have actively signed up for a loyalty program
* You define loyalty based on other factors, such as newsletter subscription or purchase behavior (number of orders, spend)
* Other engagement data available in Engage
In these cases, there is no need to introduce a separate loyalty identifier, as segmentation can be handled using existing data in Engage.
## Showing loyalty data
Due to Shopify limitations, the **Engage theme app block** used to display loyalty data such as point balance, member level, promotions, and vouchers is not supported on the **New customer account** page. This is consistent with the current Shopify app documentation, which notes that the theme app block is not applicable for new customer accounts.
The block can still be used on other supported storefront pages outside of checkout and the customer account page. The **Checkout extension for promotions and vouchers** is not affected by this change.
### Customer account UI extensions
If you want to display loyalty data within Shopify's new customer account experience, one possible direction is to build a **Customer Account UI extension** in Shopify. Shopify supports extensions on customer account pages such as **Order index**, **Order status**, and **Profile** pages, which makes this a relevant path for merchants who want a more tailored account experience.
At a high level, this means:
* Creating a customer account extension in Shopify
* Connecting that extension to Engage APIs
* Fetching enriched customer and loyalty data
* Presenting that data in a way that fits your brand and account experience
A key benefit of this approach is flexibility. It gives merchants more control over the *design, content, and overall look and feel*, while still allowing loyalty data to be surfaced in the account experience.
Shopify's customer account extensions are designed for custom functionality in the account area, and Engage's "Get enriched profile" endpoint is specifically described as suitable for populating an e-commerce “My Pages” or other landing page with full customer profile data.
### Which data can be shown
Using Engage's enriched profile API, merchants can retrieve a customer's profile data in a single request. For real-time updates of specific entities like promotions or reward points, merchants may need to use the corresponding entity endpoints directly.
```text theme={null}
+-----------------------------+
| Shopify Storefront |
| (Customer Account Pages) |
+-------------+---------------+
|
| Customer Account UI Extension
v
+-----------------------------+
| Custom Account Extension |
| (UI + Logic controlled by |
| merchant) |
+-------------+---------------+
|
| API request (customer identifier)
v
+-----------------------------+
| Voyado Engage API |
| (Enriched Profile API) |
+-------------+---------------+
|
| Loyalty + profile data
v
+-----------------------------+
| Custom Account Extension |
| (renders loyalty data: |
| points, vouchers, etc.) |
+-------------+---------------+
|
v
+-----------------------------+
| Customer Account UI |
| (Branded loyalty experience)|
+-----------------------------+
```
Here, loyalty data is fetched from Engage via API and rendered through a custom Shopify Customer Account UI extension, giving full control over the account experience.
# Promotions and vouchers in checkout
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/promotions-vouchers-in-checkout
This extension allows customers to redeem discounts, while giving merchants full control over visibility. The key benefits are:
* Customers can apply discounts easily, reducing friction in checkout
* The retailer can choose to display offers to everyone or only logged-in users
* Management and smart targeting of promotions can be done directly in Engage
This guide explains enabling and configuring the **Loyalty Checkout** extension to display promotions and reward vouchers at checkout, enabling a smooth redemption experience for the customer.
## Limitations and requirements
1. **Shopify Plus** is required since Checkout UI extensions are not available for standard plans
2. You must enable either **Promotion sync** or **Voucher sync** (or both) in the Voyado Engage app settings. If neither is enabled, the extension will not sync or display anything at checkout
3. Promotions are **language-specific** and must be created per language in Engage and assigned to matching customer segments
4. Only **Engage-linked promotions and vouchers** are supported — Shopify-native discounts that aren't linked are not displayed within the app block
5. The app block UI components adhere to Shopify’s **Checkout UI component framework**
## Configuration
Follow these steps to configure Engage promotions and vouchers in your Shopify store checkout.
* Go to **Shopify Admin > Settings > Checkout > Customize Checkout**
* In the checkout editor, add the app block **Loyalty Checkout extension** where you want it displayed. Recommended placement is just below the discount code field
Choose whether promotions/vouchers should be shown to:
* All users (anonymous visitors)
* Only logged-in customers
If a customer is not logged in, they are identified when they input their email address during checkout. Then the app syncs with Engage and displays relevant promotions and vouchers.
Promotions assigned to a customer in Engage will not be synced or redeemable if the customer does not exist in Shopify. Make sure the customer profile is created in both systems.
You can customize heading and button text labels within the app block settings.
Overriding these labels disables translation support.
Labels are auto-translated into: English (en), Swedish (sv), Spanish (es), Norwegian (nb), Italian (it), Greek (el), German (de), Arabic (ar), Portuguese (pt), Hungarian (hu), Danish (da), Dutch (nl), French (fr), Bosnian (bs), Malaysian (ms), Indonesian (id), Finnish (fi), Mandarin (zh).
* **Your offers** (can be overridden)
* **Apply** (can be overridden)
* **Applied** (can be overridden)
* **Show**
* **Hide**
* **\[Amount] off your order**
* **\[Currency code] will be converted to your currency**
* **Enable Promotion Sync** to show promotions managed via Engage.
* **Enable Voucher Sync** to display reward vouchers.
* **Enable Both:** Show both promotions and vouchers.
* **Disable Both:** Nothing will be shown at checkout.
Vouchers will be shown in the group currency defined in the general app settings, which should match your default Shopify store currency.
Now set up and manage promotions or reward vouchers directly in Engage. Make sure they’re assigned to the appropriate customer segments and linked to the correct language (if multilingual).
# Resend order notification
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/resend-order-notification
You can resend a transactional order notification directly from the **Order detail page** in Shopify.
To do this:
1. Go to **Shopify Admin**
2. Open the specific **Order**
3. Press the **More actions** button
4. Press **Resend order notification**
The Voyado Engage app will now resend the order notification.
## Which notification is sent?
The notification sent depends entirely on the current order status:
| **Order state** | **Notification sent from Engage** |
| :------------------ | :-------------------------------- |
| Unfulfilled | Order confirmation |
| Fulfilled | Order fulfilled (shipment email) |
| Partially fulfilled | Partial shipment email |
| Cancelled | Order cancelled |
| Refunded | Order refunded |
The app does not let you manually choose the notification type. Instead, it automatically evaluates the order's current state and triggers the correct transactional event in Engage.
## Correcting incorrect email
If a customer accidentally enters the wrong email during checkout, customer service can fix this and resend the notification. There are two approaches, depending on the desired outcome:
To do this:
1. Update the email address on the order in Shopify
2. Click **Resend order notification**
What happens then is:
* The app sends the order notification using the updated email
* A new contact will be created in Engage using that email address (if it does not already exist)
* The existing customer profile in Shopify remains unchanged
Use this option if:
* The mistake only affects this specific order
* You do not want to modify the main customer profile
To do this:
1. Update the email address on the order
2. Update the email address on the Shopify Customer profile
3. Select **Resend order notification**
What happens then is:
* The Shopify customer profile is updated
* The corresponding contact in Engage is updated with the new email address
* The order notification is sent to the corrected email
* No duplicate contact is created in Engage
Use this option if:
* The customer's email should be permanently corrected.
* You want to avoid creating a new contact in Engage.
## Receipt validation before resending
Before resending the order notification, the app performs a validation check:
> Has the transaction (receipt) already been synced to Engage?
If the receipt has **not** been synced, the app will sync it automatically, but only if it matches your configured **Receipt sync stage** setting in the Voyado Engage app.
### Receipt sync stage and resend
In the Voyado Engage app settings, you will define at which stage receipts are synced:
* At order confirmation (Unfulfilled stage)
* At fulfillment stage
When you resend a notification, this setting will be considered.
* If **Unfulfilled**, the receipt will be synced if the order is currently unfulfilled
* If **Fulfilled** the receipt will only be synced if the order is currently fulfilled
This ensures that:
* Receipt data in Engage stays aligned with your configuration
* No receipts are synced prematurely
* Resending a notification does not bypass your defined sync logic
If the receipt has already been synced, it will not be duplicated.
For what this means in practice:
| Order status | Receipt sync stage | Result |
| :----------- | :----------------- | :----------------------------------------------------------------------- |
| Unfulfilled | Unfulfilled | Receipt is synced (if not already), and order confirmation email is sent |
| Unfulfilled | Fulfilled | Receipt is NOT synced. Order confirmation email is still sent |
| Fulfilled | Fulfilled | Receipt is synced (if not already), and fulfillment email is sent |
# Reward vouchers
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/reward-vouchers
In Engage, a contact's points can be converted into a voucher which can then be used to make purchases. Here's how to integrate Engage reward vouchers into your Shopify flow.
## Prerequisites
Before integrating reward vouchers, ensure the following:
* The Voyado Engage app for Shopify is installed and connected to your Shopify store
* An API key has been generated in Engage to allow secure communication between Shopify and Engage
* The Rewards module is enabled in your Engage environment (check this with your Voyado AM)
A customer's vouchers (and promotions) are only synced when they visit a page containing the **Promotions & Loyalty App Block**, or during **Shopify Checkout** when they enter their email. If the app block is placed, for example, on the **My Account** page, vouchers will only sync when the customer visits that page. To ensure proper syncing, add the app block to all necessary locations on your Shopify site where vouchers should be updated.
Read more about the Checkout extension here:
### Enable voucher sync
1. Access App Settings:
* Log in to your Shopify Admin panel.
* Navigate to **Apps** and select the **Voyado Engage** app.
2. Configure Voucher Sync:
* Within the app settings, locate and enable the **Loyalty voucher sync** option.
3. Combination options - Choose whether a voucher can be combined with:
* Product discounts
* Order discounts
* Shipping discounts
### Create and sync vouchers in Engage
This function lets you convert points to Engage vouchers for eligible customers.
When the customer logs into Shopify, the voucher will be created as a Shopify discount.
The **Promotions & Loyalty App Block** will then display the IDs of available vouchers, allowing customers to use them in the discount code field during checkout.
### Redeem vouchers in Shopify
The voucher appears as a fixed amount discount in Shopify.
If a voucher is reactivated in Engage, it will re-sync the next time the customer logs in.
The voucher can be used at checkout and will be redeemed in Engage once used.
## Testing and Troubleshooting
To test reward vouchers:
* Create a test voucher in Engage
* Conduct trial purchases to verify the integration's functionality
If vouchers are not applying correctly, verify that **currency conversion** is correctly configured in Engage.
Ensure also that the **Promotions & Loyalty App Block** is placed on all necessary pages in your web shop to properly trigger the syncing.
# Running as headless
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/running-as-headless
Running Shopify as headless means separating the Shopify e-commerce engine from its front-end, allowing you to replace it with your own front-end (the "head" here referring to the visual parts of Shopify).
This allows you to connect a Shopify back-end to multiple front-ends, such as websites, mobile apps, kiosks, chat interfaces and more. You'll still have access to Shopify's core e-commerce functions -- payment processing, inventory, product management -- while at the same time gaining full control over the design and functionality of the front-ends of all your digital touchpoints and making your customer's experiences exactly how you want them.
## Headless vs traditional
**Traditional Shopify** is easy and fast to set up. A single installation package bundles all you need to create a store, display your products, manage your inventory, and process payments.
In a **headless Shopify implementation** you use the Storefront API to connect a Shopify backend with your front-end (or front-ends) of choice. You can build your front-end using Next.js, React, or any technology you like. A headless installation package will include all core e-commerce features you need, minus the front-end.
## The Shopify API
Headless Shopify is enabled by the Shopify storefront API. Developers can leverage the API to store, fetch, and configure information related to carts, customers, checkout, orders, products, and more. You can access the Shopify through a REST API or with GraphQL.
## Headless pros and cons
Running Shopify headless has the following general advantages:
* **Omnichannel shopping:** Use the same Shopify engine to reach all your customers and easily add more touchpoints as and when you need them.
* **Better SEO:** Customize the views that affect SEO and build a user-friendly website that loads faster and ranks higher on search engines.
* **Faster loading:** Move processing to the backend and optimise your front-end to show only what is needed at any time and no more.
* **Customization:** Use the front-end technology and design that suits you best, and enjoy the flexibility to upgrade both of those things in the future without affecting the backend.
But there are also a few possible disadvantages:
* **Shopify's built-in design features**: You'll no longer be able to use things like themes, templates, or any other built-in design elements. You'll need to build your front-end and all its design elements more or less from scratch.
* **Support needed:** Full customization will require constant developer support. Managing multiple front-ends can be a lot of work for inexperienced or understaffed development teams.
## Running headless with Engage
In the case of Engage, running headless Shopify comes with a few more considerations:
* Abandoned cart will not work, since it is tied to the front-end. To use abandoned cart, the tracking script must be manually implemented by whoever builds your custom frontend.
* As mentioned, the Engage app theme block is not used in headless. The information it displays -- vouchers, promotions, points and member levels -- can all be accessed through the Engage API (contact overview).
# Shopify Flow with custom triggers
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/shopify-flow-custom-triggers
Shopify Flow is an e-com automation platform that you can use to automate tasks and processes within your Shopify store and across your apps. Shopify Flow monitors your store for events and lets you create a sequence of actions that are taken in response. You can automate tasks and processes within your store and across your apps by creating workflows using triggers, conditions, and actions.
Using Shopify Flow's “Send HTTP request“ action, you can trigger a marketing automation in Engage and build user journeys based on the various customer activities in Shopify.
This example looks at how to synchronize selected customer tags from Shopify to Engage and link them to a contact. By configuring a custom trigger in Engage and invoking that trigger within Shopify Flow, you will be able to associate tags as labels in Engage.
## Configuration in Engage
Follow these steps:
Config Hub is found under **Administration** on the left-hand menu in Engage.
Go to the **Custom Triggers** page and create a new custom trigger with the values you need. For example:
* Name: “Gender - Shopify tags”
* TriggerId: “genderTags“
* Description: “Set gender labels in Voyado Engage“
To your new custom trigger, add a new field. For example:
* Name: “gender"
* Description: “Gender“
Pick the custom trigger you just created from the list of triggers
Add a value split in your automation
Input the expected values coming from Shopify Flow and select “Ok”.
Add a “Set label“ activity in each leg of the split
Now activate the automation.
## Configuration in Shopify
Follow these steps:
Create a new flow in Shopify Flow
Choose a trigger (for example: “Customer tags added”).
Add the action “Flow” > “Send HTTP Request“
Choose POST as the HTTP method.
Input the Request URL listed below in the URL field. Be sure to replace “\[tenantId]“ with the actual name of your tenant.
Add the request headers as shown in the section "Request headers" below. Remember to replace the value of *apikey* with your actual API key, which you can find via the [Config Hub](https://help.engage.voyado.com/hc/en-gb/articles/23405185859228-API-connections)
Add the body and loop through the tags you want to send over to Engage. Remember to change the name of the “gender“ field to something more relevant if you are syncing tags that are not related to this specific use-case.
### The request URL
This URL triggers the custom trigger endpoint by using the Shopify ID which is linked to the *externalId* field in Voyado Engage.
```http theme={null}
https://[tenantId].voyado.com/api/v2/automation/customTriggers/[TriggerId]/triggerByExternalContactId/{{customer.id | remove_first: "gid://shopify/Customer/"}}
```
Remember to replace the \[tenantId] and \[TriggerId] in the URL with your values.
### The request header
*apikey: 00000000-0000-000-000000000000*
*Content-Type: application/json*
### Payload body in Shopify Flow
The request payload loops through all the tags of a customer in Shopify and checks for a matching tag defined in the payload.
The for-loop code example below checks if a customer has any of the tags: “Male“, “Female“ or “Other“ and sends it through to Engage as "gender":
```liquid theme={null}
{
"gender" : "{%- for tags_item in customer.tags -%}
{%- if tags_item contains "Male" -%}
{{tags_item}}
{%- elsif tags_item contains "Female" -%}
{{tags_item}}
{%- elsif tags_item contains "Other" -%}
{{tags_item}}
{%-endif -%}
{%- endfor -%}"
}
```
The code example above results in a request payload to Engage that looks like this:
```json theme={null}
{
"gender" : "Female"
}
```
# Sync of email marketing preferences
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/sync-email-marketing-prefs
Email marketing preferences can be synchronized in two different ways between Engage and Shopify, depending on how the integration is configured:
**Webhook disabled**: Preferences are only synced via order events
**Webhook enabled**: Preferences synced continuously based on updates in both systems
In the sections below you'll see how each configuration affects data behavior.
## 1: When webhook is disabled
If the marketing preference webhook in Engage is **not enabled** in the app configuration, email marketing preferences are only synced when the **order/create payload** comes from Shopify, such as when an order is placed. No real-time sync occurs outside of order events.
There are three cases to consider here:
When:
* A customer does not exist in Engage
* And they place an order in Shopify
Then:
* A contact will be automatically created in Engage
* The `acceptsEmail` value will be set to the marketing preference value in the Shopify order
When:
* A customer with marketing preference of "true" places an order in Shopify
* And they already exists in Engage with `acceptsEmail` = "false"
Then:
* The `acceptsEmail` value will be updated to "true" in Engage
When:
* A customer with marketing preference of "false" places an order in Shopify
* And they already exists in Engage with `acceptsEmail` = "true"
Then:
* The `acceptsEmail` field is omitted in the update payload
* The value in Engage remains "true" (meaning that no downgrade occurs)
So when the webhook is disabled, we will **not** automatically overwrite a positive opt-in with a negative value coming from an order.
## 2: When webhook is enabled
If the Engage marketing preference webhook is enabled:
* We listen to all email marketing preference updates
* Changes are synchronized more dynamically between systems
* Preference updates can override existing values depending on the event type
When:
* The customer creates a new Shopify account with email marketing preference set to "false"
* A contact already exists in Engage, having been created via another system, with `acceptsEmail` = "true"
Then:
* We omit the `acceptsEmail` field when updating the contact in Engage
* This means the `acceptsEmail` value will remain "true"
So we do not automatically downgrade `acceptsEmail` during contact creation when marketing preference is "false".
When:
* In Shopify the marketing preference is "false"
* In Engage the `acceptsEmail` value is "true"
* The customer updates billing information in Shopify
Then:
* The update payload from Shopify will includes the marketing preference value ("false")
* This will override the value in Engage so that `acceptsEmail` will now be "false"
Because of this behavior, it is critical during onboarding to ensure that email marketing preferences are fully aligned between Shopify and Engage before going live.
So when the webhook is enabled:
* We listen to all email marketing preference updates
* Changes made in Shopify will update Engage
* Changes made in Engage can be synchronized back to Shopify (if configured)
## Important exception
We always override an `acceptsEmail` value of "true" in Engage *except* when we receive the **customer create webhook** from Shopify with an email marketing preference value of "false" in the payload.
In other words, a marketing preference value of "false" at customer creation will not downgrade an existing "true" value of `acceptsEmail` in Engage.
## Pre-selected opt-in setting
Voyado does **not** recommend enabling support for **pre-selected opt-in** in the Shopify app setup (or relying on Shopify's pre-selected opt-in behavior).
The reason is that in Shopify, once a customer has opted in, they may effectively remain opted in even if they actively deselect the checkbox in a later checkout. This can lead to inconsistent consent states across systems.
For example, a customer can be unsubscribed in Engage based on an order event, but later be set back to opted-in when Shopify sends a customer update (e.g., after billing details are updated).
Shopify's region-based pre-selection adds further complexity and increases the risk of incorrect consent handling.
So do not enable the setting above and be sure to align the consent states between Shopify and Engage before go-live.
## Key recommendations
During onboarding, it is essential to:
* Audit and align all email marketing preferences between systems
* Decide whether the webhook should be enabled based on the desired source of truth
* Clearly define whether Shopify or Engage should control opt-in logic going forward
Misalignment before go-live can result in unintended opt-in overrides.
# Task monitoring overview
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/task-monitoring-overview
In the Task Monitoring Overview you can see the data being sent between Voyado Engage and the Shopify app.
You also have some tools at your disposal to warn you if data is not being sent when you expect it to be.
## Alert settings
In this section in the app you are able to specify a span of time inside a certain time window. If no orders are received inside that time, it might be that something has gone wrong in the data or the connection, and a warning is then sent out the emails that have been subscribed to it.
Outside of the specified check window, no alert will be raised.
This is how the service is configured in the app:
**Order silence period:** If this amount of time passes and no orders are successfully synced between the app and Engage, the system raises an alert. This is an indication that something has gone wrong.
**Scheduled order silence check window:** Here you can specify the daily time window during which order silences will trigger an alert. This is useful if, for example, you know that you never get any orders during the night, and that monitioring is not needed then.
**Error rate threshold:** The percentage of errors out of the total that will trigger an alert.
**Alert notification addresses:** Here you input the *additional* email addresses you want to receive any alerts. The email address connected to your Shopify store will always receive these alerts.
### Example with several stores
In this example the user has connected several stores to their Engage account:
| Value name | Store 1 | Store 2 | Store 3 |
| ------------------------ | ------- | ------- | ------- |
| Approx orders per day | 10 | 100 | 1000 |
| Average first order time | 06:00 | 12:00 | 06:00 |
| Average last order time | 21:00 | 21:00 | 21:00 |
The user should now configure the alert settings for these differently as shown here:
For Store 1, the order silence check window is from 6:00 to 21:00 and the order silence period is 6 hours, which is long because the store has a small number of orders per day. This means if no orders are sent in a 6-hour period inside this time window, an alert will be triggered.
For Store 2, the order silence check window is from 12:00 to 21:00 and the order silence period is 4 hours. If the data connection is down when the check window begins (at 12:00 in this case) and no data is sent, then an alert will first be sent when the order silence period has passed, which is 16:00 here.
Finally, Store 3 has been configured with an order silence check window from 6:00 to 21:00 and an order silence period of 3 hours. This store probably has a larger volume of orders, and a period of 3 hours with no orders can be deemed suspicious. In general, busier stores should have shorter order silence periods.
## Task monitoring
You can access the task monitoring service under **Task overview** in the left-hand menu in your Shopify store, under the settings for your Voyado Engage app. The task monitoring service page itself looks like this:
### Summary section
In the top sections you can see basic stats for "Contact sync", "Order sync" and "All tasks".
The stats displayed here will always be based on all the available data. They will not be dynamically updated based on whatever filters you add in the following "Task listing" section.
### Task listing section
In the second section, "Task listing", you can see an expanded view of the tasks (all transfers of data) sent between your Voyado Engage app for Shopify and your Engage environment. This interface allows an individual task to be selected to view all properties about it, excluding the associated task data.
The listing presents a summary of a task’s properties:
* Task ID (unique for each task)
* Task State (Success, Error, Pending)
* Task type
* Shopify Entity ID
* Created at
* Duration (ms)
The "Sort" button (the double arrows) allows you to sort tasks, ascending or descending, by:
* Created at
* Started at
* Completed at
The "Search and filter" button beside the Sort button opens up a search field where you can search by:
* Task ID
* Shopify Entity ID
* Voyado Engage Entity ID
The "Add Filter" button allows you to filter your tasks by:
* Task type (See Task Translations)
* Task state (Success, Error, Pending)
* Created at (UTC Timezone)
### Viewing a task
By clicking on the ID, you can open up a task and see it in more detail, including the exact data that was sent.
### All task types
Below are the different types of tasks that can turn up in the task listing.
#### Data import tasks
| Task type | Description |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| ProcessBulkImportData | When the app initiates processing of bulk import data. |
| HandleBulkImportCreateRequest | When the merchant initiates a bulk import process from settings within the app. |
| HandleBulkImportCreate | When the app initiates a bulk import create in Shopify. |
| HandleBulkOperationFinish | When the app initiates handling a bulk operation finished by Shopify. |
| BulkOperationFinishWebhook | When Shopify finishes a bulk operation and the app receives this webhook. |
| TriggerNextBatch | When the app initiates a consecutive bulk import action. For example, triggering order bulk import action after the customer bulk import finishes. |
#### Customer sync tasks
| Task type | Description |
| ---------------------------------- | --------------------------------------------------------------------------------------------- |
| CustomerWebhook | On creation or update of customer in Shopify, the app receives this webhook. |
| IndexShopCustomers | When the app initiates timestamp based customers polling for customer indexing for each shop. |
| IndexCustomer | When a customer is created or updated. |
| SyncContact | When app initiates a customer sync to Engage. |
| UpdateCustomerMarketingPreferences | When the app initiates a sync of marketing preferences from Shopify to Engage. |
| SyncCustomerMarketingPreferences | When the app initiates sync of marketing preferences from Engage to Shopify. |
#### Order sync tasks
| Task type | Description |
| -------------------------------- | -------------------------------------------------------------------------------------------------------- |
| OrderWebhook | Upon creating or update of an order in Shopify the app receives this webhook. |
| IndexOrder | When a customer is created or updated in the app's database. |
| FulfillmentWebhook | On fulfillment create in Shopify, the app receives this webhook. |
| IndexOrders | When the app initiates timestamp based orders polling for order indexing for each shop. |
| SyncOrder | When the app initiates order sync to Engage via a POST to the /receipts endpoint. |
| SyncOrderFulfillmentNotification | When the app initiates order fulfillment notification sync to Engage via a POST to the /orders endpoint. |
| SyncOrderNotification | When the app initiates order notification sync to Engage via a POST to the /orders endpoint. |
#### Refund sync tasks
| Task type | Description |
| ---------------------- | ------------------------------------------------------------------------------------------------------ |
| RefundWebhook | When a refund is created in Shopify the app receives this webhook. |
| IndexRefund | When a refund is created or updated in the app's database. |
| SyncRefundNotification | When the app initiates an order refund notification sync to Enagae via a POST to the /orders endpoint. |
| SyncRefund | When the app initiates a refund sync to Engage via a POST to the /receipts endpoint. |
#### Settings tasks
| Task type | Description |
| ---------------- | --------------------------------------------------------------------------- |
| IndexStores | When an Engage store is created or updated in the app's database. |
| SyncShopCurrency | When the app initiates a shop currency sync from Shopify to app's database. |
| ShopWebhook | When a shop is updated in Shopify, the app receives this webhook. |
# Using the app
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/using-the-app
Here's some further information about using the Voyado Engage app for Shopify.
## Contact types
Shopify New Customer Accounts syncs all Shopify customers to the `member` contact type in Engage.
## Unidentified contacts
It's possible for a customer to be created in Shopify if an unidentified user starts a checkout but don't complete it. This will result in a contact being created in Engage who lacks vital information such as email or mobile number. This, almost always, is bad.
To avoid this, deselect "Send abandoned checkout emails automatically" which you'll find under **Settings > Checkout > Abandoned checkout emails** in your Shopify admin.
## Contact types and loyalty
When using loyalty with reward points, your contact types determine how those points are collected (or not collected).
* If you've chosen to make everyone contact type "Member" then all your customers can collect points in Engage.
* If you've chosen to use both "Member" and "Contact" then only Members can collect points in Engage.
In both situations, you can exclude certain Members from reward points by setting up a filter in the Rewards module.
Setting up a filter needs to be done by your Voyado team, so contact them for help.
## Multi-market support
If you have several Shopify stores for each of your markets, you can install the Engage app for each store and connect each Shopify store to a single store in Engage.
If however you have one Shopify store with several markets set up, you can map each market to a different store in Engage.
## Preferences / Accepts email
The Shopify app sets the Accepts email flag / preference at two different times:
**At customer creation:** When a customer is created in Engage, the Accepts email flag is set based on what the customer chose to do. For example, if they sign up for My Pages without setting any consent, Accepts email will be set to "false" in Engage, since the customer hasn’t opted into marketing. But if the customer opts in for the newsletter, the Accepts email flag will be set to "true" in Engage, since they have now opted into marketing.
**At checkout:** If the customer opts in during checkout in Shopify, that opt-in flag will be sent to Engage and used to update the Accepts email preference.
## Newsletter subscribers
If a merchant is using the native Shopify theme block for collecting subscribers, these subscriber will be synced to Engage.
If the merchant is using a third-party platform, they will need to either connect that platform to Engage OR change that platform to one which already has an Engage integration, such as Redeal or Triggerbee.
## Displaying loyalty data
There is a specific Engage theme block available in Shopify. It will be populated with a contact's loyalty data if they have logged in or if they've entered the site through an email send-out (soft-identification), allowing them to be identified. This theme block displays:
* Available promotions
* Available vouchers
* Reward point balance
* Member level
Theme block functionality in the Voyado Engage app will be further developed to support multiple theme blocks, each one displaying a specific combination (or just one) of these values.
## Syncing receipts to Engage
Receipts for purchase are synced for both account holders (Member) and guests (Contact). In the app settings you can choose if this happens at the order confirmation stage or at the order fulfillment stage.
Receipts for returns are synced to Engage when a refund is registered in Shopify. Only the products that have been refunded will be sent to Engage, not the whole order.
Shopify has recently connected the Refund entity to the Return entity, allowing you to verify if a refund with a total of 0 is related to a specific returned product. Previously, refunds with a total amount of 0 were excluded because when an item was removed from an Unfulfilled order (a non shipped order), this was not exported to Engage, since it was not an actual return. But now this verification can be done and new logic added around it.
The steps to get this up and running are:
1. Log in to your Shopify store.
2. Open the Voyado Engage app.
3. The app will prompt user to update data access
4. Update the data access and allow the app to access returns.
## Transactional communication (Shopify plus only)
Discounted products in Shopify are not defined as discounted in the payload received by Engage when triggering transactional emails. This means that discounts can't be indicated in emails.
These states will trigger a transactional communication from Engage:
* Order confirmed
* Order fulfilled
* Order partially fulfilled
* Order cancelled
* Order refunded
Receipts for returns are synced to Engage when a refund is registered in Shopify. Only the products that have been refunded will be sent to Engage, not the whole order.
The state "PARTIALLY\_FULFILLED" is used when, for example, two product are part of a purchase, and both are not sent to the customer at the same time. Then a transactional email can be triggered for only the item that has been fulfilled. Once the second item is fulfilled, the state of the transaction becomes "FULFILLED", triggering another transactional email if needed, and the receipt can then be sent to the /receipts endpoint.
Here you can see the various states of an order.
## Web pixel tracking
Web pixel tracking allows the Engage app for Shopify to track user behavior in a way similar to a cookie, and grants many useful functions.
Web pixel tracking will only run when consent is granted in the context where it is required. In Shopify’s Customer Privacy API the marketingAllowed consent has to be accepted to allow the app to start tracking events and sending them to Engage.
There are some prerequisites for web pixel tracking to work:
* The tracking module in Engage must be enabled.
* The product feed import setup in Engage must be connected to the locales of your Shopify store (For example, en-GB, en-SE).
* The “Soft Identification Embed Block” in your Shopify Engage app must be enabled.
* The “Voyado Soft ID Decrypt Key“, provided by your Voyado team, must have been entered.
* The email template module for abandoned cart emails must exist.
* Marketing automations need to be in place to trigger abandoned cart emails.
### 1 - Identification
The app supports identification in two ways. Visitors are either identified when they log, in or when they enter your site via a personalized link in an email sent from Engage. Once a visitor is identified, the app will connect incoming events to them, as well as previously anonymous events that were connected to the same session and cookie.
### 2 - Cart tracking
By enabling this feature you will start tracking the cart activity of your visitors on-site and trigger abandoned cart emails through Engage. Every time the cart updates, the app will trigger a cart event to Engage containing the products and the current state of the cart.
### 3 - Cart abandonment
You can decide in Engage when a cart should be considered abandoned by entering those criteria when you set up your automation.
### 4 - Locales
When setting up your automations, you will be able to use locale as a filter in order to send emails in the correct currency and language, connecting each locale to a separate product feed.
There is a [liquid variable in Shopify](https://shopify.dev/docs/api/liquid/tags/variable-tags) which is set based on which locale the customer is shopping in. So if a theme has en-US setup on the store, and you have used a language selector to view the site in US english, then the app will pick up from the theme that the current locale is en-US and use that in events.
This can be seen in Shopify under "Settings / Languages" where you can view all available published languages on the store. Under "Settings / Markets" you'll see the all your markets (locales) and there you can check the default languages assigned to each market.
### 5 - Product view tracking
By enabling this, the app can collect a visitor's product views on-site which you can then segment and act upon in Engage.
This setting also enables abandoned browse tracking. This works out-of-the-box and is currently in beta.
# Webhooks for preferences
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/webhooks-for-preferences
Voyado Engage uses a third-party service called Svix as a "Webhooks as a Service" platform. This keeps your Shopify account in sync with any changes made to a customer's marketing preferences for email, postal and SMS communication.
Because “Svix“ is a third-party service, an agreement must be signed before you can use this feature in Voyado Engage. Reach out to your Voyado team and they will help you.
Before you can complete the setup for this service, you'll need an encryption key. Contact your Voyado team to get this.
If you are already live with the Voyado Engage app for Shopify, you must make sure that all marketing preferences are currently in sync between Engage and Shopify before you activate this webhooks feature. Otherwise there is a risk of overriding the correct opt-in/out status in Engage.
## How it works
Svix is used to dispatch events from Engage to a POST endpoint hosted by the Voyado Engage app.
Here is an example of the workflow from Engage to Shopify:
1. The customer opts-out from email marketing through an email sent to them from Voyado Engage.
2. The change in their preferences triggers an encrypted event to Svix.
3. Svix passes the event to the Voyado Engage app, where it is placed in a queue.
4. The app decrypts the event payload and updates the customer's preferences in Shopify
## Prerequisites
There are some prerequisites before this will work:
* The “Webhooks” module need to be enabled in Engage
* You need to have permissions to access the “Webhooks Dashboard“.
* You will have received a 32 character encryption key from your Voyado team
* You've made sure that all customers marketing preferences are in sync between Shopify and Engage
## Setting it up
Here are the steps to follow:
1. Enter the Voyado Engage app for Shopify.
2. Go to “Settings“ and scroll down to the section “Synchronize marketing preference changes from Engage to Shopify.”
3. Enable the functionality by checking the box “Enable“.
4. Input your Encryption key and select “Save”.
1. Copy the webhook URL to your clipboard.
2. Login into Voyado Engage and go to the “Webhooks Dashboard” in the Administration menu.
3. In the top right corner, select “Add endpoint“.
4. Paste in the webhook URL in the "Endpoint URL" field.
5. Enable the events`contact.acceptsEmail.changed`and`contact.acceptsSms.changed`under the section "Message Filtering".
6. Select “Create“ and you are good to go!
## Email marketing options “Preselected“
If you have marketing options set to “Preselected“, you'll have to activate this setting below in the Voyado Engage app. This is needed to sync the correct consent given in the checkout by the consumers.
Now press "Save" and you're done.
# What's new?
Source: https://partner-integrations.voyado.com/docs/ecom/shopify/whats-new
Here you'll find the changes and updates to the Voyado Engage app for Shopify.
There is an RSS feed for this page allowing you to subscribe to changes as they are published.
## App disabled when invalid API key used
With this update, the app automatically disables itself when it encounters an invalid or deleted API key. To resume syncing, merchants need to reconnect the app with a valid API key. Previously, if a customer's API key was revoked (for example, after they churn), the app would remain active and would need to be manually uninstalled.
## Skip customers without email in POS orders
POS orders that include a customer who doesn't have an email address are now filtered out, preventing errors.
## Improved handling of refunds for unfulfilled orders
Previously, syncing a refund for an order that had not yet reached the specified receipt-sync stage would cause the error: “Cannot handle refund due to related order not being synced.” This has now been addressed, aligning refund behavior with the expected syncing logic, which is:
* If receipt-sync stage is set to "Fulfilled" the app ignores the refund until the order is fully fulfilled
* If receipt-sync stage is set to "Unfulfilled" the app syncs the refund immediately
## Fallback store optional in store-to-country mapping
A customer without a specific Engage store will now sync. The “Recruited in store” field will be left empty instead of blocking the sync. Previously, if a customer's country wasn't mapped to a store in Engage, and no fallback store was configured, the app would return a validation error.
If no fallback store is set, orders from unmapped countries won't sync. Be sure to map all shipping countries or else define a fallback store to avoid missing data.
## Shopify app now uses GraphQL
GraphQL is a flexible and modern way to retrieve data from an API, allowing faster syncing and smaller data loads. You will need to go into Shopify and update your Voyado Engage app before April 1st to avoid any issues.
## New UI extensions
The app's POS UI extensions were upgraded to Shopify's new Unified UI Extension Package, improving performance and maintainability, and giving access to the latest Shopify extension features.
## Admin action extension
The existing admin link has been migrated to an Admin Action Extension for a more integrated experience within Shopify Admin.
## Script tag upgrade
Shopify is moving away from script tags, requiring users to move from the `checkout_complete` event to the Web Pixel API's `checkout_completed` event. The `cr` parameter sent to Engage has also been adjusted to exclude the`key` attribute from the cartToken, ensuring consistency across all pixel events.
## New lang attribute
Added instructions for updating contacts to use the new `lang` attribute.
## Handling of zero-value refunds
Added handling of refunds with an amount of 0.
## Web pixel tracking update
Web pixel tracking now allows identification in checkout by email.
## Task monitoring overview
Task monitoring overview page and config panel added.
## Setup and configuration additions
New sections were added to the setup and configuration guide:
* Headless API keys
* Synchronize marketing preferences
* Synchronize marketing preference changes from Shopify orders
## Headless loyalty API
Headless loyalty API added, for displaying loyalty information without using the Shopify front-end.
## Shopify POS integration
Shopify POS integration moved out of beta.
## UI update
New UI released for the Voyado Engage app.
## Shopify POS integration
The Shopify POS integration was released.
## PARTIALLY\_FULFILLED state
Transactional state PARTIALLY\_FULFILLED was added.
## Abandoned browse
Abandoned browse now works out-of-the-box.
## Change in handling of receipt number
Receipt number in Engage is now connected to `order.name` from Shopify instead of `order.number`.
This will not affect already imported orders. Merchants with already imported orders should use the search term “Contains” when segmenting in Engage on specific order number or receipt numbers.
Some merchants may not be affected by this at all since order number and order name can be the same in Shopify. The main change then is a suffix added to the number. Example: "12345" becomes "12345VOY".
## Cancelled order update
A cancelled order no longer triggers a refund email.
## Migration of orders
Added migration of orders for customers who were imported to Engage outside of the Shopify app. For example, through a CSV file import in Engage.
## Consents handled correctly in checkout
The "Accepts email" flag / consent in Engage is now updated correctly when completing checkout in Shopify.
## Validation mismatch fixed
The validation mismatch on orders within the app has now been resolved. Previously, order totals did not match those in Shopify and were therefore not imported.
## Error handling improvement
Better error handling of error message *409 - ContactWithKeyIsBeingCreated*.
## Fix for zero-discount entries
When syncing orders, any zero-discount entries will now not be sent to Engage.
## Products of interest
Products of interest now sent to Engage.
## Migration added
Migration of customers and orders added.
## Assigning of vouchers and promotions
Assigning vouchers and promotions in Engage for use in Shopify.
## Abandoned cart added
Triggering of abandoned cart actions in Engage.
## Contacts sync
Sync of contacts between Engage and Shopify.
## Transactional communication
Transactional communication now sent out from Engage.
## Orders sent
Orders (receipts), both purchase and return, sent to Engage.
## App theme block
App theme block in Shopify showing customer's available vouchers and promotions.
## Redemption added
Redeeming of promotions and vouchers.
## Soft identification added
Soft identification (also called soft ID) added to app.
# Assign promotions
Source: https://partner-integrations.voyado.com/docs/ecom/shopware/How to/promotions
**General Settings**, **Cart and Order Conditions**, and **Discount Rules** are managed within Shopware itself. You must therefore first create your promotion in Shopware before syncing it with Engage and assigning it to your customer base.
Once the promotion is assigned to one or more customers, they must log into their account to access the discount. During the login process, Shopware assigns the promotion by linking the customer to a Rule using their `externalId` in Voyado Engage, which corresponds to their `Customer ID` in Shopware.
If you plan to run a promotion campaign that can be reused, we strongly recommend creating the assignment directly in **Shopware**.
If a customer creates an account in two different sales channels using the same email address, and both are connected to the same Voyado Engage environment, the promotion will only be linked to the `externalId` generated during the first account creation.
If a personal promotion has been assigned in Shopware and redeemed through a third-party system (POS), it will remain active in Shopware.
## Create and sync a promotion
1. Log into your Shopware store
2. Navigate to **Marketing > Promotions**
3. Select **Add Promotion**
1. **Promotion Name:** Enter a name for the promotion
2. **Priority:** Set the desired priority
3. **Valid From:** Choose a start date
If you don't set a start date, the promotion will not be synced to Engage
4. **Valid Until:** Set this to unlimited
5. **Max. Total Uses:** Set this to unlimited
6. **Max. Uses Per Customer:** Set to 1 to minimize the risk of abuse. This extra validation assures the promotion can only be used once per customer.
7. Activate the promotion.
8. Select **Save**.
In the **Promotion Codes** section:
1. Select "Fixed promotion code"
2. Enter your promotion code
Discount codes used with Engage can only contain:
* **A-Z, a-z**.
* **0-9**.
* **Underscore (\_)**
* **Hyphen (-)**.
* **Percentage sign (%)**
Go to the **Conditions** tab and configure:
1. **Pre-conditions**: Define any necessary pre-requirements.
2. **Shopping Cart & Order Rules**: Enter the desired conditions under **Rule-based conditions.**
Do NOT set any Customer rules; Engage will manage these when assigning the promotion.
* Go to the **Discounts** tab and:
* Define the discount logic (e.g., percentage, fixed amount, or free shipping).
* Click **Save**.
1. Navigate to **Marketing** **Voyado Configuration**
2. Select on the **Promotion Sync-up** tab
3. In the **Sales Channel List**, select the Sales Channel linked to the promotion
4. Mark the promotions you want to sync to Engage
5. Select **Sync Promotions**
The promotion will now be created in Engage as a Draft Promotion. It can then be activated and assigned manually or via the Automation tool.
Once assigned in Engage, eligible customers will be able to use the promotion when they log into their account by applying the code in the discount code field.
# Resend order and shipment confirmations
Source: https://partner-integrations.voyado.com/docs/ecom/shopware/How to/resend-orders
Manually re-send an order confirmation or shipment confirmation to a customer directly from the Shopware order detail page.
When an order confirmation or shipment confirmation fails to reach a customer, you can trigger a resend without leaving the Shopware admin. The Voyado Engage app adds two action buttons to the order detail page that let you re-trigger either notification on demand.
This feature requires Voyado Engage app version 2.3.0 or higher. Both customer sync and order sync must be enabled in your integration configuration.
## Resend a notification
In the Shopware admin, go to **Orders** and open the order you want to act on.
In the top-right corner of the order detail page, click the **⋯** (more actions) button.
Choose one of the two options:
* **Resend Order Confirmation** — re-sends the order confirmation and sets the order status in Engage to confirmed. If the order is already marked as completed in Shopware, the receipt is also re-sent to Engage.
* **Resend Shipment Confirmation** — re-sends the shipment confirmation, sets the order status in Engage to shipped, and always re-sends the receipt to Engage.
## What happens when you trigger an action
Voyado resolves the order and contact before sending the notification:
* **Contact** — Engage checks whether the order's customer email already exists as a contact. If it does, the contact record is updated with the latest data from the order. If it doesn't, a new contact is created (requires customer sync to be enabled).
* **Order** — Engage checks whether the order already exists.
* If it doesn't exist, a new order record is created with full order details before the notification is sent.
* If it exists and is linked to a contact, the order status is updated if needed, then the notification is sent.
* If it exists but has no linked contact, the order record is replaced and the notification is sent.
Triggering an action more than once for the same order is safe — existing records are updated rather than duplicated where possible.
## Troubleshooting
| Symptom | Likely cause |
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| Action buttons are not visible on the order detail page | The installed app version is below 2.3.0. Update the app. |
| Action fails with a sync error | Customer sync or order sync is not enabled in the integration configuration. |
| Action fails with an address error | The order's shipping or billing address could not be resolved from the Shopware order data. |
| No response or empty result | The shop configuration was not found. Verify the shop is correctly configured in the Voyado integration settings. |
If you see an error referencing `support@voyado.com`, customer synchronization is not configured for this shop. Contact [Voyado support](mailto:support@voyado.com) to resolve this.
# Good to know
Source: https://partner-integrations.voyado.com/docs/ecom/shopware/good-to-know
Important behaviours, limitations, and edge cases to be aware of when implementing or operating the Voyado Shopware integration.
## Web activity tracking only fires for identified contacts
Anonymous visitors are not tracked. A product view, cart event, or back-in-stock sign-up is only sent to Engage if the visitor has a resolved Voyado contact ID stored in the browser (`voyado-cid`). This is populated by login or by arriving via a personalised email link with the `eclub` URL parameter.
Visitors who have not logged in and did not arrive via a tracked link will not generate any tracking events, even if they have given cookie consent.
## Consent is always required
Even for identified contacts, no data is sent until the visitor has accepted cookie consent on the storefront. The `voyado-analytics=1` cookie must be present. If consent has not been given — or has been revoked — all tracking is suppressed.
## Duplicate cart events are suppressed
The integration compares the current cart contents against a snapshot stored in the browser's local storage before sending a cart tracking call. If the cart has not changed since the last call (same products, same quantities), the call is not sent. Reloading a cart page or checkout page does not produce duplicate events in Engage.
## Promotion line items are excluded from cart tracking
Cart tracking only includes real product lines. Shopware discount and promotion line items are filtered out before the cart payload is sent to Engage. This prevents promotion codes from appearing as tracked products.
## Session reset on login page
When the integration detects that the visitor has navigated to the login page, it clears the tracking session ID from storage. This ensures that if a different customer logs in on the same browser, their session starts clean.
## Order completion sends an empty cart
When an order is placed, the integration sends a cart-tracking call with an empty product array. This signals to Engage that the cart has been converted and should not be treated as abandoned.
## Promotions widget requires contact identification
The personalised promotions widget is only shown to contacts with a resolved `voyado-cid`. Visitors without a contact ID will not see the widget, regardless of whether the feature is enabled in the plugin configuration.
## Stock-level sync only triggers on restock events
The inventory sync pipeline only creates a pending record when a product's quantity crosses from ≤ 0 to > 0. Quantity changes that do not cross this threshold — for example, a product going from 10 units to 5 units — are not forwarded to Engage.
## Back in stock must be enabled per sales channel
The **Back in stock** feature must be explicitly enabled in the Accelerator configuration for each sales channel. Stock-level updates for channels where this is not enabled are silently dropped.
## Promotions and duplicate externalId
If a customer creates accounts in two different sales channels using the same email address, and both channels are connected to the same Engage environment, a promotion will only be linked to the `externalId` generated during the first account creation.
## Promotions redeemed via POS remain active in Shopware
If a personal promotion has been assigned in Shopware and redeemed through a third-party system (such as a POS), it will remain active in Shopware. This is not automatically reflected in Engage.
## What to read next
# Introduction
Source: https://partner-integrations.voyado.com/docs/ecom/shopware/introduction
The Voyado Shopware integration connects your Shopware store to Voyado Engage to unify customer data, automate marketing, and drive retention. It syncs orders, shipments, and customer details, embeds behavioural tracking directly into the storefront, and powers personalisation features including abandoned cart automations, back-in-stock notifications, and targeted promotions.
No separate tag management system is required. The integration runs as a self-contained Shopware plugin.
## What this integration does
* **Contact and Order sync** — syncs customer registrations, orders, cancellation, returns and shipment events to Engage
* **Web activity tracking** — captures product views, cart events, and order completion from identified contacts in real time
* **Back-in-stock notifications** — registers customer interest in out-of-stock products and pushes stock-level updates to Engage when inventory restores
* **Personalised promotions** — syncs Shopware promotions to Engage and surfaces assigned voucher codes to identified contacts in the cart
All web tracking is consent-gated. Nothing is sent to Engage until the visitor has accepted cookie consent on the storefront.
## Who this is for
This documentation is for developers and implementation partners installing or extending the Voyado Shopware plugin. It covers installation, configuration, tracking behaviour, and the technical architecture of the integration.
## How it works at a high level
The Shopware plugin extends the storefront using Shopware's Twig template inheritance system. This injects tracking scripts and structured data attributes into the relevant pages without modifying Shopware core files.
When a visitor accepts consent and is identified as a known Voyado contact — either by logging in or arriving via a personalised email link — the integration begins sending behavioural events to the Voyado Accelerator API. Contact identification, session state, and cart snapshots are persisted in the browser's local and session storage.
Stock-level sync runs as a server-side pipeline: a `product.written` webhook triggers the Accelerator API, which detects restock events and pushes updated stock levels to Engage on a scheduled interval.
Promotions are created in Shopware, synced to Engage via the plugin configuration, and then activated and assigned in Engage.
## What to read next
# Prerequisites
Source: https://partner-integrations.voyado.com/docs/ecom/shopware/prerequisites
Before installing and configuring the Voyado Shopware integration, confirm the following are in place.
## Required products and access
* Shopware 6.1.0 or higher
* An active Voyado Engage licence with the Shopware app enabled
* Access to the Shopware admin panel with plugin installation permissions
* The Voyado Shopware plugin package
* A product feed connected to Engage for each market locale (for example, `sv-SE`)
* Engage email templates configured for back-in-stock and abandoned cart automations
## Required credentials and configuration
The integration requires the following values during setup:
* **Store ID** — generated in the Shopware admin after installing the plugin; must be sent to your Voyado team to complete configuration
**Important: Store ID must be unique per environment**
Your Store ID must be unique across all your Shopware environments (test, staging, and production). If environments share the same Store ID, data syncing to Voyado Engage can be corrupted or mixed between environments.
This typically happens when a staging or test environment is created by cloning a production database, since Shopware stores the shop identifier in the database and both environments will inherit the same ID.
**To ensure each environment gets a unique Store ID after cloning:**
1. Update the `APP_URL` in the environment's `.env.local` file to match the staging or test domain (for example, `APP_URL=https://staging.my-shop.com`).
2. When you next open the Shopware admin, you'll be prompted with a **Domain change detected** modal. Select **Reinstall your apps** to generate a new shop ID and re-register all app connections under the new domain.
3. Reinstall the Voyado plugin in the new environment. A new Store ID will be generated.
4. Send the new Store ID to your Voyado team so the environment can be configured separately in Engage.
For more details, see Shopware's staging environment guide:
[https://developer.shopware.com/docs/guides/hosting/installation-updates/creating-a-staging-instance.html](https://developer.shopware.com/docs/guides/hosting/installation-updates/creating-a-staging-instance.html)
## Consent management
The integration enforces consent before any data is collected. Your storefront must dispatch a `voyadoConsentGranted` browser event when a visitor accepts cookie consent, and a `voyadoConsentRevoked` event when consent is withdrawn.
This is handled automatically when using Shopware's built-in cookie banner. If you use a third-party CMP, confirm it can dispatch these events or that you can trigger them manually.
If your CMP cannot dispatch `voyadoConsentGranted` and `voyadoConsentRevoked`, tracking will not activate regardless of whether the plugin is installed correctly.
## Customer responsibilities
* Ensure cookie consent configuration is aligned with your privacy policy
* Confirm that `voyadoConsentGranted` and `voyadoConsentRevoked` fire correctly in your consent setup
* Decide whether to enable the personalised promotions widget (optional, controlled by a toggle in the plugin configuration)
* Create the `hasAccount` custom contact attribute in Engage before syncing contacts (see [Setting up](/docs/shopware/setting-up))
## Implementation partner responsibilities
* Install the Voyado Shopware plugin and send the Store ID to the Voyado team
* Verify shop ID and sales channel ID are correctly configured
* Confirm consent events fire correctly in a test environment before go-live
* Validate contact identification for both login-based and soft-identification flows
* Confirm phone number validation is in place on all customer registration forms
## Before you continue
Verify:
* The Voyado Shopware plugin is installed and active
* The Store ID has been shared with the Voyado team and configuration is confirmed
* Cookie consent dispatches the correct browser events
* The `hasAccount` attribute exists in Engage
* A test Voyado contact is available to validate identification and tracking
## What to read next
# Configuration
Source: https://partner-integrations.voyado.com/docs/ecom/shopware/setting-up
Follow these steps to install the Voyado Shopware plugin, configure the required contact attribute in Engage, map your sales channels, and verify that tracking is working correctly.
## Before you start
Complete the steps in [Prerequisites](/docs/ecom/shopware/prerequisites) before proceeding.
## Install the plugin
Access your Shopware admin panel.
Navigate to **Extensions > Store**, search for "Voyado", select the extension, and click **Add extension**, then **Install extension**.
Go to **Marketing > Voyado Configuration**, copy the **Store ID**, and send it securely to your Voyado team. The team will notify you when the extension is configured on the Engage side.
## Create the hasAccount contact attribute
The `hasAccount` attribute in Engage determines whether a contact is a registered customer or a guest in Shopware. Create it before you begin syncing contacts.
Go to **Administration > Config hub > Contacts > Contact attributes**.
Select **Add attribute** and fill in the following:
| Field | Value |
| ----- | ------------- |
| Name | `Has account` |
| Id | `hasAccount` |
| Type | `Consent` |
Choose which panel to display the attribute in, then select **Save**.
## Map sales channels to Engage stores
Mapping Shopware sales channels to Engage stores lets you track where customers register and ship orders. This data is available as a filter for automations and segmentation.
An Engage Store can be linked to both a customer and an order, enabling segmentation by country or physical store location.
Go to **Marketing > Voyado Configuration**.
Under **Store and Country Mapping**, select the sales channel you want to configure.
Choose the Engage store to use as a fallback. Any country without a specific mapping will default to this store.
Select **Add New Option** to map individual countries to Engage stores. Repeat until all required countries are mapped.
Shopware does not validate phone numbers in the same way as Engage. Add validation to all phone number fields in your customer registration forms. Voyado recommends using the [Google libphonenumber library](https://github.com/google/libphonenumber) for accurate validation.
## Configure cookie consent for web activity tracking
When the plugin is installed, it automatically adds a **Voyado Analytics** cookie entry under the **Marketing** consent group in Shopware's default cookie banner.
If you use a third-party cookie banner, you must manually add the **Voyado Analytics** cookie to your consent configuration. It must be categorised under a marketing or tracking-related group and presented to the user with the ability to grant or withdraw consent. Without this, web activity tracking will not function.
### Triggering consent manually from a third-party CMP
Available in app version 2.1.0 and higher.
If you use a third-party consent management platform (CMP) such as Consentmanager, OneTrust, Cookiebot, or Google Tag Manager, trigger the `voyadoConsentGranted` browser event after the visitor accepts marketing or analytics cookies.
When this event fires, `voyado.js` sets the `voyado-analytics=1` cookie and initialises tracking without requiring a page reload.
Call this after the visitor has accepted the relevant consent category:
```javascript theme={null}
window.dispatchEvent(new Event('voyadoConsentGranted'));
```
1. Create a new **Custom HTML** tag in GTM.
2. Add the following code:
```html theme={null}
```
3. Set the trigger to fire when the visitor grants the relevant consent. If you use a data layer event, push it from your CMP:
```javascript theme={null}
dataLayer.push({
event: 'voyado_consent_granted'
});
```
Then use `voyado_consent_granted` as the GTM trigger condition for the Custom HTML tag.
## Verify the setup
With the plugin installed and the Voyado team confirmation received, run through the following checks in a test environment.
In the Shopware admin panel, navigate to **Extensions > My Extensions** and confirm the Voyado plugin status is **Active**.
Open any storefront page and inspect the page source. Locate the hidden element with the ID `voyado-tracking-data`. Confirm it carries the correct `data-shop-id`, `data-sales-channel-id`, and `data-language` attribute values for your store.
If it is missing, the plugin template overrides are not loading correctly.
Using browser developer tools, confirm that accepting cookies dispatches a `voyadoConsentGranted` event and sets the `voyado-analytics` cookie to `1`. Confirm that revoking consent dispatches `voyadoConsentRevoked` and removes the cookie.
If you are using a third-party CMP, this wiring must be configured in the CMP — not in the Voyado plugin.
Log in to the storefront with a test customer account and navigate to the account page. Confirm that a `voyado-cid` value is written to the browser's local storage.
If your Engage email campaigns use personalised links with the `eclub` parameter, open a test link in a browser where no customer is logged in. Confirm that `voyado-cid` is written to local storage after the page loads.
With consent active and a test contact identified, navigate to a product detail page. In the browser's network panel, confirm a POST request is sent to `/api/v2/shopware/product-tracking`. The request should include the product ID, product number, and session ID.
Add a product to the cart. Confirm a POST request is sent to `/api/v2/shopware/cart-tracking` approximately 2 seconds after the button click. View the cart page and the checkout confirm page — a tracking call should fire on each. Complete a test order and confirm a final cart-tracking call with an empty product array is sent on the order confirmation page.
The personalised promotions widget is enabled by the Voyado team in the back-end admin. Contact your Voyado representative to enable or disable it for your store.
## Troubleshooting cart tracking
If cart tracking is not working, the Voyado Twig blocks may not be present in your theme. This can happen when using a custom theme or after modifying theme files.
**Option 1 — Reinstall the app.** This reapplies the template customisations automatically.
**Option 2 — Add the Twig block manually.** Add the following block to your theme's `cart-widget.html.twig`:
```twig theme={null}
{# Extend the default Shopware cart widget template #}
{% sw_extends '@Storefront/storefront/layout/header/actions/cart-widget.html.twig' %}
{# Override the cart widget block to include custom tracking data #}
{% block layout_header_actions_cart_widget %}
{{ parent() }}
{# Custom block for tracking cart changes #}
{% block voyado_layout_header_actions_cart_widget %}
{% set filtered_cart_items = [] %}
{% for item in page.cart.lineItems %}
{% if item.type != 'promotion' %}
{% set filtered_cart_items = filtered_cart_items|merge([item]) %}
{% endif %}
{% endfor %}
{% set cart_data = filtered_cart_items|json_encode %}
{# Store Cart Tracking Data #}
{% endblock %}
{% endblock %}
```
Confirm that the template is correctly placed and loaded in your theme after making this change.
## What to read next
# Technical details
Source: https://partner-integrations.voyado.com/docs/ecom/shopware/technical-details
This article covers the technical architecture of the Voyado Shopware integration. It is intended for developers implementing, extending, or debugging the integration.
## Architecture overview
The integration is a Shopware plugin that extends the storefront using Shopware's Twig template inheritance system. It injects a JavaScript module (`voyado.js`) and structured data attributes into specific storefront pages. The JavaScript reads these attributes at runtime and sends tracking events to the Voyado Accelerator API via `POST` requests with JSON bodies.
Stock-level sync runs as a server-side pipeline separate from browser tracking. A `product.written` webhook triggers the Accelerator API, which detects restock events and pushes stock levels to Engage on a scheduled interval.
No Shopware core files are modified. All template changes are non-destructive Twig block overrides.
## Script loading
Two scripts are loaded on every storefront page via the base template override:
* `voyado.js` — the Voyado integration script, served from the plugin bundle
* Redeal widget script — a companion script for the on-site messaging add-on
Both are loaded with the `defer` attribute and do not block page rendering.
## Data passing
Tracking data is passed from the Shopware PHP/Twig layer to the browser using hidden HTML elements with `data-*` attributes. The JavaScript reads these attributes at runtime to construct API call payloads. This keeps Twig templates clean and decouples data preparation from behavioural logic.
## Browser storage
| Storage type | Key | Contents | Cleared when |
| --------------- | ------------------ | ---------------------------------------------- | ----------------------------------------------------------- |
| Local storage | `voyado-cid` | Voyado contact ID | Not automatically — persists across sessions |
| Local storage | Cart ID | Random identifier for the current cart journey | Not automatically |
| Local storage | Cart snapshot | JSON of previous cart state for deduplication | Overwritten on each cart tracking call |
| Session storage | Session ID | Unique ID for the current browsing session | Browser tab closed; or when visitor navigates to login page |
| Cookie | `voyado-analytics` | Consent state (`1` = granted) | Consent revoked |
Nothing is written to any storage before the `voyado-analytics` cookie is set.
## Cookie consent flow
The integration listens for two named browser events:
* `voyadoConsentGranted` — sets `voyado-analytics=1` and activates tracking
* `voyadoConsentRevoked` — removes the cookie and stops all tracking
The Shopware built-in cookie banner fires these events automatically. Third-party CMPs must be configured to dispatch them. See [Setting up](/docs/shopware/setting-up) for GTM and JavaScript examples.
## Contact identification
**Login-based:** When a logged-in customer visits their account page, the integration reads their Shopware customer ID and email from the page and calls `POST /api/v1/Shopware/store-contactid`. The returned Voyado contact ID is stored as `voyado-cid` in local storage.
**Soft identification:** Personalised email links include an `eclub` URL parameter containing an encrypted contact reference. On page load, the integration calls `POST /api/v2/shopware/getSoftDecryptionKey` to decrypt the parameter, then resolves the contact ID and stores it as `voyado-cid`.
## Template overrides
| Template file | What it injects or enables |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `base.html.twig` | `voyado.js`, CSS, and `voyado-tracking-data` element (shop ID, sales channel ID, language) on every page |
| `product-tracking-script.twig` | Server-side preparation of product and stock data — no browser output |
| `buy-widget-form.html.twig` | `voyado-product-tracking-buy-widget-form` data element; back-in-stock form when product is out of stock |
| `cart-widget.html.twig` | `voyado-cart-tracking` element with serialised cart line items (promotion lines excluded) |
| `action.html.twig` | Product ID, product number, and minimum purchase quantity on listing page product cards |
| `index.html.twig` (checkout/finish) | Completed order line items as a JSON data attribute for cart conversion signal |
| `offcanvas-cart.html.twig` | Placeholder element for the promotions widget in the mini-cart |
| `login.html.twig` | Login page URL marker used to trigger session reset |
## Cart tracking
### Deduplication
Before each cart tracking call, the integration serialises the current cart line items and compares them to the snapshot stored in local storage. If the payload is identical, the call is suppressed. The snapshot is updated after each successful call.
### Triggers
| Trigger | Behaviour |
| --------------------------------- | ---------------------------------------------------------------------------- |
| Add to cart button click | 2-second delay, then reads cart contents from `voyado-cart-tracking` element |
| Cart page load (`/checkout/cart`) | Fires immediately on page ready |
| Checkout confirm page load | Fires immediately on page ready |
| Checkout finish page load | Fires with empty product array — signals cart conversion |
## Product tracking payload fields
The `voyado-product-tracking-buy-widget-form` element carries the following `data-*` attributes, which are included in the product tracking request:
* `data-product-id` — Shopware product ID
* `data-product-number` — product SKU
* `data-page-url` — URL of the product detail page
* `data-is-out-of-stock` — boolean stock status
* `data-language` — storefront language
* `data-sales-channel-id` — Shopware sales channel ID
* `data-shop-id` — Voyado shop identifier
The session ID and contact ID are added from browser storage at call time.
## Web tracking data flow
```text theme={null}
Visitor accepts consent
│
▼
voyado-analytics=1 cookie set
│
▼
Contact identification
├── Login → Store contact ID in Local storage → voyado-cid stored
└── Email link (encrypted parameter) → Decrypt parameter → Store contact ID in Local storage → voyado-cid stored
│
▼
Product page visit
└── POST api/v3/productviews (contact ID, product ID, SKU, URL, session ID)
│
▼
Add to cart
└── POST /api/v3/carts (contact ID, cart line items, cart ID)
│
▼
Cart page / checkout confirm
└── POST /api/v3/carts (updated cart snapshot)
│
▼
Order placed (checkout finish)
└── POST /api/v3/carts (empty product array — cart closed)
```
## Storefront theme extensions
The Voyado app extends the Shopware storefront theme with several Twig template overrides. These are bundled with the app and applied automatically on installation — no manual theme editing is required.
The overrides inject hidden data containers into specific pages and components. The storefront JavaScript reads these containers and fires tracking events to Engage.
These template overrides use Shopware's standard `sw_extends` inheritance. They call `parent()` before injecting Voyado markup, so existing theme blocks are preserved.
The following templates are extended:
Extends the product card buy button block on listing pages.
Injects a hidden element with the following data attributes:
| Attribute | Value |
| ------------------ | ------------------------------------ |
| `data-product-id` | The Shopware product UUID |
| `data-item-number` | The product number (`productNumber`) |
| `data-quantity` | The minimum purchase quantity |
Fires a **product-tracking** event. This is visible in the browser's Network console.
Extends the buy widget on product detail pages.
Injects a hidden element with the following data attributes:
| Attribute | Value |
| ------------------------------ | ----------------------------------------------------------- |
| `data-product-page-url` | The SEO URL of the current product page |
| `data-product-available-stock` | Whether the product is available (`page.product.available`) |
| `data-product-id` | The Shopware product UUID |
| `data-product-number` | The product number |
| `data-language-id` | The current language ID |
| `data-saleschannel-id` | The current sales channel ID |
| `data-app-shop-id` | The Shopware app shop ID |
Fires a **product-tracking** event. Also renders the back-in-stock notification form when the product is out of stock. See [Back-in-stock subscription flow](#back-in-stock-subscription-flow).
Extends the cart widget in the header.
Injects a hidden element with a `data-cart` attribute containing a JSON-encoded array of the current cart line items. Promotion line items are excluded.
Fires a **cart-tracking** event. This is visible in the browser's Network console.
Extends the order confirmation page shown after a successful checkout.
Injects a hidden element with the following data attributes:
| Attribute | Value |
| ------------------------------- | ----------------------------------------------------------------------------- |
| `data-checkout-finish-page-url` | The URL of the checkout finish page |
| `data-shop-id` | The Shopware app shop ID |
| `data-saleschannel-id` | The current sales channel ID |
| `data-language` | The sales channel language ID |
| `data-time` | The server timestamp at page render (`Y-m-d H:i:s`) |
| `data-product-data` | JSON-encoded array of ordered products (product ID, quantity, product number) |
Fires a **cart-tracking** event on order completion. Promotion line items are excluded.
If your Shopware theme overrides the same blocks that the Voyado app extends, the Voyado template overrides may not render correctly. Verify that `buy_widget_buy_form_inner`, `component_product_box_action_buy`, `layout_header_actions_cart_widget`, and `page_checkout_main_content` are not overridden in your custom theme.
***
## Back-in-stock: stock-level sync
Stock-level sync runs as a two-step server-side pipeline, independent of browser tracking.
### Pipeline overview
```mermaid theme={null}
sequenceDiagram
participant SW as Shopware
participant API as Accelerator API
participant DB as App DB
participant ENG as Engage
SW->>API: POST product.written
API->>API: Validate webhook signature
API->>SW: Fetch live product + visibility data
API->>DB: Store pending record (if restock)
Note over API,DB: Scheduled job runs on interval
DB->>API: Load pending records
API->>ENG: PUT /api/v3/inventory/stock-levels
ENG-->>API: 200 OK
API->>DB: Mark records as Success
```
### Step 1 — Webhook ingestion
When a product record is written in Shopware, Shopware fires a `product.written` event and sends a webhook to the Accelerator API. The API validates the request using the `shopware-shop-signature` header — requests that fail validation are rejected before any processing.
After validation, the API fetches live product data and sales channel visibilities directly from Shopware using the product ID from the payload.
A pending stock update record is only created when both conditions are met:
* The product's previously stored quantity was ≤ 0
* The product's current `availableStock` from Shopware is > 0
Quantity changes that do not cross the zero boundary are ignored.
### Webhook registration
All webhooks are registered automatically when the Voyado app is installed in Shopware. The inventory webhook is registered for the `product.written` event.
### Sales channel and site matching
Each product visibility from Shopware includes a `salesChannelId`. The integration matches this against your configured site and channel mapping.
**Back in stock** must be enabled in the Accelerator configuration for each sales channel you want stock-level updates to flow through. Updates for channels where this is not enabled are silently dropped.
### Step 2 — Scheduled push to Engage
A scheduled job polls for pending records and sends them to Engage using `PUT /api/v3/inventory/stock-levels`.
Payload fields per record:
The current available stock quantity for the product.
The product number in Shopware.
The Sales Channel ID in Shopware.
Records remain in `Pending` state until Engage returns a successful response. They are picked up on subsequent scheduled runs until delivery succeeds.
***
## Back-in-stock: subscription flow
The subscription flow is independent of the stock-level sync pipeline. It records a customer's opt-in to be notified when an out-of-stock product restocks, and writes that subscription to Engage.
### Storefront payload
On form submission, the storefront posts to the Accelerator API:
```json theme={null}
{
"shop_id": "",
"saleschannel_id": "",
"shopUrl": "",
"email": "customer@example.com",
"product_id": "",
"language_id": "",
"accept_email": "on"
}
```
On success, the API returns: `"Thank you! We will notify you when the product is available."`
### Processing pipeline
The API resolves the site configuration using `shop_id` and `saleschannel_id`. The call returns early with no subscription created if either of the following is not enabled:
* Shopware integration enabled
* Back in stock feature enabled
The API makes two calls to Shopware:
* `GET /api/product/{product_id}` — the `productNumber` field becomes the `Sku` on the subscription
* `GET /api/language/{language_id}/locale` — the locale code (for example, `en-GB`) becomes the `Locale` field
The API resolves or creates a contact in Engage based on the submitted email address and marketing consent value:
| Scenario | Outcome |
| ------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| Contact exists + `acceptsEmail` = `true` | Existing contact updated: `acceptsEmail` set to `true` |
| Contact does not exist + `acceptsEmail` = `true` | New contact created with `acceptsEmail` = `true` |
| Contact does not exist + `acceptsEmail` = `false` | New contact created with `acceptsEmail` = `false` |
| Contact exists + `acceptsEmail` = `false` | Existing contact unchanged — `acceptsEmail` preference is not overridden from `true` to `false` |
Once a valid contact ID is resolved and the locale lookup succeeds, the API posts the subscription to Engage:
```http theme={null}
POST /api/v3/inventory/backinstock/subscriptions
apikey:
Content-Type: application/json
{
"ContactId": "",
"Sku": "",
"Locale": "en-GB",
"ExternalId": ""
}
```
Engage returns `201 Created` for a new subscription or `409 Conflict` if the contact already has an active subscription for that SKU. Both responses are treated as success — `409` is the expected response on duplicate submissions.
Once a valid contact ID is resolved and the locale lookup succeeds, the API posts the subscription to Engage:
```http theme={null}
POST /api/v3/inventory/backinstock/subscriptions
apikey:
Content-Type: application/json
{
"contactId": "",
"sku": "",
"locale": "en-GB",
"externalId": ""
}
```
Engage returns `201 Created` for a new subscription or `409 Conflict` if the contact already has an active subscription for that SKU. Both responses are treated as success — `409` is the expected response on duplicate submissions.
### Subscription payload fields
The Engage contact ID resolved from the customer's email address.
The product number from Shopware (`productNumber`).
The locale code resolved from the Shopware language record, for example `en-GB`.
The Shopware product UUID.
***
## Technical considerations
* The `voyado-cid` in local storage persists across browser sessions with no automatic expiry. If a different contact logs in on the same browser, `voyado-cid` is overwritten only after the new contact's ID is successfully resolved. The session ID is reset when the visitor navigates to the login page.
* The 2-second delay on add-to-cart tracking is hardcoded to allow Shopware's cart update to complete before the cart contents are read. This delay is not configurable.
* Listing page add-to-cart events use the product data from `action.html.twig`, which does not include the product detail page URL — only the product ID, product number, and minimum purchase quantity.
* Stock-level sync only activates for restock events (quantity crossing from ≤ 0 to > 0). Quantity changes that do not cross the zero threshold are not forwarded to Engage.
# What's new?
Source: https://partner-integrations.voyado.com/docs/ecom/shopware/whats-new
Here you'll find the changes and updates to the Voyado Engage app for Shopware.
There is an RSS feed for this page allowing you to subscribe to changes as they are published.
## Bug fixes
* Fixed an issue where certain product data returned by Shopware in an unexpected format could cause sync errors. Product events now handle this format correctly.
* Reduced additional cases where webhook events could fail with a "store configuration not found" error, by extending the fallback lookup introduced on 2026-07-02 to more integration endpoints.
## Bug fixes
* Fixed a case where store configuration could intermittently fail to be found, causing sync errors even for correctly configured stores. The integration now falls back to an alternate lookup when the primary one returns no result.
## Bug fixes
* Fixed cart tracking not firing for products added to the cart via the off-canvas modal. Tracking events are now sent correctly regardless of which add-to-cart flow the customer uses.
Available in app-version **2.3.4 and higher**
## Improvements
* Cart tracking now correctly fires when a customer empties their cart. Removing the last item from the cart now sends a tracking event to Voyado Engage, so abandoned-cart and re-engagement flows handle the cart-cleared state correctly.
Available in app-version **2.3.4 and higher**
* Requests to Voyado Engage that receive a temporary service-unavailable response are now automatically retried with a backoff, reducing the risk of data loss during brief outages.
* Outbound API calls now enforce a 10-second timeout, preventing slow responses from blocking order and event processing.
## Bug fixes
* Fixed an issue where saving a contact's consent and privacy policy settings could fail with a 422 error. Privacy policy acceptance is now persisted reliably when a contact is created or updated.
## Bug fixes
* Fixed cart tracking events being rejected when no cart ID was available. This affected customers who reached checkout via custom themes or without going through the standard add-to-cart flow. Cart IDs are now sourced from Shopware's native session context token instead of being generated client-side, ensuring cart tracking works reliably for all customers.
Available in app-version **2.3.3 and higher**
## Improvements
* Orders with large numbers of line items are now processed more reliably. Order event payloads that exceed SQS message size limits are automatically offloaded to S3, preventing processing failures for complex orders.
## Bug fixes
* Order line items that are not part of a bundle are no longer grouped together incorrectly. Standalone items previously shared a blank grouping value that Engage displayed as "\*", lumping unrelated items into one group. They now appear individually as expected.
* Sales tax amounts on orders, receipts and returns are now always reported as positive values.
* Orders containing discounted bundle/composition items now calculate tax using each item's own tax rate instead of the order's overall rate. Orders with mixed tax rates that were previously rejected by Engage now sync correctly.
## Improvements
* More reliable retrieval of order data from Shopware, reducing transient failures when fetching order details.
* Events are now processed more reliably in batches. If one event fails, the remaining events in the same batch continue to process independently rather than failing together.
# Extensions introduction
Source: https://partner-integrations.voyado.com/docs/extensions/extensions-introduction
Here you'll find information to integrate your extension with Engage.
Choose an option on the left to get started.
# Ingrid
Source: https://partner-integrations.voyado.com/docs/extensions/ingrid/ingrid
**Ingrid is a delivery experience platform, making shopping stress-free for the consumer. Ingrid helps retailers simplify shipping, reduce costs, and offer more delivery options, such as real-time shipping updates, home delivery, pick-up points and lockers.**
This streamlined approach reduces cart abandonment rates and ensures timely deliveries, enhancing overall customer satisfaction. Ingrid operates in over 170 countries.
The standard integration between Ingrid and Voyado Engage offers retailers access to relevant shipping data via the same tool they use for communication to customers. Engage users gain full control of the exact delivery status and can personalize communication, saving them time and money.
Some user stories are:
* Keeping customers updated during shipping phase via email and/or SMS
* Displaying data relevant data from Ingrid for the shipping experience
* Creating customers in Engage from Ingrid if needed
## Ingrid's documentation
Ingrid maintain their own integration docs for this integration:
## Integrating Ingrid
Once Ingrid and Engage are configured, the integration is done as described below.
### Posting an order
Orders are posted by Ingrid to the Engage v2 endpoint:
```http theme={null}
POST api/v2/orders
```
You can see in the example below the `orderStatus` from Ingrid in the payload, along with other useful information in `extraData` such as `TrackingLinkHTML` and `TrackingNumber`.
```json theme={null}
{
"contact": {
"matchKey": "person@test.com",
"matchKeyType": "email"
},
"orderStatus": "Ingrid - Submitted To Carrier",
"orderNumber": "8000612",
"createdDate": "2024-08-26T07:42:49Z",
"paymentStatus": "PAID",
"shippingDate": "0001-01-01T00:00:00Z",
"currency": "EUR",
"language": "en-GB",
"totalGrossPrice": 4000,
"freightFee": {
"value": 500,
"tax": 0
},
"extraData": {
"BillingAddress_City": "Amsterdam",
"BillingAddress_Country": "NL",
"BillingAddress_Email": "ustomer@test.com",
"BillingAddress_FirstName": "Test Customer",
"CarrierName": "DHL Express",
"DeliverySenderName": "SE warehouse",
"DeliveryType": "UNKNOWN",
"DestinationAddress_City": "Amsterdam",
"DestinationAddress_Country": "NL",
"EstimatedDeliveryDate": "2024-08-28T00:00:00+02:00",
"ParcelsCount": "1",
"PaymentMethod": "",
"TrackingLinkHTML": "https://tracking-stage.ingrid.com/en-GB/cmVzb3VyY2VfdG9rZW46ZDI0NTkxNTI1MzBkNGYxZThjMDA0MWM5NzViZWViMmM",
"TrackingNumber": "3SHM00008734785",
"TrackingStatus_Step": "STEP_SUBMITTED_TO_CARRIER",
"TrackingStatus_Time": "2024-08-26T11:03:59Z"
...
```
This order data can then be used to trigger an automation.
### Creating a contact
It can happen that an order is posted to the Engage API but the contact doesn't exist in Engage. A 404 response is then returned. If this happens, Ingrid will create the contact in Engage using this endpoint:
```http theme={null}
POST /api/v2/contacts
```
And with this sort of payload:
```json theme={null}
{
"email": "john.fellow@example.com",
"mobilePhone": "+48519157444",
"firstName": "John",
"lastName": "Fellow",
"contactType": "Member"
}
```
After this, the order will be posted again to the `/orders` endpoint.
The default `contactType` is "Member" but this can be changed to whatever the merchant wants.
### Building the automation
There needs to be an automation in place to handle incoming orders. This automation will handle the various `orderStatus` values from Ingrid. To do this, you can have a value split in the automation to branch off the different order status values to send different emails, based on a contact's current order status.
### Building email templates
Create a specific email template for each order status you are going to handle. Use existing templates or design new ones with all relevant information and consistent branding and visuals.
Use `[[order.ExtraData.TrackingLinkHTML]]` in your email module to embed the `TrackingLinkHTML` page code provided by Ingrid in the order. This will embed HTML into the email which shows the package's location.
The `[[order.ExtraData.TrackingLink]]` value, if it exists in the order data, can also added to the email as a link to take the customer to Ingrid's own tracking page for the item.
## Frequently asked questions
Here are some common questions related to this integration.
### Why not use the v3/orders endpoint?
To build the integration as quickly as possible, the v2 endpoint was used, since the v3 endpoint was undergoing changes and iterations . However the v3/orders endpoint will be used in phase 2.
### Can I choose which statuses to handle from Ingrid?
Yes. you can choose, but the recommendation is to configure Engage to accept them all, and then decide in the automation engine what statuses to actually use.
### Can I use product images in the emails triggered by Ingrid?
Yes, if an `imageUrl` for the item is provided in the order payload.
# Inretrn
Source: https://partner-integrations.voyado.com/docs/extensions/inretrn/inretrn
**Inretrn (formerly known as Easycom) is a leading cloud-native SaaS platform that helps global retailers to automate the whole process of item returns. They help e-commerce vendors and logistic providers to both reduce the number of returns and make returns management more efficient, with increased profitability and sustainability in focus.**
This integration with Inretrn adds Voyado Engage's powerful automation and segmentation abilities, allowing retailers to close the loop and interact with the customer during the whole transaction lifecycle, from purchase to return.
Once integrated with Engage, Inretrn can trigger different return flows, enrich customer profiles and send return transactions (receipts). It's up to the Inretrn user to decide which Engage flows they want to use.
* Interact and communicate with your customers throughout the entire returns journey
* Use the powerful customer profitability insight segmentation to build unique and tailored campaigns
* Add new events and triggers connected to the returns process
* Customize messaging with new information based on returned products, exchanges and reason codes for returns
* Enrich your CDP with profitability insights on the individual customer level
* Reward customers with re-conversion vouchers generated in Inretrn and enable them in Engage
## Inretrn setup and configuration
Here's how to set up and configure the Engage-Inretrn integration.
### Requirements
For this integration you will need:
* An active Inretrn license
* An active Voyado Engage CXP and Omni license
* An API key to access Engage from Inretrn
### Setting up
The Engage integration is set up in Inretrn Admin under Integrations. This is where you specify your base API URL, your API key and if there are any other Engage contact types besides "Member" and "Contact" that Inretrn will need to deal with.
### Set up automation
Inretrn will create an interaction schema on their end once they activate the automation.
1. Activate the return confirmation, go in to Automations → New automation → New specific interaction → Inretrn Default Interaction schema.
2. Create an email with an Inretrn module and insert the module in the email.
3. Activate the automation:
### Migration of receipts
Inretrn will also be able to migrate existing returns of the receipts to Engage. This is done in the Inretrn configuration along with the other config.
### Setup in Inretrn
The integration with Engage is set up in Inretrn Admin under "Integrations" where you need to specify API url, API key and if there is any more contact types then member or contact in Engage that Inretrn needs to identify with.
### Example workflows in Engage with Inretrn data
Return confirmation:
The KPIs from Inretrn can be used in segmentation and create target audiences:
These target audiences can be used in to filter in reports:
The data you get from the return can also be used in building automations:
You can also use data from Inretrn to filter on the module level in the email editor:
## Using the Inretrn integration
Here are some examples of using the Inretrn-Engage integration:
### Return confirmation
When a customer makes a return they will receive a confirmation email. This is what that looks like:
### Segmenting using Inretrn KPIs
Using the Engage segmentation tool, you can filter your contacts using any of the KPIs from Inretrn.
Here the `Easycom Level` is used, along with a few other Engage values:
These target audiences can be used in to filter in Engage reports:
The data received from return transactions can be used in the Engage automation tool:
And data from Inretrn can be used to filter on the module-level in the Engage email-design tool:
### Optimizing your campaigns
Engage enables you to use your profitability insights to build sharper customer segmentation and optimize your campaigns.
For example, when sending out offers, you could:
* Send valuable offers to your most profitable customers
* Send standard offers to mid segment of customers
* Send no offers to non-profitable customers
# OneSignal
Source: https://partner-integrations.voyado.com/docs/extensions/one-signal/one-signal
**With app push notifications a retailer can send messages and updates to users directly in their mobile devices. To enable this, Engage can integrate with OneSignal, which supports seamless message composition, scheduling, follow-ups, and performance analysis. This makes it a versatile tool for real-time engagement and personalized customer communication.**
This integration with OneSignal reduces complexity by moving segmentation, scheduling and automated messaging to Engage. With all outbound messaging in a single platform, you can create relevant, timely notifications that encourage app interactions and conversions.
## Setting up the integration
**Engage:** Set up your Engage account and confirm access to the Engage API. Ensure your Engage API keys are available for integration and message automation settings. Refer to Engage’s API docs for details on API authentication, permissions, and secure API key handling.
**OneSignal:** Set up an account with [OneSignal](https://onesignal.com/) and follow the setup instructions to integrate its push notification capabilities within your app. Consult the OneSignal documentation for technical support and configuration tips.
## Using the integration
The steps are:
Log into OneSignal to start composing messages. Include text, images, and deep links that are tailored to your audience and ensure that the push notifications align with other channels, complementing SMS and email. Each message will have a unique Id that you will then use in Engage.
Navigate to automations in Engage. Add the OneSignal-composed message to a new or existing automation flow in Engage, allowing you to automate your notifications.
Use Engage’s scheduling and targeting tools to define specific segments and find the relevant recipients. Similar to our other channels, but instead of composing the message in Engage just use the Id from OneSignal.
Now analyze your results by:
* Tracking conversion rates, open rates, and engagement metrics directly within OneSignal
* Using Engage to assess delivery performance, sending speed, and segment effectiveness
* Continuously refining notification strategies based on metrics and feedback to increase open rates and customer interaction
## Use cases
Here are some common use cases:
### 1 - Event reminder for mobile users
Compose a reminder push notification in OneSignal for an upcoming sale event. Then schedule the reminder in Engage so that it reaches contacts 24 hours before the event.
### 2 - Personalized promotions
Segment customers based on past purchases and send a personalized promotion push notification. Use Engage to automate these notifications in an existing automation, enhancing relevancy by delivering tailored offers.
### 3 - Re-engagement campaigns
Identify inactive app users using Engage’s segmentation tool. Send a re-engagement push notification with a compelling incentive (such as a discount code) through an automation in Engage.
## Efficiency tips
Some tips to improve efficiency:
* **Advance scheduling:** Plan notifications well ahead of time to maintain consistent customer engagement
* **Stay updated:** Regularly check for new Engage and OneSignal features that could enhance notification capabilities
* **Monitor conversion metrics:** Use both Engage and OneSignal metrics to gauge notification success, identifying high-engagement times for scheduling
## Things to look out for
* **Configuration validation:** Verify that all settings are correctly configured in both Engage and OneSignal to avoid missed notifications or technical errors.
* **Data compliance:** Ensure adherence to acceptable use policies, particularly around data protection and user opt-in compliance.
# Sift Lab
Source: https://partner-integrations.voyado.com/docs/extensions/sift-lab/sift-lab
**Sift Lab (formerly Infobaleen) offers an AI platform that allows merchants to analyze their customer's online behavior to predict future behavior.**
An integration with Sift Lab offers the Engage user two features:
**Product Recommendations:** Sift Lab calculates product recommendations based on data points collected from various data sources. Merchants can choose to use Sift Lab's recommendation engine directly in their Engage send-outs, or consume them via the Engage API.
**Auto Target Segments:** In the Sift Lab platform, a merchant can make a segmentation of those contacts likely to buy a certain product and therefore likely to respond well to a product campaign. To be able to segment on this information, the names of the segment are imported into Voyado Engage as contact attributes.
## Custom contact attributes
Custom contact attributes are needed for the Sift Lab integration. These can be set up in the Engage Config Hub.
You'll need to create 10 contact attributes of data type “string“ with these specific IDs:
* siftlabDynamicSegment1
* siftlabDynamicSegment2
* siftlabDynamicSegment3
* siftlabDynamicSegment4
* siftlabDynamicSegment5
* siftlabDynamicSegment6
* siftlabDynamicSegment7
* siftlabDynamicSegment8
* siftlabDynamicSegment9
* siftlabDynamicSegment10
For each of these custom attributes, select “Hidden“ in the "Show in contact-card panel or tab" field.
Then be sure to select the tick boxes “Read-only in contact card”, “Segmentable” and “Exportable”.
## Including custom attributes for all contact types
You'll now need to make sure that all the contact types you are using have these new custom attributes. This configuration is done in the Voyado back-end by your Voyado specialist. Reach out to them.
## Delta Sharing
Delta Sharing is an open protocol for the secure exchange of large amounts of data. You'll need this to be activated. When this is done by your Voyado specialist, you will receive an activation URL.
## FTP access
Your Voyado team will also provide you with the FTP credentials you'll need.
The root directory of your FTP setup will have these directories:
* productRecommendationsImport
* ContactImport
Here is where you'll place the CSV files to be imported into Engage.
These imports are done using the scheduled jobs "ProductRecommendations" and "ContactImporter" which your Voyado team will activate for you. These jobs run on a predetermined schedule.
Product recommendation imports are handled hourly and the contact import is done every 5 minutes.
# Walley
Source: https://partner-integrations.voyado.com/docs/extensions/walley/walley
**Walley is a comprehensive e-commerce platform, offering tools for efficient order management, inventory control, and customer engagement. It enhances operational efficiency and provides a seamless experience for businesses and customers.**
Walley streamlines payment processes, offering secure and convenient payment options, improving the overall checkout experience, and reducing friction in the purchase journey. Through the Engage integration, it can sign up customers at checkout both online and offline.
# Wismotion
Source: https://partner-integrations.voyado.com/docs/extensions/wismotion/wismotion
Wismotion is a real-time logistics visibility platform that provides tracking and communication around order deliveries. The integration connects Wismotion to Engage via the Orders API, enabling order data storage and automated messaging based on shipment events.
Consult your Voyado account manager before activating this integration. Also involve Wismotion before starting the implementation.
## Posting an order
Wismotion can create or update orders in Engage depending on how the integration is configured. Orders are posted to:
```http theme={null}
POST /api/v3/orders
```
Use this endpoint when:
* an order has not already been created in Engage by another system, or
* Wismotion is responsible for creating the order record in Engage.
The payload contains order information, a contact reference, and any additional metadata required by the merchant. Once stored, the order data is available for use in automations and messaging.
## Creating a contact
If the contact referenced in an order does not yet exist in Engage, Wismotion can create the contact before posting the order.
```http theme={null}
POST /api/v3/contacts
```
```json Example payload theme={null}
{
"email": "john.doe@example.com",
"mobilePhone": "+46123456789",
"firstName": "John",
"lastName": "Doe",
"contactType": "Member"
}
```
After the contact is created, post the order using `POST /api/v3/orders`.
## Updating order status
Wismotion can update the status of an order in Engage when the status changes in Wismotion's system.
```http theme={null}
PUT /api/v3/orders/{orderId}
```
Typical order statuses used in Engage:
* `InProgress`
* `Completed`
Keeping order status in sync lets you branch automation logic — for example, sending different messages depending on whether an order is still being prepared or has been completed.
## Triggering Order Actions from Wismotion
Wismotion's rule engine defines when a shipment event should trigger an **Order Action** in Engage. Order Actions can be used as entry points or conditions in automations.
Supported Order Actions:
* **ConfirmShipment**
* **ConfirmDelivery**
* **ConfirmCancellation**
* **ConfirmCompletion**
* **Custom** – with a custom status text
Order Actions are sent to Engage using:
```http theme={null}
POST /api/v3/orders/{orderId}/action
```
Because order creation and updates are asynchronous, Wismotion must wait until Engage has finished processing the order and returned a `versionTag` before triggering an action. A retry mechanism that polls for a valid `versionTag` is required. See [Orders and actions](https://developer.voyado.com/docs/orders/orders-and-actions) on the Voyado Developer site for details.
```json theme={null}
{
"action": "ConfirmShipment",
"versionTag": "kyvic4wloxoljyfeshtxodig5i",
"data": {
"shipment": {
"id": "6521770000",
"shipmentNumber": "6521771052",
"milestoneId": "preparation",
"statusId": "created",
"scenarioId": "outbound_delivery",
"senderReference": "41007232",
"buyerReference": "41007232",
"serviceProviderId": "dhlfreight_sweden",
"serviceProviderParentName": "DHL",
"numberOfPackages": 1,
"grossWeight": 2.0,
"volume": 0.0,
"notifyAddress": {
"name": "...",
"address1": "...",
"zipCode": "...",
"city": "...",
"countryCode": "SE",
"email": "customer@example.com",
"smsNumber": "+46123456789",
"phoneNumber": "+46123456789"
},
"trackingUrl": "https://customer.wismotion.com/tracking?mmxat=********"
}
}
}
```
The `action` field determines which Order Action is registered in Engage. The `data` object contains shipment-specific information that can be referenced in automations and communication.
Order Actions are sent at shipment level. A single order may have multiple shipments — for example, split deliveries. Each shipment event can trigger its own automation and message in Engage.
## Building the automation
Set up an automation in Engage that starts when a relevant Order Action is received from Wismotion.
You can either:
* create one automation per action (e.g. **ConfirmShipment**, **ConfirmDelivery**), or
* use a value split in a single automation and branch on the Order Action type or shipment data.
The automation can send different messages depending on the shipment milestone, carrier, delivery method, or any other field in the `data.shipment` payload.
# Zapier
Source: https://partner-integrations.voyado.com/docs/extensions/zapier/zapier
**Zapier is an integration platform, which is an online service that allows you to connect different apps and web services to each other. You can create automated workflows that retrieve data by specifying a service and trigger and then pass that data on to another service or services.**
For example you can set up a Zapier flow that, whenever your company's name is mentioned on X, automatically:
* posts a message in a Slack channel
* sends a mail to your Marketing department
* calls an API endpoint.
As another example, when someone comments on your updates on LinkedIn, you can set up a flow to save the person who commented in an excel document as a possible lead, and then do ten other things.
With over 1,500 apps supported in Zapier, you can connect them in basically unlimited ways.
## Voyado Engage app for Zapier
Voyado has developed a custom app in Zapier called "Voyado Engage" which allows you to create flows that leverage some pre-made connections with Engage. To get access to this app, contact your Account Manager.
The Voyado Engage app for Zapier allows you to:
* Identify a customer
* Create a customer (with 5 custom attributes)
* Update a customer (with 5 custom attributes)
* Trigger a custom trigger (using 10 extra fields and 10 HTML fields)
* Opt in a customer to receive email newsletter and SMS messages
## Example of usage
Let's say the client has Facebook Lead ads. With Zapier, when a lead is captured through Facebook, that info can then be sent to Engage through an API call.
In addition to using an app or service as a trigger, Engage can also be triggered by a so-called 'Catch hook', which means intercepting an API call that is sent to Zapier.
For example, a pop-up on a customer's website asks the user to enter an email address. Then that email address is captured and send to Engage via the Engage App in Zapier.
## Setting up a Zapier connection
First of all, a trigger is needed, such as the Facebook Lead ads in the previous example:
The client chooses which Facebook account to use and which page. If everything has worked, sample data can be captured in the Zapier app, allowing you to see which data is available. In this case, it is an email address, name, date and the Facebook campaign that was used.
Now you know what data is available, you can set up the flow in Zapier.
First, create a new flow that will connect to the Engage App:
Once the connection to the app is authenticated, you can decide what action to take:
This is how a workflow in Zapier usually looks if connected to Facebook leads, where first a trigger from Facebook is sent with the email address. The email address is used to identify the contact in Engage. Depending on whether the customer exists or not in Engage, you can create or update the contact with the data coming from Facebook.
Then you test the flow in Zapier. If everything looks good, the data should get to Engage.
# Our partner integrations
Source: https://partner-integrations.voyado.com/docs/partner-integrations
Welcome to Engage partner integrations. Voyado has teamed up with many partners to bring you integrations to make your implementation and usage of Engage easier.
Select an option below. You can also search for a particular integration or ask the AI below.
You can find more documentation on our Developer site:
A complete list of all partners and their integrations can be found on Voyado's website:
# Centric
Source: https://partner-integrations.voyado.com/docs/pos/centric/centric
With Centric's Omnichannel Retail Suite, retailers can offer consumers a seamless experience across all sales channels.
The Suite offers:
* Seamless ecosystem integration, allowing online and offline channels to be easily integrated with the back-end
* Smoother service and checkout, giving access to all product and stock information
* Increased customer loyalty with centrally managed promotions to support your marketing campaigns
The Voyado Engage integration with Centric adds Engage's powerful loyalty features.
## Multimarket support
Centric's Omnichannel Business Platform (OBP) can hold separate loyalty programs for a client where they have one program for each country. Each Loyalty program can be connected to a specific Engage instance by specifying, in OBP, which Engage tenant should be connected to which loyalty program.
It is also possible to connect all loyalty programs to just one tenant in Engage. This can be done if the logic of your reward program is the same in all markets.
Each loyalty program holds a *loyalty account ID* which needs to be defined during the project.
## Contacts
Contacts are created real-time in Engage through inPosition where you can choose between three parameters:
* Mobile phone
* SSN (More correctly, the Swedish Personal Identity Number)
* Email
Contact registrations from other sources than POS are first created in Engage and then exported via file into OBP. The key value of the integration is CustomerID (OBP) connected to externalId (Engage) which is set by Engage.
If you are connected to Dunn and Bradstreet (formerly Bisnode) then an address lookup will be done when a customer is created by their SSN or mobile phone number, which allows you to fetch personal information about that customer. A new dialog will appear with the customer information already filled out and allows staff to do a face to face validation of the customer information provided and edit it if incorrect.
### Updating a contact
All customer changes in Engage will be exported to OBP by a XML file export.
### Searching for contact
Since the search of a customer is initially made to OBP and not Engage, inPosition allows you to search for a customer using several parameters (firstname, email, address etc).
If the customer is not found in OBP then it does a lookup in Engage.
* If they exist in Engage, the customer is saved in the OBP registry.
* If not, the customer is created in both platforms.
Only one parameter (email) is used when doing the Engage lookup.
## Receipts
Purchases and returns are sent from OBP in file-based format every 5 minutes. The entity in OBP is called "POSLog".
## Multichannel promotions
A promotion template in Engage is linked to a Coupon Template in OBP. In OBP there are three layers in a promotion:
* Promo pack: This is the basis of the Coupon template and is where you determine what rules to apply to the promotion in OBP.
* Coupon template: This is what Engage will refer to when retailers create their promotion.
* Customer coupons: By assigning a Promotion/Coupon template in Engage, customer coupons will be generated in OBP.
### Monetary and percentage discounts
OBP needs to have 2 different promo pack templates set on their end. They need to create a template with an ActivationVoucherID = 100 which is connected to a percentage discount and an ActivationVoucherID = 200 which is connected to a monetary discount.
Engage controls the value of that discount and will override the value in OBP.
**Example:** If the template in OBP has a 0% discount and in Engage you set it to 20% then Engage will override the 0%, giving a 20% discount.
### Other discounts
In OBP you are able to create more advanced discounts, such as 20% off a certain product or article group. These discounts can also be referred to with a multichannel promotion of type EXTERNALOFFER in Engage by setting the external code to be the same as the ActivationVoucherID in OBP.
### Assigning a promotion
Once you have assigned the promotions in Engage, they will be exported by file to OBP and enabled in the POS.
### Redeeming a promotion
Promotions are redeemed through the POSLog (Receipts) and these are sent to Engage every 5 minutes.
## Reward vouchers
### Assigning a voucher
Engage is master of generating vouchers which are connected to *e-vouchers* in OBP. When vouchers are generated in Engage, they are exported file-based and created in OBP.
### Redeeming a voucher
Vouchers are not redeemed in real-time, but through the POSLog (Receipts) that are imported into Engage (every 5 minutes).
# Front Systems
Source: https://partner-integrations.voyado.com/docs/pos/front-systems/front-systems
Front Systems' cloud based platform digitalizes retail, unifies commerce and connects “best of breed” applications to deliver a seamless omnichannel experience. Its mobile Point Of Sale gives retailers a competitive advantage by turning brick-and-mortar stores into digital warehouses enabling the convenience and experiences today's shoppers demand
## Requirements
Here is what you'll need to start this integration:
* An active Voyado Engage license
* An Engage API key
* An active license for the Front Systems POS.
## Capabilities
Here's what the integration between Engage and Front Systems can offer.
### Contacts
Turn your customer into an Engage contact in-store using a single data point (a mobile phone number) to start them on their journey on the Engage marketing automation platform. Once registration is completed, you can send the customer an SMS with a link to a registration form.
This enables them to complete their registration, providing more customer information but also allowing them to agree to the consents needed to join your loyalty program.
### Receipts
Once you have registered or identified a known customer in-store, this integration will send all future purchases and returns to Engage, enabling you to be more targeted in all your communication from Engage to this customer.
### Multichannel promotions
By referring to a specific price list in Front Systems when you create a multichannel promotion in Engage, you can assign personal discounts to contacts which will then be presented and enabled in the POS.
In order to achieve this, you need to follow these steps:
1. Create the discount and its price logic in Front Systems.
2. Go to Engage, create your multichannel promotion and do this:
* Set the validity time period
* Tick the box **Can be used in store**
* Configure the promotion to use an **External promotion code**
* Enter the unique price list ID that was generated in Front Systems
3. Assign the promotion to your customer segment and you are done!
### Vouchers
Front Systems supports full voucher handling through its integration with Voyado Engage. This includes both fetching the vouchers assigned to identified customers and redeeming them when they have been used in-store.
When a customer is identified at the POS, any active vouchers connected to their Engage profile will automatically be retrieved and made available for use. Once a voucher is redeemed, this information is sent back to Engage, ensuring the voucher status is updated there in real-time, preventing the voucher's reuse.
### Product recommendations in-store
You are required to have the Product recommendation module active in Engage. When this is done, Front Systems can get the product recommendations of the identified customer and present them in the POS. This allows your store staff to upsell recommended products.
# Integrating your POS
Source: https://partner-integrations.voyado.com/docs/pos/integrating-your-pos
Here you'll learn how to integrate your Point-of-Sale (POS) system with Voyado Engage.
In this article we will cover how to:
* Connect to the Engage API
* Sync and manage customer data
* Handle transactions
* Deliver digital receipts
* Set up personalized promotions and vouchers
* Migrate existing data
In Engage, customers are called **contacts**. This includes members, subscribers and prospects.
## 1. Basic requirements
To start building an integration with Engage, here's what you need:
* **Base URL** - Your Engage environment endpoint
* **API Key** - Your authentication key generated in Engage
* **Source** - A string identifying the system or integration sending the data (such as “ECOM”)
* **StoreExternalId** - A unique identifier per store, site, or market
The `storeExternalId` attribute is a unique string for each store and it should always reflect the store location, such as for example "store03-stockholm" or "online\_store\_finland".
## 2. Handling customers
The flow begins with identifying the customer.
### 2.1 Identifying a customer
FIrst check if the customer already exists in Engage. The default unique identifier for contacts in Engage is **email** but other options exist:
* Mobile phone number
* Member number
* Personal identify number
### 2.2 Registering a customer
If no match is found, you will need to create a new Engage contact for the customer. To keep it fast and easy at checkout, build your integration so that only one identifier (email or phone) is required from the customer to add them.
Registering a new contact will starts Engage's automation workflows (if one is set up).
### 2.3 Data to include
When posting a contact's data to Engage, always include the following in your payload:
* **Source**: For example "ECOM"
* **StoreExternalId**: Reflects the customer's market/shipping country
* **Country**: Set from address, site geo-location, or store settings
* **Language**: Based on site language or customer choice (ISO 639-1)
### 2.4 Displaying customer info
The Engage `/contactoverview` endpoint can be used fetch the customer's full data profile (known as their enriched profile).
Here are some useful data points from the enriched profile:
* First name
* Last name
* Address
* Gender
* Birthday
* Communication preferences
* Loyalty level
* Points
* Available vouchers
* Available promotions
* Consents
Use this to display relevant loyalty data on “My Pages” and in checkout:
### 2.5 Update customer profile
When a customer updates their data (for example name or address or marketing preferences), you'll need to push that update to Engage.
Only include the fields you want to change in your update payload. Empty values will in the update payload will overwrite the existing data that is stored in Engage.
## 3. Working with receipts
Engage uses receipts (the total data of a customer's transactions) to track purchases and power customer segmentation, enabling personalized experiences and analytics.
### 3.1 Registering purchases
Send each completed receipt from your POS to Engage.
Be sure to include any discounts, vouchers and promotions and:
* Spread the discount value across all item lines
* Include `promotionId` or `voucherNumber` if applicable
### 3.2 Local currency support
If your POS operates in a different currency than the customer's group currency, include a currency conversion in your payload (as the attribute `exchangeRateToGroupCurrency`).
If your POS is unable to include a currency conversion rate in the transaction. then a conversion scheme to handle this can be set up in Engage.
A currency code must always be included in the transaction.
### 3.3 Registering returns
When a return is made, you must send a return receipt containing the details of the returned products.
### 3.4 Sending digital receipts post-purchase
You can send digital receipts post-purchase from Engage, which include:
* Customer details
* Order and item information
This is done through the `/orders` endpoints:
When the state of orders change, marketing automation flows in Engage can be triggered:
Custom data can be included in the order via `data` or on then item level using `item.ExtraData`.
## 4. Personalized promotions in POS
You can use Engage's segmentation and automation tools to assign individual promotions or vouchers, such as “10% off for Gold members” or “€10 Voucher“. Some important points about promotions (and vouchers):
* Promotions are created in Engage and referenced in the e-com by an external ID
* It is the e-com that handles pricing rules and redemption logic
* It is Engage that handles personal assignments of the discount
### 4.1 Welcome promotion at sign-up
If your loyalty program offers welcome promotions, customers often expect to receive and redeem such a promotion immediately, especially during an in-store purchase. To enable this, you can directly assign a personal promotion in Engage using the request:
```http theme={null}
POST /api/v3/promotion-assignments
```
By doing this you can:
* Avoid delays caused by asynchronous automation flows
* Prevent queue build-up and customer frustration in physical stores.
* Ensure the promotion can be redeemed during the same transaction where the customer signs up
### 4.2 Creating promotion in POS
Create the promotion in the POS system first. For example:
* Promotion name: Welcome 10%
* Discount logic: 10% off first purchase
* Promotion code: WELCOME10
This promotion will be responsible for price handling at checkout.
### 4.3 Creating promotion in Engage
Now create a corresponding promotion in Engage for the welcome offer. This promotions references the POS promotion you just made through its external promotion code (`externalId`) which must match the POS promotion code / internal ID if the POS owns the price logic.
What Engage does here is:
* Controls the assignment
* Controls the validity period
* Connects the promotion to the contact
* Makes it available on the customer's profile
### 4.4 In-store sign-up flow
Here is how the promotion is handles in the sign-up flow.
* Customer registers as a loyalty member in the POS
* POS either updates the customer in Engage or creates them there
Immediately after successful sign-up, the POS must call:
```http theme={null}
POST /api/v3/promotion-assignments
```
With:
* The customer identifier (`contactId`)
* The promotion identifier (`promotionId`)
This makes the promotion personal and instantly available.
Immediately after successful purchase, the POS must call:
```http theme={null}
POST /api/v3/promotion-assignments/[assigmentId]/redeem
```
With:
* The promotion assignment identifier (`assigmentId`)
* The redemption channel as "POS" ("redemptionChannel" : "POS")
## 5. Assigning vouchers
Points are converted to vouchers in Engage and created as a personally assigned monetary discount in the POS.
Engage handles the pricing rules and the POS then redeems the voucher using the Engage API.
## 6. Data migration (before go-live)
Before going live, you must migrate into Engage your:
* Historical customer data
* Historical transaction data
You can choose what to sync and and how far back to sync it.
Voyado recommendeds you go back a maximum of 24 months for receipts (transactions).
# Introduction
Source: https://partner-integrations.voyado.com/docs/pos/ls-central/introduction
LS Central is an all-in-one retail solution that extends Microsoft Dynamics 365 Business Central. LS Central brings together in one single platform financials (the Microsoft ERP), Point of Sale (POS), store operations, supply chain management, inventory, eCommerce, and customer loyalty. LS Central is a SaaS hosted in the highly secure and reliable Microsoft Dynamics 365 cloud.
Voyado Engage extends LS Central with several powerful features such as marketing automation and customer segmentation.
This integration with Voyado Engage requires version 26 or higher of LS Central.
## Requirements
The following are required to integrate Voyado Engage and LS Central:
* Access to LS Central (via username and password)
* Access to the Engage frontend (via username and password)
* Access to the Voyado Engage API (via your personal API key)
At this link you can investigate and test the Engage API:
```http The Engage API theme={null}
https://lsretail.staging.voyado.com/api/v2/ui/index
```
And this is the frontend used by Voyado Engage customers:
```http theme={null}
https://lsretail.staging.voyado.com
```
# Setting up
Source: https://partner-integrations.voyado.com/docs/pos/ls-central/setting-up
Follow the steps below to set up your LS Central - Engage integration.
## Basic setup
1. Open LS Central and select **Voyado Interaction Setup**.
2. The following panel will open. All the settings for your Voyado integration are collected here.
3. Selecting **Actions** in the top left will bring up a few useful options.
4. "Insert Default Values" in the top left will populate the fields with default values to get you started.
5. "Voyado WS Status" is a quick way to confirm that communication between LS Central and Voyado Engage has been set up correctly and is working. It requires that you have filled in the following data under **General**:
* API Key
* Base URL
* Voyado WS Status method (contacts/count)
If all these have been correctly entered, a request will be made to the Voyado Engage API asking for the total number of contacts. If a valid response arrives, a popup will let you know that communication is working.
6. "Open Voyado Web Json Log" opens the log showing you all the communication between LS Central and Voyado Engage. Here you can examine requests made, methods executed, payloads sent, request status etc.
7. "Insert default Voyado POS Panels" creates the POS panels you'll need to use the integration.
Your basic integration is done. You'll be visiting the **Voyado Integration Setup** page in LS Central a lot so spend some time getting to know it.
## Voyado POS module
In LS Central, go to **Retail Modules**. On the list you'll find the **VOYADO POS MODULE** (codeunit 10033466).
Install it as you would any other module.
You'll need to have Member Management correctly set up in LS Central.
After the **VOYADO POS MODULE** has been installed you will need to refresh **Web Request V2**. Do this by publishing and subscribing again from **Web Request V2** page.
Your **VOYADO POS MODULE** is now installed. It comes with some new commands to use on the POS.
# Working with
Source: https://partner-integrations.voyado.com/docs/pos/ls-central/working-with
Here's how you work with the LS Central integration with Engage.
## Bonus checks
Bonus checks, unlike Promotions, are always created first in Voyado Engage. They are then imported into LS Central whenever needed and used to create data entries using the template **Voyado Bonuschecks** found under POS Data Entry types. These can then be applied to transactions in the normal way.
### Setting up bonus checks
In your **Voyado Integration Setup** there are two options under **Bonus checks / Bonus check type** and these are VOUCHER and COUPON.
Note there is a new Tender Type specifically for bonus checks (14). This should already be set.
Through LS Central you can choose to handle bonus checks as a COUPON or VOUCHER. Both of these are applied to the contact's total as a discount; they are not used as tender. This avoids issues such as the POS suggesting giving the customer a cash refund for the amount remaining, or generating new bonus points on the tendered amount.
Both options for **Bonuscheck Type**, VOUCHER and COUPON, are applied as a discount.
### Bonus checks template
In LS Central, go to **POS Data Entry Types**. There you should see **Voyado Bonushecks** listed as a type. This is the template used by LS Central to create bonus checks.
Select this to view the details.
If **Use Full Remaining Balance** is set to ON, the bonus check will be entirely used up the first time it is used and then be automatically redeemed in Voyado Engage.
If **Use Full Remaining Balance** is set to OFF, the bonus check can be used many times, as long as it still has money remaining. This amount will of course decrease every time it is used.
### Using a bonus check
When a member is identified in the POS, LS Central checks if that member already has data entries of type **Voyado Bonuscheck**. If there are, these will first be deleted.
A sync will then be performed with Engage to fetch any bonus checks and new data entries will be created in the LS Central. Bonus checks are thus created on-the-fly whenever a member is identified in the POS (and deleted after).
To see the bonus checks available for a member, select **Voyado Bonuschecks** in the POS (which uses the new command VOYADOMEMBERBONUS).
You will see something like this:
From here you choose the bonus check you want to use (or that the customer wants to use) and then select **Add to Transaction** as usual.
### Bonus check states
Engage and LS Central use different naming conventions for the current state of bonus checks. Natively in Engage, a bonus check's state can be either **Used** or **Unused**. When an Engage-created bonus check is imported and viewed in LS Central, the states shown (in the column *Voyado Status*) are **REDEEMED** and **UNUSED**:
* **Used** in Engage = **REDEEMED** in LS Central
* **Unused** in Engage = **UNUSED** in LS Central
## Promotions
A Promotion is first created as a Store Coupon in LS Central. This data is then sent over to Voyado with the press of a button, where it's used to create a matching Voyado Promotion.
Here are the steps to follow:
### Creating a store coupon
Go to **Store Coupon List** in LS Central and create a Store Coupon. Check that the details are filled out as in the example below:
* **Code**: The id of the campaign
* **Description**: A short description
* **Coupon Issuer**: Who is the coupon issuer
* **Coupon Reference No**.: The reference id
* **Price Group**: The price group that will be applied.
* **Calculation Type**: This must be set to Discount
* **Validation Period ID**: Validation period for the campaign
* **Status**: Enabled/Disabled
Here you define which items will be part of the campaign, as you would do for any Store Coupon.
* **Calculation Type:** Discount
* **Discount Type:** Discount %
* **Value:** The discount percentage that will be applied.
* **Barcode Mask:** Barcode mask (already set up)
Here you'll see that the Promotion works as a Discount Percentage.
* **Handling:** Discount
* **Entry Validation:** Apply to Entry
* **Coupon ID Method:** Serial No.
* **Member Type:** Club
* **Member Value:** The id of the club
* **Voyado Promotion:** Enabled/Disabled
* **Voyado Promotion Type:** Multichannel-Promotion
### Creating promotion in Engage
When your Store Coupon is set up, go to the top menu in LS Central. Select **Actions** and then **Create Promotion In Voyado**.
This sends all the information to Engage, creating a Promotion. In Engage, your new Promotion will look like this:
You'll notice that the **External id** of the Voyado Engage Promotion matches the **Code** value of the Store Coupon. This is how the integration understands that these two are the same. Now this Promotion can be assigned to members and segments in Engage and become part of an automation.
If you edit the Promotion in Voyado, you should then always manually sync it in LS Central.
To make this Promotion available online, tick the **Can be used online** checkbox on the Engage page.
### Using promotion in-store
Once a customer is identified in the POS, select the button **Voyado Promotions** (which uses the new command VODAYOMEMBERPROMOS). LS Central will then receive all the active promotions for this member and confirm that each one:
* Was created in LS Central
* Is currently enabled in LS Central
Coupon entries will now be shown in the POS and can be applied to purchases. When one of them is used, the coupon entry in LS Central is deleted and the Promotion is redeemed in Engage. This means the next time LS Central requests a member's active promotions, the one just used won't turn up, since it has been redeemed.
Only promotions that were created in LS Central can be used.
### Using a promotion online
Assuming the **Can be used online** option has been ticked for the Promotion in Voyado Engage, it should now be usable with online purchases.
### Creating and redeeming promotions
To ensure that promotions are created and redeemed correctly, be sure that the Promotions section of your **Voyado Integration Setup** looks like this.
## Transactions
All transactions, both purchases and returns, are sent on-the-fly from LS Central to Voyado Engage. Engage runs a background process to read in new data, so there might be a slight delay before receipts turn up in the Engage frontend.
In LS Central transaction receipts can be found in the **Transaction Register**.
Receipts in Engage can be found under a contact's **Transaction History**.
If a receipt does not turn up in Engage, for whatever reason, there is functionality in LS Central to help with this.
### Missing receipts
Each transaction creates a receipt in LS Central's **Transaction Register**. An individual receipt looks like this.
Under the Voyado heading is the indicator **Is in Voyado** which lets you know if the receipt has safely made it to Engage.
It can be tricky, in isolation, to tell if the indicator is set to ON or OFF. Here's what both states look like:
**The indicator in the YES / ON position:**
**The indicator in the NO / OFF position:**
If a receipt could not be transferred to Engage, you can try sending it manually with **Send receipt to Voyado** on the top row. You will be informed if this has worked. If an error occurs, check the log on the **Voyado Integration Setup** page for details.
Resending a receipt from LS Central to Engage is mostly for first-line support to use if something has gone wrong.
### Handling returns
Returns also turn up under a contact's **Transaction History** in Engage. In the example here, the topmost transaction is a return. They can be manually sent in the same way as other transactions, if needed. Note that a return transaction's **Total** is negative.
## Contacts
Voyado is the owner of all contacts. This means that any changes made to a contact in the POS will always be synced up to Voyado Engage. Likewise, contact data will always be fetched from Engage before it is shown on the POS.
A new customer added in LS Central will automatically be created as contact type **member** in Voyado Engage.
### Voyado Member Search
Installing the **VOYADO POS MODULE** added a new search panel to the POS: the **Voyado Member Search**. This uses the attribute specified in **Voyado Integration Setup / General** to search for a member. The attribute used can be Email, Mobile Phone No or SSN (to be added down the line) and the attribute you've chosen is shown on the panel's name (in this case, Email).
Type your search and select **OK**. If a member is found, they'll become the active contact in the POS.
You, the customer, can choose what parameter to use for identifying a member in the POS. This is set in the **Voyado Integration setup** in LS Central.
### Member Management Panel
This panel can be opened either by a Voyado Member Search or manually with the button **VOYADO M. CONTACT** on the POS (which uses the new command VOYADOMEMBERCONTACT).
If you have an active member, their data will be visible here.
If you've not identified the member, you can now search for them by entering Email or Mobile Phone No and pressing **Voyado Search** on the bottom row.
The search will first check LS Central and then Voyado. Data will also be synced to Voyado if necessary, for example, if a change was made to that member's data in LS Central but not yet saved to Voyado.
Write mobile phone numbers without spaces (example: +34777888555)
This search has a few possible outcomes:
If the member cannot be found in LS Central or in Voyado, no data will be returned. The user can then create a member for this customer directly on the POS.
Email and Name are mandatory fields when creating new members (LS Central requires them both). So if you have a customer's Mobile Phone Number but not their email, just write in a fake email instead (along with Name and Mobile Phone Number) and LS Central will accept it. This fake email does not have to be unique.
This is the sequence to create a new member:
1. Enter Name and Email and any other data such as Mobile Phone No
2. Select **SAVE**
A new member will be now created in both LS Central and Voyado.
Selecting **SAVE** is always safe to do when you've filled in Name and Email. If that member exists, their data will be retrieved and shown. If not, a new member will be created. **SAVE** is your friend!
This could happen, for example, if the member created their account online and has never used the POS. If a search is made for a member like this, data from Voyado will be populated in the panel. However, Club Code, Scheme Code, Account No. and Contact No. will be empty.
Select **SAVE** and the member will be automatically created in LS Central (and any additional data will also be synced to Voyado).
In this case, you will get all the member's information and can choose to update it (for example, perhaps the person has changed name). Again, selecting **SAVE** will automatically sync any such changes to Voyado.
### Things to keep in mind
* If a new member's country code is not specified, the country code for the store will be used by default, since Engage requires a country code to be sent.
* In LS Central there are no controls about a member's phone prefix, but Engage requires a correct prefix. It is important for the POS user to enter the prefix correctly.
## New POS commands
The **VOYADO POS MODULE** comes with several new commands:
1. VOYADOMEMBERBONUS: See a Voyado member's bonus checks
2. VOYADOMEMBERCONTACT: See a Voyado member's contact info
3. VOYADOMEMBERPROMOS: See a Voyado member's promotions
4. VOYADOMEMBERSEARCH: Search for a Voyado member by phone, email, SSN
5. VOYADOSEARCHPHONE: Search a Voyado member by phone
If you created the default POS panel setup using the option in the **Voyado Integration Setup**, these commands will already be mapped to the relevant buttons on the POS for you.
## Member management setup
Voyado must be chosen as the Default Club Code under Member Management Setup in LS Central. If it is not, you cannot save changes to a contact from the EPOS.
However, from the EPOS, you can select NEW and then LINK TO ACCOUNT to set this.
# Orisha Commerce
Source: https://partner-integrations.voyado.com/docs/pos/orisha-commerce/orisha-commerce
## Introduction
Orisha Commerce (formerly Cow Hills Retail) is a Dutch company providing omnichannel point-of-sale software for retailers. They are fully cloud-based and their POS can run on all kinds of hardware, including iOS and android, allowing staff to, for example, walk around the store and process customer's purchases on the spot.
Orisha Commerce already have access to loyalty and promotion functions through their promotions engine, Treazure. But by using a standard POS integration with Voyado Engage they can leverage Engage's automation capabilities and more to deliver a much richer experience.
Note that this is a point-follower integration. This means that Treazure is the arbitrator of points and Engage will only send point updates whenever that happens in its system.
The integration is only supported by later versions of the Orisha Commerce / Treazure software. Check with the Orisha Commerce team to see if the version you are using is compatible with the Voyado Engage integration.
This integration between Orisha Commerce and Engage covers the following areas:
* Identifying a contact
* Registering a contact
* Updating a contact
* Sending transactions (receipts) to Engage
* Assigning personal promotions
* Applying promotions to purchases
* Enabling Engage to act as point follower
## Prerequisites
To set up your integration you'll need:
* A login to Engage
* An API key for the Engage API
* A Treazure account
If you are using multiple markets in Engage, these can be set up to work from a single Orisha Commerce instance.
## Configuration
Orisha Commerce themselves take care of the configuration. Contact them for more details.
## Contacts
An end-user in Engage is called a "contact". In Engage there are many contact types: "Contact", "Member" as well as custom types based on a retailer's specific requirements.
Orisha Commerce is able to search for contacts in Engage without specifying the contact type. This allows a search to be made for a contact, regardless of their contact type, using only an address or mobile number. However, all contacts registered and updated in-store through the Orisha Commerce POS will be saved as type "Member".
Your goal should be to have all your end-users as contact type "Member". This allows them to be awarded loyalty in form of points and vouchers, making use of the power of Engage, and allows you the retailer to gather more useful data.
All contact data displayed in the Orisha Commerce POS can be updated and saved. Custom attributes can also be added in the POS and then synced back to Engage.
Orisha Commerce is able to search for contacts in Engage without specifying the contact type. However, all contacts registered and updated in-store through the Orisha Commerce POS will be of type "Member".
### Identifying a contact
Orisha Commerce uses v1 of the Engage API endpoint /contacts. Version 1 is used because searching based on address and postal (zip) code is something still commonly done in retailers in the Netherlands amd v1 of the Engage API supports this.
This is an example swagger page for the Engage API:
```http theme={null}
https://voyadodemoecom.voyado.com/api/v2/ui/index
```
Select "Voyado API v1" in the top-right dropdown to access the version 1 API.
Now select "Contacts" and the first option "Get contacts through query". Create your search query with the details you will use, and send it as the query parameter.
For example, your query might be: ZipCode:"111 11" AND Street:"Examplegatan 5"
The full API call in this example is then:
```http theme={null}
https://voyadodemoecom.voyado.com/api/v1/contacts?query=ZipCode%3A%22111%2011%22%20AND%20Street%3A%22Examplegatan%205%22
```
You must use version 1 of the `/contacts` endpoint in the Engage API to check if a contact exists. The contact type is not needed. Note that `/contacts` is the only v1 endpoint used; everything else in this integration uses the Engage v2 API.
Upon making this request, you will find out if this contact is already in the system, or if they are not. Here are the two situations and what happens in each:
In this case, data in this format will be returned:
```json theme={null}
{
"totalResults": 1,
"results": [
{
"firstName": "Example",
"lastName": "Examplesson",
"email": "example@example.com",
"socialSecurityNumber": null,
"mobilePhone": null,
"zipCode": "111 11",
"street": "Examplegatan",
"city": null,
"externalId": "11de71a1-4bc6-4a11-a4ef-8ebac0480b11",
"id": "d0011111-45f2-492f-8d31-aec500a07f11",
"contactType": "Member",
"memberNumber": "01010101010101"
}
]
}
```
The value `id` returned contains the unique contact ID and will be used in the display step below.
In this case, Orisha Commerce will create a new contact in Engage as contact type Member.
This creates a contact and returns a data set containing id, their unique contact ID value.
### Displaying a contact's data
Now that the contact has been identified, Orisha Commerce takes their unique ID and performs a lookup against the `/contactoverview` endpoint in version 2 of the API.
Orisha Commerce now fetches the contact's full data from Engage, containing such information as address, target audience, promotions, tier levels, purchase history, points and consents. This is used to populate the POS, depending on what the retailer wants to see.
Orisha Commerce can also fetch extra contact attributes from Engage. These are configured under "sections" in Orisha Commerce.
Extra attributes are read-only in the POS and can't be changed from there.
### Updating a contact
If a contact's details are updated in the POS, Orisha Commerce will send an update to Engage, syncing the new values. See the Engage API documentation to learn how this is done:
## Promotions
In Treazure, coupons and vouchers are two different concepts.
* **Vouchers** are connected to a customer's profile and turn up automatically in the POS.
* **Coupons** need to be physically taken to the store either on a mobile screen or on paper.
In this integration only Treazure vouchers will be used, together with Engage multichannel promotions.
Read about the Engage API for promotions here:
### Creating a promotion
An Orisha Commerce promotion that uses data from Engage needs to be set up in both systems. The use of a unique ID (external promotion code) allows a Treazure voucher and a Engage multichannel promotion to be connected.
Engage handles assignments of the promotion to the contact or contacts, and Orisha Commerce handles the actual price rule (20% off, 3 for 2, 20 kr discount, or whatever).
Here's how to connect an Engage multichannel promotions to a Treazure voucher.
In Engage, go to Promotions / Active and then select the **New promotion** button. From the dropdown select **Multichannel promotion**.
This creates a new multichannel promotion.
Now you configure the promotion. Make it "Can be used in store" and select "External promotion code" in the dropdown. Decide on an external promotion code and fill it in.
Then copy this external promotion code value and switch over to Treazure.
In Treazure, go to Voucher definition and select "+ Add" to create a new voucher.
Configure your new voucher.
Now enter the external promotion code you copied from Engage into the **Code** box.
Change **Type** to CRM since this is not a Treazure voucher but an external one.
A voucher in Treazure is not linked directly to a promotion, it is instead added to a filter group first.
So create a filter group of type "Voucher".
Give it a Code (name) and a Description, and save it.
Select "Add" and select the Treazure voucher you made earlier from the list. Hit "Save".
Now your filter group is ready.
In Treazure, create a new promotion.
Give your promotion a name and description. Fill in the other fields.
Under **Article filter** add the articles included in the promotion (write ALL for all).
Under **Voucher filter** add the filter group you just made.
Add whatever other settings you need to your promotion under **Promotion settings**. Add the stores and validation period. Now your promotion is ready to use.
Since Engage uses an expiry date for its multichannel promotion, when you make your promotion in Treazure, you must **set it to a date far in the future**. This enables the Engage expiry date to be the one that decides if a promotion is still active or not.
### Using a promotion
If the setup has been performed correctly in both Engage and Treazure, the Engage promotion should now turn up for the specified customers when they are identified in the POS and their data is fetched from Engage.
As for any external promotion in Engage, the external promotion code is used by the POS to fetch the price rule from the external system (from Treazure, in this case).
The Orisha Commerce POS can also show the normal promotions from Treazure that are not connected to any promotions in Engage.
### Redeeming a promotion
Redeeming a promotion is currently done through the receipt. The discount is applied across all items and then the promotion's unique ID is added to the "usedPromotions" array in the payload that is sent to the Engage /receipts endpoint.
This is how that looks in the payload:
```json theme={null}
{
...
"usedPromotions": [{
"promotionId": "1234dfaa-31c5-2e22-bb88-7fffc5fe8bf7"
}]
}
```
See the Engage documentation for more information:
## Handling receipts
A vital part of the integration between Orisha Commerce and Engage is handling receipts. Learn more here:
### Handling purchases
If a customer makes a purchase, Orisha Commerce sends that receipt to the `/receipts` endpoint of the Engage API using contact ID as the identifier.
If there is a promotion or discount used, it is first applied to as a discount across each line item. The relevant promotion ID will also be included on the receipt.
### Handling returns
If a customer makes a return, Orisha Commerce sends that receipt to the Engage API using a contact's contact ID as the key. Again, see the Engage documentation for details.
## Engage as point follower
In this integration Treazure (Orisha Commerce's Loyalty CRM) is the master of points and vouchers, allowing customers to buy items with points, create vouchers directly on the fly and also have different type of points-buckets.
This means that Treazure decides what the points are, and Engage will act as *point follower*.
Read more about point follower here:
When Engage is acting as point follower for Treazure, there are the three cases to consider:
Since Treazure is the point master, point changes may occur that Engage does not know about. So Engage has to constantly sync its point balances to the values in Treazure. This is done on a schedule. Every hour, the current point balance for every contact is fetched from Treazure and sent to an specific API endpoint in Engage.
For this to work, point follower functionality must be enabled in Engage. Enabling this creates a connection between Engage and Treazure through Engage's iPaaS, a middleware used for point syncing. It pulls the point balances from Treazure and updates them in Engage using the endpoints below.
```http Endpoint in Treazure theme={null}
https://[client].posengine.[environment].cloud/api/v1.0/LoyaltyVault/Balances/Get
```
```json Payload theme={null}
{
"mutatedFrom": "[[todays date - 2 hours]]",
"mutatedTo": "[[todays date + 2 hours]]",
"loyaltyPointDefinitionId": "[[loyaltyId]]"
}
```
```http theme={null}
https://[client].posengine.[environment].cloud[href]/result
```
```http Response href in Engage theme={null}
https://[client].voyado.com/api/v2/point-accounts/balances
```
When Engage is point follower, points added manually in the Engage UI or through Engage automations are not added directly. A request is instead sent to Treazure, using the following webhook provided by Treazure. For this to work, you need to activate Engage's webhook functionality.
```http Endpoint in Treazure theme={null}
https://[client].posengine.[environment].cloud/api/v1.0/LoyaltyVault/Account/[contactId]/Transaction
```
Here, \[client] and \[environment] depend on your setup, and \[contactId] is the GUID for the specific contact.
The webhook returns the new point balance for that specific contact when is then set directly in Engage.
When doing a remote points adjustment like this, you can add a description in the Engage UI. The Treazure API, however, limits the length of this description to 100 characters. Anything longer will cause an error and the update will not be accepted. So be sure to keep your description under 100 characters.
As well as fetching the point balances, Engage can fetch the total point history for a contact. This is useful, for example, for displaying the total points history on the contact card in the Engage UI.
Since only the point balance is updated by the hourly sync, a webhook needs to be configured in Engage to fetch the full points history. This is done by your Voyado team in the Rewards module in the Engage back-end. The webhook looks like this:
```http Endpoint in Treazure: theme={null}
https://[client].posengine.[environment].cloud/api/v1.0/LoyaltyVault/Account/[contactId]/LoyaltyPrograms/[loyaltyId]/History
```
It's also possible to migrate points from Treazure to Engage through the point migration service. This is useful for customers who have a existing loyalty program in Treazure and want to go live with Engage as point follower. See how this is done here.
# Deeper knowledge
Source: https://partner-integrations.voyado.com/docs/pos/shopify/deeper-knowledge
Here is some more useful information about the integration.
## Multi location support
If you have several Shopify locations you can install the app for each store and connect your Shopify store to a store in Voyado Engage.
## Contacts sync
All contacts who have signed up in the Shopify POS app will be created in Engage as contact type "Member" regardless of the settings chosen for contact types in the app configuration in Shopify.
Already existing contacts of type "Contact" will be changed to "Member" when their details are updated in the POS app.
## Receipts sync
Receipts are synced to Engage for every purchase made in the Shopify POS as soon as the order is fulfilled. Return receipts are sent when a refund is registered in Shopify. *Only* products that have been refunded will be sent to Engage, not the whole order.
## Recruited-in store
Shopify does not send a recruited-in store when a customer is created. Instead, the recruited-in store in Engage is set from the store that is listed on the customer's first transaction to be received.
## Contacts and loyalty
Since all contacts are of type "Member" if you want to exclude some contacts from collecting reward points in Engage on their purchases, you can do so by setting up a filter in the Rewards module. This needs to be done by your Voyado team, so contact them for help.
## Sync of transactions (receipts)
Receipts are synced to Engage for all identified purchases in the Shopify POS as soon as an the order is fulfilled. Return receipts are synced to Engage when a refund is registered in Shopify. Only products that have been refunded will be sent to Voyado, not the whole order.
## Transactional communication
This is for Shopify Plus merchants only.
Discounted products in Shopify are not defined as discounted in the payload received by Engage when triggering transactional emails. This means that discounts can't be indicated in emails.
These states will trigger a transactional communication from Engage:
* Order confirmed
* Order fulfilled
* Order partially fulfilled
* Order cancelled
* Order refunded
Receipts for returns are synced to Engage when a refund is registered in Shopify. Only the products that have been refunded will be sent to Engage, not the whole order.
The state "PARTIALLY\_FULFILLED" is used when, for example, two product are part of a purchase, and both are not sent to the customer at the same time. Then a transactional email can be triggered for only the item that has been fulfilled.
Once the second item is fulfilled, the state of the transaction becomes "FULFILLED", triggering another transactional email if needed, and the receipt can then be sent to the /receipts endpoint.
Here you can see the various states of an order:
## External reference
The `shopifyId` will be stored in the `externalId` field for the contact in Engage.
## Preferences / consents
The Shopify POS app sets the accepts-email and accepts-SMS flags when the customer is created in Engage, based on their existing preferences.
For example, if the customer signs up in-store without setting any consent, the accepts-email flag will be set to "false" in Engage, since they haven't opted into marketing. If they opt in for newsletter on creation, the accepts-email flag will be set to "true" in Engage.
# Payload examples
Source: https://partner-integrations.voyado.com/docs/pos/shopify/payload-examples
Here are some payload examples sent from the Shopify POS app to Engage.
```json theme={null}
{
"city": "Hull",
"contactType": "member",
"country": "United Kingdom",
"countryCode": "GB",
"email": "john.doe@voyado.com",
"externalId": 6725073076536,
"language":"en",
"firstName": "John",
"lastName": "Doe",
"mobilePhone": "+46 16 779 3703",
"preferences": {
"acceptsEmail": true,
"acceptsPostal": false,
"acceptsSms": false
},
"street": "Streetlife Museum",
"zipCode": "HU1 1PS"
}
```
```json theme={null}
{
"contact": {
"contactType": "member",
"matchKey": "aa34ebae-ffcf-4d73-99e4-af720106c055",
"matchKeyType": "contactId"
},
"createdDate": "2022-12-21T15:56:30+00:00",
"currency": "GBP",
"exchangeRateToGroupCurrency": 0.877969,
"items": [
{
"articleName": "Example Pants",
"articleNumber": "13435",
"discounts": [],
"grossPaidPrice": 49.99,
"quantity": 1,
"sku": "13435",
"taxAmount": 8.33,
"taxPercent": 20,
"type": "PURCHASE"
}
],
"paymentMethods": [
{
"description": "bogus",
"type": "bogus",
"value": 49.989999999999995
}
],
"receiptNumber": 1064,
"storeExternalId": "pos-uk",
"taxDetails": [
{
"description": "GB VAT",
"value": 7.99
},
{
"description": "GB VAT",
"value": 0
}
],
"totalGrossPrice": 49.989999999999995,
"uniqueReceiptId": 5221505696056,
"usedBonusChecks": [],
"usedPromotions": []
}
```
```json theme={null}
{
"contact": {
"contactType": "member",
"matchKey": "aa34ebae-ffcf-4d73-99e4-af720106c055",
"matchKeyType": "contactId"
},
"createdDate": "2022-12-22T10:10:48+00:00",
"currency": "GBP",
"exchangeRateToGroupCurrency": 0.877969,
"items": [
{
"articleName": "Example Pants",
"articleNumber": "13435",
"grossPaidPrice": 49.989999999999995,
"quantity": -1,
"sku": "13435",
"taxAmount": 8.331666666666667,
"taxPercent": 20,
"type": "RETURN"
}
],
"paymentMethods": [
{
"description": "bogus",
"type": "bogus",
"value": -49.989999999999995
}
],
"receiptNumber": 1064,
"storeExternalId": "pos-uk",
"taxDetails": [
{
"description": "Tax Refund",
"value": 8.33
}
],
"totalGrossPrice": -49.989999999999995,
"uniqueReceiptId": 940100682040
}
```
```json theme={null}
{
"contact": {
"matchKey": "accelerators@voyado.com",
"matchKeyType": "email"
},
"orderStatus": "CONFIRMED_POS",
"paymentStatus": "PAID",
"orderNumber": "#1052",
"createdDate": "2023-09-22T12:35:39+00:00",
"shippingDate": "2023-09-22T12:35:40Z",
"statusChangedDate": "2023-09-22T12:35:41+00:00",
"storeId": "pos-uk",
"currency": "GBP",
"language": "en",
"totalGrossPrice": 2074.95,
"totalTax": "0.0",
"freightFee": {
"value": "0",
"tax": 0
},
"taxDetails": [],
"extraData": {
"CreatedDate": "2023-09-22T12:35:39+00:00",
"ShippingDate": "2023-09-22T12:35:40Z",
"ShippingAddressEmail": "accelerators@voyado.com",
"PaymentMethod": "cash",
"BillingAddressEmail": "accelerators@voyado.com"
},
"items": [
{
"type": "PURCHASE",
"quantity": 1,
"grossPaidPrice": 24.95,
"taxAmount": 0,
"taxPercent": 0,
"sku": "n/a",
"description": "Selling Plans Ski Wax - Selling Plans Ski Wax",
"imageUrl": "https://cdn.shopify.com/s/files/1/0811/4015/4690/products/snowboard_wax.png?v=1691742154",
"targetUrl": "https://voyado-pos-test.myshopify.com/products/selling-plans-ski-wax",
"articleName": "Selling Plans Ski Wax",
"articleNumber": "n/a",
"discounts": []
},
{
"type": "PURCHASE",
"quantity": 2,
"grossPaidPrice": 2050,
"taxAmount": 0,
"taxPercent": 0,
"sku": "sku-hosted-5",
"description": "The Collection Snowboard: Oxygen",
"imageUrl": "https://cdn.shopify.com/s/files/1/0811/4015/4690/products/Main_d624f226-0a89-4fe1-b333-0d1548b43c06.jpg?v=1691742152",
"targetUrl": "https://voyado-pos-test.myshopify.com/products/the-collection-snowboard-oxygen",
"articleName": "The Collection Snowboard: Oxygen",
"articleNumber": "sku-hosted-5",
"discounts": []
}
]
}
```
```json theme={null}
{
"contact": {
"matchKey": "accelerators@voyado.com",
"matchKeyType": "email"
},
"orderStatus": "FULFILLED_POS",
"paymentStatus": "PAID",
"orderNumber": "#1052",
"createdDate": "2023-09-22T12:35:39+00:00",
"shippingDate": "2023-09-22T12:35:40Z",
"statusChangedDate": "2023-09-22T12:35:41+00:00",
"storeId": "pos-uk",
"currency": "GBP",
"language": "en",
"totalGrossPrice": 2074.95,
"totalTax": "0.0",
"freightFee": {
"value": "0",
"tax": 0
},
"taxDetails": [],
"extraData": {
"CreatedDate": "2023-09-22T12:35:39+00:00",
"ShippingDate": "2023-09-22T12:35:40Z",
"ShippingAddressEmail": "accelerators@voyado.com",
"PaymentMethod": "cash",
"BillingAddressEmail": "accelerators@voyado.com"
},
"items": [
{
"type": "PURCHASE",
"quantity": 1,
"grossPaidPrice": 24.95,
"taxAmount": 0,
"taxPercent": 0,
"sku": "n/a",
"description": "Selling Plans Ski Wax - Selling Plans Ski Wax",
"imageUrl": "https://cdn.shopify.com/s/files/1/0811/4015/4690/products/snowboard_wax.png?v=1691742154",
"targetUrl": "https://voyado-pos-test.myshopify.com/products/selling-plans-ski-wax",
"articleName": "Selling Plans Ski Wax",
"articleNumber": "n/a",
"discounts": []
},
{
"type": "PURCHASE",
"quantity": 2,
"grossPaidPrice": 2050,
"taxAmount": 0,
"taxPercent": 0,
"sku": "sku-hosted-5",
"description": "The Collection Snowboard: Oxygen",
"imageUrl": "https://cdn.shopify.com/s/files/1/0811/4015/4690/products/Main_d624f226-0a89-4fe1-b333-0d1548b43c06.jpg?v=1691742152",
"targetUrl": "https://voyado-pos-test.myshopify.com/products/the-collection-snowboard-oxygen",
"articleName": "The Collection Snowboard: Oxygen",
"articleNumber": "sku-hosted-5",
"discounts": []
}
]
}
```
```json theme={null}
{
"contact": {
"matchKey": "accelerators@voyado.com",
"matchKeyType": "email"
},
"createdDate": "2023-09-22T12:37:50+00:00",
"storeId": "123",
"orderNumber": "#1052",
"currency": "GBP",
"language": "en",
"totalGrossPrice": -2074.95,
"totalTax": 0,
"orderStatus": "REFUNDED_POS",
"paymentStatus": "PAID",
"extraData": {
"CreatedDate": "2023-09-22T12:37:50+00:00",
"ReturnDate": "2023-09-22T12:37:50+00:00",
"BillingAddressEmail": "accelerators@voyado.com"
},
"items": [
{
"type": "RETURN",
"quantity": -1,
"grossPaidPrice": 1037.475,
"taxAmount": 0,
"taxPercent": 0,
"sku": "n/a",
"articleName": "Selling Plans Ski Wax",
"articleNumber": "n/a",
"description": "Selling Plans Ski Wax",
"imageUrl": "https://cdn.shopify.com/s/files/1/0811/4015/4690/products/snowboard_wax.png?v=1691742154",
"targetUrl": "https://voyado-pos-test.myshopify.com/products/selling-plans-ski-wax"
},
{
"type": "RETURN",
"quantity": -2,
"grossPaidPrice": 1037.475,
"taxAmount": 0,
"taxPercent": 0,
"sku": "sku-hosted-5",
"articleName": "The Collection Snowboard: Oxygen",
"articleNumber": "sku-hosted-5",
"description": "The Collection Snowboard: Oxygen",
"imageUrl": "https://cdn.shopify.com/s/files/1/0811/4015/4690/products/Main_d624f226-0a89-4fe1-b333-0d1548b43c06.jpg?v=1691742152",
"targetUrl": "https://voyado-pos-test.myshopify.com/products/the-collection-snowboard-oxygen"
}
]
}
```
# Introduction
Source: https://partner-integrations.voyado.com/docs/pos/shopify/pos-introduction
Shopify is a user-friendly e-commerce platform helping small and mid-sized businesses to quickly build a modern online store. It allows merchants to design, manage and sell their products across multiple sales channels. The Shopify POS app expands Shopify's capabilities by allowing merchants to sell almost anywhere, from brick and mortar stores to markets to pop-up shops.
Voyado Engage is a multichannel marketing automation platform used by hundreds of retailers. Engage enables merchants to act on their customer data, granting the insights and campaign tools they need to create extraordinary experiences across all sales and marketing channels.
This POS integration allows you to connect the Shopify POS app to Engage, giving you the power and flexibility of both platforms. You'll first install the standard Shopify POS mobile app from the iOS store (or Play store for android), and then the Voyado Engage app in your Shopify account.
With these two apps configured you are ready to access Engage features through the Shopify POS app on your handheld device, allowing you to supercharge the Shopify POS experience for your customers.
## What the integration has to offer
The Engage app for Shopify offers a range of exciting functionality, including:
* Keeping the consents (email / SMS / postal preferences) of your customers in sync between Engage and Shopify
* Enabling several types of transactional communication sent out from Engage
* Sending customer's orders to Engage to allow segmentation and BI insights
* Using a tile in the Shopify POS app showing a customer's vouchers, promotions, points and member level
* Assigning vouchers and promotions in Engage that can then be used in Shopify
* Redeeming of promotions and vouchers through the Shopify-Engage connection
* Migrating (importing) customers and their orders into Engage from the Shopify app
The POS integration between Engage and Shopify uses the same Shopify app, called "Voyado Engage", as the basic e-com integration. The POS integration just requires a few extra settings in that app (along with the mobile Shopify app). So when configuring the POS integration, you'll either be:
* Adding some extra configuration to an already functioning Voyado Engage app in Shopify
* Configuring both the e-com integration and the POS integration at the same time
In either case, you'll need to consult the docs for the basic e-com integration before or during the POS integration.
## More information
Find the full developer documentation foe Engage here:
Here are Shopify's docs for the Shopify POS app:
## Release notes
This POS integration is a part of larger integration of Voyado Engage with Shopify.
The combined release notes for both can be found here:
# Promotions and vouchers
Source: https://partner-integrations.voyado.com/docs/pos/shopify/promotions-and-vouchers
To enable the use of promotions (discounts) and vouchers in your Shopify POS app, the setup on the Shopify side has to be complete. During that setup you'll need to have selected the options below. The first enables promotions, and the second enables vouchers:
You can now view a customer's loyalty information in the Shopify POS app. To do this, add a customer to the cart. When you then select the "Manage Voyado discounts" tile, and assuming you have enabled both promotions and vouchers during the setup in Shopify, you'll see two tabs:
**Personal discounts:** Here you can see any discounts (promotions) that are available for that customer.
**Reward vouchers:** Here are listed the vouchers available for that customer.
## Creating Personal discounts
A Personal discount is created in Engage as a multichannel promotion.
Under the "Promotions" side-menu in Engage, select "New Promotion" and then "Multichannel promotion".
Now choose either "Monetary discount" or "Discount in Percent" as the value type.
Don't pick "External promotion code" for a promotion that you intend to be used in the Shopify POS.
Now assign this promotion to your customers. When a customer with this promotion assigned is identified in the Shopify POS app, selecting the "Manage Voyado discounts" tile will generate the appropriate discount based on the promotion you just created in Engage, in the local currency. This discount can now be added to a purchase during checkout in the POS app.
Once the order is placed, the promotion will be redeemed in Engage.
## Creating Reward vouchers
In Engage, a contact's reward points can be converted to a loyalty voucher / reward voucher, which is an amount of money that can then be used for purchases.
This is done under **Promotions > New Promotion > Reward voucher**.
To learn how to convert points to vouchers, see here:
Any vouchers from Engage will be created as discounts in the Shopify POS app, in the local currency, when a customer is identified there.
Apply the voucher by selecting it once the customer has an item in their cart.
Once the order is placed, the voucher will be redeemed in Engage.
# Setup and configuration
Source: https://partner-integrations.voyado.com/docs/pos/shopify/setup-and-config
Here's how you set up the Shopify POS integration with Engage.
This article has two main sections:
1. Getting your Shopify app to work for the POS integration
2. Setting up the Shopify mobile POS app (if you are using it)
## POS configuration of Shopify app
This involves some extra configuration added to an already functioning implementation of the Voyado Engage app for Shopify.
Complete the e-com configuration and then return here for the extra configuration needed for the POS integration.
Then (or if your e-com configuration is already done) go through the steps below. There are the additional configuration steps you'll need to get the POS integration working with your "Voyado Engage" app in Shopify.
There are three things you'll need to adjust in the app settings:
1. Store to Country Mapping
2. Promotions & reward voucher sync
3. Data import
### 1 - Store to Country Mapping
In this step, you'll connect your stores in Engage to the location in Shopify, using the second option on the panel, **Shopify POS location**. The values for the first option, **Shipping country**, will already exist if you have already done the e-com configuration.
If, however, you're doing the e-com and POS configurations at the same time, you can take these two tasks in any order.
If you've *not yet* filled in anything in this panel, it'll look like this:
If you *have* already filled in the shipping country values, the panel will look like this:
In both cases, select "Add mapping" to get started.
Now select the second option, "Shopify POS location":
You will see two drop-downs. The first has all your Voyado Engage stores, the second your Shopify locations.
Only Engage stores of type "RETAIL" will appear in the "Voyado store" list.
Select the Shopify location for each of your Engage stores.
Then select "Save".
### 2 - Promotions & reward voucher sync
To use promotions and vouchers from Engage in the Shopify POS app, you'll need to activate that here. Promotions and vouchers from Engage are handled as different kinds of discounts in Shopify.
"Enable promotion sync" allows you to use Engage promotions in the Shopify POS app.
"Enable loyalty voucher sync" allows vouchers to be created in Engage and used in the Shopify POS.
To use promotions and vouchers in the basic e-com integration, you'll need to have enabled the app embed block. This, however, *does not apply* for the POS integration, where selecting the check-boxes in the panel is enough.
For details on using promotions and vouchers in the POS integration, see here:
### 3 - Data import
This allows you to migrate customers and orders from your Shopify account to Engage through the Voyado Engage app, enabling you to start your Engage journey with your data already in place.
If you have the Shopify POS integration with Engage, this step will migrate that data as well.
There are two cases to consider here:
Here, you'll select the "Import customer data" options and then hit "Submit". This will migrate all your Shopify customers (and POS customers, if applicable) to Engage. If they don't already exist in Engage, they will be created there as contacts.
If a migrated customer already exists in Engage, the app will not update their data, but just fetch the contactId reference from Engage and store that in Shopify.
This app can also handle customers that were created only in Engage or imported there through other channel, such as a CSV file import, or via some other platform. This is important in the next step when migrating orders.
"Import customer data" will fetch and store the contact ID of any customer who was created in Engage outside of the app.
This starts a migration of Shopify orders, both purchases and returns, to Engage (and POS orders, if applicable). For this to work, the customer who made the order must already exist as a contact in Engage. That's why you'll always select the "import customer data" option here. Doing this ensures that customer data is synced before orders data is migrated (as there always needs to be a customer to connect an order to).
If, for example, a customer exists in Engage but not in Shopify, the app, when matching orders to customers, will fetch the contactId reference from Engage and store it in Shopify. This is relevant for any customer data imported into Engage outside of the app.
The order data option allows you to specify "Start date" and "End date". Then you will only sync those orders created inside that time window. Hit "Submit" to start the migration.
When doing an order data migration, the app will process the data in this order: customer import first, and then the order import.
The migration of customers and orders can activate automations for those customers that exist in Engage. If you have automations set up to trigger on "New contact registered", "Product purchase" or "New return", you should deactivate these during this migration.
## Shopify POS mobile app
This is the procedure for installing and using the Voyado Engage POS app for Shopify on your mobile device.
The Shopify POS app can be downloaded from the Google Play Store or the App Store depending on what mobile device you want to use as your Shopify POS.
Open the app on your device and log in with your Shopify account credentials. You'll need to enter a PIN code to allow fast unlocking of the app. Then go to the "Home" screen, which will look like this (here, the app is in Dark mode, in basic mode the background is white).
You'll now need to install the connection to Engage. Select "Add tile" and then "App". Here, search for the Voyado Engage POS app and install it. Once that's done, the "Manage Voyado discounts" tile will appear.
The installation is now complete.
# Sitoo
Source: https://partner-integrations.voyado.com/docs/pos/sitoo/sitoo
## Introduction
Sitoo is a cloud-native mobile point of sale (mPOS) and omnichannel platform for global retailers, empowering retailers to sell everywhere and fulfil anywhere.
An open REST API enables Sitoo's real-time data to be shared across all retail systems. The cloud-native mPOS platform is scalable, built for high transaction volumes, and also has an offline mode. It's used by retailers in Europe, EMEA, Asia-Pacific and across North America.
Sitoo has a native integration with Voyado Engage, enabling you to:
* Register your customers in Sitoo and sync them to Engage in real-time
* Identify customers directly in Sitoo, regardless if they were registered in store or online.
* Sync purchases and returns from Sitoo to Engage
* Assign personal discounts based on segments in Engage connected to campaigns in Sitoo.
* Reward customers with vouchers generated in Engage and enable them in Sitoo.
* Enable self check-out and let customers identify themselves and redeem their offers and vouchers.
* Build offline campaigns with labels assigned through the marketing automation platform in Engage.
Here's how to use the Engage integration with Sitoo.
## Requirements
* An active Engage CXP and Omni license
* An active Sitoo license
## Configuration in Engage
Here is what your Engage team needs to do:
* In the client's tenant, create an API-key user for the Sitoo integration.
* Send the API key and the tenant's base URL for API access to Sitoo.
* If the client has stores in the US, enable the feature toggle “SkipReceiptTotalGrossPriceValidation“ since the US uses a sales tax applied to the totalGrossPrice and not to each line item.
* If the store is not in a country using the defined group currency, then the currency needs to be retrieved using an exchange rate. This needs to be set up in Engage using a fixed exchange rate.
## Configuration in Sitoo
The API docs for Sitoo can be found here:
An Engage integration is configured in Sitoo using [YAML](https://en.wikipedia.org/wiki/YAML). Using this, you can choose which attributes to use for searching and which to use for for creating, editing and displaying in the POS.
The YAML-configuration is located in Sitoo under **Settings / General / POS Settings / Advanced Settings**.
This will open up the window where you enter your YAML, which will look something like this:
Here's how to configure each section in the YAML.
### Connection and country settings
Under `handler` in the YAML is where you set base URL, API key and the country settings:
```yaml theme={null}
...
handler:
voyado:
api_url: 'https://example.voyado.com/api/'
api_key: 2b5f1234-12c4-4e20-a3d0-0749a51862aa
locale: en-GB
currency_code: EUR
...
```
### Attributes used to search for contacts
Under `search_types` and `client_settings` you'll define the attributes used to search for a contact in Engage:
```yaml theme={null}
...
client_settings:
search_types:
- mobile
- email
- personal_id
- member_number
...
```
### Contact lookup (Dun & Bradstreet)
Here you can configure the personal attribute used to enrich your contact's profiles through a vendor like Dun & Bradstreet. Under "client\_settings" you can define `lookup_type` as either "personal\_id" (for their personal identity number) or "mobile" (for their mobile number):
```yaml theme={null}
...
client_settings:
lookup_type: personal_id
...
```
### Attributes for creating contacts
In the `client_settings` section under `fields_add` is where you add the fields from Engage that will be accessible in Sitoo when adding a contact. These can either be "editable" or "readonly".
```yaml theme={null}
...
fields_add:
email: editable
name: editable
personal_id: editable
mobile: editable
invoice_address: editable
accepts_email: editable
accepts_sms: editable
accepts_mail: editable
consents: editable
...
```
If `consents` is set to "editable" then all consents will be visible in the POS when adding a contact.
### Attributes for editing contacts
These are the attributes available in the POS when updating an already existing contact. These are added to the `client_settings` section under `fields_edit`. The attributes that you want to be editable are listed as "editable". If they are not to be editable, make them "readonly".
```yaml theme={null}
...
fields_edit:
email: editable
name: editable
personal_id: editable
mobile: editable
invoice_address: editable
accepts_email: editable
accepts_sms: readonly
accepts_mail: readonly
consents: readonly
...
```
### Custom attributes
Under `sections` you can choose which custom attributes to display in the POS. You can add different subject lines and then the attributes connected to that subject line.
Attributes of type "array" cannot be displayed in the POS.
Here, `attribute` is the field name in Engage and `title` is the text displayed in POS.
```yaml theme={null}
...
sections:
-
title: 'Customer info'
fields:
-
title: 'Regular store'
attribute: currentStore.name
-
title: 'Customer number'
attribute: memberNumber
-
title: 'Reward points'
attribute: bonusPoints
-
title: Tier-level
attribute: bonusBasedLevel
-
title: 'Points left for upgrade'
attribute: bonusBasedLevelLeftForUpgrade
-
title: Age
attribute: age
-
title: ZIP
attribute: zipCode
display_true: JA
-
title: 'Personal ID'
attribute: socialSecurityNumber
-
title: C/O
attribute: careOf
display_false: Ingen
-
title: 'Finns ej'
attribute: nullAttr
-
title: 'Secrecy marked'
attribute: secrecyMarked
display_false: 'Sekretess åberopad'
...
```
The `display_false` and `display_true` values contain the texts displayed if the field has data (display\_true) or if it doesn't (display\_false).
Engage standard attributes are always editable in Sitoo, and the fields listed as editable in `fields_edit` are in addition to these. Engage custom attributes (meaning those that are *not* standard attributes) can be viewed in Sitoo but not edited.
### Default discounts and vouchers
These are general member discounts which are applied in Sitoo when a contact is identified. The discounts and vouchers are created in Sitoo and do not have to be connected to a promotion in Engage.
```yaml theme={null}
...
voucher_passwords_default:
- pricelist_member_2021
- spring_member
...
```
### Discounts and vouchers connected to labels
These are discounts automatically applied when a contact with a certain label is identified. The voucher is created in Sitoo and in the configuration you can define which discount or voucher is triggered by which label.
```yaml theme={null}
...
voucher_passwords_from_labels:
-
label_name: Staff
voucher_passwords:
- staffdiscount
...
```
### Returning item purchased with voucher
If such an item is returned, the voucher used to buy it will not be automatically reactivated. This needs to be manually done in Engage.
## Engage API endpoints
Sitoo needs to access several Engage API endpoints to allow this integration to work.
### Retrieving a contact
```http Get contact's full data theme={null}
GET v2/contactoverview
```
```http Get all labels for contact theme={null}
GET v1/contacts/contactId/labels
```
The endpoint used to get a contact's labels uses V1 of the API.
### Creating / updating a contact
```http Creating a contact theme={null}
POST v2/contacts
```
```http Updating a specific contact theme={null}
POST v2/contacts/contactId
```
### Fetching consents
```http See all consents in Engage theme={null}
GET v2/consents
```
```http See consents which are true for specific contact theme={null}
GET v2/contactoverview
```
### Fetching from Dun & Bradstreet
```http Get contact's enhanced data using personal identity number or mobile phone number theme={null}
GET v2/personlookup/getpersonlookup
```
You'll see an example of the response on your Swagger page.
### Fetching transactions for a contact
```http Get transactions for a contact (results are paged) theme={null}
GET v2/contacts/contactId/transactions
```
### Creating a transaction
```http Add transaction using contactId as match key theme={null}
POST v2/receipts
```
### Redeeming a promotion
```http Redeeming a promotion theme={null}
POST v2/contacts/contactId/posoffers/promotionId/redeem
```
### Redeeming a reward voucher
```http Redeeming reward voucher theme={null}
POST /api/v2/contacts/contactId/bonuschecks/rewardVoucherId/redeem
```
Bonus check is an older name for reward voucher in Engage.
# Gamifiera
Source: https://partner-integrations.voyado.com/docs/ratings-and-reviews/gamifiera/gamifiera
Gamifiera offers a range of innovative tools, including reviews, UGC creation tools, gamification and 3D avatars, to help cultivate a vibrant community of brand advocates, all in one place.
Enriched data from Voyado Engage, such as reward points, member level and the points needed to reach the next level, can be displayed in Gamifiera's online module. You can also send data to Engage whenever an achievement has been completed in Gamifiera to create points there.
The features offered by the Gamifiera-Engage integration include:
* Ratings and Reviews functionality
* Easily integrated community functions
* Collection of personal attributes
* Gamification of customer behavior
This integration helps you to understand your loyal customers' interests and get to know them better. This information can then be used to create segmentations in Engage, using its advanced tools, to allow you to build more relevant and valuable customer experiences.
You can download the full PDF presentation of the integration here:
# Lipscore
Source: https://partner-integrations.voyado.com/docs/ratings-and-reviews/lipscore/lipscore
Brands are increasingly collecting feedback on their products and customer's in-store experiences. Lipscore is a nordic leader in this space. Lipscore reviews and ratings can be easily incorporated into Engage.
In Engage, the data from Lipscore can be used for the segmentation of customers based on their reviews, ratings, and other data, enabling targeted communication to customers.
## How it works
Here is how the integration works:
1. Lipscore is configured to fetch contact and product data, as well as transactions and their line items, from Engage using Engage's **Delta Share** service.
2. Lipscore processes this data to decide which contacts should be sent an email prompting them to leave a product review, and which products should be included in the prompt.
3. The email can be sent from Lipscore or from Engage. If the second option, the processed data goes to a **custom automation trigger** that must be already set up to receive the data and send the email.
4. The processed contact / product data can optionally also be sent to Engage as an **interaction**. This allows it to be saved and used for segmentation.
### In Email Design Studio
After you have added the custom trigger (see below) the Lipscore starter module can be found in the module **Starter library** in the "Partner" category. Add the module to the canvas and save it in your Team library for future use in sendouts. As the module is based on HTML code sent by Lipscore, you will not be able to style the content.
### In classic email editor
The custom trigger request to Engage contains HTML-code (reviewHTML), generated by Lipscore, which must be personalized and rendered in the email template in Engage.
Below are examples of the different emails that can be sent:
## Setting up delta share access
This integration requires [delta sharing](https://developer.voyado.com/docs/delta-sharing/delta-sharing) to be correctly set up for you. This is done in the Engage back end. Contact your Voyado PM about this.
## Setting up custom trigger
You'll need to create a custom automation trigger to use the Lipscore integration with Engage. This trigger can be set up in the Engage Config Hub.
Once you have access to Config Hub, follow the steps below.
Select **Create custom trigger**.
Enter `Name`, `TriggerId` and `Description` for your custom trigger.
* **Name**: A human readable name, shown in the Engage UI
* **TriggerId**: The unique ID for this custom trigger
* **Description**: A summary of what the trigger is used for
It's important that `TriggerId` and `Name` here are correct.
Select **Next**.
Now you will add the fields that Lipscore will send in the payload request. For each one, select **Add field** and then enter "Name" and "Description" as in the table. Press **Save** after each one.
| **Name** | **Description** |
| :--------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| reviewHTML | A HTML block creating the look and feel for the email. Currently included are the 5 stars, a link to a landing page, and product data such as name and image |
| type | Type of send-out, either `productReview` or `serviceReview` |
| language | Language from Lipscore (as ISO 639) |
| sourceName | Source name is assigned during integration by Lipscore. Usual format is “\[your base store name] – \[your Voyado store name]” |
| sourceId | Source ID is the external store ID of your Engage store |
Your custom trigger should now show up on the list of triggers when you create a new automation in Engage. It is recommended to use `type` as the entry criteria for the automation.
## Setting up automation for review emails
Lipscore has a guide for sending review emails through Engage:
## Interactions in Lipscore
The Lipscore integration allows data to be sent to Engage using an *interaction*. Data sent this way can be viewed in the Engage UI and also stored and used for segmentation.
### 1 - Creating the interaction schema
Interactions in Engage are defined by a schema. This is the structure of the schema used for the Lipscore integration:
```json theme={null}
{
"jsonSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"ratingId": {
"type": "integer",
"displayName": "Rating ID",
"showInContactCard": "false"
},
"rating": {
"type": "integer",
"displayName": "Rating",
"showInContactCard": "true",
"addToSegmentation": "true"
},
"comment": {
"type": "string",
"displayName": "Comment",
"showInContactCard": "true"
},
"productSku": {
"type": "string",
"displayName": "Sku",
"showInContactCard": "true",
"addToSegmentation": "true"
},
"name": {
"type": "string",
"displayName": "Name",
"showInContactCard": "true"
},
"brand": {
"type": "string",
"displayName": "Brand",
"showInContactCard": "true"
},
"type": {
"type": "string",
"displayName": "Type",
"showInContactCard": "true",
"addToSegmentation": "true"
},
"sourceId": {
"type": "string",
"displayName": "Source ID",
"showInContactCard": "true"
}
}
},
"id": "completedProductRating",
"displayName": "Completed product rating"
}
```
To create the Interaction, the schema above is sent to this endpoint:
```http theme={null}
POST api/v3/interactionschemas
```
Lipscore will set up the schema on their end. Some configuration in Engage needs to be done before this schema can be used so get in touch with Voyado before setup.
### 2 - Sending the interaction
Once the schema has been created and posted, you can send interactions of this type. In the case of the schema above, the interactions you'll send looks like this:
```json theme={null}
{
"contactId": "930dca46-7ed5-4761-84f5-b18d010f031b",
"schemaId": "completedProductRating",
"payload": {
"ratingId": 6028323,
"rating": 4,
"comment": "This is sooooooooo cool..",
"productSku": "",
"name": "The Collection Snowboard: Liquid",
"brand": "Hydrogen Vendor",
"type": "productReview"
}
}
```
The schemaId (is this case "completedProductRating") must match the one used in the schema definition payload.
The attribute "type" can have the following values:
* **productReview**: The first time this contact reviews this product
* **productRating**: The first time this contact rates this product
* **serviceReview**: The first time this contact reviews this service
* **serviceRating**: The first time this contact rates this service
* **updated\_productReview**: Contact updates an existing product review
* **updated\_productRating**: Contact updates an existing product rating
* **updated\_serviceReview**: Contact updates an existing service review
* **updated\_serviceRating**: Contact updates an existing service rating
This payload is sent to the interactions endpoint:
```http theme={null}
POST api/v3/interactions
```
### 3 - Using the interaction data
An interaction is picked up in Engage by either the "New Interaction" or "New specific interaction" automation triggers. It can then be used to start an automation.
Use the "New specific interaction" trigger here since it allows you to pick certain values inside the interaction to decide whether to trigger the automation or not.
You will also be able to filter via specific fields that were sent by Lipscore:
Interaction data will be displayed on the contact card (in the "Interactions" tab).
The data received from interactions can also be used for segmentation.
### 4 - Updating an existing review
When a product review is updated through an interaction, the “type” in the payload will be set to "updated\_productReview". By specifying in your automation trigger which values of "type" will trigger the automation (for example, "productReview" and "serviceReview") you can prevent the automation from running in cases like this.
For example, you might just want to send a mail when the review is first sent, and not when it is updated.
If such an update is sent to Engage, Lipscore will remove the original review and create a new one, since existing interactions can't be updated.
## Lipscore data fields
These are the Engage data fields used by the Lipscore integration.
### Contact
| Data fields |
| :------------------ |
| contact.contactId |
| contact.email |
| contact.firstName |
| contact.lastName |
| contact.mobilePhone |
| contact.countryCode |
### Receipt
| Data fields |
| :------------------------ |
| receipt.receiptId |
| receipt.receiptNumber |
| receipt.externalId |
| receipt.createdOnDateTime |
| receipt.storeExternalId |
| receiptItem.articleNumber |
| receiptItem.articleName |
| receiptItem.localPrice |
| receiptItem.localCurrency |
| receiptItem.articleGroup |
### Article
| Data fields |
| :-------------------- |
| article.articleId |
| article.articleNumber |
| article.gtin |
| article.sku |
| article.articleName |
| article.brand |
| article.mainCategory |
# Trustvoice
Source: https://partner-integrations.voyado.com/docs/ratings-and-reviews/trustvoice/trustvoice
Trustvoice is an online platform that allows businesses to collect customer reviews to compare and use them for sales and marketing. It aggregates both professional and user reviews from thousands of sources in many different languages Trustvoice can send reviews to Engage which can then be viewed in the Engage UI, used in segmentation or acted on using Engage automations.
The Trustvoice integration can be used for the following in Engage:
* Enriching a customer's profile (their contact card) with review data
* Enabling the Engage user to perform segmentation of their contact's reviews
* Triggering automations post-purchase to prompt users to leave a review (coming soon)
## Integrating Trustvoice
The Trustvoice integration in Engage involves *Interactions* and *custom contact attributes*. A custom automation trigger will be added in a later iteration.
Contact your account manager at Voyado before activating this integration. If Trustvoice will be using delta share data, you as a customer will need help from Voyado to perform the setup.
The general steps in the integration are:
* Enable interactions (must be done in the Voyado backend)
* Create API keys that will be shared with Trustvoice
* Create custom attributes (explained below)
* Set up the custom trigger used to trigger review emails
* Set up Delta share (must be done in the Voyado backend)
### 1 - Enable interactions
Start by activating interactions for your Engage account (ask your Voyado PM to do this for you).
See more about interactions here:
### 2 - Define the interaction schema
Every interaction in Engage is defined by a *schema*.
Here is the structure of the schema used for the Trustvoice integration:
```json theme={null}
{
"jsonSchema":{
"$schema":"https://json-schema.org/draft/2020-12/schema",
"type":"object",
"properties":{
"productSku":{
"type":"string",
"displayName":"Sku",
"showInContactCard":"true",
"addToSegmentation":"true"
},
"rating":{
"type":"integer",
"displayName":"Rating",
"showInContactCard":"true",
"addToSegmentation":"true"
},
"comment":{
"type":"string",
"displayName":"Comment",
"showInContactCard":"true"
}
}
},
"id":"completedProductRating",
"displayName":"Completed Trustvoice review"
}
```
To create the Interaction, this schema is sent to the endpoint:
```http theme={null}
POST api/v3/interactionschemas
```
Trustvoice will set up the schema on their end.
### 3 - Create the custom attributes
Trustvoice uses some custom contact attributes in Engage to send review information. You'll need to set there attributes up first. Navigate to **Administration > Configure Engage** and then **Contact attributes**.
Now create the following three custom attributes:
| Id | Name | Type | Description. |
| :----------------- | :------------------- | :------ | :----------------------------------------------- |
| reviewLatest | Review Latest | Date | The most recent date of a review |
| reviewLatestValue | Review Latest Value | Integer | The score / value of the contact's latest review |
| reviewAverageGrade | Review Average Grade | Number | The contact's overall review rating |
Make these attributes "Segmentable", "Exportable" and "Read-only in contact card".
You should also map these three custom attributes to a specific contact panel giving you an easy way to view them (for example, a tab on the contact card named "Rating and Review").
Make sure you pick the correct Type for the custom attributes.
Here is a payload sent from Trustvoice to Engage to update these attributes for a contact:
```json theme={null}
{
"reviewAverageGrade":4.5,
"reviewLatest":"2024-11-20T13:00:00.000Z",
"reviewLatestValue":5,
"interests":"sport"
}
```
This is sent to this endpoint:
```http theme={null}
POST api/v2/contacts/{contactId}
```
Or for API v3:
```http theme={null}
PATCH api/v3/contacts/{contactId}
```
### 4 - Send the interaction
Once the schema has been created and posted, you can send interactions of this type. In the case of the schema above, the interactions you send will look like this:
```json theme={null}
{
"schemaId": "completedProductRating",
"contactId": "ea50e150-e12a-49f9-a496-b21001450d55",
"createdDate": "2022-07-05T09:26:01.000Z",
"payload": {
"productSku": "17184225",
"rating": 5,
"comment": "Ett bra grepp precis som jag förväntade mig. "
}
}
```
The `schemaId` (in this case "completedProductRating") must match the one used in the schema definition payload.
This payload is sent to the interactions endpoint:
```http theme={null}
POST api/v3/interactions
```
The interaction can be picked up in Engage by a custom automation trigger and used to start an automation. An example of the response is:
```json theme={null}
{
"id": "gvwixukdja3w5v6afac47pkoi27346i52wyeu37faaqik76cocyjv4ih2gj7zwyiojsxm2lfo5jwk3tu",
"self": {
"contactId": "6e48d16c-05c0-46bd-be1d-b06f0085c2b0",
"href": "https://qaretail1.acceptanstest.voyado.com/api/v3/interactions/gvwixukdja3w5v6afac47pkoi27346i52wyeu37faaqik76cocyjv4ih2gj7zwyiojsxm2lfo5jwk3tu",
"created": "2023-12-14T10:56:16+00:00"
}
}
```
The interaction details can be viewed on the contact card, on the "Interactions" tab.
### 5 - Set up custom trigger
Set up the custom trigger according to the instructions here:
1. Name the custom trigger “Trustvoice review”
2. Give it the `triggerId` of “sendReview”
Add the three fields to be used in the custom trigger's payload:
| **Name** | **Description** |
| :--------- | :--------------------- |
| reviewHTML | The products to review |
| type | Type of send-out |
| language | Language in Trustvoice |
### 6. Request delta share
This will be setup by a CX engineer from the Voyado team. Contact your account manager to enable this functionality.
## Trustvoice FAQ
Here are some commonly asked questions regarding the Trustvoice integration:
Yes, as long as they gather that information in the review process that can be stored in Engage as a custom attribute.
Yes, you are able to filter on rating and reviews.
Yes, at least for product reviews.
Trustvoice sets up the schema.
Yes, that is possible to do.