Skip to content

Kassanet Integration

Overview

Kassanet is the underlying POS platform used by both Hendrickx and Vanhoutte POS providers. This integration handles the core communication protocol with the Kassanet API, including encrypted data exchange, menu import, order submission (bill creation and payment), table number management, and connection monitoring. Individual location pages for Hendrickx and Vanhoutte use Kassanet as their backend engine -- the AbstractKassanetService provides the shared functionality, while HendrickxService and VanhoutteService extend it with provider-specific behavior.

Purpose

This integration lets you connect a location to a Hendrickx or Vanhoutte POS register to import the POS menu into Upvendo and automatically push customer orders to the POS after payment.

Key Concepts

  • Provider-Based Architecture: Kassanet is not a standalone integration page. It is accessed through either the Hendrickx (/hendrickx) or Vanhoutte (/vanhoutte) integration. The provider parameter (hendrickx or vanhoutte) determines which service class handles requests.
  • Blowfish Encryption: API communication can use Blowfish CBC encryption with a shared encryption token. Requests are encrypted before sending and responses are decrypted after receiving. The encryption is optional per integration (enable_encryption flag).
  • HMAC Signature Authentication: Every API request includes an HMAC-SHA256 signature computed from the request date and body, using the integration's signature key.
  • Chained Job Pipeline: Menu import is split into a chain of sequential background jobs to prevent timeouts: ImportKassanetMenuJob > ImportKassanetCategoriesJob > ImportKassanetProductsJob > ImportKassanetDisplayGroupsJob. Each job processes one stage and dispatches the next.
  • Table Number Management: Kassanet manages table numbers that map to POS registers. Upvendo synchronizes these tables with in-house settings and manages table assignments for orders using distributed locking to prevent conflicts.

Prerequisites

  • An active Hendrickx or Vanhoutte POS register with API access enabled
  • The POS register must have products, categories, and display groups configured
  • A location created in Upvendo (Settings > Locations) and selected in the topbar
  • Payment providers configured (Viva Wallet for kiosk, Stripe for online ordering) -- Kassanet does NOT handle payments
  • The Kassanet API endpoint (Connection URL) must be reachable from the Upvendo server
  • Branding and billing profiles configured

Setup Steps

Step 1: Prepare Prerequisites

  1. Set up payment providers at Settings > Payments (/settings/payments)
  2. Configure billing at Settings > Billing (/settings/billing)
  3. Configure branding at Settings > Brand (/settings/brand)
  4. Create and select your location at Settings > Locations (/settings/locations)

Step 2: Connect the POS

  1. Go to Hendrickx (/hendrickx) or Vanhoutte (/vanhoutte)
  2. Click Connect or Add Channel
  3. Enter your Kassanet credentials:
    • Connection URL (base_url): The Kassanet API endpoint URL
    • Signature Key (signature_key): HMAC authentication key
    • Encryption Token (encryption_token): Blowfish encryption key
  4. Optionally set a Daily Sync Time (sync_time in HH:mm format, location timezone) for automatic menu sync

Step 3: Sync Menu

  1. Click Sync Now to trigger a menu import
  2. The system dispatches ImportKassanetMenuJob which runs the chained import pipeline:
    • Categories and subcategories are imported first
    • Products and modifiers are imported next
    • Display groups are processed and table numbers are synchronized
  3. After completion, the menu appears under Menus > Items (/menus/items)

Step 4: Test the Connection

  1. Click Test Connection on the integration page
  2. The system calls the Kassanet test endpoint to verify connectivity
  3. A successful test also checks for the webshop payment type and updates the connection status
  4. If the connection is successful, any queued orders that failed due to disconnection are automatically requeued

Data Sync Details

What Syncs

Kassanet EntityUpvendo EntityNotes
CategoriesCategoriesNested subcategories supported
ProductsItemsIncluding price, kitchen name, and external IDs
Product ModifiersModifier GroupsModifier groups with individual modifier options
Product SelectionsDisplay GroupsProduct selections map to display groups
Table NumbersTable SectionsSynced to in-house table settings with QR codes
Stock LevelsInventoryStock levels synced after menu import

Sync Direction

  • Menu Import (Kassanet to Upvendo): One-way. Products, categories, modifiers, display groups, and table numbers are pulled from the Kassanet API.
  • Order Push (Upvendo to Kassanet): One-way. After payment confirmation, orders are pushed to Kassanet as bills via GetKassanetBillJob and PayKassanetBillJob.
  • Auto-Sync: If a sync_time is configured, the system automatically runs a full menu sync at that time daily. The sync time is stored in UTC after converting from the location's timezone.

Conflict Resolution

  • During import, existing items are matched by external_ids.{provider} fields. Matched items are updated; new items are created.
  • Placeholder items (kitchen name zz or matching pager patterns) are automatically cleaned up after import.
  • Modifier group IDs are reset before product import to ensure clean mapping.

Actions

Connect

  • Initiate: POST /api/backoffice/kassanet/{provider}/{locationId} -- saves credentials and settings for the integration. The provider parameter is hendrickx or vanhoutte.
  • Re-initiating on an existing integration updates the credentials without creating a duplicate.

Sync

  • Sync Menu: POST /api/backoffice/kassanet/{provider}/{locationId}/sync-menu -- triggers the full import pipeline
  • Test Connection: GET /api/backoffice/kassanet/{provider}/{locationId}/test -- tests API connectivity and updates connection status
  • Get Status: GET /api/backoffice/kassanet/{provider}/{locationId}/ -- returns integration details, credentials, sync status, and logs
  • Auto Sync Settings: Configured via the initiate endpoint with the sync_time parameter

Disconnect

  • Delete Integration: DELETE /api/backoffice/kassanet/{provider}/{locationId} -- removes the integration and triggers a ReloadMenu event. Cleans up categories, display groups, items, modifiers, menus, and inventory data linked to the provider.

Order Flow

  • GetKassanetBillJob: After a customer places an order and payment is confirmed, this job retrieves the bill from Kassanet for the assigned table number. It validates the bill total against the transaction total.
  • PayKassanetBillJob: After the bill is retrieved, this job submits payment to the Kassanet POS. Payment runs on the payments-medium queue.

Fields

Credentials (stored in ThirdPartyIntegration.credentials)

FieldTypeDescription
base_urlstringKassanet API endpoint URL
signature_keystringHMAC-SHA256 signature key for authentication
encryption_tokenstringBlowfish CBC encryption key for encrypted endpoints

Settings (stored in ThirdPartyIntegration.settings)

FieldTypeDescription
sync_timestringDaily auto-sync time in UTC (HH:mm format)
next_run_timestringNext scheduled sync run time (managed by scheduler)
tablesarrayTable numbers retrieved from Kassanet
table_section_idstringID of the Upvendo table section synced with Kassanet
tables_usageobjectMap of table numbers to usage data (last_used timestamp)

Sync Status (stored in ThirdPartyIntegration.sync_status)

FieldTypeDescription
statusstringsuccess, error, or in_progress
messagestringHuman-readable sync status message
detailsobjectContains display_groups_imported, menu_id, etc.
last_syncstringISO 8601 timestamp of the last sync attempt

Kassanet API Endpoints Called

EndpointMethodDescription
testGETTest connectivity and get system info
GetAllProductsGETFetch all products with categories
GetProductSelectionGETFetch display group definitions
TableNumbersGETFetch available table numbers
GetFreeTableNumberGETGet next free table number for order
GetBillGETRetrieve bill for a specific table number
GetPaymentTypesGETFetch available payment types

Business Rules

  • Each location can have one Kassanet integration per provider (one Hendrickx OR one Vanhoutte per location, or one of each).
  • Menu import runs as a chained job pipeline with 3 retry attempts, 30-second backoff, and 300-second timeout per job stage.
  • Table number assignment uses distributed MongoDB-based locking with a 5-minute lock timeout to prevent race conditions when multiple orders target the same table.
  • API requests use exponential backoff for retryable errors (timeouts, HTTP 500/502/503/504/408) with a maximum retry count.
  • If the POS register is unreachable, the location is marked as "disconnected." When connectivity is restored (via test), the location is marked as "connected" and queued orders are automatically reprocessed.

FAQs

What is the difference between Kassanet, Hendrickx, and Vanhoutte?

Kassanet is the underlying POS platform. Hendrickx and Vanhoutte are POS providers that run on the Kassanet platform. In Upvendo, you connect via the Hendrickx or Vanhoutte page -- both use the same Kassanet API protocol.

Can I create menu items in Upvendo and push them to Kassanet?

No. Menu sync is one-way from Kassanet to Upvendo. Items must exist in the POS register first. You can then customize descriptions, images, and display order in Upvendo.

What happens when the POS register goes offline?

Orders are queued with a need_requeue flag. When the connection is restored (detected via the test endpoint), all queued orders are automatically reprocessed.

How does auto-sync work?

If you set a daily sync time (e.g., 06:00 in your location's timezone), the system converts it to UTC and runs a full menu import at that time every day. The scheduler manages the next_run_time field.

Why are some items missing after sync?

Placeholder items with kitchen name zz or matching pager patterns are automatically cleaned up after import. Also check that items are assigned to product selections (display groups) in the POS.

Troubleshooting

"Connection test failed" or "Disconnected" status

Verify the Connection URL is correct and reachable. Check that the Signature Key and Encryption Token match what is configured in the POS register. Ensure the POS register is powered on and connected to the internet.

"Invalid base64 input" or "Blowfish decryption error"

The Encryption Token is incorrect or has changed. Update the credentials with the correct token from the POS register configuration. Ensure the enable_encryption flag matches the POS configuration.

The import pipeline may have failed at one of the job stages. Check the integration logs on the Hendrickx/Vanhoutte page. Each job has a 300-second timeout and 3 retry attempts. If consistently failing, check the POS register's API responsiveness.

"Total amount mismatch" in logs

The bill total from Kassanet does not match the transaction total in Upvendo. This is logged as a critical error. Verify that prices in the POS match prices in Upvendo, and check for any tax calculation differences.

Orders not appearing in the POS

Check the integration connection status (should be "connected"). Verify the table section is configured correctly. Check the order's external_data.{provider}.status field -- if error, the errMessage field contains the specific Kassanet error. If the POS was offline, orders will be requeued when connectivity is restored.

Assistant Guidance

When a user asks about Kassanet, Hendrickx, or Vanhoutte integration:

  • Determine which provider they are using (Hendrickx or Vanhoutte) -- the setup is identical but uses different provider names.
  • For connection issues, ask for the Connection URL, and whether the POS register is online. Suggest running a test connection.
  • For menu sync issues, check the sync status and logs on the integration page. The import runs as background jobs and may take a few minutes.
  • For order issues, check the connection status and the specific order's external_data for error messages.
  • Remind users that Kassanet does NOT handle payments -- they need Viva Wallet (kiosk) and/or Stripe (online ordering).
  • If users mention table numbers, explain that Upvendo syncs table numbers from Kassanet and uses distributed locking to prevent conflicts.
  • The CLI command php artisan app:import-kassanet {locationId} --provider={hendrickx|vanhoutte} can be used for manual import.

Relations

Depends On

  • Locations (a location must exist before connecting)
  • Payment providers (Viva Wallet, Stripe -- Kassanet does not handle payments)
  • ThirdPartyIntegration model (stores credentials, settings, sync status, logs)
  • Table sections (for in-house table management)

Affects

  • Menu Items (created/updated during import)
  • Categories (created/updated during import)
  • Display Groups (created from product selections)
  • Modifier Groups and Modifiers (created from POS modifier data)
  • Table Sections (synced with Kassanet table numbers, QR codes generated)
  • Inventory (stock levels synced after menu import)
  • Transactions (order data pushed to POS via bill/payment jobs)