Перейти к содержанию

API Эндпоинты для POS интеграции

Полная документация API эндпоинтов для интеграции с кассовой системой и работы с бонусной программой.

Базовый URL

Production: https://gateway.sagi.kz
Sandbox:    https://test.sagi.kz

Все запросы требуют авторизации через JWT токен в заголовке Authorization: Bearer {token}.


ВАЖНОЕ ПРИМЕЧАНИЕ

Все эндпоинты API возвращают результат в следующем формате:

type Response struct {
    Code    int32       `json:"code"`
    Message string      `json:"message"`
    Data    interface{} `json:"data,omitempty"`
}

В документации ниже показано только содержимое поля data для упрощения чтения. В реальных ответах API все данные будут обернуты в структуру Response.

Пример реального ответа:

{
  "code": 200,
  "message": "Success",
  "data": {
    "id": 1460220481801031680,
    "phone": "+77071234567",
    "first_name": "Иван"
  }
}


1. Поиск клиента

GET /api/v1/promoters/find

Поиск клиента по номеру телефона для работы с бонусной программой.

Query параметры: - phone (string, обязательный) - номер телефона клиента (формат: +77071234567) - branch_id (int64, обязательный) - ID филиала для проверки черного списка

Пример запроса:

curl -X GET "{{baseURL}}/api/v1/promoters/find?phone=+77071234567&branch_id=1234567890123456" \
  -H "Authorization: Bearer {token}"

Успешный ответ (200) - объект User:

{
  "id": 1460220481801031680,
  "first_name": "Иван",
  "last_name": "Иванов",
  "birthday": "02-10-2025",
  "avatar": "https://storage.example.com/avatars/user.jpg",
  "phone": "+77071234567",
  "username": "",
  "tags": [
    {
      "id": 128390023012930123,
      "name": "Соседи по дому",
      "bonus_percentage": 50,
      "background_color": "",
      "color": "",
      "created_at": 1761647590144,
      "updated_at": 1761647590144,
      "user_count": 0,
      "is_discount": false
    }
  ],
  "send_code_for_use_cashback": true,
  "gradation_status": ""
}

Ошибки: - 404 - Пользователь не найден - 400 - Неверный формат телефона - 403 - Пользователь в черном списке филиала


2. Редактирование личных данных клиента

PUT /api/v1/customers/{user_id}/personal-info

Редактирование ФИО и даты рождения клиента.

Тело запроса:

{
    "first_name": "Иван",
    "last_name": "Иванов",
    "birthday": "15-03-1990",        // формат DD-MM-YYYY
    "phone_number": "+77071234567",
    "new_phone_number": "+77716254424",
    "branch_id": 12399231239344,
    "tags": [23412432412341, 32142341234234, 12341234344934]
}

Пример запроса:

curl -X PUT "{{baseURL}}/api/v1/customers/1460220481801031680/personal-info" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "Иван",
    "last_name": "Иванов",
    "birthday": "15-03-1990"
  }'

Успешный ответ (200) - объект User:

{
  "id": 1460220481801031680,
  "phone": "+77071234567",
  "first_name": "Иван", 
  "last_name": "Иванов",
  "birthday": "1990-03-15T00:00:00Z"
}


3. Получение баланса клиента в филиале

GET /api/v1/branches/{branch_id}/private/balance

Получение доступных бонусов клиента в конкретном филиале.

Query параметры: - user_id (int64, обязательный) - ID пользователя - group_id (int64, обязательный) - Group ID филиала

Пример запроса:

curl -X GET "{{baseURL}}/api/v1/branches/1234567890123456/private/balance?user_id=1460220481801031680&group_id=9876543210987654" \
  -H "Authorization: Bearer {token}"

Успешный ответ (200) - число (float64):

2500.50


4. Получение информации о частном филиале клиента

GET /api/v1/branches/{branch_id}/customers/{user_id}/private-branch

Получение детальной информации о клиенте в филиале.

Пример запроса:

curl -X GET "{{baseURL}}/api/v1/branches/1234567890123456/customers/1460220481801031680/private-branch" \
  -H "Authorization: Bearer {token}"

Успешный ответ (200) - объект PrivateBranch:

{
  "branch_id": 1234567890123456,
  "group_id": 9876543210987654,
  "balance": 2500.50,
  "is_client": true,
  "cash_back_percent": 5.0,
  "daily_tx_count": 2,
  "daily_tx_limit": 5,
  "spend_amount": 45000.0,
  "updated_at": 1705332000000
}


5. Получение процента кешбека клиента

GET /api/v1/branches/{branch_id}/cashback

Получение актуального процента кешбека для клиента с учетом всех условий и ограничений.

Query параметры: - user_id (int64, обязательный) - ID клиента - type (string, опциональный) - тип заказа ("direct", "qr") - use_certificate (boolean, опциональный) - использование сертификата

Пример запроса:

curl -X GET "{{baseURL}}/api/v1/branches/1234567890123456/cashback?user_id=1460220481801031680" \
  -H "Authorization: Bearer {token}"

Успешный ответ (200) - число (float64):

5.0

Логика расчета: - Проверяется наличие клиента в черном списке филиала - Учитывается дневной лимит транзакций (если превышен → кешбек = 0) - Применяются градационные настройки кешбека - Возвращается максимальный процент из доступных

Ошибки: - 400 - Клиент в черном списке филиала - 404 - Филиал или клиент не найден


6. Получение информации о штампах клиента

GET /api/v1/branches/{branch_id}/customers/{user_id}/award

Получение детальной информации о накопленных штампах и доступных наградах клиента.

Пример запроса:

curl -X GET "{{baseURL}}/api/v1/branches/1234567890123456/customers/1460220481801031680/award" \
  -H "Authorization: Bearer {token}"

Успешный ответ (200) - объект UserAward:

{
  "id": "60f1b2b3c4d5e6f7g8h9i0j1",
  "title": "Бесплатный кофе",
  "description": "Получите бесплатный кофе за 10 покупок",
  "stamp_count": 10,
  "received_stamp_count": 7,
  "created_at": 1642204800000,
  "activated_at": 1642204800000,
  "expired_at": 1735689600000,
  "total": 3,
  "is_active": true
}

Случай отсутствия данных: Если клиент еще не участвовал в программе наград, возвращаются настройки филиала с received_stamp_count: 0.

Бизнес-логика: - Если received_stamp_count >= stamp_count → клиент может получить награду - Программа наград должна быть активна (is_active = true)


7. Выдача награды клиенту

POST /api/v1/branches/{branch_id}/awards/{award_id}/give

Выдача подарка клиенту при достижении необходимого количества штампов.

Тело запроса:

{
  "user_id": 1460220481801031680,
  "stamp_count": 10
}

Пример запроса:

curl -X POST "{{baseURL}}/api/v1/branches/1234567890123456/awards/60f1b2b3c4d5e6f7g8h9i0j1/give" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": 1460220481801031680,
    "stamp_count": 10
  }'

Успешный ответ (200) - объект UserAward:

{
  "id": "60f1b2b3c4d5e6f7g8h9i0j1",
  "title": "Бесплатный кофе",
  "description": "Получите бесплатный кофе за 10 покупок",
  "stamp_count": 10,
  "received_stamp_count": 0,
  "total": 4,
  "updated_at": 1705332000000
}

Условия: - Клиент должен иметь достаточное количество штампов - Программа наград должна быть активна в филиале - Счетчик штампов сбрасывается к 0 после выдачи награды


8. Создание транзакции для начисления бонусов

POST /api/v1/branches/{branch_id}/cash/order

Создание транзакции для начисления или списания бонусов.

Тело запроса:

{
  "user_id": 1460220481801031680,       // ID клиента (обязательное)
  "amount": 2000,                       // сумма покупки в тенге (обязательное)
  "bonus_amount": 1000,                 // сумма списываемых бонусов (0 если не списываем)
  "comment": "Покупка в кассе #1",      // комментарий к транзакции (опционально)
  "user_phone": "+77077000087",         // телефон для незарегистрированных клиентов (опционально)
  "add_stamp": false,                   // начислить штампик true/false (опционально)
  "stamp_count": 1,                     // количество начисляемых штампиков (опционально)
  "give_award": false,                  // выдается ли награда true/false (опционально)
  "use_balance_code": "123456"          // код подтверждения для списания (требуется при bonus_amount > 0)
}

Описание полей: - user_id - уникальный идентификатор клиента в системе - amount - общая сумма покупки в тенге - bonus_amount - сумма к списанию с баланса бонусов (0 = только начисление) - comment - произвольный комментарий, отображается в истории - user_phone - используется для создания нового клиента, если user_id не указан - add_stamp - добавить штамп в программу наград (не может быть true одновременно с give_award) - stamp_count - количество штампов к добавлению - give_award - выдается ли награда (не может быть true одновременно с add_stamp) - use_balance_code - код подтверждения, отправленный клиенту SMS (обязателен при списании бонусов)

Пример запроса:

curl -X POST "{{baseURL}}/api/v1/branches/1234567890123456/cash/order" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": 1460220481801031680,
    "amount": 2000,
    "bonus_amount": 0,
    "comment": "Покупка в кассе #1",
    "user_phone": "+77077000087",
    "add_stamp": true,
    "stamp_count": 1,
    "give_award": false
  }'

Успешный ответ (201) - объект Order:

{
  "id": 12345678901234567890,
  "order_number": 1001,
  "type": "direct",
  "status": "CREATED",
  "initial_order_total_amount": 2000.0,
  "order_total_amount": 2000.0,
  "created_at": 1705332000000,
  "sender": {
    "id": 1460220481801031680,
    "first_name": "Иван",
    "last_name": "Иванов",
    "phone": "+77077000087"
  },
  "recipient": {
    "id": 1234567890123456,
    "name": "Кофейня Аромат",
    "address": "ул. Абая 10"
  }
}

Важные правила: - add_stamp и give_award не могут быть одновременно true - use_balance_code обязателен при bonus_amount > 0 и если филиал требует код подтверждения


9. Завершение транзакции и начисление бонусов

POST /api/v1/orders/{order_id}/cash/complete

Завершение транзакции и фактическое начисление/списание бонусов клиенту.

Тело запроса:

{
  "use_balance": false,              // списывались ли бонусы (true/false)
  "amount": 0,                       // сумма списанных бонусов (обязательно указать при use_balance=true)
  "payment_method": "cash"           // способ оплаты: cash, card, online, mixed
}

Описание полей: - use_balance - ОБЯЗАТЕЛЬНО true при списании бонусов, false при начислении - amount - при СПИСАНИИ указать желаемую сумму списания, при начислении указать 0 - payment_method - способ оплаты остатка суммы после списания бонусов

Пример запроса (без списания бонусов):

curl -X POST "{{baseURL}}/api/v1/orders/12345678901234567890/cash/complete" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "use_balance": false,
    "amount": 0,
    "payment_method": "card"
  }'

Пример запроса (со списанием 1000 тенге бонусов):

curl -X POST "{{baseURL}}/api/v1/orders/12345678901234567890/cash/complete" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "use_balance": true,
    "amount": 1000,
    "payment_method": "mixed"
  }'

Успешный ответ (200):

null

При успешном завершении возвращается пустой ответ.


10. Отправка кода подтверждения для списания бонусов

POST /api/v1/customers/{user_id}/send-use-cashback-code

Отправка SMS кода подтверждения для списания бонусов клиента.

Тело запроса:

{
  "branch_id": 1234567890123456
}

Пример запроса:

curl -X POST "{{baseURL}}/api/v1/customers/1460220481801031680/send-use-cashback-code" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "branch_id": 1234567890123456
  }'

Успешный ответ (200) - строка (код):

"1234"

Ошибка неверного кода (400):

{
  "code": 3025,
  "message": "code for using private balance is wrong"
}


11. Отмена транзакции

POST /api/v1/orders/{order_id}/revert-transaction

Отмена транзакции и возврат начисленных бонусов. Также отменяет начисление штампов.

Тело запроса: пустое

Пример запроса:

curl -X POST "{{baseURL}}/api/v1/orders/12345678901234567890/revert-transaction" \
  -H "Authorization: Bearer {token}"

Успешный ответ (200) - объект Order:

{
  "id": 12345678901234567890,
  "status": "DECLINED",
  "updated_at": 1705335600000,
  "error": {
    "code": 3015,
    "message": "order was manually reverted"
  }
}

Условия: Статус транзакции должен быть "COMPLETED".


12. Частичный возврат

PATCH /api/v1/orders/{order_id}/refund

Частичный возврат суммы и соответствующих бонусов. Штампы остаются.

Тело запроса:

{
  "amount": "500"                      // сумма возврата как строка (не должна быть >= суммы транзакции)
}

Пример запроса:

curl -X PATCH "{{baseURL}}/api/v1/orders/12345678901234567890/refund" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "500"
  }'

Успешный ответ (200) - объект Order:

{
  "id": 12345678901234567890,
  "updated_at": 1705335600000,
  "initial_order_total_amount": 2000.0,
  "order_total_amount": 1500.0,
  "refunds": [
    {
      "amount": 500.0,
      "refunded_bonus": 25.0,
      "created_at": 1705335600000
    }
  ]
}

Условия: - Статус транзакции должен быть "COMPLETED" - Сумма возврата не должна быть больше или равна сумме транзакции - Поле amount передается как строка


13. Обновление токена авторизации

POST /api/v1/auth/refresh_token

Обновление истекшего JWT токена с помощью refresh token.

Заголовки: - Authorization: Bearer {expired_token} - истекший токен - Content-Type: application/json

Тело запроса: пустое

Пример запроса:

curl -X POST "{{baseURL}}/api/v1/auth/refresh_token" \
  -H "Authorization: Bearer {expired_token}"

Успешный ответ (200):

{
  "code": 200,
  "expire": "2024-03-16T14:30:00Z",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Ошибки: - 401 - Токен недействителен или не может быть обновлен - 403 - Refresh token истек

Примечания: - Используется для автоматического обновления токенов в POS системах - Рекомендуется настроить cron-задачу для периодического обновления