Quick start
This article describes communication over HTTP layer between Portos eKasa API service and your application.
How to communicate with HTTP REST API
The default data format is JSON. The default encoding is UTF-8.
Please insert following headers to every HTTP request:
Content-Type:application/json; charset=utf-8
Accept:application/json
Receipt registration
Basic receipt registration
To print receipt you can use following URL: POST {{server_address}}/api/v1/requests/receipts/cash_register
The request accepts following content in body:
{
"request": {
"data": {
"items": [
{
"type": "Positive",
"name": "Coca cola",
"price": "3.00",
"unitPrice": "1.500000",
"quantity": {
"amount": "2.0000",
"unit": "x"
},
"vatRate": "20.00",
"description": "this is an additional line printed below product name"
}
],
"payments": [
{
"name": "Hotovosť",
"amount": "3.00"
}
],
"headerText": "This text will be printed before all items",
"footerText": "This text will be printed at the end of receipt",
"cashRegisterCode": "88812345678900001"
},
"externalId": "unique-id-given-by-your-application"
}
}
The request
property contains two fields: data
and externalId
.
"data" field
The data
field contains information about receipt. Receipt contains several required and optional fields:
items
: this is an collection of products. Items collection can contain up to 500 items. Each product has several properties:type
: type of receipt item. During regular sales, usepositive
value. The other available types are described below.name
: name of product, limited to 255 characters and must not contain special symbols (only alphanumeric values +CR
+LF
are allowed).price
: total price for this product, with precision up to 2 decimal places. Price must be equal to multiplication ofunitPrice
andquantity
fields.unitPrice
: product unit price with precision up to 6 decimal places.quantity
: object with requiredamount
property with positive numeric value and precision up to 4 decimal places and optionalunit
field. If unit field will not be specified, default valuex
will be used. Theunit
field must not be empty string (""
), usenull
value instead or ommit this field at all.vatRate
: percentual VAT rate. In current version, the only allowed values are20
,10
and0
.description
: this is an optional field that may contain string value with unlimited length. This description will be printed below thename
on receipt. This can be used for additional information for customer, such as serial numbers, expiration dates etc.
payments
: this is an optional collection. When this collection is provided, the total sum of all payment amounts must be equal or greater thant total amount of receipt (sum of itemsprice
property). Each payment has two required fields:name
: description of payment method, such as "Cash" (Hotovosť) or "Credit card" (Platobná karta). Length of payment name is limited to 255 characters and must not contain special symbols (only alphanumeric values +CR
+LF
are allowed).amount
: amount of payment with precision up to 2 decimal places.
headerText
: optional text printed above all receipt items.footerText
: optional text printed at the end of receipt.cashRegisterCode
: required field that must contain unique cash register code, issue by tax authority. This value should be inserted in your application's configuration.
The fields data.item.description
, data.headerText
and data.footerText
can be formatted (to achieve bold font, underline, horizontal alignment and so on). To learn more about text formatting, please see token syntax article.
"externalId" field
The externalId
is optional unique identifier, that is generated by your application. With this value, you can look up information about receipt later.
Receipt registration response analysis
After sending the receipt registration request, HTTP WEB API will return and response object.
Several HTTP Status codes are used in response:
200
: receipt was successfully registered in "eKasa" server of tax authority. We call this "online mode".202
: receipt was accepted by Portos eKasa system, but was not registered in "eKasa" server of tax authority due to internet connectivity issue (also referred as "offline mode").400
: the request contains validation errors.403
: the operation could not be completed due to error.500
: server-side error occurs.
Example of "online" registration response
HTTP status is 200. The response object contains following fields:
request
: consists of original data and several new fields, generated by Portos eKasa system, such asreceiptNumber
andokp
(receipt verification code).response
: this field contains unique receipt identifier (data.id
) generated by eKasa server of tax authority. You would need this unique identifier in returning goods scenario, so best practice is to remember this identifier in database of your application.
Example:
{
"request": {
"data": {
"receiptNumber": 2,
"okp": "04eacca4-6ff07dea-c2c85513-28181bb6-f46edcb0",
... // this object contains all other information about data in requested
},
"externalId": "unique-id-given-by-your-application",
... // other fields related to registration request
},
"response": {
"data": {
"id": "O-7DBCDA8A56EE426DBCDA8A56EE426D1A"
},
"processDate": "2019-04-27T20:57:42+02:00"
},
"isSuccessful": true, // true value means record was registered succesfully
"error": null,
"$type": "Receipt"
}
Example of "offline" registration response
HTTP status is 202. When receipt is registered in "offline mode" (accepted by Portos eKasa API, but not registered in eKasa server of tax authority), response object is different.
The main difference is that response
object containing information from eKasa server is null
. Therefore we don't have unique receipt identifier of receipt. In this scenario, okp
field (located in request.data.okp
) serves as replacement for unique identifier.
Example:
{
"request": {
// data related to registration request
},
"response": null, // in offline mode, response object is null
"isSuccessful": null, // null value indicates that registration is not completed yet.
"error": null,
"$type": "Receipt"
}
Portos eKasa application prints receipt with "offline mode" notice in print layout and registeres this registration request in queue. After connectivity with tax authority server is established again, queue is being processed fully automatically.
From your application's point of view - this is successfull receipt registration.
Example of error registration respone
HTTP status is also 202. Request is processed online but rejected by tax authority. This state is indicated by two fields:
error
field now contains rejection reasonisSuccessful
field now containsfalse
value.
Example:
{
"request": {
// data related to registration request
},
"response": null,
"isSuccessful": false, // false value indicates that registration was rejected by tax authority
"error": { // error reason provided by tax authority
"message": "This is the error reason specified by tax authority.", // rejection reason
"code": -10 // rejection error code
},
"$type": "Receipt"
}
Example of registration response for malformed request
HTTP status is 400. Receipt is not printed because registration request contians invalid data.
Example:
{
"errors": { // collection of broken validation rules
"Items[0].Name": [ // the path to the property with broken validation rule with list of error messages
"Názov nesmie byť prázdny." // validation message e.g. "the name must not be empty"
]
},
"code": -900,
"type": "https://ekasa.ninedigit.sk/docs/webapi/apierrorcodes.html#900-validationerror",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "0HLLN8OC1QVLU:00000002"
}
Example of response for internal server error
HTTP status is 500, that indicates Portos eKasa API server error.
Example:
{
"traceId": "0HLLN8QFOGJQN:00000002",
"code": null,
"title": "Internal server error", // error title
"status": 500,
"detail": "This is the error message detail", // error message
"instance": "/api/v1/requests/receipts/cash_register"
}
Receipt registration with returning goods
When returning goods, we must specify referenceReceiptId
field in item object. The value contains identifier of original receipt, that was printed when the product was originally sold. If original receipt was registered in online mode, we use response.data.id
value. If original receipt was registered in offline mode, we use request.data.okp
value. If item was sold before eKasa receipts were used, text value containing daily sales report number and/or receipt number can be entered.
Example:
...
"items": [
{
"type": "returned", // we specify that this item is returned by purchaser
"name": "Porduct name",
"quantity": {
"amount": 2.0000, // amount to return (always an positive number)
"unit": "x"
},
"unitPrice": -15.00,
"price": -30.00,
"vatRate": 20.00,
"referenceReceiptId": "O-7DBCDA8A56EE426DBCDA8A56EE426D1A"
}
],
...
Regecipt registration with discount
When adding discount to receipt, you must add new receipt item with:
type
set todiscount
quantity.amount
set to1
unitPrice
andprice
set to negative value
Example:
...
"items": [{
"type": "discount",
"name": "Zľava",
"quantity": {
"amount": 1.00,
"unit": "ks"
},
"unitPrice": -10.00,
"price": -10.00,
"vatRate": 20.00,
"description" : null
}],
...
Receipt copy
To print receipt copy, send an POST
HTTP request to URL: {{server_address}}/api/v1/requests/receipts/print_copy?cashRegisterCode=88812345678900001&externalId=5cb23300ce3ccc2d38ccdbde
Please, don't forget to replace cashRegisterCode
and externalId
query parameters with values.
Deposit and withdrawal
As required by slovak legislation, when cashier inserts cash into cash drawer (or wallet) that was not received as payment, and deposit receipt must be printed. Same goes when cashier takes money from cash drawer or wallet - withdraw receipt must be printed.
To register deposit transaction, send an POST
HTTP request to URL {{server_address}}/api/v1/requests/receipts/deposit
To register widhtraw transaction, send an POST
HTTP request to URL {{server_address}}/api/v1/requests/receipts/withdraw
For both deposit
and withdraw
transactions, request.data.amount
must be positive number, with precision up to 2 decimal places.
Example body:
{
"request": {
"data": {
"cashRegisterCode": "88812345678900001",
"amount": 10.00
}
}
}
Drawer opening
To open cash drawer, send an POST
HTTP request to URL: {{server_address}}/api/v1/printers/open_drawer
.
No HTTP payload (message body) is required.
Nonfiscal receipt printing
To print record other than receipt, send and POST
HTTP request to URL {{server_address}}/api/v1/printers/print
. The body contains object with single text
string property.
Body example:
{
"text" : "this is and print output line 1,\nthis is and print output line 2."
}
Text can be also formatted, to achieve bold font, underline, horizontal alignment and so on. To learn more about text formatting, please see token syntax article.