Oblodai Rust SDK
Официальный Rust SDK для платёжного шлюза Oblodai: приём платежей, выплаты, массовые операции
(пачки), платёжные и payout-ссылки, сплит-платежи, счета на e-mail, статические кошельки, вебхуки.
Автоподпись запросов, разбор ответов в типизированные структуры, обработка ошибок и автоматические
повторы с защитой от дублей (Idempotency-Key).
Базовый URL. По умолчанию —
https://api.oblodai.com. При необходимости переопределите черезConfig::base_url(...)и свои ключи.
Установка
[]
= "1"
= "1"
Требуется Rust 1.75+.
Учётные данные
Храните ключи в переменных окружения (см. .env.example):
# необязательно: export OBLODAI_BASE_URL=https://api.oblodai.com
// читает OBLODAI_PUBLIC_ID / OBLODAI_SECRET / OBLODAI_BASE_URL
let client = from_env?;
Быстрый старт
use ;
use json;
Проверка вебхуков
Подпись вебхука отличается от подписи запроса — SDK делает и то, и другое. Для входящих вебхуков
берите сырое тело и заголовки X-Webhook-Timestamp / X-Webhook-Signature.
use ;
use Value;
Чтобы отключить replay-защиту: VerifyOptions { max_age_seconds: 0, now: None }.
Обработка ошибок
Все ошибки — enum [Error]. Ошибки API несут машиночитаемый код.
use Error;
match client.payouts.create
err.is_retriable() подскажет, временная ли ошибка; err.code() вернёт код для Error::Api.
Варианты ошибок
| Вариант | Когда |
|---|---|
Error::Api { code, status, .. } |
API вернул конверт error. |
Error::Connection(_) |
Сеть недоступна или таймаут. |
Error::Signature(_) |
Не прошла проверка подписи вебхука. |
Error::Serialization(_) |
Ошибка (де)сериализации. |
Error::Config(_) |
Некорректная конфигурация. |
Повторы (retry)
Временные ошибки (5xx, 429, сетевые сбои) повторяются автоматически с экспоненциальным backoff
и джиттером. Ошибки запроса (4xx), а также payout.funds_maturing (средства ещё дозревают —
немедленный повтор не поможет) считаются терминальными и не повторяются. Заголовок Retry-After
от сервера соблюдается как есть (не обрезается до max_delay, лишь до абсолютного потолка в 300 с).
use ;
use Duration;
let config = new.retry;
// .retry(None) — отключить повторы
Важно про таймаут. Таймаут не означает, что операция не прошла. Повтор безопасен благодаря заголовку
Idempotency-Key(см. ниже): если операция уже создана — сервер вернёт её же, дубля не будет.
Идемпотентность (v1.1.0, ломающее изменение)
Создающие вызовы (payments().create/refund/resolve/create_batch/refund_batch,
payouts().create/create_mass/create_batch/refund, account().transfer_to_personal) шлют заголовок
Idempotency-Key — UUID v4, сгенерированный один раз до повторов: все внутренние ретраи
одного вызова уходят с одним и тем же ключом, поэтому таймаут+повтор не создаёт дубль. Заголовок в
подпись запроса не входит.
order_idбольше НЕ подставляется автоматически (поведение v1.0.x удалено). Он уходит как есть — это ваш бизнес-идентификатор, задавайте его явно, чтобы потом находить операцию черезinfo. Для выплатorder_idобязателен всегда (payout.order_id_required).- Свой ключ идемпотентности (дедупликация между вызовами/процессами): передайте поле
idempotency_keyв параметрах создающего вызова — оно уйдёт в заголовок и не попадёт в тело:
client.payments.create?;
payout_links()— исключение: эндпоинты/v1/payout/link*заголовок не поддерживают, SDK его не шлёт. Дедуплицируйте создание ссылок через per-linkreference.
Свой HTTP-транспорт
По умолчанию используется встроенный клиент на reqwest (фича reqwest-client, включена). Чтобы
подставить свой транспорт (или для тестов без сети), отключите фичу и реализуйте трейт
[HttpTransport]:
[]
= { = "1", = false }
use ;
use Arc;
;
let client = with_transport.unwrap;
Обзор методов
// Платежи
client.payments.create
client.payments.info
client.payments.history
client.payments.services
client.payments.qr
client.payments.resend
client.payments.refund
client.payments.set_accepted / list_accepted
client.payments.set_accuracy / get_accuracy
client.payments.set_autorefund / get_autorefund
client.payments.create_batch // пачка платежей (до 5000)
client.payments.refund_batch // пачка возвратов
client.payments.send_email // счёт на e-mail
client.payments.resolve // судьба недоплаты: Accept | Refund
// Выплаты
client.payouts.create
client.payouts.create_mass
client.payouts.create_batch // пачка выплат (до 5000)
client.payouts.info
client.payouts.history
client.payouts.services
client.payouts.calculate
client.payouts.approve
client.payouts.refund
client.payouts.get_fee_config / set_fee_config
client.payouts.get_refund_fee_config / set_refund_fee_config
// Кошельки
client.wallets.create
client.wallets.block
client.wallets.blocked_address_refund
client.wallets.qr
// Аккаунт
client.account.balance
client.account.referral
client.account.transfer_to_personal
client.account.vrcs
// Вебхуки
client.webhooks.register
client.webhooks.deliveries
client.webhooks.test_payment
// Настройки
client.settings.list_auto_withdraw / set_auto_withdraw / delete_auto_withdraw
client.settings.list_allowlist / add_allowlist / remove_allowlist / enable_allowlist
// Массовые операции: состояние пачки
client.batches.info
// Платёжные ссылки (переиспользуемые, «донатные»)
client.payment_links.create
client.payment_links.list / info / toggle
client.payment_links.public_get // публично, без подписи
client.payment_links.checkout // публично, без подписи
// Сплит-платежи
client.splits.create_rule // {address,network} ИЛИ {merchant_id} + percent
client.splits.list_rules / delete_rule
client.splits.get_config / set_config
// Payout-ссылки («крипто-чеки», payout-ключ)
client.payout_links.create // задавайте expires_in_hours явно!
client.payout_links.create_batch // до 500 ссылок
client.payout_links.list / info / cancel
client.payout_links.claim_info // публично, без подписи
client.payout_links.claim // публично, без подписи
// Курсы (публично, без ключа)
client.rates.list
Payout-ссылки: коротко
Вы резервируете средства в ссылку, не зная кошелька получателя; получатель открывает публичную
страницу claim_url, вводит адрес — порождается обычная выплата. claim_token/claim_url
возвращаются только в ответе create — сохраните их сразу. Задавайте expires_in_hours
(1–720) явно: при 0/отсутствии бэкенд клампит срок к 1 часу. Непорученная ссылка возвращает
резерв по истечении срока или при cancel.
let link = client.payout_links.create?;
println!; // отдайте получателю
Замечания
- Суммы — строки в единицах валюты (
"25.00"), не числа. Так сохраняется точность. - Дубли исключает заголовок
Idempotency-Key(см. раздел «Идемпотентность»).order_id— ваш бизнес-идентификатор для поиска операции, задавайте его явно; SDK его не подставляет. - Секрет — только на сервере. SDK серверный; не встраивайте ключ в клиентские приложения.
- Тела запросов принимаются как
serde_json::Value— стройте макросомjson!.
Лицензия
MIT