Чем песочница отличается от рабочего режима и как перейти без потерь

Обновлено 6 июля 2026 · Начало работы · Версия в Markdown
Содержание
  1. Что такое песочница и зачем она нужна?
  2. Клиент не получил счёт? Сначала проверьте режим
  3. Как включить рабочий режим
  4. Тестовые организации и их ключи удаляются — как не потерять настройки
  5. Технические отличия песочницы (для разработчиков)
  6. Полный цикл прогона в песочнице (для разработчиков)
  7. Возврат в песочнице: по-настоящему, а не симуляцией
  8. QR-счёт: создание и отсканирование в песочнице
  9. Проверка номера телефона: sandbox-моки
  10. Чек-лист выхода в рабочий режим
  11. Частые ошибки
  12. Вопросы и ответы

Что такое песочница и зачем она нужна?

Песочница — это режим, в котором ApiPay работает «понарошку»: вы создаёте счета, получаете вебхуки, смотрите статусы — но в Kaspi ничего не уходит, и настоящих денег нет. Это безопасная среда, где можно отладить интеграцию (сайт, Telegram-бот, CRM), не рискуя выставить реальный счёт живому человеку.

Оплату тестового счёта вы имитируете сами: в личном кабинете отметьте счёт оплаченным или отменённым, а из кода — методом simulate-status (подробный прогон — в разделе для разработчиков ниже). Так проверяются все ветки: успех, отмена, истечение, ошибка.

Песочница бесплатна всегда: таймер триала на неё не идёт, подписка не нужна. Многие живут в ней неделями, пока пишут интеграцию, — это нормально.

Гоняете цикл автономным ИИ-агентом? Для этого есть отдельное руководство «Интеграция с ApiPay с помощью ИИ» — эта статья про ручной прогон человеком.

Клиент не получил счёт? Сначала проверьте режим

Самый частый сценарий: «всё подключили, счёт создаётся, а оплата в Kaspi не приходит». В 9 из 10 случаев включён тестовый режим. Проверьте три признака:

  1. Плашка в кабинете. Вверху горит «ТЕСТОВЫЙ РЕЖИМ … Счета не передаются в Kaspi» — это он.
  2. Ответ API. У счёта is_sandbox: true.
  3. Номер счёта. kaspi_invoice_id начинается с SANDBOX-.

Любой из трёх признаков означает: счёт живёт в песочнице, покупатель его не увидит. Включите рабочий режим — и всё «взлетит» без единой правки кода.

Как включить рабочий режим

  1. Убедитесь, что кассир подключён: Настройки → «Авторизация Kaspi» (какой номер подойдёт — в статье «Требования к номеру кассира»). Без кассира счетам физически не через что уходить в Kaspi.
  2. В Настройках переключите режим на «Рабочий».
  3. Выставьте пробный счёт на свой личный номер и оплатите на минимальную сумму — убедитесь, что push пришёл и вебхук отработал.

Переключение обратимо: можно вернуться в тестовый режим и снова выйти — например, чтобы проверить новую фичу интеграции. Аккаунт, API-ключ и настройки вебхука при этом остаются те же: отдельного «sandbox-ключа» в ApiPay нет.

С момента активации рабочего доступа у вас есть 3 бесплатных дня триала (при самостоятельном подключении кассира они включаются сразу), дальше — тариф. Подробности — в статье «Тестовый период» (/guides/testovyy-period).

Тестовые организации и их ключи удаляются — как не потерять настройки

Это самое важное место статьи для тех, кто работает через партнёрский API (платформы, CRM, white-label).

У обычного клиента (личный кабинет apipay.kz) всё просто: режим — переключатель, ключ один и тот же, ничего не пропадает.

У партнёров иначе. Тестовые организации — отдельные сущности со своими API-ключами. При переводе партнёрского аккаунта в production все тестовые организации удаляются полностью — вместе с их тестовыми счетами, возвратами, подписками — а их API-ключи деактивируются. Это сделано специально («чистый старт»), восстановлению они не подлежат. Кроме того, тестовая организация архитектурно не может стать боевой: ключи, выданные тестовой организации, с боевой никогда не заработают.

Чтобы переход прошёл без нервов:

  • Не храните ничего ценного в тестовых организациях. Всё, что там лежит, — расходный материал.
  • Вынесите конфигурацию наружу. URL вебхука, названия организаций, соответствия «ваш клиент → организация ApiPay» держите в своей системе, а не «в памяти» тестовой среды.
  • Планируйте перевыпуск ключей. После перехода создайте боевые организации и выпустите для них новые ключи и вебхук-секреты. Полный API-ключ показывается один раз — при создании; дальше видна только маска (key_hint). Сразу кладите его в менеджер секретов.
  • Помните про лимиты песочницы: до 20 тестовых организаций на партнёра и до 500 тестовых счетов на организацию.

Если после перехода «ключ внезапно перестал работать» — почти всегда это один из двух штатных случаев: ключ принадлежал удалённой тестовой организации, либо ключ перевыпустили повторным вызовом (повторная выдача ключа организации перегенерирует его — старый мгновенно умирает).

Технические отличия песочницы (для разработчиков)

  • Вебхуки-ретраи короче: в песочнице 3 попытки доставки (через 5 и 15 секунд), в рабочем режиме — 11 попыток с нарастающими интервалами до 1 часа. Если ваш endpoint «просыпается» медленно, в тесте вы можете не дождаться повтора — это отличие среды, а не баг.
  • Симуляция статусов — метод simulate-status (для счёта по номеру) и параметр simulate при создании QR-счёта; полный прогон — в разделе «Полный цикл прогона» ниже.
  • Подписки в песочнице доступны только при верифицированной организации — иначе API вернёт 400.
  • Имена тестовых организаций генерируются автоматически (вида «ТОО Синие птицы») — так их не спутаешь с боевыми.
  • Настройка вебхуков, HMAC-подпись и локальное тестирование — в статье «Настройка вебхуков ApiPay» (/guides/nastroyka-webhookov-apipay) и на странице /local-testing.

Полный цикл прогона в песочнице (для разработчиков)

Прогоните перед продом весь путь реальными запросами: создать счёт → дождаться pending → симулировать статус → проверить вебхук → сделать возврат. Каждый шаг — обычный запрос к публичному API (https://api.apipay.kz/api/v1, заголовок X-API-Key), без единого телефонного номера живого человека.

Главный нюанс порядка — processing → pending перед симуляцией. POST /invoices (счёт по номеру) обрабатывается асинхронно: 201 приходит со status: "processing". Метод simulate-status переводит счёт из pending, поэтому сразу после создания симулировать нельзя — сначала опросите GET /invoices/{id} (лимит 1000/мин, читает из кэша) до status: "pending". Симуляция не-pending счёта вернёт 400 invalid_status_transition (в ответе — current_status и allowed_from: ["pending"]).

BASE="https://api.apipay.kz/api/v1"
KEY="YOUR_API_KEY"

ID=$(curl -s -X POST "$BASE/invoices" -H "X-API-Key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount":10000,"phone_number":"87770000001","description":"Sandbox test"}' | jq -r '.id')

until [ "$(curl -s "$BASE/invoices/$ID" -H "X-API-Key: $KEY" | jq -r '.status')" = "pending" ]; do sleep 1; done

curl -s -X POST "$BASE/invoices/$ID/simulate-status" -H "X-API-Key: $KEY" \
  -H "Content-Type: application/json" -d '{"status":"paid"}'

curl -s "$BASE/webhook-logs?invoice_id=$ID&event=invoice.status_changed" \
  -H "X-API-Key: $KEY" | jq '.data[] | {event, status, response_status}'

curl -s -X POST "$BASE/invoices/$ID/refund" -H "X-API-Key: $KEY" \
  -H "Content-Type: application/json" -d '{"amount":5000,"reason":"Sandbox refund"}'

Метод POST /invoices/{id}/simulate-status — только для тестовых счетов (is_sandbox: true; боевой счёт → 403 not_sandbox), свой лимит 60 запросов/мин на ключ (общий бюджет 200/мин не тратит). Тело — { "status": <enum> }; опционально kaspi_source_type (GOLD|RED|LOAN|BUSINESSACCOUNT|BANKINTEGRATIONACCOUNT) и kaspi_sale_type (Remote|QR|Static|Restaurant); при paid без них они выбираются случайно.

status Что происходит со счётом Какой вебхук уходит Условия / ошибки
paid → терминальный paidpaid_at) invoice.status_changed (paid) из pending
cancelled → терминальный cancelled invoice.status_changed (cancelled) из pending
expired → терминальный expired invoice.status_changed (expired) из pending
error → терминальный error, error_code: sandbox_simulated_error, error_message (свой текст параметром error_message ≤255; дефолт «Симулированная ошибка (sandbox).») invoice.status_changed (error) — как при реальной ошибке из pending
qr_scanned остаётся pending (транзиентное суб-событие) invoice.qr_scanned (qr_substate: "scanned") только QR-счёт: не-QR → 400 not_qr_invoice; повтор → 400 already_scanned

Критерий успеха каждого шага — в GET /webhook-logs по нужному event появляется запись status: success.

Возврат в песочнице: по-настоящему, а не симуляцией

Возврат — единственная операция цикла, которую в песочнице делают реальным запросом POST /invoices/{id}/refund (полный или частичный amount, опц. reason, опц. позиционный return_items[]). Отдельного simulate для возврата нет. Возврат возможен только у счёта в paid — поэтому порядок такой: simulate-status paid → затем refund.

В песочнице бэкенд сам доставляет вебхуки возврата: invoice.refunded (со status: completed либо failed + refund.error_code при неудаче) и — на первый частичный возврат — дополнительно invoice.status_changed со status: partially_refunded. Проверить возвраты по счёту — GET /invoices/{id}/refunds. Нюанс ретраев: refund-вебхуки в песочнице ретраятся по полной боевой сетке (11 попыток), в отличие от invoice-вебхука (3 попытки в песочнице).

QR-счёт: создание и отсканирование в песочнице

  • Создать QR-счётPOST /invoices/qr: запрос синхронный, 201 приходит сразу со status: "pending" и QR-полями (отдельного pending-вебхука у QR нет), description ≤100 символов.
  • Sandbox-шорткат: в теле POST /invoices/qr можно передать simulate: paid|cancelled|expired — QR-счёт создастся сразу в терминальном статусе с мгновенной отправкой вебхука (когда сам скан проверять не нужно).
  • Отсканирование: чтобы проверить событие invoice.qr_scanned, вызовите simulate-status со status: qr_scanned (только для QR; статус остаётся pending, один раз — повтор даст 400 already_scanned). После скана транзиентно возможны и paid, и cancelled — симулируйте нужную ветку следом.
  • Возврат и отмена QR-счёта не поддерживаются — это ограничение самого QR-флоу.

Проверка номера телефона: sandbox-моки

POST /clients/check в песочнице не ходит в Kaspi и ничего не пишет в кэш/счётчики — отдаёт детерминированный ответ ровно по двум номерам:

  • 87770000001{ "has_kaspi": true, "client_name": "Иван И." }
  • 87770000002{ "has_kaspi": false, "client_name": null }
  • любой другой валидный номер → { "has_kaspi": false, "client_name": null }

Это единственные телефонные значения, которые стоит использовать в тестах. Формат имени Kaspi — имя и первая буква фамилии с точкой; полная фамилия не отдаётся.

Чек-лист выхода в рабочий режим

Перед переключением убедитесь, что в песочнице прошло:

  • [ ] POST /invoices → счёт дошёл до pending (поллинг GET /invoices/{id} работает).
  • [ ] Симулированы все терминалы — paid, cancelled, expired, error — и по каждому в GET /webhook-logs есть status: success с нужным event.
  • [ ] Для QR (если используете): qr_scanned → затем paid/cancelled.
  • [ ] Возврат: simulate-status paidrefund → пришёл invoice.refunded (completed), а первый частичный дал partially_refunded.
  • [ ] Приёмник вебхуков проверяет HMAC-подпись по raw body и отвечает 2xx быстрее 5 секунд (детали — «Настройка вебхуков ApiPay»).
  • [ ] Обработчик дедуплицирует по (invoice.id, invoice.status) и идемпотентен.
  • [ ] Ветки ошибок разобраны по error_code (включая виденный sandbox_simulated_error).
  • [ ] POST /clients/check используется точечно, а не перебором.
  • [ ] Переключение — в кабинете; после него is_sandbox станет false, а simulate-status перестанет быть доступен — это ожидаемо.

Частые ошибки

  • Ждать реальный push Kaspi в песочнице. Не придёт by design — имитируйте оплату сами.
  • Включать рабочий режим до подключения кассира. Сначала кассир (Настройки → «Авторизация Kaspi»), потом режим.
  • «Оплатил тариф, а счета всё ещё SANDBOX-». Оплата тарифа не переключает режим сама — проверьте переключатель в Настройках. Если рабочий режим включён, а счета всё равно тестовые — напишите в поддержку, разберём.
  • Партнёру: перейти в production, не сохранив конфигурацию. Тестовые организации и ключи удалятся штатно — подготовьтесь по чек-листу выше.
  • Потерять API-ключ. Он показывается один раз при создании. Не записали — перевыпустите ключ (старый перестанет работать).
  • Тестировать «на проде» на счетах клиентов. Для экспериментов есть песочница — она для этого и существует.

Вопросы и ответы

Песочница платная? Сколько можно в ней сидеть?

Бесплатна всегда, по времени не ограничена. Лимит — 500 тестовых счетов на организацию.

Нужен ли отдельный API-ключ для песочницы?

Нет. У клиента личного кабинета ключ один и тот же для обоих режимов — переключается только режим. Отдельные тестовые ключи есть только у тестовых организаций партнёров, и они удаляются при переходе в production.

Можно ли вернуться из рабочего режима в тестовый?

Да, переключение обратимо в обе стороны. Счета, созданные в песочнице, останутся тестовыми навсегда.

Идёт ли триал, пока я в песочнице?

Нет. 3 бесплатных дня относятся к рабочему доступу; песочница бесплатна независимо от них.

Что произойдёт с тестовыми счетами при переходе в рабочий режим?

У клиента ЛК они останутся в истории с пометкой тестовых. У партнёра при переходе в production тестовые организации удаляются целиком вместе со счетами и ключами.

Как понять из кода, что счёт тестовый?

По полю is_sandbox: true в ответе API и вебхуке, и по префиксу SANDBOX- в kaspi_invoice_id.

Почему сразу после создания счёт нельзя симулировать?

POST /invoices возвращает счёт в статусе processing, а simulate-status переводит счёт из pending. Опросите GET /invoices/{id} до pending, потом симулируйте — иначе получите 400 invalid_status_transition с allowed_from: ["pending"].

Как проверить номер телефона в песочнице, не имея реального клиента?

Используйте детерминированные моки POST /clients/check: 87770000001has_kaspi: true (имя «Иван И.»), 87770000002has_kaspi: false. Любой другой валидный номер вернёт has_kaspi: false. В Kaspi запрос при этом не уходит.

Интеграция с ИИ

Не настраивайте вручную — поручите ИИ

Скопируйте готовый промпт и вставьте своему ИИ-ассистенту — он подключит приём платежей примерно за 15 минут. Настраивает ИИ, а не вы.

Остались вопросы — напишите нам в WhatsApp: +7 708 516 74 89. Отвечаем быстро, без звонков.

Написать в WhatsApp

Для разработчика. Полная спецификация API — apipay.kz/docs. Эта статья в Markdown — /guides/pesochnitsa-i-rabochiy-rezhim.md. Справочник фактов для ИИ-агента — apipay.kz/llms.txt.