Trade · Автодонат

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 (сумма к зачислению).