LOKO Merchant API
  • Getting Started
    • 🔌Процес інтеграції
    • 💂Отримання токену
    • 🪃Опрацювання Callback(Webhook)
  • General Terms & Conditions
    • 🔓Scope
    • ⚙️Environment
    • 🔑Company & Store
  • API Reference
    • Orders
    • Stores
    • Menu
      • Separate Product & Offer
      • Common Product + Offer (deprecated)
      • Common Menu Import
      • Stop-list
      • Import categories
    • Callbacks (webhooks)
Powered by GitBook
On this page
  • Навіщо це потрібно?
  • Як генерується підпис?
  • Як почати отримувати сповіщення?
  • Як правильно опрацьовувати сповіщення?
  • PHP
  1. Getting Started

Опрацювання Callback(Webhook)

❓ Як опрацьовувати зворотні виклики

PreviousОтримання токенуNextGeneral Terms & Conditions

Last updated 8 months ago

Callback (або Webhook) – це механізм взаємодії між двома сервісами, під час якого сервіс ініціатор надсилає сповіщення (або повідомлення) про подію усім підписникам (subscribers) HTTP запитом, методом POST з тілом JSON (з деталями замовлення). Детальніше можна прочитати у Вікіпедії за посиланням

Навіщо це потрібно?

Використання механізму зворотних викликів може знадобитись у випадках, коли вам необхідно реагувати на події щодо змін замовлення – наприклад, таких як зміна статусу або призначення кур'єра.

Використання механізму зворотних викликів не є обов'язковим – використовуйте його у разі потреби.

Як генерується підпис?

Підпис генерується з даних, доступних за ключем data, які сортуються за цим ключем та перетворюються на JSON-рядок, з якого генерується hash . Приклади генерування підпису можна побачити нижче 👇

Як почати отримувати сповіщення?

  1. Отримайте для автентифікації.

  2. Отримайте список подій, доступних для підписки.

Надішліть запит:

curl -X GET {PLATFORM_SERVICE_API_URI}/v1/merchant/callback/events \
    -H 'Accept: application/json' \
    -H 'Authorization: Bearer {AUTH_TOKEN}'

Отримайте відповідь:

{
  "total": 5,
  "items": [
    {
      "name": "order.new",
      "description": "Fires when new order created"
    },
    {
      "name": "order.item.changed",
      "description": "Fires when order item is changed"
    },
    {
      "name": "order.status.changed",
      "description": "Fires when order status is changed"
    },
    {
      "name": "order.courier.assigned",
      "description": "Fires when courier is assigned to order"
    },
    {
      "name": "store.availability.changed",
      "description": "Fires when store is open/closed"
    }
  ]
}
Не забудьте замінити companyIds на власний companyId.
У форматі JSON Array можна передавати декілька companyId.

Відправляємо запит:

curl -X POST {PLATFORM_SERVICE_API_URI}/v1/merchant/callback/subscriptions \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {AUTH_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "companyIds": [
      "e80594bf-9fea-4e3e-b86f-1099b270332d" 
    ],
    "callback": "https://example.com/loko_callback",
    "events": [
      "order.new",
      "order.status.changed"
    ]
  }'

Отримуємо відповідь:

{
  "id": "1eef00db-7b85-6af6-a354-7b32ee5b2732",
  "companyIds": [
    "e80594bf-9fea-4e3e-b86f-1099b270332d"
  ],
  "secret": "26955465c98511bbc2e181ca4c0dea603fc9b6e178527837847324e47b9d16f5",
  "events": [
      "order.new",
      "order.status.changed"
  ],
  "callback": "https://example.com/loko_callback"
}

Якщо у відповіді немає secret, це означає, що підписник, швидше за все, не створився – потрібно спробувати ще раз або звернутись до підтримки.

Зберігаємо secret з відповіді – він знадобиться нам в наступних кроках.

  1. Отримуйте сповіщення на переданий callback uri.

Як правильно опрацьовувати сповіщення?

Оскільки ми з вами працюємо у відкритому інтернеті, на ваш callback uri можуть надіслати будь-який HTTP запит з будь-якими даними, тому вам обов'язково необхідно впевнитись, що сповіщення прийшло від LOKO Merchant Platform.

Для цього в нас є secret, який ми отримали раніше. Ви маєте впровадити механізм верифікації сповіщень у себе для верифікації запитів.

  1. Отримуємо сповіщення на вказану callback uri.

Приклад отримання нового замовлення:

{
  "event": "order.new",
  "data": {
    "id": "1eef0201-0ffc-6bfa-96ff-c92a5222082e",
    "number": "1000098772",
    "storeId": "1ec7d241-dcdc-6038-a7a4-d7ed6fe2bd2a",
    "status": "new",
    "listPrice": {
      "value": 8595,
      "currency": "UAH"
    },
    "netPrice": {
      "value": 8595,
      "currency": "UAH"
    },
    "comment": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec.",
    "estimatedCookingTime": null,
    "items": [
      {
        "id": "1eef0201-0ffc-6f1a-b9a9-c92a5222082e",
        "quantityOrdered": 19,
        "quantityFulfilled": null,
        "productId": "1ec8e4ac-cb3e-6226-83c5-3f90aeb9f844",
        "name": "Беконатор",
        "offerId": "1ec8e4ae-67b9-6618-bad5-e3d05e871eec",
        "sku": "000111",
        "itemPrice": {
          "value": 225,
          "currency": "UAH"
        },
        "listPrice": {
          "value": 4275,
          "currency": "UAH"
        },
        "attributes": [],
        "cancellations": []
      },
      {
        "id": "1eef0201-0ffd-6028-bcdf-c92a5222082e",
        "quantityOrdered": 18,
        "quantityFulfilled": null,
        "productId": "1ec8e4b2-f4b0-6158-96a2-439045e34ccd",
        "name": "Ковбой",
        "offerId": "1ec8e4b4-05bf-6574-a00a-55f8ae794fe0",
        "sku": "000222",
        "itemPrice": {
          "value": 240,
          "currency": "UAH"
        },
        "listPrice": {
          "value": 4320,
          "currency": "UAH"
        },
        "attributes": [],
        "cancellations": []
      }
    ],
    "customer": {
      "firstName": "Эмгыр",
      "lastName": "вар Эмрейс",
      "phone": "0992229988"
    },
    "courier": null,
    "promos": [],
    "createdAt": "2024-04-01T12:05:00+00:00",
    "updatedAt": "2024-04-01T12:05:00+00:00",
    "isTest": false
  },
  "signature": "8d7626b04a7b1c46ece632604ff6905c922b4d7b9f2da21ae2327d5d6b835ef4f33b70fe0356faddf31ff04c764477b26a2a0eb7895ce9adb8989d5d82c2ece5"
}

Приклад отримання змін по доступності бранчі (магазину):

{
  "event": "store.availability.changed",
  "data": {
    "id": "1edf0896-2696-67ae-becf-7dcbdaa34879",
    "company": {
      "id": "1ec7d235-cc2c-64a6-9ee3-0711604a764e"
    },
    "availability": {
      "open": true
    }
  },
  "signature": "e2e1d99a91b123f629220d1260a2a3a40d991b11405a71587c0c26623bbc92b862049eeb1161b3dd998f33b4d6615bdf2966b467a53ec06cd10ae39f6b12dbba"
}

З відповіді треба дістати signature для подальших дій.

  1. Верифікуємо тіло за допомогою secret та signature.

PHP

<?php

declare(strict_types=1);

namespace App;


final class SignatureGenerator
{
    public const SIGNATURE_ALGORITHM = 'sha512';

    public static function generate(array $data, string $secretKey): string
    {
        $encodedData = json_encode(self::prepareData($data), flags: JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE);

        return hash_hmac(self::SIGNATURE_ALGORITHM, $encodedData, $secretKey);
    }

    public static function verify(array $data, string $signature, string $secretKey): string
    {
        return hash_equals(self::generate($data, $signature), $signature);
    }

    public static function prepareData(array $data): array
    {
        ksort($data, flags: SORT_REGULAR);
        foreach ($data as $key => $item) {
            $data[$key] = !is_array($item)
                ? $item
                : self::prepareData($item);
        }
        return $data;
    }
}


$secretKey = 'supersecret';
$rawRquestBody = '{}';
$requestBody = json_decode($rawRequestBody);

if (!SignatureGenerator::verify($requestBody['data'], $requestBody['signature'], $secretKey)) {
    // Signature is not valid, we will not complete this request
    return;
}

// Signature is valid. Do something!
  1. Готово! Ви успішно обробили сповіщення.

Створіть підписника . Для створення потрібно вказати та , на які реагуватиме система – ви будете отримувати сповіщення на вказаний вами callback uri.

🪃
https://uk.wikipedia.org/wiki/Webhook
HMAC-SHA512
токен
company_id
за допомогою ендпоїнта
список подій