Skip to main content
SDK — это готовая библиотека, которая берёт на себя всю «рутину» интеграции с Oblodai: подписывает запросы, разбирает ответы, проверяет подписи вебхуков, повторяет запросы при сбоях. Вам остаётся вызвать пару методов.
Новичку: если вы пишете свой сайт/бэкенд — берите SDK, а не «голый» HTTP. Так вы не ошибётесь в подписи запроса (самый частый источник проблем на старте).

Какой SDK выбрать

Все SDK устроены одинаково — одни и те же понятия и почти одинаковые названия методов. Освоив один, вы сразу поймёте остальные.

PHP

composer require oblodai/sdk

TypeScript / Node.js

npm install @oblodai-npm/sdk

Python

pip install oblodai

Go

go get github.com/oblodai/oblodai-go

Rust

cargo add oblodai
v1.1.0 — текущая версия в реестрах (Packagist · npm · PyPI · Go modules · crates.io). Ломающее изменение против v1.0.x: идемпотентность переехала с авто-order_id на заголовок Idempotency-Key — см. принцип 3 и CHANGELOG вашего SDK. npm-пакет: @oblodai-npm/sdk.
Чтобы устанавливать пакеты, понадобятся сами инструменты вашего языка: Composer (PHP), npm (Node.js), pip (Python), Go (go), Cargo (Rust).

Что вам понадобится (для любого SDK)

  1. public_id и secret — пара ключей вашего мерчанта. public_id — несекретный идентификатор, secret — тайна, которой подписываются запросы. Один ключ на весь функционал (и приём, и выплаты). Ключи берутся в кабинете my.oblodai.com — см. Регистрация и ключи.
  2. Сервер. SDK работает только на сервере (бэкенд). Секрет никогда не должен попадать в браузер или мобильное приложение.
  3. Публичный URL для вебхуков — адрес на вашем сервере, куда Oblodai будет присылать уведомления об оплате (например https://ваш-сайт.ру/oblodai/webhook).

Шесть принципов за минуту

Эти правила одинаковы во всех SDK — понимание их избавит от 90 % ошибок.
  1. Ключи — из переменных окружения. Не пишите секрет в коде. Задайте OBLODAI_PUBLIC_ID и OBLODAI_SECRET, и создавайте клиента через fromEnv() / from_env(). Базовый URL по умолчанию — боевой https://api.oblodai.com; переопределить можно переменной OBLODAI_BASE_URL (необязательно).
  2. Суммы — строками. "25.00", не число 25.0. Так не теряется точность.
  3. Повтор безопасен — но защита от дублей устроена по-разному в двух версиях. Это главное отличие v1.1.0 от v1.0.x.
    • Ловушка при обновлении на v1.1.0. Если вы полагались на то, что order_id «появится сам» в ответе, — теперь его там не будет. Задавайте order_id явно (см. следующий раздел). Сама защита от дублей при этом работает и без него — уже заголовком.
    • order_id — это ВАШ бизнес-идентификатор, по которому вы потом находите платёж через payments.info и сопоставляете со своим заказом. Ключом идемпотентности он быть перестал.
    • Выплаты: order_id обязателен в обеих версиях — этого требует сам API (без него вернётся payout.order_id_required). Задавайте свой уникальный номер выплаты.
    • Ходите в API напрямую, без SDK? Тогда шлите заголовок Idempotency-Key сами (или полагайтесь на order_id) — иначе повтор задублирует операцию. Подробно — Идемпотентность.
  4. Оплату подтверждает вебхук, а не редирект. Покупателя редиректит на «спасибо», но статус заказа меняйте только получив вебхук (и перепроверив статус через payments.info).
  5. Вебхуки надо зарегистрировать. Один раз вызовите «регистрацию вебхука» — получите webhook-секрет и храните его. Именно им проверяются входящие уведомления (это НЕ ваш API-секрет). Без регистрации уведомления не приходят.
  6. Валюта цены — это не валюта расчёта. Два разных поля, и их постоянно путают:
    • currency — валюта ЦЕНЫ. Может быть одной из 23 фиатных валют — USD, EUR, GBP, RUB, UAH, PLN, CZK, TRY, CNY, INR, BRL, CAD, AUD, CHF, AED, ZAR, MXN, IDR, THB, VND, NGN, JPY, KRW — или любой монетой (USDT, BTC, TRX, …). Указать цену в рублях или евро можно, и это надёжно: курс монеты приходит сразу в нужной валюте, ничего не перемножается.
    • to_currency — валюта РАСЧЁТА. Здесь только крипта, фиата не бывает никогда. Баланс, выплаты и возвраты — тоже всегда в крипте: шлюз не хранит фиат.
    • У JPY и KRW ноль знаков после запятой: "amount": "10000", а не "10000.00". У остальных — 2.
    • Тенге (KZT), сом (KGS), сум (UZS) пока не поддерживаются — вернётся payment.unknown_currency.
    • Правило, о которое спотыкаются: цена в фиате + задана только network без to_currency400 payment.to_currency_required. Либо задайте to_currency, либо не задавайте ни то, ни другое — тогда получится валюто-агностичный счёт и монету выберет сам покупатель.
    Полный список того, в чём можно назначать цену, отдаёт rates.currencies() — в ответе поле pricing_currencies (монеты + фиат с признаком "fiat": true).

Как связать платёж со своим заказом

Всегда возвращается uuid платежа — по нему платёж ищется через payments.info. Но удобнее искать по своему order_id, поэтому задавайте его сами и сохраняйте до вызова:
Почему «до вызова». Если create() бросит исключение (сеть отвалилась после того, как SDK исчерпал повторы), ответа у вас не будет — и записать uuid будет неоткуда. Дубля при этом не возникнет (все повторы шли с одним Idempotency-Key), но чтобы потом найти этот платёж, вам нужен ключ, который вы придумали сами. Поэтому: сначала записали свой order_id, потом отправили.
Где взять order_id из ответа:

Что нового в v1.1.0

  • Массовые операции. До 5000 платежей / возвратов / выплат одним запросом — одна отметка rate-limit вместо тысячи. Обработка в фоне: постановка возвращает batch_id, результаты по каждому элементу забираются через «инфо о пачке». Есть режим on_error: continue (по умолчанию) или stop (остановиться на первой ошибке). См. Массовые операции, Пачка, Инфо о пачке.
  • Платёжные ссылки (донаты). Переиспользуемая ссылка: по ней платят много людей, каждый платёж — свой инвойс со своим адресом. Сумма фиксированная, свободная или в диапазоне; валюту и сеть можно закрепить или дать выбрать клиенту; ссылка может быть бессрочной. Это единственный способ принимать платежи вообще без бэкенда (Tilda, Wix и т. п.). См. Платёжные ссылки, Ссылка, Публичный доступ к ссылке.
  • Сплит-платежи. Доля каждого платежа автоматически уходит партнёру — на внешний адрес (необратимо) или аккаунту на платформе (обратимо: возврат отзовёт долю). См. предупреждение о возвратах ниже, Сплит-платежи, Правило сплита, Настройки сплита.
  • Счёт на e-mail — письмо покупателю с кнопкой «Оплатить». Чек об оплате уходит автоматически на payer_email, если вы задали его при создании платежа. См. Счета на e-mail, Отправка счёта.
  • Крипто-чеки (payout links) — выплата без адреса получателя: вы резервируете сумму, получатель открывает claim_url и сам вводит свой адрес. Группа payout_links / payoutLinks / PayoutLinks: create, create_batch (до 500 ссылок), list, info, cancel + публичные claim_info / claim (без подписи). См. Крипто-чеки, Payout-ссылка, Публичный claim.
  • Резолв недоплатыpayments.resolve(action=accept|refund): недоплаченный платёж можно принять как есть (accept, глушит авто-возврат) или вернуть плательщику (refund). См. Резолв платежа.
  • Новые поля платежа: payer_address (откуда пришли деньги), refunds[] и refund_status (none|partial|full).
  • address в возврате больше не обязателен — по умолчанию вернём на адрес плательщика. Для Bitcoin/UTXO, где адрес плательщика неизвестен, address по-прежнему нужен.

Сплиты и возвраты — прочитайте, прежде чем включать

Возврат списывается с вашего баланса на всю сумму, что прислал плательщик. Если бы доля партнёра уходила сразу, вам могло бы стать нечем возвращать. Поэтому отправка партнёрам откладывается на окно удержания (refund_hold_hours), и в момент отправки база пересчитывается как «оплачено − возвращено». Возврат внутри окна сам уменьшает или отменяет отчисление. Возврат после отправки: долю на внешний адрес вернуть нельзя (придётся пополнить баланс), а долю партнёра-на-платформе мы отзовём автоматически.

Типичный сценарий приёма платежа

Одинаков во всех языках:
Пошагово с кодом — на странице вашего языка. Начните с приёма первого платежа, если хотите сперва понять сам API.

Логи (диагностика)

Логирование во всех SDK выключено по умолчанию и включается одинаково — переменной окружения или своим логгером. Секреты (secret, X-Signature, webhook-секрет) и тела запросов не логируются никогда — только метод, путь, HTTP-статус, время, номер попытки, задержка ретрая и код ошибки. Самый простой способ — переменная окружения (значения debug · info · warn · error):
Тогда в stderr пойдут понятные строки:
Свой логгер (в прод — направьте в свою систему логов) задаётся в конфиге клиента:
  • TypeScriptnew OblodaiClient({ ..., logger: (level, msg, fields) => … })
  • Python — стандартный logging: настройте логгер logging.getLogger("oblodai")
  • Gooblodai.Config{ ..., Logger: slog.Default() }
  • RustConfig::new(...).logger(Arc::new(|level, msg| …))
  • PHPnew Client($publicId, $secret, ['logger' => function (string $level, string $msg) { … }])

Лимиты частоты и повторы (встроено)

Все пять SDK сами переживают временные сбои, и повторы включены по умолчанию — отдельно настраивать ничего не нужно:
  • Что повторяется: HTTP 429 (лимит частоты) и 5xx, а также сетевые сбои/таймауты. Ошибки запроса (4xx, кроме 429) не повторяются.
  • Retry-After: на 429 шлюз присылает Retry-After: 60 — SDK ждёт именно столько; иначе — экспоненциальный backoff с джиттером.
  • Дефолты: до 4 попыток, старт 500 мс, потолок задержки 30 с. Настраивается через RetryConfig/ RetryOptions (или отключается) в конфиге клиента.
  • Лимит самого API — 120 запросов/мин на IP. Подробно — Ограничение частоты.
Go, внимание. Раньше в Go-SDK повторов по умолчанию не было (Retry: nil означало «не повторять») — из пяти библиотек ошибалась одна. Это исправлено: теперь nil = повторы включены, как везде. Отключить их можно осознанно — Retry: oblodai.NoRetry().
Упираетесь в лимит частоты? Не разгоняйте параллелизм — используйте массовые операции (с v1.1.0): до 5000 элементов одним подписанным запросом = одна отметка rate-limit вместо тысяч.

Куда дальше

Выберите язык из карточек выше и откройте его страницу — там установка, рабочий пример и все методы.

Справочник API

Точные поля каждого метода API.

Глоссарий

Незнакомый термин — смотрите здесь.

Модули для CMS

Не пишете код — возьмите готовый модуль.