API для разработчиков
Подключите Millida Trade к своему сайту: приём платежей как через платёжную систему и автоматическая выдача товаров без MC-плагина.
Обновлено 21 июля 2026 г.
Merchant API позволяет встроить Millida Trade в собственный сайт: принимать оплату (Millida работает как платёжная система) и выдавать товары на сервере без установки плагина — ваш бэкенд сам забирает очередь команд.
База API: https://api.millida.net/v2/merchant. Все суммы — в копейках (1 ₽ = 100 копеек).
Получение API-ключа
Ключ выпускается в личном кабинете магазина: раздел «Интеграции → API-ключи». При создании вы один раз получаете секрет вида mtk_live_… — сохраните его, повторно он не показывается.
Ключ можно ограничить правами (scopes):
payments— создание и управление счетами;deliveries— забор и подтверждение очереди выдачи;read— чтение счетов, серверов и товаров.
Пустой набор прав = полный доступ. Ключ можно отозвать или перевыпустить в любой момент.
Аутентификация
Передавайте ключ в заголовке Authorization: Bearer или X-Api-Key:
Authorization: Bearer mtk_live_xxxxxxxxxxxxxxxx
Ключ привязан к одному магазину. Лимит запросов — 240/мин на ключ (создание счёта — 120/мин).
Millida как платёжная система
Сценарий: у вас свой сайт-витрина, оплату проводит Millida. Создаёте счёт, перенаправляете покупателя на paymentUrl, после оплаты получаете вебхук.
Создать счёт на произвольную сумму
POST /v2/merchant/invoices
Content-Type: application/json
{
"externalId": "order-1042",
"amountKopecks": 19900,
"description": "VIP на 30 дней",
"playerNickname": "Steve",
"customerEmail": "player@example.com"
}
Ответ:
{
"id": "clx…",
"externalId": "order-1042",
"status": "pending",
"amountKopecks": 19900,
"subtotalKopecks": 19900,
"discountKopecks": 0,
"promoCode": null,
"commissionKopecks": 995,
"netKopecks": 18905,
"paymentUrl": "https://millida.trade/checkout/clx…",
"paidAt": null,
"createdAt": "2026-06-16T10:00:00.000Z"
}
Перенаправьте покупателя на paymentUrl — там он выберет СБП или карту. externalId — ваш идентификатор заказа; повторный запрос с тем же externalId вернёт тот же счёт (защита от дублей).
Что означают суммы:
| Поле | Смысл |
|---|---|
subtotalKopecks | Сумма до скидки |
discountKopecks | Скидка по промокоду |
amountKopecks | Итог к оплате (subtotal − discount) |
commissionKopecks | Комиссия платформы |
netKopecks | Вам к зачислению (amount − commission) |
Счёт по каталогу магазина
Если товары заведены в магазине Millida, передайте позиции — сумма и выдача рассчитаются автоматически:
POST /v2/merchant/invoices
{
"externalId": "order-1043",
"playerNickname": "Steve",
"items": [{ "productId": "prod_…", "quantity": 1 }]
}
Проверить статус
GET /v2/merchant/invoices/clx…
Статусы: pending, paid, delivered, failed, cancelled, refunded. Список — GET /v2/merchant/invoices?status=paid&limit=50.
Промокоды и реферальная программа
Типовой сценарий: у каждого ютубера/стримера свой промокод. Игрок вводит его при оплате, вы автоматически видите покупки по этому коду и начисляете блогеру процент.
1. Заведите промокоды
Промокоды создаются в личном кабинете магазина — раздел «Акции и промокоды» (см. статью «Промокоды и акции»). Там же задаются процент или фиксированная скидка, срок действия, лимит применений и ограничение на одного игрока.
2. Передайте код при создании счёта
Поле у игрока на вашем сайте, значение — в promoCode:
POST /v2/merchant/invoices
{
"externalId": "order-1050",
"amountKopecks": 19900,
"playerNickname": "Steve",
"customerEmail": "player@example.com",
"promoCode": "YOUTUBER10"
}
Скидку считаем мы — по вашим же акциям. Присылать её размер не нужно и нельзя: так покупатель не сможет подделать цену через DevTools.
Ответ уже со скидкой:
{
"id": "clx…",
"status": "pending",
"subtotalKopecks": 19900,
"discountKopecks": 1990,
"promoCode": "YOUTUBER10",
"amountKopecks": 17910,
"commissionKopecks": 896,
"netKopecks": 17014,
"paymentUrl": "https://millida.trade/checkout/clx…"
}
Регистр кода не важен — youtuber10 и YOUTUBER10 это один промокод.
Если код невалиден (не существует, истёк, исчерпан, не набрана минимальная сумма, уже использован этим игроком), придёт 400 с понятной причиной в поле message — покажите её покупателю и дайте оформить заказ без кода.
3. Получите факт оплаты
Промокод и суммы приходят в вебхуке invoice.paid — по нему и начисляйте процент блогеру (см. раздел «Вебхуки» ниже).
4. Сверка и отчёты
Все оплаты по конкретному коду одним запросом — удобно для партнёрской панели и ежемесячной сверки:
GET /v2/merchant/invoices?promoCode=YOUTUBER10&status=paid&limit=100
Ответ — список счетов с subtotalKopecks, discountKopecks, amountKopecks и paidAt по каждому. Постранично — через cursor из поля nextCursor.
Что важно знать
- Счётчик применений тратится только при оплате. Созданный, но неоплаченный или отменённый счёт лимит промокода не расходует.
- Скидка 100 % через API недоступна. Счёт на 0 ₽ невозможно оплатить, поэтому подарочные промокоды работают только на витрине Millida. Обычные (процент, фиксированная сумма) — работают.
- Комиссия считается от суммы после скидки, то есть от того, что реально заплатил покупатель.
- Для лимитов нужен идентификатор игрока. Если у промокода стоит ограничение «на одного игрока» или «только первая покупка», передавайте
playerNicknameи/илиcustomerEmail— без них такой код не применится. - Скидка на конкретные товары работает только в режиме каталога (
items). Для счёта на произвольную сумму (amountKopecks) такой промокод будет отклонён — позиций для проверки нет.
Выдача без плагина
Сценарий: вы не ставите MC-плагин, а сами исполняете команды на сервере. Укажите команды при создании счёта — после оплаты они попадут в очередь, а ваш бэкенд их заберёт.
Команды в счёте
POST /v2/merchant/invoices
{
"externalId": "order-1044",
"amountKopecks": 9900,
"playerNickname": "Steve",
"delivery": {
"serverId": "srv_…",
"commands": ["lp user Steve parent add vip", "say Steve купил VIP"]
}
}
serverId берётся из GET /v2/merchant/servers.
Забрать очередь
Опрашивайте очередь (например, раз в 3–5 секунд). Выданные команды атомарно резервируются за вами:
GET /v2/merchant/deliveries?limit=20
{
"deliveries": [
{
"id": "del_…",
"orderId": "clx…",
"externalId": "order-1044",
"serverId": "srv_…",
"playerNickname": "Steve",
"commands": ["lp user Steve parent add vip", "say Steve купил VIP"],
"allowOffline": false
}
]
}
Подтвердить выполнение
После исполнения команд на сервере подтвердите доставку:
POST /v2/merchant/deliveries/del_…/ack
{ "success": true }
При ошибке отправьте { "success": false, "message": "player offline" } — доставка вернётся в очередь и придёт снова (до 20 попыток).
Вебхуки
Укажите webhookUrl при создании ключа — и получайте уведомления о событиях счёта. Вместе с URL выдаётся webhookSecret для проверки подписи.
События: invoice.paid, invoice.failed, invoice.delivered.
Вебхуки приходят только по счетам, созданным через API этим ключом. Покупки, сделанные напрямую на витрине Millida, в ваш вебхук не попадают — если промокоды нужны и там, смотрите статистику акций в личном кабинете магазина.
POST https://ваш-сайт/webhook
X-Millida-Event: invoice.paid
X-Millida-Signature: sha256=…
{
"event": "invoice.paid",
"data": {
"id": "clx…",
"externalId": "order-1050",
"status": "PAID",
"amountKopecks": 17910,
"subtotalKopecks": 19900,
"discountKopecks": 1990,
"promoCode": "YOUTUBER10",
"promotionId": "promo_…",
"commissionKopecks": 896,
"netKopecks": 17014,
"playerNickname": "Steve",
"paidAt": "2026-07-21T10:01:00.000Z"
}
}
amountKopecks — итоговая сумма платежа, promoCode — код, применённый к этому заказу (null, если промокода не было). Этой пары достаточно, чтобы начислить блогеру процент: например, 10 % от amountKopecks при promoCode === "YOUTUBER10".
Пример обработчика:
app.post('/webhook', (req, res) => {
const { event, data } = req.body;
if (event === 'invoice.paid' && data.promoCode) {
creditPartner(data.promoCode, Math.round(data.amountKopecks * 0.1));
}
res.sendStatus(200);
});
Проверка подписи
Подпись — HMAC-SHA256 от «сырого» тела запроса с вашим webhookSecret. Сравнивайте безопасно (constant-time):
import { createHmac, timingSafeEqual } from 'crypto';
function verify(rawBody, header, secret) {
const expected = 'sha256=' + createHmac('sha256', secret).update(rawBody).digest('hex');
const a = Buffer.from(header);
const b = Buffer.from(expected);
return a.length === b.length && timingSafeEqual(a, b);
}
Безопасность
- Секрет ключа храните на сервере, не на фронтенде. Скомпрометированный ключ — отзовите и перевыпустите в ЛК.
- Сумму к зачислению всегда берите из вебхука/
GET /invoices/:id, а не из данных, пришедших с клиента. - Всегда проверяйте подпись вебхука и идемпотентность по
externalId(вебхук может прийти повторно). - Комиссия платформы удерживается автоматически; в ответе видны
commissionKopecksиnetKopecks(сумма к зачислению).