Skip to main content

Config

POST /pos/config

Downloads the core device configuration: terminal info, merchant details (tip, tax, surcharge), location, EMV parameters, security settings, branding, and operational intervals. Legacy VIPAY terminal_parameters are delivered separately via Terminal Parameters because that payload is large (~200 KB).

This is step 7a in the POS activation flow (after keys, before terminal parameters and activate).

MSK encryption: The HTTP response is an MSK-encrypted envelope (TR31-DATA). Decrypt with the terminal MSK (from POST /pos/keys) using AES-256-CBC to obtain the core config JSON described below.

See End-to-End Example for the full activation walkthrough including MSK decrypt.

Purpose

  • Retrieve the terminal ID and device ID mapping
  • Get the merchant name, key, tip/tax/surcharge JSON (tip_info, tax_info, surcharge_info from the merchants table), and associated location details
  • Load EMV configuration (AID list, terminal capabilities, terminal type)
  • Apply security settings (PIN requirements, contactless limits, fallback rules)
  • Set branding (theme and logo URL)
  • Configure operational intervals (heartbeat, update check)

Not included here: terminal_parameters (acquirer lists, CA keys, EMV kernel configs). Fetch them with POST /pos/terminal-parameters and merge locally — see Terminal Parameters.

Authentication

POS Attestation Auth — requires the attestation token received from POST /pos/attest.

HeaderRequiredFormatDescription
AuthorizationYesAttestation {token}The attestation token from the attest step. Uses the Attestation scheme (not Bearer). The token starts with att_, is cached in Redis, and is valid for 5 minutes from issuance. Example: Attestation att_f83kLmP9s2ab
X-Device-IdYesPOS-{8_HEX_CHARS}The same device ID used during attestation. The server verifies that this device ID matches the one bound to the attestation token. Example: POS-8F3A2C91

See the Headers Reference for complete details.

Request

No request body is required.

Response structure

The decrypted config contains back-office fields only: terminal, merchant, location, security, emv, branding, and device_config. Merge terminal_parameters from the separate terminal-parameters endpoint into your local config object before activation.

Response

200 OK — MSK-encrypted envelope

The API returns ciphertext, not plain JSON. Decrypt locally with MSK to obtain the config object.

{
"format": "TR31-DATA",
"ciphertext": "A1B2C3...",
"initialization_vector": "000102030405060708090A0B0C0D0E0F",
"mode": "CBC",
"key_kcv": "ABCD12"
}
FieldDescription
formatAlways TR31-DATA
ciphertextAES-256-CBC encrypted config payload (hexBinary)
initialization_vectorIV used for encryption (hexBinary, 16 bytes)
modeEncryption mode — CBC
key_kcvMSK key check value for verification

Decrypted config JSON

After MSK decrypt, the plaintext is UTF-8 JSON with this structure:

{
"terminal": {
"terminal_id": "TID-004812",
"device_id": "POS-8F3A2C91"
},
"merchant": {
"merchant_key": "mk_acme_corp",
"name": "Acme Corp",
"tip_info": {
"tip_type": "percentage",
"tip_label": "Tip",
"tip_enabled": true,
"tip_description": "Show your appreciation",
"allow_custom_tip": true,
"maximum_tip_amount": 0,
"minimum_tip_amount": 0,
"suggested_tip_amounts": [1, 3, 5],
"default_tip_percentage": 18,
"suggested_tip_percentages": [15, 18, 20]
},
"tax_info": {
"tax_rate": 2.35,
"tax_number": "512512512512515125",
"tax_region": "US-AZ",
"tax_enabled": true,
"tax_inclusive": true,
"liability_accepted": true
},
"surcharge_info": {
"surcharge_type": "percentage",
"surcharge_label": "Credit card surcharge",
"surcharge_enabled": true,
"liability_accepted": true,
"surcharge_percentage": 3,
"surcharge_description": "A 2.5% processing fee applies to Visa credit card transactions. Debit cards are not subjected to this surcharge.",
"surcharge_fixed_amount": 3,
"maximum_surcharge_amount": 0,
"apply_to_credit_cards_only": true,
"minimum_transaction_amount": 0
}
},
"location": {
"name": "Main Street Store",
"timezone": "America/New_York"
},
"security": {
"pin_required": true,
"online_pin": true,
"contactless_limit_minor": 5000,
"fallback_allowed": true
},
"emv": {
"aid_list": [
"A0000000031010",
"A0000000041010",
"A00000002501"
],
"terminal_capabilities": "E0F0C8",
"additional_terminal_capabilities": "F000F0A001",
"terminal_type": "22",
"application_version_number": "0001"
},
"branding": {
"theme": "dark",
"logo": "https://cdn.viopay.io/acme/logo.png"
},
"device_config": {
"heartbeat_interval_sec": 60,
"update_check_interval_sec": 3600
}
}

Field reference for terminal_parameters (acquirers, CA keys, EMV kernels): Terminal Parameters.

Response Fields

terminal
FieldTypeDescription
terminal_idstringTerminal key assigned to this device
device_idstringPhysical device identifier
merchant
FieldTypeDescription
merchant_keystringUnique merchant key
namestringMerchant business name
tip_infoobjectOptional. Tip settings copied from merchants.tip_info (JSON). Omitted when unset or empty. Example shape: tip_type, tip_label, tip_enabled, tip_description, allow_custom_tip, maximum_tip_amount, minimum_tip_amount, suggested_tip_amounts, default_tip_percentage, suggested_tip_percentages (same structure as the back-office merchant tip profile).
tax_infoobjectOptional. Tax settings copied from merchants.tax_info (JSON). Omitted when unset or empty. Example shape: tax_rate, tax_number, tax_region, tax_enabled, tax_inclusive, liability_accepted (same structure as the back-office merchant tax profile).
surcharge_infoobjectOptional. Surcharge settings copied from merchants.surcharge_info (JSON). Omitted when unset or empty. Example shape: surcharge_type, surcharge_label, surcharge_enabled, liability_accepted, surcharge_percentage, surcharge_description, surcharge_fixed_amount, maximum_surcharge_amount, apply_to_credit_cards_only, minimum_transaction_amount (same structure as the back-office merchant surcharge profile).
location
FieldTypeDescription
namestringLocation name (empty if not assigned)
timezonestringIANA timezone (defaults to UTC)
security
FieldTypeDescription
pin_requiredbooleanWhether PIN entry is required
online_pinbooleanWhether online PIN verification is used
contactless_limit_minorintegerContactless limit in minor units (e.g., 5000 = $50.00)
fallback_allowedbooleanWhether magnetic stripe fallback is permitted
emv
FieldTypeDescription
aid_liststring[]Supported Application Identifiers (Visa, MasterCard, Amex)
terminal_capabilitiesstringEMV terminal capabilities (hex)
additional_terminal_capabilitiesstringAdditional capabilities (hex)
terminal_typestringEMV terminal type code
application_version_numberstringEMV application version
branding
FieldTypeDescription
themestringUI theme (dark or light)
logostringURL to the merchant/reseller logo
device_config
FieldTypeDescription
heartbeat_interval_secintegerHow often to send heartbeats (seconds)
update_check_interval_secintegerHow often to check for firmware updates (seconds)

401 Unauthorized

{
"error": {
"code": "4001",
"message": "Invalid or expired attestation token",
"trace_id": "abc123..."
}
}

404 Not Found

{
"error": {
"code": "4004",
"message": "Device not found",
"details": {
"device_id": "POS-UNKNOWN"
},
"trace_id": "abc123..."
}
}

Code Examples

MSK required

The API returns an MSK envelope, not plain JSON. Samples below show the HTTP call; after receiving the response, run MSK decrypt on the envelope to obtain the core config object. Then call Terminal Parameters and merge. See End-to-End Example.

curl -X POST https://api.viopay.io/pos/config \
-H "Authorization: Attestation att_f83kLmP9s2ab" \
-H "X-Device-Id: POS-8F3A2C91" \
-H "Content-Type: application/json"

What's Next?

After MSK-decrypting the core config, fetch and merge Terminal Parameters, then activate the device:

Next step → Terminal ParametersActivate

See also: End-to-End Example steps 7a–8.