Купить пакет eSIM
/api/partner/v1/esim/orders- Scope
esim:write- Idempotency-Key
- обязателен
Резервирует цену пакета на вашем балансе и запускает выпуск.
Ответ — заказ в статусе processing, а не eSIM. Выпуск асинхронный: дождитесь события esim.issued или опрашивайте GET /esim/orders/{id}, пока status не уйдёт из processing.
До завершения заказа деньги на балансе зарезервированы, а не списаны. esim.issue_failed возвращает резерв целиком. operation.needs_review означает, что провайдер не дал однозначного ответа: eSIM может существовать, деньги остаются в резерве, мы разбираемся — не покупайте повторно.
Idempotency-Key обязателен. Повтор с тем же ключом возвращает исходный заказ — второй eSIM куплен не будет.
Тело запроса
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
external_id | string | нет | Ваш собственный идентификатор заказа. Необязателен; уникален в пределах аккаунта — вторая покупка с тем же external_id отклоняется с 409 idempotency_conflict. По нему заказ находится через GET /esim/orders/external/{external_id}, если наш ответ потерялся. (до 128 символов) |
package_id | string (uuid) | да | Из GET /esim/packages |
Пример запроса
BODY='{"package_id":"5b2f7c1a-3d4e-4f60-8a71-9c0d1e2f3a4b","external_id":"order-1001"}'
IDEM=$(uuidgen)
TS=$(date +%s)
SIG=$(printf '%s\n%s\n%s\n%s\n%s' "$TS" "POST" "/api/partner/v1/esim/orders" "$BODY" "$IDEM" \
| openssl dgst -sha256 -hmac "$PP_SECRET" -hex | awk '{print $NF}')
curl -sS -X POST "https://api.plativputi.com/api/partner/v1/esim/orders" \
-H "X-Key-Id: $PP_KEY_ID" \
-H "X-Timestamp: $TS" \
-H "X-Signature: $SIG" \
-H "Idempotency-Key: $IDEM" \
-H "Content-Type: application/json" \
-d "$BODY"import { randomUUID } from "node:crypto";
const res = await pp("POST", "/esim/orders", {
"package_id": "5b2f7c1a-3d4e-4f60-8a71-9c0d1e2f3a4b",
"external_id": "order-1001"
}, { idempotencyKey: randomUUID() });import uuid
res = pp("POST", "/esim/orders", body={
"package_id": "5b2f7c1a-3d4e-4f60-8a71-9c0d1e2f3a4b",
"external_id": "order-1001",
}, idempotency_key=str(uuid.uuid4()))$res = pp('POST', '/esim/orders', [
'package_id' => '5b2f7c1a-3d4e-4f60-8a71-9c0d1e2f3a4b',
'external_id' => 'order-1001',
], uuid4());pp() — функция-обёртка с подписью из раздела Аутентификация и подпись.
Ответ
202 Accepted — EsimOrderDTO
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
created_at | string | да | — |
error_code | string | нет | provider_rejected | refunded | needs_review | order_expired | unknown_order_status |
external_id | string | нет | — |
id | string | да | Наш идентификатор заказа eSIM |
operation_id | string | да | Операция, держащая ваши деньги, — тот же id, что приходит в событиях |
operation_status | string | да | processing | succeeded | failed | needs_review — судьба вашего резерва |
package | EsimPackageDTO | нет | Пакет в его текущем виде; price_usd выше — то, что вы заплатили |
package.countries | array<string> | да | ISO alpha-2 коды стран, которые покрывает пакет. Пусто, если провайдер не опубликовал список. |
package.currency | string | нет | — |
package.data_gb | string | да | Объём трафика в ГБ, десятичная строка. Не имеет смысла, если unlimited = true. |
package.has_5g | boolean | да | true, если в опубликованной сети упомянут 5G. false означает и «не указано». |
package.id | string | да | Идентификатор пакета — передайте его как package_id в POST /esim/orders |
package.network | string | нет | Поколение сети / операторы, как их опубликовал провайдер, если известны |
package.price_usd | string | нет | Сколько покупка этого пакета спишет с вашего баланса, USD |
package.region_code | string | да | ISO 3166-1 alpha-2 для пакета одной страны, иначе код региона (EUROPE, ASIA, GLOBAL, …) |
package.region_name | string | да | — |
package.sms | integer | нет | Включённые SMS, если они есть в пакете |
package.title | string | да | — |
package.unlimited | boolean | да | — |
package.validity_days | integer | да | — |
package.voice_minutes | integer | нет | Включённые минуты звонков, если они есть в пакете |
price_usd | string | да | Сколько эта покупка резервирует / списала с вашего баланса, USD |
profile | EsimProfileDTO | нет | Появляется, когда eSIM выпущена И покупка списана (operation_status succeeded) |
profile.activation_code | string | да | Полная строка LPA (LPA:1$<SM-DP+>$<matching id>). Секрет: кто им владеет, тот может установить eSIM. Не пишите его в логи и не храните открытым текстом. |
profile.apn | string | нет | — |
profile.iccid | string | да | — |
profile.matching_id | string | нет | — |
profile.qr_payload | string | да | Строка для QR-кода установки (совпадает с activation_code). Картинку рисуете вы. |
profile.smdp_address | string | нет | — |
refreshed | boolean | нет | Только у usage-refresh. false: отдано сохранённое значение (обновляли меньше минуты назад или спрашивать провайдера пока не о чем) |
settled_at | string | нет | — |
status | string | да | processing | active | exhausted | expired | needs_review | failed | refunded |
usage | EsimUsageDTO | нет | — |
usage.activated_at | string | нет | — |
usage.data_remaining_gb | string | нет | Последнее показание. Обновить — POST /esim/orders/{id}/usage-refresh. |
usage.data_total_gb | string | нет | — |
usage.expires_at | string | нет | — |
usage.unlimited | boolean | да | — |
Примеры ответа
{
"id": "7e6d5c4b-3a29-4180-9f7e-6d5c4b3a2918",
"operation_id": "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f",
"external_id": "order-1001",
"status": "processing",
"operation_status": "processing",
"price_usd": "5.26",
"package": {
"id": "5b2f7c1a-3d4e-4f60-8a71-9c0d1e2f3a4b",
"title": "Turkey · 5GB 30 days",
"region_code": "TR",
"region_name": "Turkey",
"countries": [
"TR"
],
"data_gb": "5",
"unlimited": false,
"validity_days": 30,
"network": "4G/5G",
"has_5g": true
},
"usage": {
"data_total_gb": "5",
"unlimited": false
},
"created_at": "2026-10-07T09:13:02Z"
}{
"title": "Payment Required",
"status": 402,
"detail": "partner_balance_exhausted",
"errors": [
{
"message": "balance_exhausted",
"location": "error.code",
"value": "balance_exhausted"
}
]
}Ошибки
| HTTP | Код | Когда |
|---|---|---|
| 402 | balance_exhausted | Доступного баланса (available) не хватает на операцию. Пополните счёт. |
| 404 | esim_package_not_available | Пакет eSIM неизвестен, снят с продажи или сейчас недоступен. Возьмите актуальный из GET /esim/packages. Деньги не двигались. |
| 404 | esim_price_below_cost | Цена пакета по вашему eSIM-тарифу не выше нашей себестоимости — покупка отклонена до резерва, деньги не двигались. Повтор не поможет; напишите нам, мы поправим тариф. |
| 404 | tariff_not_available | eSIM для вашего аккаунта не включён. |
| 409 | idempotency_conflict | Этот Idempotency-Key уже использован для другой покупки (другой пакет или другой external_id), либо external_id уже занят другой операцией. |
| 422 | amount_above_limit | Цена пакета выше лимита на одну операцию для вашего аккаунта. |
| 422 | — | Нет заголовка Idempotency-Key или обязательного поля. |
| 429 | daily_issue_limit | Достигнут лимит покупок eSIM за последние 24 часа: по числу покупок или по сумме в USD, если для аккаунта задан суточный потолок. |
| 503 | maintenance | Технические работы на этом направлении. Деньги не двигались — повторите позже с тем же Idempotency-Key. |
Плюс общие ошибки подписи и лимитов — см. Ошибки.