Show / Hide Table of Contents

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, use positive 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 of unitPrice and quantity fields.
    • unitPrice: product unit price with precision up to 6 decimal places.
    • quantity: object with required amount property with positive numeric value and precision up to 4 decimal places and optional unit field. If unit field will not be specified, default value x will be used. The unit field must not be empty string (""), use null value instead or ommit this field at all.
    • vatRate: percentual VAT rate. In current version, the only allowed values are 20, 10 and 0.
    • description: this is an optional field that may contain string value with unlimited length. This description will be printed below the name 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 items price 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 as receiptNumber and okp (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 reason
  • isSuccessful field now contains false 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 to discount
  • quantity.amount set to 1
  • unitPrice and price 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.

In This Article
Na začiatok stránky Nine Digit, s.r.o. ©