Перейти к содержимому
API-документация

Выпустить карту

POST/api/partner/v1/cards
Scope
cards:write
Idempotency-Key
обязателен

Резервирует средства и запускает выпуск.

Ответ — это операция, а не карта. Выпуск асинхронный: карта создаётся у эмитента в течение следующих секунд. Дождитесь события card.issued или опрашивайте GET /operations/{id}, пока status не перестанет быть processing.

Баланс резервируется, а не списывается, пока операция не завершится. При неудаче резерв снимается полностью.

Idempotency-Key обязателен. Повтор с тем же ключом вернёт исходную операцию — вторая карта не будет выпущена никогда.

Первая карта нового держателя ждёт проверки личности у эмитента и выпускается заметно дольше последующих.

Тело запроса

ПолеТипОбяз.Описание
amountstring (decimal)нетНачальное пополнение, десятичная строка в USD. Не передавайте или передайте "0", чтобы выпустить пустую карту.
amount_typestringнетcredit (по умолчанию) — amount придёт на карту, мы считаем, сколько спишем. debit — amount спишется с баланса, мы считаем, сколько придёт на карту.
card_namestringнетНеобязательная подпись карты (до 64 символов)
holder_external_idstringдаexternal_id, зарегистрированный через POST /cardholders. Наш id держателя здесь тоже находится, но хранить нужно external_id — по нему дедуплицирует POST /cardholders. (до 128 символов)
tariff_idstring (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_idstringнетКарта, созданная или изменённая операцией; у выпуска появляется, когда карта создана
created_atstringдаКогда операция принята, UTC
error_codestringнетПочему операция не удалась. Все значения и что с ними делать — в разделе Ошибки.
hold_amountstring (decimal)даЗарезервировано на балансе, пока операция в процессе
idstringдаИдентификатор операции
kindstringдаissue | topup | close | cashout
net_amountstring (decimal)даЗачислено на карту (для закрытия — возвращено с неё)
refundRefundDTOнетТолько для закрытия: остаток карты, возвращённый вам
refund.amountstring (decimal)нетЗачислено на ваш баланс: residual − fee
refund.feestring (decimal)нетУдержано по close_refund_fee_pct тарифа
refund.residualstring (decimal)нетСколько было на карте при закрытии
refund.statusstringдаrefunded | zero (карта была пустой) | unknown (баланс прочитать не удалось; ничего не зачислено, урегулируем вручную)
settled_atstringнетКогда операция пришла в конечный статус, UTC
statusstringда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КодКогда
402balance_exhaustedДоступного баланса (available) не хватает на операцию. Пополните счёт.
404tariff_not_availableТариф не найден, выключен или снят с продажи. Возьмите актуальный из GET /tariffs.
404not_foundДержатель holder_external_id не зарегистрирован — сначала POST /cardholders.
422amount_below_limitСумма на карту ниже минимума тарифа (min_topup).
422amount_above_limitСумма выше максимума тарифа (max_topup) или лимита на одну операцию для вашего аккаунта.
422—Нет заголовка Idempotency-Key или обязательного поля.
429daily_issue_limitДостигнут суточный лимит выпуска карт для аккаунта.
503maintenanceТехнические работы на этом направлении. Деньги не двигались — повторите позже с тем же Idempotency-Key.

Плюс общие ошибки подписи и лимитов — см. Ошибки.