To communicate with the PayServer from your POS Software you can use the PayProtocol (P3),
which is designed specifically for easy payment integration. This protocol is
platform and technology agnostic, all you need is a TCP socket, which is available
on all major platforms.
We also offer the
PayClient, a ready-made
library that implements the protocol in C#/.NET. If your system uses these
technologies we highly recommend you use this library instead of doing your
own implementation. The PayClient provides all the functionality of the protocol
encapsulated in a easy-to-use, native API.
The P3 protocol itself only defines the messages exchanged between the client and the
server. The server supports two transport layer protocols used to deliver the
messages: WebSocket and framed TCP.
This option makes use of the modern and high-level
WebSocket protocol. This protocol is based on top
of TCP so it is technically possible on all platforms, however, depending on
your technology and language it might not have an available implementation.
An advantage of this protocol is that, if it is already implemented in your
technology, it provides a much simpler integration for you. It is also
implemented in all modern web browsers, so you can use it to integrate a
card reader with your web-based POS Software or eCommerce System.
The WebSocket protocol the PayServer uses adheres to WebSocket 13 specification (RFC 6455),
which defines the initial handshake, message framing and fragmentation as used by
the server. We recommend using a pre-made implementation library rather than
implementing WebSocket from scratch; if such library is not available for your
technology it is better to use our second transport option.
This option makes use of the relatively low-level TCP protocol,
which is natively implemented on all major platforms and should be
available from all languages and technologies. However, because of
its simplicity, it takes more of an effort to implement.
On the TCP level all messages are simply a stream of bytes. To distinguish the messages,
length prefix framing is used to specify the length of the message in big-endian
order. This framing results in each application message being prefixed by a 4 byte
header. The application message itself is a UTF-8 encoded JSON.
Therefore, to read a message, you would first read four bytes of
the input stream as an unsigned integer X. Then you would read the
next X bytes of the actual application message, which you process
as a UTF-8 string. Similarly, to send a message, you first
calculate its size in bytes and send this value as a 4 byte
unsigned integer, then the message. A standard caveat of this
transport protocol is that the message may be split into multiple
packets and not received at the same time.
The P3 protocol is based on the classic request-response messaging pattern. For each
request the client sends it can expect exactly one corresponding response from the
server. However, contrary to some other popular protocols, the response doesn't
have to be returned right away or before another request. Some requests, such as a
request to execute a transaction, may produce long running operations. For these
cases the protocol makes an extension to the request-response model. The protocol
includes:
Update messages, which inform the client about the state of the
operation before the final response arrives.
, and action messages, which prompt the client to send another request
in order to continue with the process.
Every request the client sends needs to contain a
tag
, which allows you to keep track which update,
action or response message is related to the request you've sent.
Your implementation needs to provide a unique
tag
value for each request you make. We suggest generating a UUID for
this.
For example when running an
EXECUTE_TRANSACTION_REQUEST
with
tag
ea99bacc-c05e-4cb5-b2c1-858172124873
, you will receive
this tag in all subsequent
EXECUTE_TRANSACTION_UPDATE
,
EXECUTE_TRANSACTION_ACTION
and
EXECUTE_TRANSACTION_RESPONSE
messages.
Further, when you request a transaction, you send in the path to
the device which you wish to use for the transaction.
The messages defined by the P3 protocol are formatted in
JSON.
Every message includes the same header fields:
{
"type": "<message type>",
"resource": "path/to/device",
"tag": "a required tag which will be present in all updates/responses for this request and must be generated by integrator",
// ...
}
The
resource
specifies a configured
resource for which is the message intended. If there is none the
field is
null
or can be omitted.
As mentioned, there are four categories of messages:
request
,
response
,
update
and
action
. The
response messages also include status and error information in the
header:
{
// ...
"status": "OK|ERROR",
"error": {
"type": "error type",
"message": "error message",
"developerMessage": "information which may be useful to the integrating developers"
}
// ...
}
The
status
is
OK
if the message was processed by the server and correctly executed.
If there was something wrong with the execution, the message status
is
ERROR
.
The
error
field is non-null if and only
if the
status
of the response is
ERROR
. In some cases, there may still be a
response body to according to the message type; for example, if you
are executing a transaction which failed at a later stage, you can
find the transaction data inside the message body.
The data for each message is embedded in a field with the same
name as the message type, but converted to lowerCamelCase. For
example, if you send a
LOGIN_MERCHANT_REQUEST
you should also populate field
loginMerchantResponse
in the message JSON
object. Similarly, when the server sends a
LOGIN_MERCHANT_RESPONSE
you can expect only the
loginMerchantResponse
field of the message
to contain the message type specific data.
All the message types and their message data supported by the P3
protocol are specified in
message
specification.
Usage of the protocol and sample message flows are shown in
protocol usage.