Appearance
Hendrickx Onboarding
Overview
Hendrickx is a location-specific in-house POS integration commonly used in Belgium, built on the shared Kassanet protocol (the same engine that powers Vanhoutte). Each location must be connected separately with its own credentials. Hendrickx does NOT process the customer's payment - Upvendo collects the money (Viva Wallet for Kiosk, Stripe for Online Ordering / QR) and Kassanet only records the payment tender on the POS bill.
Important: The only profile enforced at connect time is the Branding Profile. Payment and Billing profiles are optional and can be set up later (ThirdPartyIntegrationHelper::checkRequiredProfiles only requires a branding profile for Hendrickx). You must also create a location and select it from the backoffice topbar before connecting. The guided-setup checklist still lists Payment and Billing as steps, but they are not blocking prerequisites for the connect itself.
Integration Type
- Scope: Location-specific (each location connects separately, with its own
base_url/signature_key/encryption_token) - Family: Kassanet (Hendrickx and Vanhoutte share
AbstractKassanetService;HendrickxServiceonly sets the provider namehendrickx) - Payment Processing: Not included. Upvendo collects payment via Viva Wallet (Kiosk) or Stripe (Online Ordering / QR); Kassanet records the tender on the POS bill via
PayBill - In-House Exclusivity: A location may have only one in-house POS. Hendrickx, Vanhoutte, and ShopCaisse are mutually exclusive per location, and conflict with the merchant-scoped Square / MplusKassa / Lightspeed
- Menu Sync: One-way pull from Hendrickx (menu items must exist in the POS first; Upvendo imports the catalog)
- Order Sync: One-way push to Hendrickx (orders sent after payment is confirmed)
Discovery Flow (JSON - for deterministic parsing)
discovery_questions
[
{
"id": "channels",
"text": "What channels do you want to set up with Hendrickx?",
"text_i18n": {
"nl": "Welke kanalen wil je instellen met Hendrickx?",
"fr": "Quels canaux souhaitez-vous configurer avec Hendrickx ?",
"de": "Welche Kanäle möchten Sie mit Hendrickx einrichten?",
"es": "¿Qué canales quieres configurar con Hendrickx?",
"it": "Quali canali vuoi configurare con Hendrickx?",
"pt": "Que canais quer configurar com o Hendrickx?"
},
"options": [
"Kiosk only",
"Online ordering only",
"Both"
],
"labels": {
"nl": {
"Kiosk only": "Alleen kiosk",
"Online ordering only": "Alleen online bestellen",
"Both": "Beide"
},
"fr": {
"Kiosk only": "Kiosque uniquement",
"Online ordering only": "Commande en ligne uniquement",
"Both": "Les deux"
},
"de": {
"Kiosk only": "Nur Kiosk",
"Online ordering only": "Nur Online-Bestellung",
"Both": "Beides"
},
"es": {
"Kiosk only": "Solo quiosco",
"Online ordering only": "Solo pedidos en línea",
"Both": "Ambos"
},
"it": {
"Kiosk only": "Solo chiosco",
"Online ordering only": "Solo ordini online",
"Both": "Entrambi"
},
"pt": {
"Kiosk only": "Apenas quiosque",
"Online ordering only": "Apenas pedidos online",
"Both": "Ambos"
}
}
},
{
"id": "menu_ready",
"text": "Do you already have your menu set up in Hendrickx?",
"text_i18n": {
"nl": "Heb je je menu al ingesteld in Hendrickx?",
"fr": "Votre menu est-il déjà configuré dans Hendrickx ?",
"de": "Ist Ihr Menü bereits in Hendrickx eingerichtet?",
"es": "¿Ya tienes tu menú configurado en Hendrickx?",
"it": "Hai già configurato il tuo menu in Hendrickx?",
"pt": "Já tem o seu menu configurado no Hendrickx?"
},
"options": [
"Yes, my menu is in Hendrickx",
"No, I need to create it"
],
"labels": {
"nl": {
"Yes, my menu is in Hendrickx": "Ja, mijn menu staat in Hendrickx",
"No, I need to create it": "Nee, ik moet het nog aanmaken"
},
"fr": {
"Yes, my menu is in Hendrickx": "Oui, mon menu est dans Hendrickx",
"No, I need to create it": "Non, je dois le créer"
},
"de": {
"Yes, my menu is in Hendrickx": "Ja, mein Menü ist in Hendrickx",
"No, I need to create it": "Nein, ich muss es erst erstellen"
},
"es": {
"Yes, my menu is in Hendrickx": "Sí, mi menú está en Hendrickx",
"No, I need to create it": "No, necesito crearlo"
},
"it": {
"Yes, my menu is in Hendrickx": "Sì, il mio menu è in Hendrickx",
"No, I need to create it": "No, devo crearlo"
},
"pt": {
"Yes, my menu is in Hendrickx": "Sim, o meu menu está no Hendrickx",
"No, I need to create it": "Não, preciso de o criar"
}
},
"abort_if": "No, I need to create it",
"abort_message": "Hendrickx requires your menu to be set up in the POS first. Please create your menu items in Hendrickx, then come back to continue the setup.",
"abort_message_i18n": {
"nl": "Hendrickx vereist dat je menu eerst in de kassa staat. Maak je menu-items aan in Hendrickx en kom daarna terug om de installatie te voltooien.",
"fr": "Hendrickx nécessite que votre menu soit d'abord configuré dans le système de caisse. Créez vos articles dans Hendrickx, puis revenez pour poursuivre la configuration.",
"de": "Hendrickx erfordert, dass Ihr Menü zuerst im Kassensystem eingerichtet ist. Legen Sie Ihre Menüartikel in Hendrickx an und kehren Sie dann zurück, um die Einrichtung fortzusetzen.",
"es": "Hendrickx requiere que tu menú esté configurado primero en el TPV. Crea tus artículos en Hendrickx y luego vuelve para continuar la configuración.",
"it": "Hendrickx richiede che il menu sia prima configurato nel POS. Crea i tuoi articoli in Hendrickx e poi torna per continuare la configurazione.",
"pt": "O Hendrickx exige que o seu menu esteja primeiro configurado no POS. Crie os seus artigos no Hendrickx e depois volte para continuar a configuração."
}
}
]setup_steps
{
"Kiosk only": [
{"id": "branding_profile", "title": "Set up Store Branding", "route": "/settings/brand"},
{"id": "create_location", "title": "Create Location", "route": "/settings/locations"},
{"id": "select_location", "title": "Select Location from Topbar", "action": "open_location_selector"},
{"id": "connect_pos", "title": "Connect Hendrickx", "route": "/hendrickx", "channel": "hendrickx"},
{"id": "sync_menu", "title": "Sync Menu", "route": "/hendrickx"},
{"id": "menu_for_kiosk", "title": "Build Menu for Kiosk", "route": "/menus/menu-builder"},
{"id": "in_house_settings", "title": "Set up In-House Settings", "route": "/in-house/settings"},
{"id": "device_profile", "title": "Create Device Profile", "route": "/device-management/profiles"},
{"id": "kiosk_device", "title": "Set up Kiosk & Activate Payment", "route": "/device-management/devices"},
{"id": "payment_profile", "title": "Set up Payment Profile", "route": "/settings/payments", "optional_for_go_live": true},
{"id": "billing_profile", "title": "Set up Billing Profile", "route": "/settings/billing", "optional_for_go_live": true},
{"id": "test_kiosk", "title": "Activate Kiosk & Test Order", "optional_for_go_live": true}
],
"Online ordering only": [
{"id": "branding_profile", "title": "Set up Store Branding", "route": "/settings/brand"},
{"id": "create_location", "title": "Create Location", "route": "/settings/locations"},
{"id": "select_location", "title": "Select Location from Topbar", "action": "open_location_selector"},
{"id": "connect_pos", "title": "Connect Hendrickx", "route": "/hendrickx", "channel": "hendrickx"},
{"id": "sync_menu", "title": "Sync Menu", "route": "/hendrickx"},
{"id": "menu_for_online_ordering", "title": "Build Menu for Online Ordering", "route": "/menus/menu-builder"},
{"id": "online_settings", "title": "Set up Online Settings", "route": "/online-settings"},
{"id": "configure_online_ordering", "title": "Set up Online Ordering", "route": "/online/online-ordering"},
{"id": "payment_profile", "title": "Set up Payment Profile", "route": "/settings/payments", "optional_for_go_live": true},
{"id": "billing_profile", "title": "Set up Billing Profile", "route": "/settings/billing", "optional_for_go_live": true},
{"id": "test_online_ordering", "title": "Open Online Ordering URL & Test Order", "route": "/online/online-ordering", "optional_for_go_live": true}
],
"Both": [
{"id": "branding_profile", "title": "Set up Store Branding", "route": "/settings/brand"},
{"id": "create_location", "title": "Create Location", "route": "/settings/locations"},
{"id": "select_location", "title": "Select Location from Topbar", "action": "open_location_selector"},
{"id": "connect_pos", "title": "Connect Hendrickx", "route": "/hendrickx", "channel": "hendrickx"},
{"id": "sync_menu", "title": "Sync Menu", "route": "/hendrickx"},
{"id": "menu_for_kiosk", "title": "Build Menu for Kiosk", "route": "/menus/menu-builder"},
{"id": "menu_for_online_ordering", "title": "Build Menu for Online Ordering", "route": "/menus/menu-builder"},
{"id": "in_house_settings", "title": "Set up In-House Settings", "route": "/in-house/settings"},
{"id": "device_profile", "title": "Create Device Profile", "route": "/device-management/profiles"},
{"id": "kiosk_device", "title": "Set up Kiosk & Activate Payment", "route": "/device-management/devices"},
{"id": "online_settings", "title": "Set up Online Settings", "route": "/online-settings"},
{"id": "configure_online_ordering", "title": "Set up Online Ordering", "route": "/online/online-ordering"},
{"id": "payment_profile", "title": "Set up Payment Profile", "route": "/settings/payments", "optional_for_go_live": true},
{"id": "billing_profile", "title": "Set up Billing Profile", "route": "/settings/billing", "optional_for_go_live": true},
{"id": "test_kiosk", "title": "Activate Kiosk & Test Order", "optional_for_go_live": true},
{"id": "test_online_ordering", "title": "Open Online Ordering URL & Test Order", "route": "/online/online-ordering", "optional_for_go_live": true}
]
}The step list above uses the canonical step ids the back office derives from the
/api/back-office/setup-statusflags (src/utils/emily/setupStepIds.ts). The "Select Location from Topbar" step uses the action literalopen_location_selector(the valuetopbar_location_selectonly appears as an inbound alias from Emily's API and is normalized to it). Payment and Billing carryoptional_for_go_live— they are labelled as go-live prerequisites but gate nothing; step gating is by declared prerequisites, not list order. TheBASE_SETUP_STEPSconstants incomponents/dialogs/guided-setup/types.tsare legacy and are not what a merchant sees. See Guided Setup.
Connect Hendrickx
Route: /hendrickx (backend API: POST /api/back-office/kassanet/hendrickx/{locationId} → KassanetIntegrationController::initiate)
- Configure a Branding Profile (
/settings/brand) - the only profile enforced at connect time. Payment (/settings/payments) and Billing (/settings/billing) are optional and can be added later. - Create a location (
/settings/locations) and select it from the topbar. - On
/hendrickx, open the connect form and enter the three Kassanet credentials:- Connection URL (
base_url) - the Kassanet API endpoint URL (validated as a URL) - Signature Key (
signature_key) - the HMAC-SHA256 signing key - Encryption Token (
encryption_token) - the Blowfish encryption key
- Connection URL (
- Optionally set a Daily Sync Time (
sync_time) for automatic menu sync. The value must beHH:00orHH:30(minutes restricted to00or30). The time you type is the local time at the location and it stays at that local time all year - it does not move when the clocks change for daylight saving. A caption under the field names the timezone the sync will run in ("Runs in the ... timezone"). Leave it blank to disable auto-sync. - Saving the form auto-triggers a menu sync immediately after connecting. You can also click Sync Now to re-run the import.
The connect form takes exactly the three credentials plus
sync_time.enable_encryptionis not a form field - it defaults totruein code (KassanetIntegration::getEnableEncryption()), so payloads are encrypted by default. Theprovidervalue (hendrickx) is injected from the route, not entered by the merchant.
Prerequisites Checklist
Complete these before (or alongside) connecting Hendrickx:
1. Branding Profile Setup (Required)
- Go to Settings -> Brand (
/settings/brand) - Configure your store's branding (logo, colors, etc.)
This is the only prerequisite the backend enforces at connect time. Connecting without a branding profile is rejected with HTTP 400: "Missing required profiles: branding profile. Please create them before setting up an integration."
2. Payment Profile Setup (Optional)
- Go to Settings -> Payments (
/settings/payments) - Set up your payment providers:
- Viva Wallet for Kiosk payments (terminal-based)
- Stripe for Online Ordering / QR payments
- Configure payment methods (Card, Bancontact, etc.)
Payment is not blocked at connect time, but you will need a configured provider before you can take a real order on a channel.
3. Billing Profile Setup (Optional)
- Go to Settings -> Billing (
/settings/billing) - Complete your billing information
4. Location Creation (Required to connect)
- Go to Settings -> Locations (
/settings/locations) - Create your location with business name/address, hours, and contact info
- Select this location from the topbar before connecting Hendrickx (each Hendrickx connection is tied to a single selected location)
In-House Exclusivity
A location can have only one in-house POS at a time. When you try to add a second in-house channel, the connect is rejected with HTTP 400: "Another in-house channel is already enabled for this merchant."
The check uses two channel lists (ThirdPartyIntegrationHelper):
- Location-scoped in-house channels (
IN_HOUSE_CHANNELS): Hendrickx, Vanhoutte, ShopCaisse. Connecting Hendrickx is blocked if another of these is already connected on the same location. - Merchant-scoped in-house channels (
IN_HOUSE_MERCHANT_SCOPED_CHANNELS): Square, MplusKassa, Lightspeed. Connecting Hendrickx is blocked if any of these is connected anywhere for the merchant.
So Hendrickx conflicts per-location with Vanhoutte/ShopCaisse, and per-merchant with Square/MplusKassa/Lightspeed. (See In-House Settings.)
Catalog & Order Flow
Menu Sync (Hendrickx -> Upvendo, one-way)
Menu items must exist in the Hendrickx POS first; Upvendo only reads the catalog. Clicking Sync Now (or connecting, or the daily auto-sync) dispatches a chained import: ImportKassanetMenuJob -> ImportKassanetCategoriesJob -> ImportKassanetProductsJob -> ImportKassanetDisplayGroupsJob, importing categories/subcategories, products (with prices and PLU codes), modifier groups/modifiers, display groups, table numbers, and stock levels. The synced menu appears under Menus.
Order Flow (Upvendo -> Hendrickx, one-way, three stages)
Orders are created in Upvendo (Kiosk, Online Ordering, or Table QR) and pushed to Hendrickx after payment is confirmed, in three stages:
text
1. CreateOrder -> Registers items + table number on the POS guest check
|
2. GetBill -> Reads the POS bill total for the table
|
3. PayBill -> Records the payment tender on the bill (Viva Wallet for Kiosk, Stripe for Online/QR, falling back to the Webshop type)The create stage runs via ProcessOrderJob; the bill and pay stages run as GetKassanetBillJob and PayKassanetBillJob. If the POS is offline, the order is flagged need_requeue and reprocessed when connectivity is restored. (POS-side preparation, fulfillment, and the storefront checkout flow are not verified here.)
For full protocol, endpoint, and order-stage details, see the Hendrickx Integration and Kassanet Integration docs.
Guided-Setup Steps
The back-office guided-setup wizard (Emily) drives onboarding. The fallback step order for Hendrickx is:
- Set up Store Branding -
/settings/brand - Create Location -
/settings/locations - Select Location from Topbar - action
open_location_selector - Connect Hendrickx -
/hendrickx(channelhendrickx) - Sync Menu -
/hendrickx - Build Menu for Kiosk -
/menus/menu-builder - Build Menu for Online Ordering -
/menus/menu-builder - Set up In-House Settings -
/in-house/settings - Create Device Profile -
/device-management/profiles - Set up Kiosk & Activate Payment -
/device-management/devices - Set up Online Settings -
/online-settings - Set up Online Ordering -
/online/online-ordering - Set up Payment Profile -
/settings/payments - Set up Billing Profile -
/settings/billing - Activate Kiosk & Test Order
- Open Online Ordering URL & Test Order -
/online/online-ordering
Once the base steps are complete, the wizard offers channel checklists:
- Kiosk: Build Menu for Kiosk (
/menus/menu-builder) -> Set up In-House Settings (/in-house/settings) -> Create Device Profile (/device-management/profiles) -> Set up Kiosk & Activate Payment (/device-management/devices) -> Set up Payment Profile (/settings/payments) -> Set up Billing Profile (/settings/billing) -> Activate Kiosk & Test Order - Online Ordering: Build Menu for Online Ordering (
/menus/menu-builder) -> Set up Online Settings (/online-settings) -> Set up Online Ordering (/online/online-ordering) -> Set up Payment Profile (/settings/payments) -> Set up Billing Profile (/settings/billing) -> Open Online Ordering URL & Test Order (/online/online-ordering)
Step completion is auto-detected from the merchant's real data via GET /api/back-office/setup-status; merchants generally do not mark steps manually. The "Connect POS" step only completes when the integration is both connected and tested. See Guided Setup.
Related Documentation
- Hendrickx Integration (protocol, endpoints, order stages)
- Kassanet Integration (shared engine for Hendrickx + Vanhoutte)
- Guided Setup
- In-House Settings