С чего начать
Для подключения достаточно основного API-ключа, адреса API и готового комплекта выше. Резервный ключ хранится отдельно и используется только если основной потребуется заменить.
Основной адрес
https://api.installios.ru/v1
Используйте его во всех новых интеграциях.
Резервный маршрут
https://installios.ru/api/partner/v1
Оставлен для совместимости и аварийной проверки.
Заголовки каждого запроса
Authorization: Bearer iosp_ВАШ_ОСНОВНОЙ_КЛЮЧ Accept: application/json Content-Type: application/json X-Request-ID: ваш-идентификатор-запроса
Не размещайте ключ в браузере или мобильном приложении. Все запросы выполняются только с вашего сервера. API-ключ, webhook-секрет, логины, пароли и коды нельзя писать в журналы.
Навигация
Как проходит одна установка
fallback_url — готовая нейтральная инструкция с QR, реквизитами и кнопками установки.code.ready.Первый тест за 15 минут
Тестовый партнёр работает в sandbox: сумма рассчитывается, но реальный долг не создаётся.
- Скачайте комплект и укажите ключ в
.envили в окружении Postman. - Запустите
START_TEST_WINDOWS.cmdлибо коллекцию Postman «01 — безопасная проверка». - Убедитесь, что API отвечает, каталоги получены, заявка создана, повтор не создал дубль, страница и QR открываются.
- Для реального теста кода сначала вызовите
POST /orders/{id}/code-waits, затем запросите код на iPhone и проверяйтеGET /code-waits/{wait_id}.
Успешный результат: ответы 2xx, повторный заказ вернул тот же id, код не старше 60 секунд, а balance.debt_kopecks в sandbox остался равен нулю.
1. Каталоги и приложения
GET/catalogs
curl -sS "$API_BASE/catalogs" \ -H "Authorization: Bearer $API_KEY"
{
"ok": true,
"data": {
"catalogs": [
{"id": "cat_...", "name": "maxim", "applications_count": 18}
]
}
}
GET/catalogs/{catalog_id}/applications
{
"ok": true,
"data": {
"catalog": {"id": "cat_...", "name": "maxim"},
"applications": [{"id": "app_...", "name": "ВКонтакте"}]
}
}
API намеренно не передаёт внутренние UID, IPA-адреса, версии и технические данные учёток.
2. Создание заявки
POST/orders
Автоматический выбор учёток — рекомендуемый режим
{
"external_order_id": "SC-10482",
"source_mode": "auto",
"applications": [
{"id": "app_..."},
{"id": "app_..."}
]
}
Ручной выбор каталога
{
"external_order_id": "SC-10483",
"source_mode": "manual",
"applications": [
{"id": "app_...", "catalog_id": "cat_..."}
]
}
В одной заявке можно передать до 50 приложений. API сам объединит их в группы по Apple-учёткам.
Защита от дублей: при сетевом повторе отправляйте тот же external_order_id. Первый ответ будет HTTP 201, повторный — HTTP 200 с тем же id. Новый внешний номер при повторе создавать нельзя.
Что приходит в ответе
idзаявки и актуальный срокexpires_at;initial_ttl_seconds— срок до первого ожидания кода,code_window_ttl_seconds— срок после него;- группы по учёткам и приложения внутри них;
- основная и резервная короткие ссылки каждого приложения;
fallback_url— готовая полная инструкция для клиента;qr_urlдля открытия этой страницы на другом устройстве;- расчётная и фактически начисленная сумма в копейках.
Таймер пилота «Сервис»: новая заявка действует 24 часа. Первый успешный вызов ожидания кода сокращает срок всей заявки, клиентской страницы и всех установочных ссылок до 1 часа от этого момента. Повторные вызовы час не добавляют. Всегда сохраняйте новое order_expires_at из ответа API.
3. Реквизиты, клиентская страница и продление
GET/orders/{id}/credentials
Возвращает логин и пароль отдельно для каждой группы. Чтение доступно только пока заявка активна и всегда фиксируется в аудите.
POST/orders/{id}/extend
Один раз создаёт новые реквизиты и ссылки на настроенный первоначальный срок. Все прежние ссылки заявки сразу отключаются.
Политика хранения: реквизиты и коды используйте только в оперативной памяти. После окончания заявки их необходимо удалить из вашей системы, логов, аналитики и резервных копий.
Если не хотите собирать собственный интерфейс установки, просто откройте клиенту fallback_url. На странице уже есть QR, инструкция, логин, пароль, получение кода и обе ссылки каждого приложения.
4. Получение кода
Правильный порядок: сначала API включает ожидание, затем клиент запрашивает код на iPhone. Код, появившийся раньше ожидания, не выдаётся.
POST/orders/{id}/code-waits
Idempotency-Key: code-SC-10482-group-1
{"group_id": "grp_..."}
В ответе приходит order_expires_at. При первом успешном запуске это новый срок всей заявки; обновите таймер в своей системе и больше не используйте прежнее значение expires_at.
Сохраните полученный wait_id и проверяйте его раз в секунду:
GET/code-waits/{wait_id}
| Статус | Что делать |
|---|---|
active | Продолжать polling раз в секунду. Клиент уже может запросить код. |
succeeded | Сразу показать поле code клиенту. Учитывайте valid_for_seconds. |
code_expired | Код старше минуты. Создать новое ожидание и попросить клиента запросить новый код. |
timed_out | За время ожидания код не появился. Повторить процесс по действию клиента. |
Активное ожидание работает до 5 минут. На одной учётке одновременно может ждать любое количество клиентов; один свежий код получат все ожидания, включённые до его появления. Для одной группы разрешено не более трёх успешных получений.
5. Webhook — необязательное ускорение
Polling полностью поддерживается. Webhook позволяет получать события быстрее и использовать polling только как страховку.
События: order.created, order.extended, order.expired, code.ready, billing.charged, billing.reversed, payment.recorded, order.completed.
| Заголовок | Назначение |
|---|---|
X-InstallIOS-Event | Уникальный ID события. Используйте для защиты от повторной обработки. |
X-InstallIOS-Timestamp | Unix-время создания подписи. |
X-InstallIOS-Signature | sha256=HMAC-SHA256(secret, timestamp + "." + raw_body) |
Проверяйте подпись по точному сырому телу до JSON-разбора, отклоняйте слишком старый timestamp и отвечайте HTTP 2xx только после безопасного сохранения события. Повторы одного X-InstallIOS-Event не должны менять результат.
6. Финансы
GET/balance · GET/ledger · GET/ledger.csv
Тариф фиксируется для каждого приложения при создании заявки. В рабочем режиме вся сумма заявки начисляется один раз после первого успешного кода. Частичные платежи уменьшают долг, а переплата автоматически становится авансом.
Денежные поля передаются целым числом в копейках: 10000 = 100 ₽.
Ошибки и безопасные повторы
| HTTP | Что означает | Что делать |
|---|---|---|
| 400 | Неверные поля | Исправить запрос, не повторять без изменений. |
| 401 | Ключ отключён, ошибочен или IP не разрешён | Проверить основной ключ; по согласованию перейти на резервный. |
| 404 | ID не найден или недоступен партнёру | Обновить каталог и проверить ID. |
| 409 / 410 | Заявка истекла, уже продлена или действие конфликтует | Прочитать текущую заявку и показать понятное состояние оператору. |
| 429 | Лимит запросов или успешных кодов | Для общего лимита ждать Retry-After; лимит кодов не обходить. |
| 500 / 503 | Временная серверная ошибка | Повторить через 2, 5, 15 и 30 секунд с прежними идентификаторами. |
Каждый ответ содержит request_id. Передавайте его владельцу при разборе ошибки, но не прикладывайте ключи, реквизиты и коды.
Чек-лист перед рабочим запуском
- Ключ находится только в серверном секрет-хранилище.
- Одинаковый
external_order_idне создаёт дубль заявки. - Клиентская страница и QR открываются на iPhone.
- Ожидание кода включается до запроса на iPhone.
- Код старше 60 секунд нигде не показывается.
- Реквизиты и коды не попадают в логи и удаляются после заявки.
- Webhook-подпись проверяется, а повтор события безопасен.
- В sandbox долг не увеличивается.
- В рабочем тесте одна заявка создаёт ровно одно начисление.