Iiko API integration tips

Iiko API is a JSON API. Each request should be signed by a special temporary request token. You can get a token using your Iiko account username and password, provided by Iiko service.
Iiko API integration tips

Iiko API is a JSON API. Each request should be signed by a special temporary request token. You can get a token using your Iiko account username and password, provided by Iiko service.

To get a token go to https://card.iiko.co.uk/api/0/auth/access_token?user_id=$username&user_secret=$password, where $username and $password are your username and password mentioned before.

All further actions will be made with the usage of the token. We will pass the token value in query as the "access_token" key's value. Also one can set timeout value using "request_timeout" key and "H:i:s" format.

All entities inside Iiko logic, such as restaurants, nomenclature as so on, are connected to the base entity - organization. This way, before using other capabilities of Iiko API, let's get an organization list using /api/0/organization/list?access_token=$access_token&request_timeout=$request_timeout, where $access_token is your temporary token obtained before, and $request_timeout is obviously timeout. From the given list (actually array) choose the required one and save it's Id.

Let's now use the organization Id to get it's nomenclature for example. Be careful, because the orgationisation Id can be used in a query, as well in request body, and even in a path, and it doesn't depend on request method (GET/POST). See the docs (link https://docs.google.com/document/d/1pRQNIn46GH1LVqzBUY5TdIIUuSCOl-A_xeCBbogd2bE/edit#) to be sure how to use it for a particular case. Using the following adress /api/0/nomenclature/$organizationId we can get a list of all organization products and categories (or groups according to Iiko) of your organization. Each entity has it's own Id in Iiko system, and you must store it in your website database, because we will use it later. Be careful, because a product can be of different types and some of products can be compound, like products with ingredients. Even more, if product's ingredients are marked as required - it can not be passed to Iiko without ingredients' information. Also an ingredient can have it's minimum and maximum amounts so an inconsistency with these limits can lead to a failure of Iiko order storing.

By the way, you should know before starting, that mass import of groups and products can be made only by Iiko employee. Also take into account, that all other changes can be applied to Iiko entities with the help of Iiko Biz terminal, which will be installed to your working PCs.

When storing an order to Iiko using API, one could provide a lot of useful information. Use the previously obtained temporary token and organization Id to get lists of available entities:

payment types - /api0/rmsSettings/getPaymentTypes?organization=$organizationId&access_token=$access_token,
order types - /api0/rmsSettings/getOrderTypes?organization=$organizationId&access_token=$access_token,
marketing sources - /api0/rmsSettings/getMarketingSources?organization=$organizationId&access_token=$access_token,
delivery terminals - /api0/deliverySettings/getDeliveryTerminals?organization=$organizationId&access_token=$access_token.

Pay attention, any update of aforementioned types/sources/terminals in a Iiko Biz terminal will lead to entity Id update, so, if synchronize the data periodically - make one more synchronization after another update. You will not spent a lot of time, but this will help to avoid Iiko's rejection to store an order.

Let's now take a look at the process of order storing. Here we will use all the data, we got earlier. One can see the json formatted website order' data, that we will pass to the Iiko service:

    "organization" : $organizationId,
    "deliveryTerminalId" : $deliveryTerminalId,
    "customer" :
       "id" : $customerId,
       "name" : "Asabix",
       "phone" : "+380979981891",
       "email" : "[email protected]"
    "order" :
       "date" : $deliveryDate,
       "phone" : "+380979981891",
       "customerName" : "Asabix",
       "fullSum" : "613.00",
       "isSelfService" : true,
       "orderTypeId" : $orderTypeId,
       "personsCount" : $personsCount,
       "marketingSourceId" : $marketingSourceId,
       "items" : [
          "id" : $firstProductId,
          "name" : "First Product",
          "amount" : "1",
          "code" : $firstSku,
          "sum" : "502.00"
          "id" : $secondProductId,
          "name" : "Second Product",
          "amount" : "1",
          "code" : $secondSku,
          "sum" : "111.00",
          "modifiers" : [
       "id" : $firstModifierId,
       "name" : "First Modifier",
       "amount" : $firstModifierAmount,
       "id" : $secondModifierId,
       "name" : "Second Modifier",
       "amount" : $secondModifierAmount,
    "address" :
       "city" : "Zhytomyr",
       "street" : "Vitruka",
       "home" : "9v",
       "housing" : null,
       "apartment" : null,
       "entrance" : null,
       "floor" : null,
       "doorphone" : null,
       "comment" : "From Small To Extra Large. Everywhere. Everytime"
    "paymentItems" : [
          "id" : $paymentTypeId,
          "code" : $paymentTypeCode,
          "name" : "",
          "comment" : "full"
       "isProcessedExternally" : false

Here we can see that previously saved $organizationId parameter is used, this time in a request body. Also here are $deliveryTerminalId, $orderTypeId, $marketingSourceId, $paymentTypeId parameters we obtained before. So this way we can specify an order type, a payment type and pass detail payment info using the paymentItems key. Besides, the $paymentTypeId parameter can be replaced by $paymentTypeCode, where your can store a human-readable code, like "CASH" or "CARD". The $deliveryDate parameter means expected delivery date-time in "Y-m-d H:i:s" format, the $customerId - is an Iiko client Id, linked to a customer phone number. It is possible to get it using /api/0/customers/get_customer_by_phone or create it using /api/0/customers/create_or_update, see docs (link https://docs.google.com/document/d/1pRQNIn46GH1LVqzBUY5TdIIUuSCOl-A_xeCBbogd2bE/edit#).

Видим, что мы используем ранее сохраненный $organizationId, на этот раз в теле запроса, а также $deliveryTerminalId, $orderTypeId, $marketingSourceId, $paymentTypeId, которые были получены ранее. Таким образом мы можем узказать тип заказа, тип оплаты, а в используя ключ paymentItems и передать информацию об оплате. Кроме того, $paymentTypeId может быть заменен на $paymentTypeCode, где может храниться человекопонятный код, например "CASH" или "CARD". $deliveryDate - это желаемые дата и время доставки в формате "Y-m-d H:i:s", $customerId - Id клиента в Iiko, который привязан к номеру телефона. Его можно получить с помощью /api/0/customers/get_customer_by_phone или, если его нет, создать /api/0/customers/create_or_update, см. документацию (ссылка https://docs.google.com/document/d/1pRQNIn46GH1LVqzBUY5TdIIUuSCOl-A_xeCBbogd2bE/edit#).

Products data can be found in orders > items. Also there are $firstProductId and $secondProductId, which are Iiko products Ids, we mentioned above, and they are required when passing a products data to the Iiko service, without them the service will reject the order storing. Also for the second product the example provided on how to pass modifiers, we mentioned above. If they are required, you have to include them into an order request. They also require Ids, so you must store the Ids in you website database. Some of them can be a separate product, so their relation with products can be described by Composite design pattern. Also the pattern can help to format the product structure for an order request. The $firstModifierAmount and the $secondModifierAmount parameters remind that their values have to comply with the rules of min/max. Parameters $firstProductSku, $secondProductSku и $personsCount are optional for API, but useful for reports.

Error processing for Iiko API can an unpleasant task, because error response depends on error type. If error are handled by Iiko inner logic then they will return in a convenient format and with 4xx status code, but if errors are not handled - a stack trace can be return (in the form Java returns it). This way a response will have 500 status code and it will appear for example if you will pass modifier amount value bigger than the Iiko backend variable type supposes to or if there is a type conversion error, like integer to boolean, if one pass 1 as value instead of true, what turns out to a regular situation during a development/testing processes =).

Sure you can make requests to get all the Ids of order types, payment types and so on, each time you store an order, but at least one should synchronize a nomenclature periodically. But if the environment is stable and all the types change rarely - make them synchronized periodically too or execute synchronization manually. Without periodic you will face performance problems, but with periodic and frequent type changes - the Iiko service will reject to store orders for non-existing types and the orders will present in the synchronization queue until the next synchronization.

Key differences between Laravel and Symfony 07.09.2019 Key differences between Laravel and Symfony
Which of two frameworks Laravel or Symfony is better to choose for the implementation of the project? For what specific needs this or that framework should be used? Description of the functionality of the frameworks

Posting data to Amazon have to be made in a different way 27.09.2019 Posting data to Amazon have to be made in a different way
Let's update an order's tracking number for example.

Back to the list