ПлатиБара / Работа по API
Работа с нами по API
Подключите оплату Alipay и WeChat Pay в свой сервис: вы заводите заявку по API, платите за неё в USDT, получаете статусы вебхуками и общаетесь с нашей стороной в чате заявки — текстом и файлами (QR, скриншоты оплаты, фото ошибок).
Быстрый старт за 15 минут
- Пишете на api@platibara.world — заводим партнёра и кабинет на
crm.anypayanyday.online. - В кабинете выпускаете тестовый ключ
pb_test_…и сохраняете адрес вебхука. - Проверяете подпись на
GET /ping— он вернёт ваш код и время сервера. - Смотрите курс:
GET /rate?amount_cny=3000. - Создаёте заявку
POST /ordersс QR получателя — она списывается с вашего счёта, а в песочнице деньги не нужны. - В песочнице мы сами «оплатим» её за полминуты: ловите
order.payment_receivedиorder.paid. - Готовы — выпускаете боевой ключ
pb_live_…в том же кабинете и меняете его в своём коде.
Как это работает
- Ваш клиент выбирает оплату в Китай у вас в сервисе.
- Вы создаёте заявку у нас: направление, сумма в юанях, QR получателя, данные клиента.
- Сумма в USDT списывается с вашего счёта у нас (или переводится под конкретную сделку — как удобнее).
- Мы видим перевод в сети и отправляем заявку платёжнику. Платёж проходит в среднем до 10 минут.
- Статусы прилетают вебхуками, переписка и файлы идут через чат заявки.
- С каждой закрытой сделки вам начисляется вознаграждение — доля нашей прибыли по ступеням оборота.
Адрес и авторизация
Базовый адрес: https://crm.anypayanyday.online/pb/partner/v1
Каждый запрос подписывается. Заголовки:
| Заголовок | Значение |
|---|---|
X-API-Key | Ваш ключ |
X-Timestamp | Время в секундах (Unix), допустимое расхождение — 5 минут |
X-Signature | hex(HMAC_SHA256(secret, timestamp + "\n" + METHOD + "\n" + path + "\n" + sha256(body))) |
path — полный путь с префиксом, например /pb/partner/v1/orders. Для GET тело пустое, тогда берётся sha256("").
Python
import hashlib, hmac, json, time, httpx
API = "https://crm.anypayanyday.online/pb/partner/v1"
KEY, SECRET = "pb_live_…", "…"
def call(method, path, payload=None):
body = json.dumps(payload, ensure_ascii=False, separators=(",", ":")).encode() if payload is not None else b""
ts = str(int(time.time()))
base = f"{ts}\n{method}\n/pb/partner/v1{path}\n{hashlib.sha256(body).hexdigest()}"
sign = hmac.new(SECRET.encode(), base.encode(), hashlib.sha256).hexdigest()
return httpx.request(method, API + path, content=body or None, headers={
"X-API-Key": KEY, "X-Timestamp": ts, "X-Signature": sign, "Content-Type": "application/json"})
print(call("GET", "/ping").json())
Node.js
const crypto = require("crypto");
const API = "https://crm.anypayanyday.online/pb/partner/v1";
const KEY = "pb_live_…", SECRET = "…";
async function call(method, path, payload) {
const body = payload === undefined ? "" : JSON.stringify(payload);
const ts = Math.floor(Date.now() / 1000).toString();
const hash = crypto.createHash("sha256").update(body).digest("hex");
const base = `${ts}\n${method}\n/pb/partner/v1${path}\n${hash}`;
const sign = crypto.createHmac("sha256", SECRET).update(base).digest("hex");
const r = await fetch(API + path, {method, body: body || undefined,
headers: {"X-API-Key": KEY, "X-Timestamp": ts, "X-Signature": sign, "Content-Type": "application/json"}});
return r.json();
}
Методы
| Метод | Путь | Что делает |
|---|---|---|
GET | /ping | Проверка ключа и времени сервера. |
GET | /rate?amount_cny=3000 | Курс и сумма к оплате до создания заявки, ступени курса. |
GET | /balance | Ваш счёт: остаток, личный адрес пополнения, последние операции. |
POST | /orders | Создать заявку. Идемпотентно по external_id. |
GET | /orders/{id} | Состояние заявки. |
GET | /orders?updated_since=2026-09-20T10:00:00Z | Изменившиеся заявки, если не используете вебхуки. |
GET | /orders/{id}/messages?after=0 | Сообщения чата: текст, файлы, отметка «скриншот оплаты». |
POST | /orders/{id}/messages | Написать в чат: {"text": "…", "file_base64": "…"}. |
POST | /orders/{id}/payments | Сообщить TxID своего перевода на заявку: платить можно частями и доплачивать. {"txid": "…"}. |
POST | /orders/{id}/cancel | Отменить заявку, пока мы не увидели ваш перевод (уже засчитанные части вернутся на счёт). |
GET | /files/{id} | Скачать файл из чата (QR, скриншот оплаты, фото ошибки). |
Счёт и оплата сделок
У каждого партнёра свой адрес USDT TRC20 — ваши деньги не смешиваются ни с клиентскими, ни с чужими партнёрскими.
Адрес постоянный, смотрите его в кабинете или в GET /balance.
Схема по умолчанию — счёт: вы пополняете свой адрес заранее, а каждая заявка списывается со счёта в момент создания.
Сделка стартует сразу, без ожидания перевода и без сверки сумм. Остаток и все операции — в GET /balance и в кабинете.
Не хватает денег — заявка не создаётся, приходит 402 insufficient_funds с остатком и адресом пополнения.
Пополнение счёта для партнёров — без комиссии. Зачисление обычно за минуту после подтверждения сети;
GET /balance проверяет адрес в сети сразу.
Нужен разовый перевод под конкретную сделку — создайте заявку с "pay": "transfer": в ответе придут адрес,
точная сумма и срок. В ответе всегда есть поле paid_with: balance или transfer.
Создание заявки
POST /orders
{
"method": "alipay", // alipay | wechat
"pay": "balance", // balance (по умолчанию) — списать со счёта; transfer — перевод под эту сделку
"amount_cny": 3000, // сумма в юанях, минимум 100
"qr_base64": "iVBORw0KGgo…", // QR получателя: jpg, png или webp в base64 (или вместо него recipient_account)
"external_id": "ADV-5512", // ваш номер заказа: повтор вернёт ту же заявку
"recipient_name": "Li Wei", // обязательно от 20 000 ¥ и для Alipay без QR
"recipient_account": "li@qq.com", // обязательно от 20 000 ¥; без QR — ID кошелька или телефон получателя
"client_name": "Иван Петров", // ваш клиент — попадёт в заявку и в чат
"client_phone": "+79990001122",
"comment": "заказ 5512, поставщик Yiwu"
}
Ответ:
{
"ok": true,
"order_id": 1024,
"external_id": "ADV-5512",
"status": "received",
"paid_with": "balance",
"method": "alipay",
"amount_cny": 3000.0,
"rate": 6.56,
"usdt_due": 457.32,
"usdt_paid": 0.0, // сколько уже засчитано частями (только при pay: transfer)
"usdt_remaining": 0.0, // сколько осталось доплатить
"pay": {"from": "balance", "amount": 457.32},
// при "pay": "transfer" вместо этого приходят реквизиты:
// "pay": {"coin": "USDT", "network": "TRON (TRC20)", "amount": 457.32,
// "address": "TRsnaQpX6VJNg6XsUtzcD331H6X2N88BUh", "expires_at": "2026-09-20T18:45:00+03:00"},
"recipient": {"type": "qr", "name": "Li Wei", "account": "li@qq.com"}, // type: qr | account
"test": false,
"created_at": "2026-09-20T17:45:00+03:00"
}
Переведите pay.amount в pay.coin на pay.address. Небольшое отклонение суммы (курсовая разница,
комиссия сети) не мешает — заявка считается оплаченной. На курс мы фиксируем заявку до pay.expires_at (3 часа),
после этого она закрывается статусом expired. Платите несколькими переводами — см. «Оплата частями» ниже.
Всегда присылайте external_id — это ваш номер заказа и одновременно ключ идемпотентности: повтор того же запроса
вернёт ту же заявку с признаком "duplicate": true, поэтому ретраи по таймауту безопасны.
Передумали до оплаты — POST /orders/{id}/cancel. После того как перевод виден в сети, отмена только через чат заявки.
Оплата на номер кошелька (без QR)
Если у получателя нет QR, платим на его аккаунт: вместо qr_base64 передайте recipient_account —
ID кошелька Alipay или WeChat либо телефон. Для Alipay нужно ещё и recipient_name (Alipay просит имя получателя при переводе на аккаунт);
для WeChat имя по желанию. Остальное — как с QR: те же суммы, курс, статусы, вебхуки и чат.
POST /orders
{
"method": "alipay", // alipay | wechat
"amount_cny": 3000,
"recipient_account": "13800138000", // ID кошелька (Alipay / WeChat ID) или телефон получателя
"recipient_name": "Li Wei", // Alipay: обязательно; WeChat: по желанию
"external_id": "ADV-5513"
}
В ответе и вебхуках recipient.type — account (по номеру) или qr. Если переданы и QR, и аккаунт,
платёж идёт по QR, а аккаунт остаётся справочным.
Оплата частями и доплата
Действует для заявок с "pay": "transfer" (при balance сумма списывается со счёта целиком).
Клиент может заплатить меньше, чем нужно, или несколькими переводами на один и тот же адрес заявки. Чтобы у нас с вами не было
разногласий, сообщите нам каждый такой перевод — POST /orders/{id}/payments с TxID:
POST /orders/1024/payments
{ "txid": "9f2c…64 hex-символа…" } // хеш вашего перевода USDT TRC20 на адрес заявки
// ответ: заявка с актуальными суммами
{ "ok": true, "accepted": true, "status": "waiting",
"usdt_due": 457.32, "usdt_paid": 0.0, "usdt_remaining": 457.32, … }
// после подтверждения сети (и вебхук order.payment_partial):
{ "status": "partial", "usdt_paid": 200.0, "usdt_remaining": 257.32,
"pay": {"amount": 257.32, "address": "TRsnaQ…", "expires_at": "…продлён на час…"}, … }
- Перевод засчитывается за этой заявкой при любой сумме, как только его подтвердит сеть TRON. Сообщайте TxID сразу после отправки —
мы проверим, что перевод дошёл до адреса заявки, иначе вернём
404 tx_not_found. - Пока сумма не набралась, заявка в статусе
partial, вusdt_remaining— сколько осталось, а срок ожидания продлевается на час после каждой части (не дольше суток от создания). Приходит вебхукorder.payment_partial. - Последний перевод на остаток можно и не заявлять — если он совпал с остатком, мы засчитаем его сами. Но заявить надёжнее.
- Набралась вся сумма — работает как обычно:
order.payment_received, заявка уходит платёжнику. - Перевели больше нужного — заявка закрывается на свою сумму, лишнее ложится на ваш счёт.
- Не доплатили до конца срока или вы отменили заявку — уже полученные части возвращаются на ваш счёт
(в вебхуках
order.expired/order.cancelled— полеrefunded_to_balance), оттуда можно оплатить новую заявку. - Перевод пришёл, когда заявка уже закрыта, —
409 order_closed. Такие случаи разбираем вручную: напишите на api@platibara.world с txid.
Статусы заявки
| status | Что означает |
|---|---|
waiting | Заявка создана, ждём ваш перевод USDT на указанный адрес. |
confirming | Перевод виден в сети, ждём подтверждения. |
partial | Получена часть суммы (вы заявили перевод через /payments): доплатите остаток usdt_remaining на тот же адрес. |
received | Оплата получена, заявка у платёжника. Чат открыт. |
problem | Платёж не прошёл, нужен ответ: уточнить данные получателя. Пишите в чат заявки. |
done | Оплачено. Скриншот оплаты приходит в чат как сообщение с is_payment_proof. |
expired | Перевод не поступил за час, заявка закрыта. Создайте новую. |
cancelled | Заявка отменена, оплата (если была) возвращена на баланс. |
Вебхуки
Адрес для событий и секрет вебхука вы задаёте сами в кабинете партнёра. Секрет отдельный от ключа API — перевыпуск ключа не ломает ваш приёмник. Мы шлём POST и ждём любой ответ 2xx в течение 20 секунд.
POST ваш webhook_url
X-Event: order.paid
X-Timestamp: 1789927607
X-Signature: 6f1c… // hex(HMAC_SHA256(секрет вебхука, timestamp + "\n" + sha256(тело)))
{
"event": "order.paid",
"at": "2026-09-20T18:02:11+03:00",
"order": { "order_id": 1024, "status": "done", "usdt_received": 457.32, … }
}
| event | Когда приходит |
|---|---|
order.created | Заявка заведена. |
order.payment_partial | Засчитана часть оплаты: поля usdt_paid, usdt_remaining и txid. Срок заявки продлён. |
order.payment_received | Ваш перевод получен, заявка ушла платёжнику. |
order.paid | Платёж в Китае выполнен, в чате появился скриншот. |
order.problem | Платёж не прошёл, нужен ваш ответ. |
order.cancelled | Заявка отменена — вами по API или нашим менеджером; полученная оплата возвращается на ваш баланс (поле refunded_to_balance). |
order.expired | Перевод не пришёл за час, заявка закрыта автоматически. Если часть уже была получена — поле refunded_to_balance: она вернулась на ваш счёт. |
balance.deposit | Пополнение вашего счёта зачислено: поля amount и balance, без order. |
ping | Тестовая отправка по кнопке «Проверить вебхук» в кабинете. Без поля order. |
message.new | Новое сообщение в чате заявки от нашей стороны. |
Проверка подписи
# проверка подписи вебхука (секрет вебхука — из кабинета партнёра)
import hashlib, hmac
def verify(headers, raw_body, webhook_secret):
base = headers["X-Timestamp"] + "\n" + hashlib.sha256(raw_body).hexdigest()
want = hmac.new(webhook_secret.encode(), base.encode(), hashlib.sha256).hexdigest()
return hmac.compare_digest(want, headers["X-Signature"])
// Node.js
const crypto = require("crypto");
function verify(headers, rawBody, webhookSecret) {
const base = headers["x-timestamp"] + "\n" + crypto.createHash("sha256").update(rawBody).digest("hex");
const want = crypto.createHmac("sha256", webhookSecret).update(base).digest("hex");
return crypto.timingSafeEqual(Buffer.from(want), Buffer.from(headers["x-signature"]));
}
Правила доставки
- Нет ответа 2xx — повторяем до 8 раз с растущей паузой (1, 2, 4… минут, максимум час).
- Одно событие может прийти дважды: обрабатывайте по паре
event+order.order_idидемпотентно. - Порядок событий не гарантирован. Истина всегда в
GET /orders/{id}— при сомнении перечитайте заявку. - Отвечайте быстро, тяжёлую работу уносите в очередь: мы ждём ответ 20 секунд.
- В кабинете виден журнал отправок с ошибкой доставки, кнопка повторной отправки и кнопка «Проверить вебхук»
(шлёт событие
pingс настоящей подписью).
Если вебхуки неудобны, опрашивайте GET /orders?updated_since=… (ISO 8601, например
2026-09-20T10:00:00Z) и GET /orders/{id}/messages?after=….
Кабинет партнёра
Вход на crm.anypayanyday.online по логину, который мы выдаём вместе с доступом (пароль меняется при первом входе). В кабинете:
- тестовый и боевой ключи — выпуск и перевыпуск в один клик, оба живут параллельно;
- адрес и секрет вебхука, журнал отправок и кнопка проверки;
- счёт: личный адрес пополнения, остаток, история списаний и кнопка «Проверить пополнение»;
- все ваши заявки и чат по каждой — тот же чат, что и по API;
- ведомость вознаграждения: оборот, текущая ставка, начислено и к выплате;
- профиль: почта, телефон, язык переписки (на нём же мы переводим сообщения в чате).
Чат и файлы
Чат открывается, когда оплата получена. Ваши сообщения видит наш менеджер и исполнитель платежа, ответы приходят вам
событием message.new. Файл отправляется как file_base64 (jpg, png, webp до 8 МБ), скачивается методом
GET /files/{id}. Скриншот оплаты помечен признаком is_payment_proof.
Мы переводим переписку автоматически: вы пишете на своём языке, исполнитель читает на своём, а вам приходит перевод
на язык из профиля кабинета (пока перевод готовится, у сообщения стоит "translating": true).
Что полезно слать в чат: фото ошибки из приложения получателя, уточнённые реквизиты, комментарий клиента.
Что придёт от нас: скриншот оплаты, вопросы по получателю, если платёж не прошёл (order.problem).
Ошибки
| Код | Что проверить |
|---|---|
401 no_key / bad_key | Нет заголовка X-API-Key или ключ отключён. |
401 bad_timestamp | X-Timestamp расходится с нашим временем больше 5 минут. |
401 bad_signature | Подпись не сходится: проверьте секрет, путь и тело запроса. |
403 ip_denied | IP не в белом списке (если он задан). |
400 bad_amount / bad_method / no_qr / bad_qr | Проверьте сумму, направление и картинку QR. Нужен qr_base64 либо recipient_account. |
400 recipient_required | Нужны recipient_name и recipient_account: от 20 000 ¥ и для Alipay без QR. |
400 bad_txid / tx_too_old | txid — 64 hex-символа; перевод сделан раньше, чем создана заявка. |
404 tx_not_found | Не видим этот перевод USDT TRC20 на адрес заявки: проверьте txid и повторите через минуту. |
409 txid_used | Этот перевод уже засчитан другой заявке. |
409 order_closed | Заявка уже закрыта (оплачена, истекла или отменена) — напишите нам с txid, вернём перевод на ваш счёт. |
409 not_transfer | Заявка оплачена со счёта: заявлять переводы можно только у заявок с pay: transfer. |
400 bad_pay | Поле pay: balance или transfer. |
402 insufficient_funds | На счёте не хватает USDT — пополните свой адрес или создайте заявку с pay: transfer. |
400 bad_json / empty / bad_file | Тело не JSON; сообщение без text и file_base64; файл не base64. |
404 not_found | Заявка или файл не ваши либо не существуют. |
409 chat_closed | Чат открывается после получения оплаты. |
409 too_late | Отменять поздно: перевод уже виден в сети — напишите в чат заявки. |
413 too_large | Тело запроса больше 8 МБ. |
503 no_rate | Курс временно недоступен, повторите через минуту. |
Формат ошибки: {"ok": false, "error": {"code": "bad_amount", "message": "…"}}
Песочница с демо-данными
Ключ вида pb_test_… работает на тех же адресах и с той же подписью, но деньги не двигаются.
Заявка живёт как настоящая: через ~15 секунд мы сами «получаем» ваш перевод (order.payment_received),
ещё через ~15 секунд «платёжник» закрывает её (order.paid, статус done).
Чат, файлы, идемпотентность по external_id и вебхуки — как в бою; вознаграждение по демо-сделкам считается, но помечено тестом.
Оплату частями в песочнице проверяйте так: создайте заявку с "pay": "transfer" и вызовите POST /orders/{id}/payments
с любым txid из 64 hex-символов и полем "amount" (USDT; без него — весь остаток). Через ~5 секунд часть засчитается
(order.payment_partial или, если сумма набралась, order.payment_received). Пока вы заявляете части, демо-оплата
целиком не срабатывает.
Демо-заявки живут отдельно: они не попадают в рабочую очередь наших менеджеров и не уходят исполнителю платежа, денег с вашего счёта не списывают и в расчётах не участвуют. Переключение на боевой ключ ничего в вашем коде не меняет — те же адреса, та же подпись, те же поля; отличается только то, что заявка идёт в реальную работу и требует денег на счёте.
Боевой ключ вида pb_live_… работает параллельно тестовому: их можно держать одновременно и переключать в своём коде.
Оба ключа вы выпускаете и перевыпускаете сами в кабинете партнёра на crm.anypayanyday.online — там же заявки, чат и ведомость вознаграждений.
Новый ключ того же типа отзывает предыдущий.
Требования к получателю
- Минимальная сумма — 100 ¥, от 20 000 ¥ обязательны имя и аккаунт получателя (и для Alipay на аккаунт без QR — при любой сумме).
- Аккаунт получателя должен быть верифицирован, с заданным платёжным паролем.
- Новый аккаунт принимает до 5 000 ¥ за платёж, аккаунт на паспорт РФ — до 20 000 ¥.