MoonWay

Документация для мерчанта

Как запросить QR-код, проверить платеж и принять callback после оплаты.

Общая логика

1. Мерчант запрашивает QR Мерчант отправляет в MoonWay сумму, номер заказа и данные клиента.
2. MoonWay выбирает прокладку Платформа смотрит лимиты, диапазон сумм и дневной оборот каналов оплаты.
3. Прокладка получает QR Выбранная прокладка обращается к своему эквайрингу и возвращает QR/ссылку в MoonWay.
4. Callback идет обратно После оплаты эквайринг уведомляет прокладку, прокладка уведомляет MoonWay, MoonWay уведомляет мерчанта.

Доступ

Каждому мерчанту выдается ключ. Его нужно передавать в каждом запросе к мерчантскому API.

X-MoonWay-Key: merchant_public_key

POST/api/v1/payments

Создает платежную заявку и возвращает QR-код/ссылку на оплату.

Запрос

{
  "externalId": "order-1001",
  "amount": "1000.00",
  "currency": "RUB",
  "description": "Оплата заказа #1001",
  "customer": {
    "email": "client@example.com",
    "ip": "127.0.0.1"
  },
  "metadata": {
    "orderId": "1001"
  }
}

Ответ

{
  "uid": "pay_...",
  "externalId": "order-1001",
  "status": "pending",
  "amount": "1000.00",
  "currency": "RUB",
  "description": "Оплата заказа #1001",
  "paymentUrl": "https://...",
  "qrPayload": "ST00012...",
  "createdAt": "2026-05-22 11:30:00",
  "updatedAt": "2026-05-22 11:30:01"
}

externalId должен быть уникальным на стороне мерчанта. Если отправить тот же externalId повторно, MoonWay вернет уже созданный платеж.

GET/api/v1/payments/:uid

Возвращает актуальный статус платежа.

{
  "uid": "pay_...",
  "externalId": "order-1001",
  "status": "paid",
  "amount": "1000.00",
  "currency": "RUB",
  "paymentUrl": "https://...",
  "qrPayload": "ST00012...",
  "updatedAt": "2026-05-22 11:35:12"
}

Статусы

created заявка создана в MoonWay

pending QR-код получен, ожидается оплата

платеж успешно оплачен

failed платеж отклонен, истек или завершился ошибкой

Callback мерчанту

Когда MoonWay получает обновление статуса от прокладки, он отправляет POST-запрос на callback-адрес мерчанта.

Заголовки

X-MoonWay-Event: payment.updated
X-MoonWay-Timestamp: 1779430000
X-MoonWay-Signature: sha256=<hmac_sha256>

Тело запроса

{
  "event": "payment.updated",
  "payment": {
    "uid": "pay_...",
    "externalId": "order-1001",
    "status": "paid",
    "amount": "1000.00",
    "currency": "RUB",
    "description": "Оплата заказа #1001",
    "customer": {
      "email": "client@example.com",
      "ip": "127.0.0.1"
    },
    "paymentUrl": "https://...",
    "qrPayload": "ST00012...",
    "createdAt": "2026-05-22 11:30:00",
    "updatedAt": "2026-05-22 11:35:12"
  }
}

Подпись считается как HMAC-SHA256 от строки timestamp + "." + rawBody с использованием секретного ключа мерчанта.

Проверка подписи callback

import crypto from "node:crypto";

function verifyCallback({ rawBody, timestamp, signature, secret }) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");

  return signature === `sha256=${expected}`;
}

Ошибки

401 ключ мерчанта не передан или неверный.

400 ошибка в формате запроса.

409 нет подходящего канала оплаты по сумме или дневным лимитам.

500 внутренняя ошибка платформы.