API eSIM для банків
REST API дозволяє банку продавати eSIM у власному застосунку: показувати каталог операторів і тарифів, резервувати профіль на час оплати, після успішної оплати отримувати дані активації (LPA-рядок і/або QR) для встановлення eSIM на пристрій клієнта.
Усі запити виконуються від імені вашого банку. Ідентифікатор банку береться з JWT — передавати bankId у тілі або query не потрібно.
Середовища
| Dev | Prod | |
|---|---|---|
| Base URL | https://admin-panel.dev.deeployalty.io/esim/v1 | https://admin-panel.deeployalty.io/esim/v1 |
Шляхи в цій інструкції вказані відносно base URL (без повторення /esim/v1).
Приклад: GET /operators → https://admin-panel.dev.deeployalty.io/esim/v1/operators.
- Формат запитів і відповідей:
application/json - Дати й час: ISO-8601 UTC (
2026-01-15T10:00:00.000Z)
Swagger (OpenAPI)
Інтерактивна документація з актуальними схемами:
| Dev | Prod | |
|---|---|---|
| Swagger UI | admin-panel.dev…/esim/v1/swagger | admin-panel…/esim/v1/swagger |
Авторизація
Використовується той самий bank JWT, що й для інших інтеграцій DeepLoyalty (Core). У кожному запиті:
Authorization: Bearer <access_token>Отримання токена: JWT авторизація. Доступ до dev/prod і облікові дані узгоджуються з вашим менеджером DeepLoyalty.
На API діє обмеження частоти запитів: при перевищенні ліміту сервіс повертає 429 Too Many Requests. Реалізуйте повтор з експоненційною затримкою.
Режим видачі eSIM (deliveryMode)
Для кожного банку DeepLoyalty налаштовує режим видачі профілю. Значення повертається в відповіді POST /orders/{orderId}/confirm у полі deliveryMode:
| Режим | Поведінка |
|---|---|
local | Банк отримує activationCode і/або QR і сам показує їх клієнту в застосунку |
qr_email | У запиті confirm обов’язковий customerEmail; QR додатково надсилається на цю адресу (один раз на замовлення) |
Змінити режим може лише команда DeepLoyalty під час підключення інтеграції.
Типовий сценарій
1. GET /operators
2. GET /operators/{code}/tariffs
3. POST /orders → резерв профілю (15 хв)
4. оплата на боці банка
5. POST /orders/{orderId}/confirm → дані активації
6. GET /orders/{orderId}/qr → опційно, якщо потрібен PNG/base64Якщо клієнт відмовився від оплати — викликайте POST /orders/{orderId}/cancel, щоб одразу повернути профіль у продаж (не чекайте 15 хвилин).
Довідник операторів
Метод: GET
Шлях: /operators
Повертає операторів, доступних для продажу вашому банку. Нижче — умовний приклад структури відповіді (реальні коди й назви дивіться у Swagger або в dev).
HTTP-код: 200
[
{
"code": "mob_operator_01",
"nameUk": "Мобільний оператор (приклад)",
"nameEn": "Mobile operator (example)",
"logoUrl": null,
"country": "UA"
}
]| Поле | Опис |
|---|---|
code | Стабільний код для всіх наступних запитів |
nameUk / nameEn | Назви мовами; nameEn ніколи не порожній (fallback на nameUk) |
logoUrl | URL логотипу; null — покажіть плейсхолдер у UI |
country | ISO 3166-1 alpha-2 або global |
Тарифи оператора
Метод: GET
Шлях: /operators/{operatorCode}/tariffs
HTTP-код: 200
[
{
"code": "TARIFF_START",
"name": "Стартовий тариф (приклад)",
"description": "Опис пакета для UI",
"price": 99.0,
"currency": "UAH",
"dataVolumeMb": 10240,
"dataUnlimited": false,
"voiceMinutes": 0,
"voiceUnlimited": false,
"smsCount": 0,
"smsUnlimited": false,
"validityDays": 30,
"available": true
}
]| Поле | Опис |
|---|---|
available | false — тариф тимчасово без запасу профілів; у UI краще показати неактивним |
price / currency | Вартість для відображення клієнту |
Помилки: 404 — оператора не існує.
Спроба створити замовлення на тариф з available: false → 503.
Створити замовлення
Метод: POST
Шлях: /orders
Резервує один eSIM-профіль на 15 хвилин. Дані активації не повертаються — лише після confirm.
Тіло запиту:
{
"operatorCode": "mob_operator_01",
"tariffCode": "TARIFF_START",
"externalId": "your-bank-order-id-0001"
}| Поле | Обов’язкове | Опис |
|---|---|---|
operatorCode | Так | З GET /operators |
tariffCode | Так | З каталогу тарифів |
externalId | Так | Унікальний ідентифікатор замовлення у межах вашого банку |
HTTP-код: 201 Created (або 200 OK при ідемпотентному повторі)
{
"orderId": "11111111-2222-4333-8444-555555555555",
"externalId": "your-bank-order-id-0001",
"operatorCode": "mob_operator_01",
"tariffCode": "TARIFF_START",
"status": "reserved",
"msisdn": "380000000001",
"reservedUntil": "2026-01-15T10:15:00.000Z",
"createdAt": "2026-01-15T10:00:00.000Z",
"confirmedAt": null
}Ідемпотентність
Повторний POST /orders з тим самим externalId не створює друге замовлення і не знімає другий профіль — повертається наявне замовлення (200 OK). Використовуйте один externalId на логічне замовлення при ретраях після таймауту.
| HTTP | Причина |
|---|---|
400 | Помилка валідації |
404 | Немає оператора або тарифу |
409 | externalId уже використано з іншими operatorCode / tariffCode |
503 | Немає вільних профілів для тарифу |
Статус замовлення
Метод: GET
Шлях: /orders/{orderId}
Повертає метадані замовлення без секретів активації.
HTTP-код: 200
{
"orderId": "11111111-2222-4333-8444-555555555555",
"externalId": "your-bank-order-id-0001",
"operatorCode": "mob_operator_01",
"tariffCode": "TARIFF_START",
"status": "confirmed",
"msisdn": "380000000001",
"reservedUntil": null,
"createdAt": "2026-01-15T10:00:00.000Z",
"confirmedAt": "2026-01-15T10:05:00.000Z"
}Помилки: 404 — замовлення не знайдено або належить іншому банку.
Підтвердити оплату
Метод: POST
Шлях: /orders/{orderId}/confirm
Викликається після успішної оплати на боці банка. Позначає профіль проданим і повертає дані активації.
Тіло запиту:
{
"customerEmail": "customer@example.com"
}| Поле | Обов’язкове | Опис |
|---|---|---|
customerEmail | Залежить від deliveryMode | Обов’язковий у режимі qr_email. Не зберігається в DeepLoyalty — лише для відправки QR на пошту в межах запиту. Використовуйте домен example.com лише в тестах; у проді — реальну адресу клієнта |
HTTP-код: 200
{
"orderId": "11111111-2222-4333-8444-555555555555",
"externalId": "your-bank-order-id-0001",
"status": "confirmed",
"operatorCode": "mob_operator_01",
"tariffCode": "TARIFF_START",
"msisdn": "380000000001",
"confirmedAt": "2026-01-15T10:05:00.000Z",
"deliveryMode": "local",
"esim": {
"iccid": "8900000000000000000",
"msisdn": "380000000001",
"pin1": "0000",
"activationCode": "LPA:1$smdp.example.invalid$PLACEHOLDER-ACTIVATION-DATA",
"qrCodeUrl": "https://admin-panel.dev.deeployalty.io/esim/v1/orders/11111111-2222-4333-8444-555555555555/qr"
}
}| Поле | Опис |
|---|---|
esim.activationCode | LPA-рядок для прямого встановлення eSIM |
esim.qrCodeUrl | URL QR-зображення на хості поточного середовища |
esim.pin1 | PIN SIM; значення залежить від оператора |
Повторний confirm повертає ті самі дані (безпечний ретрай). У режимі qr_email лист клієнту надсилається один раз.
| HTTP | Причина |
|---|---|
400 | qr_email без customerEmail |
404 | Замовлення не знайдено |
409 | Замовлення cancelled або expired |
QR-код
Метод: GET
Шлях: /orders/{orderId}/qr
Доступний після confirmed.
Query format | Відповідь |
|---|---|
png (за замовчуванням) | image/png, 512×512 |
base64 | JSON { "mimeType", "base64" } |
Якщо застосунок встановлює eSIM програмно — достатньо activationCode з confirm.
Помилки: 404 — не знайдено; 409 — ще не підтверджено.
Скасувати замовлення
Метод: POST
Шлях: /orders/{orderId}/cancel
Лише для неоплаченого замовлення. Профіль одразу повертається у продаж.
HTTP-код: 200
{
"orderId": "11111111-2222-4333-8444-555555555555",
"status": "cancelled",
"externalId": "your-bank-order-id-0001",
"operatorCode": "mob_operator_01",
"tariffCode": "TARIFF_START",
"msisdn": null,
"reservedUntil": null,
"createdAt": "2026-01-15T10:00:00.000Z",
"confirmedAt": null
}Помилки: 409 — замовлення вже confirmed.
Статуси замовлення
| Статус | Опис |
|---|---|
reserved | Профіль зарезервовано, очікується оплата |
confirmed | Оплачено, активацію видано (кінцевий стан) |
cancelled | Скасовано банком до оплати |
expired | Резерв прострочено (15 хв без confirm) |
Дозволені переходи: reserved → confirmed | cancelled | expired.
Формат помилок
{
"statusCode": 404,
"timestamp": "2026-01-15T10:00:00.000Z",
"path": "/esim/v1/orders",
"method": "POST",
"error": "Not Found",
"message": "Tariff UNKNOWN_TARIFF not found for operator mob_operator_01"
}message — рядок або масив рядків (валідація).
| HTTP | Опис |
|---|---|
401 | Відсутній або прострочений токен |
403 | Токен не прив’язаний до банку |
429 | Перевищено ліміт запитів |
Рекомендації для інтеграції
- Завжди передавайте стабільний
externalIdі повторюйте його при ретраях — це захист від подвійного резерву профілю. - Явно викликайте
cancel, якщо оплата не відбулася. - Не зберігайте
activationCodeдовше, ніж потрібно для показу клієнту; це секрет встановлення eSIM. 503трактуйте як «тимчасово немає в наявності», а не як помилку контракту API — запропонуйте інший тариф або повтор пізніше.- Персональні дані клієнта (зокрема email) DeepLoyalty не зберігає після обробки запиту.
Тестування на dev
Перед продакшеном узгодьте з менеджером DeepLoyalty:
- доступ до dev-середовища та bank JWT;
- режим
deliveryModeдля вашого банку; - наявність тестових профілів на потрібних тарифах.
Рекомендований мінімальний чек-лист:
- створення замовлення →
confirm→ встановлення eSIM зactivationCodeабо QR; - повтор
POST /ordersз тим самимexternalId; - повтор
confirmпісля обриву зв’язку; cancelнеоплаченого замовлення;- обробка
503при відсутності stock.