Note |
---|
This documentation is dedicated to PayXpress V4 and later versions. |
Table of Contents | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
1) Overview
To begin with, Concert is the name of a communication protocol defined by “Association du Paiement”.
This protocol is used to define exchanges between a cash register and a POS.It card payment terminal (POS) and a cash register software. It is widely used in the payments ecosystem, it has been available since July 2020 in its version 3.20.
This document lists all the communication interfaces it supports (ex: WIFIWiFi, Bluetooth), and it describe describes data content and data exchange workflow.
Note |
---|
This documentation is dedicated to PayXpress V4 and beyond versions |
Summary
2) Supported POS Devices
This integration is supported by:
Castles Devices: S1F2, S1P
SUNMI Devices: P2 SMARTPAD
3) Transaction Flow
The Concert Protocol API allows the cash register to communicate with PayXpress (who in turn, communicates with the back end), in order to handle all aspects of the payment request (and tickets):
4) Concert in PayXpress
A part of this protocol has been implemented in PayXpress in order to support it. In our application architecture, we call it “Concert Service”. We will use this name to refer to the implementation of Concert protocol in the following documentation.
Today, Concert Service supports these communication interfaces:
Communication interface | Is supported? |
---|---|
IP/WIFI | |
IP/ETHERNET | |
USB/RS232 | |
BLUETOOTH |
5) Concert-supported connections
There are two different ways a cash register can establish physical communication with the POS terminal:
a USB cable connected to the PC, or
via IP/Ethernet (RJ45) connected to a router or through via IP/Wifi
Here is an overview of the differences between these two types of connections:
Description | USB/RS232 - USB Cable connected to PC | IP/Ethernet (RJ45) connected to Router or IP/Wifi |
---|---|---|
Can the cable be used to communicate with Cashier and for Internet? | No. You will need to have one USB cable to communicate with the PC & another cable RJ45 for Internet for the POS. | Yes. The cash register and the POS device will need to be connected to the same network to be able to communicate with each other. |
Need to install drivers in the PC of the cashier in order to communicate with the POS? | Yes. You will need to install 3 drivers so that the POS can been seen/identified by the cash register PC. | No. Communication with the POS is via IP and by configuring a static IP over the POS (recommended). |
Half-Duplex or Full-Duplex transmission communication? | Half - Duplex. | Full Duplex.
|
Max number characters that can be exchanged between the POS and the Cashier? | 512 characters | No limitation |
IP/Ethernet and IP/WIFI connection specifications
Both connection specifications are the same. Cash register and POS device will be connected to the same network in order to be able to communicate with each other.
Cash register is always the first to start a communication with the POS, so it implies that cash register knows the POS IP address and port to use before doing any calls. This port number must be configurable on both the cash register and the POS in order to adapt to different network configurations.
Info |
---|
It is recommended to set a static IP address to the POS during WIFI/Ethernet connection configuration because the DHCP could change the POS IP address anytime and disrupts cash register configuration. |
. |
To send a message, the cash register will make a connection to this port number (socket opening) and when the connection is established, the data will be sent.
The logical connection will remain established during the entire processing time of the requested action.
Once the cash register has received the return message from the POS, the cash register will close the connection (socket closure), and the terminal will wait for the reception of a new message.
For POS port configuration, it is possible to configure it in PayXpress application in “Burger menu” the Burger menu > “Settings” > “Concert configuration” > “Port”.
Any value change will trigger a dynamic restart of Concert Service without noticing notifying the user.
User The user can still check the Concert service Service configuration on the main page of PayXpress, : there is a small description of the running configuration at the bottom of the page.
Regarding security aspects, there is no SSL, no data ciphering. All the data are transferred through a socket between the cash register and the POS. A whitelist mechanism is implemented in PayXpress to filter IP addresses, in “Burger menu” the Burger menu > “Settings” > “Concert configuration” > “Whitelist”.
Any value change will trigger a dynamic restart of Concert Service without noticing notifying the user.
Developer implementation notes
Use a socket for sending data to the POS and keep it alive until the POS replies but make sure a new socket is opened each time a new query/answer is done. A timeout can be set but do not set it below 1~2 minutes for transaction query if you are running it synchronously, some transactions could take some time because there are some user input pages such as cardholder insert card page or ticket dematerialisation page the cardholder’s ‘insert card’ page and the ticket dematerialization page, so shutting down the socket would make cause the cash register to lose the transaction result (such cases can be prevented, it ; this will be covered in next the following sections).
WIFI WiFi communication is not constraint constrained to single threadthreads, so you can call as much as you want the POS device with a new socket as many times as you want, and you will get a reply for each call. Keep in mind that only one transaction can be processed in the mean at a time, so any other transaction queries would be declined if there is already one in running.
USB/RS232 connections specifications
RS232 specifications are more complex than any other, it implies a strict data structure and data exchange workflow. This section will only talk about technical specifications regarding RS232, the concert data structure will be fully explained in other section.
So USB/RS232 means cash register and POS will be linked thanks to a cable, USB or RS232. The type of cable does not matter, the communication will work the same way in Concert. Unlike WIFI, USB/RS232 is half-duplex, it means cash register and POS cannot emit and receive messages simultaneously.
This is the list of speeds (baud or symbols/s) that PayXpress supports:
Baud
Is supported?
1200
9600
19200
38400
57600
115200
Each frame is composed of max 512 data bytes.
A data byte will be composed of 7 bits of data and a bit of parity.
The parity used in concert specifications is EVEN. It means the number of raised bits (1 bit) is always even in a data byte. If the 7 bits of data contain a even raised bits number, parity bit is 0, if it is odd, parity bit is 1.
This is a security control to prevent any tampering of the data. Regarding the 7 bits of data, they are ASCII-7 and the range of supported characters begins to 0x20 (hex) SPACE
until 0x7F (hex) DEL
. You can find the list of supported characters in this table.
In a frame, the first data byte is a command that defines the meaning of the frame. All the commands are described in the table below:
NAME
DESCRIPTION
HEX VALUE
ENQ
Ask to open a new session
0x05
ACK
Positive reception acknowledge
0x06
NAK
Negative reception acknowledge
0x15
STX
Start of a message content
0x02
ETX
End of a message content
0x03
EOT
End of the session
0x04
Note |
---|
There is no parity bit for command data byte |
Info |
---|
For your information, most of the time, depending on the software, STX ( |
The specifications define the order of commands when cash register and POS communicate. Like in Ethernet/WIFI, the POS is in a waiting state and it is up to the cash register to initiate the communication.
ENQ is always the first command to be sent, it opens a new session receiver side
ACK is sent by the receiver to confirm that it successfully received the sender message
NAK in the other hand is sent by the receiver to confirm that it did not receive the sender message or data controls failed
STX and ETX are always sent together like this “STX<message>ETXlrc”. Sometimes, the word “message” in Concert specifications is used to refer to the entire frame
lrc stands for longitudinal redundancy check. It works like a checksum, it is computed using every bytes from <message> + ETX byte. You can use online websites such as this one if you want to compute lrc value and compare it to the received one you got. Once the message is received, the receiver computes on its side lrc and compare its value to the sent one, if it does not match, an error will be thrown
This exchange data flow is fully explained below with diagram and tables.
Constant/variables names
Name
Description
N1
Emitting frame counter. Max value is 3
N2
Session counter. Max value is 3
T0
Current timer, value 0 means no timer
T1
Timer, 500ms for POS, 600ms for cash register
RECEIPT
Receipt status, possible values are OK and NOK
EMIT
Emitting status, possible values are OK, ABORT and NOK
Listening procedure for cash register & POS
State
Event
R0
Standby
R1
Waiting ENQ
R2
Waiting STX
R3
Waiting EOT
Start listening
N1 = 0, N2 = 0
=> R1
T0 = 0
=> R1
Ignored
Ignored
ENQ receipt
Ignored
T0 = T1
N1 = N1 + 1
N2 = N2 + 1
emit ACK
=> R2
Ignored
Ignored
STX<message>ETX receipt and there is no data control error
Ignored
Ignored
T0 = T1
emit ACK
=> R3
Ignored
STX<message>ETX receipt but
lrc is incorrect or
parity error
Ignored
Ignored
If N1 < 3
N1 = N1 + 1
T0 = T1
emit NAK
=> R2
if N1 = 3 and N2 < 3
N1 = 0
emit NAK
=> R1
if N1 = 3 and N2 = 3
emit NAK
RECEIPT = NOK
=> R0
Timeout
Ignored
Ignored
Same as [STX/ETX receipt but lrc is incorrect or there is a parity error/R2] above
RECEIPT = OK
=> R0
EOT receipt
Ignored
Ignored
Ignored
RECEIPT = OK
=> R0
Other characters
Ignored
Ignored
Ignored
Ignored
Emitting procedure for cash register
State
Event
E0
Standby
E1
Start emitting
E2
Waiting ACK
E3
Waiting ACK
E4
Waiting Timeout
Start emitting
N1 = 0, N2 = 0
=> E1
T0 = 0
N2 = N2 + 1
=> E2
Ignored
Ignored
ACK receipt
Ignored
Ignored
T0 = 0
N1 = N1 + 1
emit STX<data>ETXlrc
=> E3
Ignored
ENQ receipt
Ignored
Ignored
emit EOT
EMIT = ABORT
=> E0
Same as [NAK receipt or other characters or parity error/E3] below
EMIT = ABORT
N1 = N2
T0 = T1
emit ACK
=> R2
NAK receipt or other characters or parity error
Ignored
Ignored
If N2 < 3
T0 = 0
emit EOT
=> E4
if N2 = 3
emit EOT
EMIT = NOK
=> E0
If N1 < 3
N1 = N1 + 1
T0 = T1
emit STX<data>ETXlrc
=> E3
if N1 = 3 and N2 < 3
N1 = 0
emit EOT
=> E4
if N1 = 3 and N2 = 3
emit EOT
EMIT = NOK
=> E0
Ignored
Timeout
Ignored
Ignored
Same as [NAK receipt or other characters or parity error/E2] above
Same as [NAK receipt or other characters or parity error/E3] above
=> E1
Developer implementation notes
Unlike Ethernet/WIFI, USB/RS232 connection does not allow any multithreading processus. Do not start any new request if there is already one in running, it will lead to errors for both of them.
Parity and LRC controls on STX<message>ETXlrc receipt can be performed both in the same time because they only concern one frame and the same data. As a reminder, parity control is only done on ASCII-7 data bytes (no command byte) and LRC is computed from all ASCII-7 data bytes + ETX byte. This is a code snippet (kotlin) which performs both controls:
Code Block |
---|
fun isParityBitOrLrcOk(frame: List<Byte>, lrc: Byte? = null): Boolean {
var isParityAndLrcOk = false
var computedLrc: Byte = 0x0
// frame only contains ASCII-7 data bytes
for (byte in frame) {
val oneBitsCount = byte.countOneBits()
// oneBitsCount is odd, there is a parity error
if (oneBitsCount % 2 != 0) {
return isParityAndLrcOk
}
// LRC Computation
if (lrc != null)
computedLrc = computedLrc xor byte
}
// Frame does not contain ETX command, do a XOR using ETX value manually
if (lrc != null && frame.last() != 0x03.toByte())
computedLrc = computedLrc xor 0x03
// Compare incoming LRC to the computed one
return lrc == null || computedLrc == lrc
} |
Same thing has to be done during the message building when cash register wants to send a message to the POS. This is a code snippet (kotlin) which builds the data to be sent with parity and lrc computation:
Code Block |
---|
fun buildChunksForEmit(dataToSend: String): String {
val commandStringBuilder = StringBuilder()
var computedLrc: Byte = 0x0
commandStringBuilder.append("02") // STX
for (char in dataToSend) {
val binaryRepresentation = char.code.toByte()
val oneBitsCount = binaryRepresentation.countOneBits()
val isOdd = oneBitsCount % 2 != 0
val binaryRepresentationWithParity =
if (isParityCheckEnabled && isOdd) it.raiseBit(8)
else it
computedLrc = computedLrc xor binaryRepresentationWithParity
commandStringBuilder.append(
binaryRepresentationWithParity
.toUByte()
.toInt()
.toString(16)
)
}
// padStart ensure LRC hex representation length will always be 2
val lrcAsString =
(computedLrc xor 0x03)
.toUByte()
.toInt()
.toString(16)
.padStart(2, '0')
val etxAndLrc = "03$lrcAsString" // ETX + LRC
commandStringBuilder.append(etxAndLrc)
return commandStringBuilder.toString()
} |
If you want to use the code snippet above, please be careful, it builds a hex representation of the string, so each byte will become two chars. It is helpful for debugging/logs but make sure when you are sending this hex string that you convert each two chars couples in one byte before.
“02” => 0x00 + 0x02
“02” => 0x02
Regarding events and state tables, Concert specifications contain a lot of examples when something goes wrong
See USB/RS232 - Specifications.
6) Format of Concert Protocol & Rules
Given its use and for simplicity, the definition of the protocol used does not follow the Basic Encoding Rules for TLV standard “BER-TLV” (ITU-T X.690).
TLV = Type Lenght Value
The Type and Length fields are fixed.
The Length field is defined by three bytes aligned on the right and completed on the left by 0s.
The Type, Length and Value (TLV) information form what is called a “Tag”:
Composition of a Tag:
Type | Length | Value |
---|---|---|
2 bytes | 3 bytes | data |
Type: encoding on 2 ASCII alpha bytes (A…Z)
Length: encoding on 3 ASCII numeric bytes (0…9)
Value: encoding on ASCII alphanumeric (0x20 – 0x7F)
An example Tag CZ: Encoding the concert protocol version to be used
Type | Length | Value |
---|---|---|
CZ | 004 | 0320 |
Type: “CZ” - Stands for version of the concert protocol used
Length: “004” - The length of the data is 4 bytes
Value: “0320” - This value refers to the version 03.20 of the protocol concert (latest version)
Constructed Tags
Tags whose first byte of the Type string is “Z” indicate it is a constructed Tag (which contains a set of TLVs).
A constructed Tag allows several simple Tags to be grouped within the same Tag.
An example of a constructed Tag
Type | Length | Type | Length | Value | Type | Length | Value |
---|---|---|---|---|---|---|---|
ZX | 014 | AX | 003 | 123 | BY | 001 | A |
ZX: is a constructed tag 14 characters long containing two simple Tags:
Tag AX - The length of the Tag is 3 characters, its value being “123”
Tag BY - Its length is 1 character, its value is “A”
The rules of using Tags
A zero-length Tag is not transmitted.
The Protocol Version Tag CZ is the first tag in the cash register or terminal message. The protocol version allows you to associate the dictionary of Tags managed in the message.
The order of other Tags in a message is not important.
There is only one level of constructed Tags: A constructed Tag does not group other constructed Tags, it can only hold simple Tags.
Except for the ZT tags which is the only one that is composed of AK & CK tags. Furthermore, it’s the only one which can be repeated.
7) Concert data structure
Depending the Concert specifications version, the structure of the data changes very significantly. This documentation will The pages below explain the main changes between V2 V3 & V3
Concert V2 data structure
First of all, in V2, there is only one supported communication method which is USB/RS232. In this version, all the data are structured following a specific order. The structure is different between the query of the cash register and the reply of the POS.
Following tables will detail the structure of data <message> including STX, ETX and LRC.
Note |
---|
There is no field for ticket, it is up to the cash register to build it on its own |
Data structure of the cash register query
Field
Length
Description
STX
1
Start of the frame
ECR#
2
Cash register number
MNT
8
amount
IND
1
Response field indicator (0 = NO REP, 1 = REP but only PAN, 2 = TLV)
EMETTEUR
1
Payment method
TYPE
1
Transaction type
DEV
3
Currency
PRIV
10
Private data (if none, it is blank, so 10 0x20 SPACE
)
DELAI
1
POS response delay
AUTO
1
Authorization request
ETX
1
End of the frame
LRC
1
Checksum (computed using bytes from ECR# to AUTO + ETX)
Data structure of the POS reply
Field
Length
Description
STX
1
Start of the frame
ECR#
2
Cash register number
STAT
1
Transaction status
MNT
8
amount
IND
1
Response field indicator (0 = NO REP, 1 = REP but only PAN, 2 = TLV)
EMETTEUR
1
Payment method
TYPE
1
Transaction type
DEV
3
Currency
PRIV
10
Private data (if none, it is blank, so 10 0x20 SPACE
)
DELAI
1
POS response delay
AUTO
1
Authorization request
ETX
1
End of the frame
LRC
1
Checksum (computed using bytes from ECR# to AUTO + ETX)
Info |
---|
A POS message could look like this (STX + <message> + ETX + lrc): |
Concert V3 data structure
API
The Concert Protocol API allows the cash register to communicate with PayXpress (who in turn, communicates with the back end), in order to handle all aspects of the payment request (and tickets):
V2 (Legacy).
Version 3.2 Data structure & Examples
See Concert V3.
Version 2.0 Data structure - Legacy version
See Concert V2 - Legacy.