Configuration Endpoints
Hyvä POS is in closed beta
Hyvä POS is currently in a closed beta (pilot phase) with a small group of merchants. It is not yet generally available: the App Store release follows the pilot, and features and configuration may still change - possibly in backwards-incompatible ways - before the general release. Want to take part? Sign up at hyva.io/pos.
These endpoints carry admin settings to the register. The device reads the global config and the unified per-terminal payload; it never writes configuration through them (the write path is PUT /V1/pos/locations/:locationId/config, documented in Locations and Terminals).
| Method | Route | ACL | Purpose |
|---|---|---|---|
GET |
/V1/pos/config |
Hyva_Pos::locations |
Global POS configuration, defaults, enforcement flags |
GET |
/V1/pos/terminals/:terminalId/config |
Hyva_Pos::locations |
Unified per-terminal bootstrap payload |
GET |
/V1/pos/postcode-patterns |
Hyva_Pos::locations |
Per-country postcode validation patterns |
GET |
/V1/pos/order-statuses |
Hyva_Pos::locations |
Registered order statuses for picker UIs |
Global Config - GET /V1/pos/config
Returns everything under Stores > Configuration > Hyvä POS as one object, plus feature-availability flags derived from the installed modules and provider pools. Called by the iPad on every settings sync, including before a PRO module is detected - it is how the app discovers what the store supports.
The response body is a JSON-encoded string (the object serialized twice). Parse the body, then parse the resulting string. Abridged example after decoding:
{
"module_version": "1.1.0",
"enabled": true,
"require_staff_login": true,
"share_held_carts": true,
"require_terminal_registration": true,
"default_order_status": "",
"default_payment_methods": "cash,card",
"default_low_stock_threshold": 10,
"default_receipt_header": "Thank you for shopping with us",
"default_receipt_footer": "",
"default_receipt_show_staff_name": true,
"default_receipt_show_order_number": true,
"default_layaway_deposit_min_percent": 25,
"default_layaway_expiry_days": 30,
"default_layaway_cancellation_fee_percent": 0,
"default_pickup_queue_filter": "all",
"card_payments": {
"provider": "mollie",
"mollie": {
"enabled": true,
"organisation_id": "org_12345",
"api_key": "live_...",
"test_api_key": "test_...",
"test_mode": false
}
},
"walk_in_customer": {
"first_name": "POS",
"last_name": "Customer",
"email": "store@example.com",
"phone": "+31 20 123 4567",
"street": "Main Street 1",
"city": "Amsterdam",
"region_id": 0,
"postcode": "1234AB",
"country_id": "NL"
},
"telemetry": { "enabled": false, "force_enabled": false, "upload_hour": 3 },
"tax": {
"price_includes_tax": true,
"apply_after_discount": true,
"discount_tax": true,
"display_type": 2,
"cart_display_price": 2,
"cart_display_subtotal": 2
},
"enforcement": { "receipt_header": "1", "payment_methods": "0", "tax_settings": "1" },
"payments": {
"pay_by_invoice_method": "checkmo",
"pay_by_invoice_invoicing_mode": "open",
"credit_limits_enabled": true,
"providers": { "mollie": { "magento_method": "mollie_methods_pointofsale" } },
"available_terminal_payment_methods": [
{ "code": "checkmo", "label": "Check / Money order" },
{ "code": "mollie_methods_pointofsale", "label": "Point of sale" }
],
"builtin_refunds_enabled": true
},
"credits": {
"store_credit_includes_tax": false,
"reward_points_includes_tax": false,
"gift_card_includes_tax": false
},
"license": { "connected": true },
"has_credit_providers": true,
"has_rma_providers": true,
"has_wishlist": true,
"has_customer_balance": false,
"has_gift_card": false,
"has_reward_points": false,
"has_rma_module": false,
"shipping_label_providers": [],
"credit_providers": [
{ "key": "store_credit", "code": "pos_builtin", "enabled": true, "label": "Store Credit" }
],
"rma_providers": [
{ "key": "rma", "code": "pos_builtin", "enabled": true, "label": "Built-in Returns" }
]
}
The default_* keys are website- or store-scope fallbacks; a location row without an explicit value inherits them. The card_payments.mollie block contains decrypted API keys for the device - scope integration tokens accordingly.
Unified Terminal Config - GET /V1/pos/terminals/:terminalId/config
The bootstrap payload the iPad pulls at activation, at launch, and whenever the heartbeat's config_hash changes. One call replaces separate fetches of config, location, staff, and roles. Also a JSON-encoded string; parse twice. Envelope keys:
| Key | Content |
|---|---|
terminal |
The terminal row, with license fields injected: license_id, license_token, license_status, license_type, license_expires_at, fiskaly_tss_id, fiskaly_api_key |
license |
The full linked license record, or null |
config |
The same object as GET /V1/pos/config |
location |
The terminal's location row, with the address already resolved (when address_use_storeview is on, store-view values are swapped in server-side) |
resolved_config |
The effective flat config: terminal overrides layered over location values over global defaults. Read this instead of re-implementing precedence |
staff |
Active staff assigned to the location (or with all_locations). The bcrypt passcode hash is stripped; passcode_updated_at is included |
roles |
The roles referenced by those staff rows |
Errors: 404 with Terminal with id "%1" does not exist. for an unknown terminal id. A deleted location yields "location": null rather than an error.
Enforcement Flags and How Locks Work
Each flag lives at hyva_pos_lock/enforcement/<field> (website scope, Stores > Configuration > Hyvä POS > Lock Settings) and is delivered in the enforcement block as string "1" (enforced - the device renders the setting read-only and shows it as managed) or "0" (the device may customize it per location). Server-side, PUT /V1/pos/locations/:locationId/config skips locked fields. Defaults are "0".
| Flag | Locks |
|---|---|
receipt_header / receipt_footer |
Receipt header and footer text |
receipt_show_staff_name / receipt_show_order_number |
Cashier-name and order-number visibility on receipts |
receipt_qr |
Receipt-bottom QR text and URL |
payment_methods |
The set of available payment methods |
mollie_magento_method |
Which Magento payment method backs Mollie-routed card sales (per-location overrides ignored) |
mollie_config |
Mollie terminal settings (keys, organisation id, test mode) |
pay_by_invoice_method / pay_by_invoice_invoicing_mode |
Pay-by-invoice payment method and invoice behavior |
store_details |
Store address, phone, and VAT number |
tax_settings |
Tax calculation and display settings |
low_stock_threshold |
The low-stock warning threshold |
held_carts |
The "Share Held Carts" toggle |
categories |
Which top-level categories appear on the register landing page |
walk_in_customer |
Walk-in customer default name / email / phone / address |
pickup_queue_filter |
The default pickup-queue filter |
Postcode Patterns - GET /V1/pos/postcode-patterns
Relays Magento's etc/postcodes.xml so the device can validate addresses client-side without a parallel hardcoded list. Returns a JSON-encoded string keyed by ISO 3166-1 alpha-2 country code; each country maps to an array of {pattern, example} rows, and any matching row is a pass (the US, for example, has both 5-digit and ZIP+4 rows):
{
"NL": [{ "pattern": "^[0-9]{4} ?[a-zA-Z]{2}$", "example": "1234AB" }],
"US": [
{ "pattern": "^[0-9]{5}$", "example": "12345" },
{ "pattern": "^[0-9]{5}-[0-9]{4}$", "example": "12345-6789" }
]
}
Order Statuses - GET /V1/pos/order-statuses
Every registered row from sales_order_status, including custom merchant statuses. Feeds the location-config "post-pickup status" dropdown (pickup_completed_status_code) so merchants never depend on hard-coded module values.