Справочник APIКарты
Выпустить карту
POST
/api/partner/v1/cards- Scope
cards:write- Idempotency-Key
- обязателен
Резервирует средства и запускает выпуск.
Ответ — это операция, а не карта. Выпуск асинхронный: карта создаётся у эмитента в течение следующих секунд. Дождитесь события card.issued или опрашивайте GET /operations/{id}, пока status не перестанет быть processing.
Баланс резервируется, а не списывается, пока операция не завершится. При неудаче резерв снимается полностью.
Idempotency-Key обязателен. Повтор с тем же ключом вернёт исходную операцию — вторая карта не будет выпущена никогда.
Первая карта нового держателя ждёт проверки личности у эмитента и выпускается заметно дольше последующих.
Тело запроса
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
amount | string (decimal) | нет | Начальное пополнение, десятичная строка в USD. Не передавайте или передайте "0", чтобы выпустить пустую карту. |
amount_type | string | нет | credit (по умолчанию) — amount придёт на карту, мы считаем, сколько спишем. debit — amount спишется с баланса, мы считаем, сколько придёт на карту. |
card_name | string | нет | Необязательная подпись карты (до 64 символов) |
holder_external_id | string | да | external_id, зарегистрированный через POST /cardholders. Наш id держателя здесь тоже находится, но хранить нужно external_id — по нему дедуплицирует POST /cardholders. (до 128 символов) |
tariff_id | string (uuid) | да | Из GET /tariffs |
Пример запроса
BODY='{"tariff_id":"3f6c2a1e-8b4d-4e2a-9c71-5d0e8f1a2b34","holder_external_id":"cust-42","amount":"50","amount_type":"credit"}'
IDEM=$(uuidgen)
TS=$(date +%s)
SIG=$(printf '%s\n%s\n%s\n%s\n%s' "$TS" "POST" "/api/partner/v1/cards" "$BODY" "$IDEM" \
| openssl dgst -sha256 -hmac "$PP_SECRET" -hex | awk '{print $NF}')
curl -sS -X POST "https://api.plativputi.com/api/partner/v1/cards" \
-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", "/cards", {
"tariff_id": "3f6c2a1e-8b4d-4e2a-9c71-5d0e8f1a2b34",
"holder_external_id": "cust-42",
"amount": "50",
"amount_type": "credit"
}, { idempotencyKey: randomUUID() });import uuid
res = pp("POST", "/cards", body={
"tariff_id": "3f6c2a1e-8b4d-4e2a-9c71-5d0e8f1a2b34",
"holder_external_id": "cust-42",
"amount": "50",
"amount_type": "credit",
}, idempotency_key=str(uuid.uuid4()))$res = pp('POST', '/cards', [
'tariff_id' => '3f6c2a1e-8b4d-4e2a-9c71-5d0e8f1a2b34',
'holder_external_id' => 'cust-42',
'amount' => '50',
'amount_type' => 'credit',
], uuid4());pp() — функция-обёртка с подписью из раздела Аутентификация и подпись.
Ответ
202 Accepted — OperationDTO
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
card_id | string | нет | Карта, созданная или изменённая операцией; у выпуска появляется, когда карта создана |
created_at | string | да | Когда операция принята, UTC |
error_code | string | нет | Почему операция не удалась. Все значения и что с ними делать — в разделе Ошибки. |
hold_amount | string (decimal) | да | Зарезервировано на балансе, пока операция в процессе |
id | string | да | Идентификатор операции |
kind | string | да | issue | topup | close | cashout |
net_amount | string (decimal) | да | Зачислено на карту (для закрытия — возвращено с неё) |
refund | RefundDTO | нет | Только для закрытия: остаток карты, возвращённый вам |
refund.amount | string (decimal) | нет | Зачислено на ваш баланс: residual − fee |
refund.fee | string (decimal) | нет | Удержано по close_refund_fee_pct тарифа |
refund.residual | string (decimal) | нет | Сколько было на карте при закрытии |
refund.status | string | да | refunded | zero (карта была пустой) | unknown (баланс прочитать не удалось; ничего не зачислено, урегулируем вручную) |
settled_at | string | нет | Когда операция пришла в конечный статус, UTC |
status | string | да | processing | succeeded | failed | needs_review |
Примеры ответа
{
"id": "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f",
"kind": "issue",
"status": "processing",
"hold_amount": "57.0464",
"net_amount": "50",
"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"
}
]
}{
"title": "Unprocessable Entity",
"status": 422,
"detail": "topup_below_min: credit 5 is below the tariff minimum of 10 USD",
"errors": [
{
"message": "amount_below_limit",
"location": "error.code",
"value": "amount_below_limit"
}
]
}Ошибки
| HTTP | Код | Когда |
|---|---|---|
| 402 | balance_exhausted | Доступного баланса (available) не хватает на операцию. Пополните счёт. |
| 404 | tariff_not_available | Тариф не найден, выключен или снят с продажи. Возьмите актуальный из GET /tariffs. |
| 404 | not_found | Держатель holder_external_id не зарегистрирован — сначала POST /cardholders. |
| 422 | amount_below_limit | Сумма на карту ниже минимума тарифа (min_topup). |
| 422 | amount_above_limit | Сумма выше максимума тарифа (max_topup) или лимита на одну операцию для вашего аккаунта. |
| 422 | — | Нет заголовка Idempotency-Key или обязательного поля. |
| 429 | daily_issue_limit | Достигнут суточный лимит выпуска карт для аккаунта. |
| 503 | maintenance | Технические работы на этом направлении. Деньги не двигались — повторите позже с тем же Idempotency-Key. |
Плюс общие ошибки подписи и лимитов — см. Ошибки.