Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

To begin with, Concert is the name of a communication protocol defined by “Association du Paiement” between a cash register and a POS.

It lists all the communication interfaces it supports (ex: WIFI, Bluetooth), it describe data content and data exchange workflow.

 

Note

This documentation is dedicated to PayXpress V4 and beyond versions

Summary

  • Concert in PayXpress

  • Concert supported connections

  • Concert data structure

  • API
    Table of Contents
    minLevel1
    maxLevel6
    include
    outlinefalse
    indent
    stylenone
    exclude
    typelist
    class
    printabletrue

    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.

    how_concert_works_w_payxpress.png

    Today, Concert Service supports these communication interfaces:

    Communication interface

    Is supported?

    WIFI

    (tick)

    IP/ETHERNET

    (tick)

    USB/RS232

    (tick)

    BLUETOOTH

    (error)

    Concert supported connections

    BLUETOOTH

    (error)

    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 Wifi

    Here is an overview of the differences between these two types of connections:

    Description

    USB Cable connected to PC​

    IP/Ethernet (RJ45) connected to Router or 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. ​
    Communication flows in two ways but it is not simultaneous so it implies that the POS cannot handle more than one request at a time.

    Full Duplex.​
    It is possible to send multiple requests at the
    same time. ​For example:​

    • Ping the POS & request a payment, for example.​

    • Payment request & Get Status of the transaction (pooling).

    Max number characters that can be exchanged between the POS and the Cashier?

    512 characters

    No limitation

    IP/Ethernet and 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.

    connections.png

    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.

    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.

     

    For POS port, it is possible to configure it in PayXpress application in “Burger menu” > “Settings” > “Concert configuration” > “Port”.

    Any value change will trigger a dynamic restart of Concert Service without noticing the user.

     

    configuring_concert_on_pos.png
    configuring_concert_on_pos_2.png

    User can still check the Concert service configuration on the main page of PayXpress, there is a small description of the running configuration at the bottom of the page.

    concert_running.png

    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” > “Settings” > “Concert configuration” > “Whitelist”.

    Any value change will trigger a dynamic restart of Concert Service without noticing the user.

     

    whitelist_page.png
    whitelist_page_2.png

    Developer implementation notes

    Use a socket for sending data to the POS and keep it alive until 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 so shutting down socket would make cash register to lose transaction result (such cases can be prevented, it will be covered in next sections).

    WIFI communication is not constraint to single thread, so you can call as much as you want POS device with a new socket, you will get a reply for each call. Keep in mind that only one transaction can be processed in the mean 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

    (tick)

    9600

    (tick)

    19200

    (tick)

    38400

    (tick)

    57600

    (tick)

    115200

    (tick)

    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.

     

    byte_1.png
    byte_2.png

    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 (0x02), ETX (0x03) and LRC characters will not be visible on screen because they are not printable text. For example, Confluence does not display them so when a frame will be used as example, it will be a picture instead of text.

     

    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  This exchange data flow is fully explained below with diagram and tables.

    data_exch.png

    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

    (error)

    “02” => 0x02

    (tick)

    Regarding events and state tables, Concert specifications contain a lot of examples when something goes wrong

    Concert data structure

    Depending the Concert specifications version, the structure of the data changes very significantly. This documentation will explain the main changes between V2 & 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):

    example_msg.png

    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):

    Concert_workflow.pngImage Added