Сценарии работы с POS системой#
Описание пошаговых сценариев работы кассовой системы с API Sagi для интеграции бонусной программы.
Первоначальная настройка (выполняется один раз)#
1. Подключение приложения к Sagi#
Авторизация: Запросите логин и пароль у бизнеса, выполните запрос к
/api/v1/auth/businessПолучение филиала: Из ответа авторизации сохраните первый элемент массива
branchesкакbranch_idПолучение Group ID: Вызовите
/api/v1/branches/{branch_id}для полученияgroup_idфилиалаНастройка товара-подарка: Для каждого заведения настройте товар-подарок (нулевой стоимости) для программы наград
Автоматическое обновление токенов: Настройте cron-задачу для вызова
/api/v1/auth/refresh_token
Что сохранить в памяти:
access_token- JWT токенbranch_id- ID филиалаgroup_id- Group ID филиалаgift_product_id- ID товара-подаркаrole- роль пользователя (для определения прав доступа)
Сценарий 1: Начисление бонусов (без списания)#
Начало работы смены#
При запуске кассы проверьте:
Наличие действительного токена (если истек - обновите)
Статус программы наград в филиале (проверьте
configuration.award.enabled)
При переходе к оплате чека#
Шаг 1: Запрос телефона клиента#
Кассир вводит номер телефона клиента в формате +77XXXXXXXXX
Шаг 2: Поиск клиента и получение информации#
# 1. Найти клиента
GET /api/v1/promoters/find?phone={phone}&branch_id={branch_id}
# 2. Получить баланс в филиале
GET /api/v1/branches/{branch_id}/private/balance?user_id={user_id}&group_id={group_id}
# 3. Получить процент кешбека
GET /api/v1/branches/{branch_id}/cashback?user_id={user_id}
# 4. Получить информацию о штампах (если награды включены)
GET /api/v1/branches/{branch_id}/customers/{user_id}/award
Шаг 3: Отображение информации кассиру#
╔══════════════════════════════════════╗
║ Клиент: Иван Иванов ║
║ Телефон: +77071234567 ║
║ Баланс бонусов: 2,500 тенге ║
║ Кешбек: 5% (макс. 100 тенге) ║
║ Штампы: 7 из 10 для награды ║
║ ║
║ □ Начислить штампики [1] шт ║
║ ║
║ Покупка: 2,000 тенге ║
║ Будет начислено: 100 тенге ║
╚══════════════════════════════════════╝
Шаг 4: Обработка штампиков#
Если
received_stamp_count==stamp_count→ показать кнопку «Выдать награду»Иначе → показать checkbox «начислить штампики» с полем ввода количества
При выборе начисления штампиков проверить:
текущие + начисляемые >= требуемых→ показать кнопку «Выдать награду»
После завершения оплаты#
Шаг 5: Создание транзакции#
POST /api/v1/branches/{branch_id}/cash/order
{
"user_id": 1460220481801031680,
"amount": 2000,
"bonus_amount": 0,
"comment": "Покупка в кассе #1",
"user_phone": "+77077000087",
"add_stamp": true,
"stamp_count": 1,
"give_award": false
}
Шаг 6: Завершение транзакции#
POST /api/v1/orders/{order_id}/cash/complete
{
"use_balance": false,
"amount": 0,
"payment_method": "card"
}
Информация в чеке#
════════════════════════════════════════
КАФЕ "АРОМАТ"
════════════════════════════════════════
Товары: 2,000 тг
────────────────────────────────────────
ИТОГО К ОПЛАТЕ: 2,000 тг
Оплачено картой: 2,000 тг
════════════════════════════════════════
БОНУСНАЯ ПРОГРАММА SAGI:
• Начислены бонусы: 100 тг
• Добавлено штампиков: 1
• Штампов накоплено: 8/10
════════════════════════════════════════
Сценарий 2: Списание бонусов с кодом подтверждения#
Шаги 1-3: Аналогично сценарию 1#
Шаг 4: Отображение с возможностью списания#
╔══════════════════════════════════════╗
║ Клиент: Иван Иванов ║
║ Баланс бонусов: 2,500 тенге ║
║ ║
║ Списать бонусы: [1000] тенге ║
║ Максимально: 2,500 тенге ║
║ ║
║ □ Начислить штампики [1] шт ║
║ ║
║ К доплате: 1,000 тенге ║
╚══════════════════════════════════════╝
Шаг 5: Отправка кода подтверждения (если требуется)#
# Если send_code_for_use_cashback = true и bonus_amount > 0
POST /api/v1/customers/{user_id}/send-use-cashback-code
{
"branch_id": 1234567890123456
}
╔══════════════════════════════════════╗
║ Код подтверждения отправлен клиенту ║
║ на номер +77071234567 ║
║ ║
║ Введите код: [______] ║
╚══════════════════════════════════════╝
Шаг 6: Создание транзакции с кодом#
POST /api/v1/branches/{branch_id}/cash/order
{
"user_id": 1460220481801031680,
"amount": 2000,
"bonus_amount": 1000,
"comment": "Покупка в кассе #1",
"user_phone": "+77077000087",
"add_stamp": true,
"stamp_count": 1,
"give_award": false,
"use_balance_code": "123456"
}
Шаг 7: Завершение со списанием#
POST /api/v1/orders/{order_id}/cash/complete
{
"use_balance": true,
"amount": 1000,
"payment_method": "mixed"
}
Информация в чеке при списании#
════════════════════════════════════════
КАФЕ "АРОМАТ"
════════════════════════════════════════
Товары: 2,000 тг
────────────────────────────────────────
Списано бонусов: -1,000 тг
К доплате: 1,000 тг
Оплачено картой: 1,000 тг
════════════════════════════════════════
БОНУСНАЯ ПРОГРАММА SAGI:
• Списано бонусов: 1,000 тг
• Начислены бонусы: 50 тг
• Добавлено штампиков: 1
════════════════════════════════════════
Сценарий 3: Выдача награды#
При достаточном количестве штампов#
Отображение кнопки «Выдать награду»#
╔══════════════════════════════════════╗
║ Клиент: Иван Иванов ║
║ Штампы: 10 из 10 (готов) ║
║ ║
║ [ВЫДАТЬ НАГРАДУ] ║
║ "Бесплатный кофе" ║
║ ║
║ Покупка: 2,000 тенге ║
╚══════════════════════════════════════╝
При выдаче награды#
# 1. Добавить товар-подарок в чек автоматически
# Товар с нулевой стоимостью
# 2. Создать транзакцию с выдачей награды
POST /api/v1/branches/{branch_id}/cash/order
{
"user_id": 1460220481801031680,
"amount": 2000,
"bonus_amount": 0,
"comment": "Покупка + награда",
"user_phone": "+77077000087",
"add_stamp": false,
"stamp_count": 0,
"give_award": true
}
# 3. Выдать награду
POST /api/v1/branches/{branch_id}/awards/{award_id}/give
{
"user_id": 1460220481801031680,
"stamp_count": 10
}
# 4. Завершить транзакцию
POST /api/v1/orders/{order_id}/cash/complete
{
"use_balance": false,
"amount": 0,
"payment_method": "card"
}
Чек с выдачей награды#
════════════════════════════════════════
КАФЕ "АРОМАТ"
════════════════════════════════════════
Товары: 2,000 тг
ПОДАРОК: Кофе американо 0 тг
────────────────────────────────────────
ИТОГО К ОПЛАТЕ: 2,000 тг
Оплачено картой: 2,000 тг
════════════════════════════════════════
БОНУСНАЯ ПРОГРАММА SAGI:
• Начислены бонусы: 100 тг
• Выдана НАГРАДА за 10 штампов!
• Штампов осталось: 0/10
════════════════════════════════════════
Сценарий 4: Обработка ошибок#
При неверном коде подтверждения#
HTTP 400 Bad Request
{
"code": 3025,
"message": "code for using private balance is wrong"
}
Действие: Показать сообщение «Неверный код. Попробуйте еще раз» и повторить ввод.
При недоступности API#
╔══════════════════════════════════════╗
║ ВНИМАНИЕ ║
║ ║
║ Сервис бонусов временно недоступен ║
║ Транзакция проведена БЕЗ начисления ║
║ бонусов ║
║ ║
║ Обратитесь в службу поддержки ║
╚══════════════════════════════════════╝
При ошибке настройки подарка#
╔══════════════════════════════════════╗
║ Товар-подарок не настроен ║
║ ║
║ Обратитесь к администратору ║
║ для настройки программы наград ║
╚══════════════════════════════════════╝
Сценарий 5: Отмена и возвраты#
Полная отмена транзакции#
POST /api/v1/orders/{order_id}/revert-transaction
# Возвращает все начисленные бонусы и штампы
Частичный возврат#
PATCH /api/v1/orders/{order_id}/refund
{
"amount": 500 # Возврат 500 тенге из 2000
}
# Возвращает пропорциональные бонусы, штампы остаются
Особенности реализации#
Проверки перед началом работы#
Токен валиден: Проверять срок действия токена при запуске смены
Настройки филиала: Загружать настройки наград (
configuration.award.enabled)Товар-подарок: Проверять наличие настроенного товара для наград
Логирование для аудита#
[2024-03-15 14:30:00] USER_SEARCH: phone=+77071234567, found=true, user_id=1460220481801031680
[2024-03-15 14:30:15] BONUS_TRANSACTION: order_id=60f1b2b3c4d5e6f7g8h9i0j1, amount=2000, bonus_used=0, cashback=100
[2024-03-15 14:30:20] STAMP_ADDED: user_id=1460220481801031680, stamps=1, total=8/10
[2024-03-15 14:30:25] TRANSACTION_COMPLETE: order_id=60f1b2b3c4d5e6f7g8h9i0j1, status=completed
Безопасность#
Никогда не логировать коды подтверждения
Хранить токены в безопасном месте
Очищать поля ввода кода после использования
Ограничить время ожидания кода подтверждения (5 минут)
Производительность#
Кешировать информацию о филиале (group_id, настройки)
Использовать локальное хранение для токенов
Реализовать повторные попытки для критичных операций
Показывать индикаторы загрузки для API запросов
Сценарий 6: Управление токенами авторизации#
Проактивное обновление токенов#
Настройка автоматического обновления#
# Пример cron-задачи (каждые 30 минут)
*/30 * * * * /path/to/refresh_token_script.sh
Скрипт обновления токена#
#!/bin/bash
CURRENT_TOKEN="your_current_token"
API_BASE="https://gateway.sagi.kz"
# Попытка обновления токена
RESPONSE=$(curl -s -w "%{http_code}" -X POST "$API_BASE/api/v1/auth/refresh_token" \
-H "Authorization: Bearer $CURRENT_TOKEN" \
-o /tmp/refresh_response.json)
HTTP_CODE="${RESPONSE: -3}"
if [ "$HTTP_CODE" -eq 200 ]; then
# Успешное обновление - сохранить новый токен
NEW_TOKEN=$(jq -r '.token' /tmp/refresh_response.json)
echo "$NEW_TOKEN" > /secure/path/token_storage
logger "Token refreshed successfully"
else
# Ошибка обновления - требуется повторная авторизация
logger "Token refresh failed with code $HTTP_CODE - manual re-authentication required"
# Уведомить администратора
fi
Обработка истечения токена в POS#
Проверка токена перед критическими операциями#
╔══════════════════════════════════════╗
║ Проверка авторизации... ║
║ ║
║ Токен истек или недействителен ║
║ ║
║ [Обновить токен] [Войти заново] ║
╚══════════════════════════════════════╝
Автоматическое обновление при ошибке 401#
# При получении HTTP 401 от любого API:
POST /api/v1/auth/refresh_token
# Если успешно → повторить исходный запрос
# Если ошибка → показать форму авторизации
Безопасность токенов#
Хранение токенов#
Зашифрованное хранилище: Не сохранять токены в открытом виде
Ограниченное время жизни: Токены истекают каждые 24 часа
Ротация: Автоматическое обновление предотвращает компрометацию
Мониторинг токенов#
[2024-03-15 09:00:00] TOKEN_REFRESH: success, expires_at=2024-03-16T09:00:00Z
[2024-03-15 09:30:00] TOKEN_REFRESH: success, expires_at=2024-03-16T09:30:00Z
[2024-03-15 10:00:00] TOKEN_REFRESH: failed, code=401, action=re-auth_required
Сценарий 7: Работа с процентами кешбека#
Динамический расчет кешбека#
Получение актуального процента#
# Перед каждой транзакцией проверять актуальный процент
GET /api/v1/branches/{branch_id}/cashback?user_id={user_id}&type=direct
Отображение информации о кешбеке#
╔══════════════════════════════════════╗
║ Клиент: Иван Иванов ║
║ Кешбек: 5% (макс. 500 тенге за день) ║
║ ║
║ Условия кешбека: ║
║ • Мин. сумма покупки: 1000 тенге ║
║ • Лимит транзакций: 5 в день ║
║ • Использовано сегодня: 2/5 ║
╚══════════════════════════════════════╝
Обработка ограничений кешбека#
Превышение дневного лимита#
╔══════════════════════════════════════╗
║ ВНИМАНИЕ ║
║ ║
║ Клиент превысил дневной лимит ║
║ транзакций с кешбеком ║
║ ║
║ Кешбек по этой покупке: 0% ║
║ Лимит восстановится завтра ║
╚══════════════════════════════════════╝
Клиент в черном списке#
# Ответ API при клиенте в черном списке
HTTP 400 Bad Request
{
"code": 3010,
"message": "phone number is in blacklist"
}
Градационный кешбек#
Расчет по сумме покупок#
0-5,000 тенге/месяц: 3% кешбек
5,001-15,000 тенге/месяц: 5% кешбек
15,001+ тенге/месяц: 7% кешбек
Расчет по количеству транзакций#
1-10 покупок/месяц: базовый процент
11-25 покупок/месяц: +1% к базовому
26+ покупок/месяц: +2% к базовому
ПРИМЕЧАНИЕ: Приведенные выше суммы и проценты являются примерами. Все параметры градационного кешбека (пороги сумм, проценты, периоды) настраиваются индивидуально для каждого бизнеса в личном кабинете администратора.