Начало работы

Быстрый старт

Пять шагов до первого тестового платежа. Понадобится терминал или любой HTTP-клиент; деньги в тестовом режиме не списываются.

Удобнее начать в песочнице: она выдаст ключ и подставит его во все примеры.
Переменные окружения
export NORDPAY_SECRET_KEY=sk_test_…
export NORDPAY_WEBHOOK_SECRET=…

1. Получите тестовый ключ

Для быстрой проверки подойдёт временный ключ песочницы: он живёт 24 часа и принадлежит отдельному тестовому магазину. Если вы уже подключены, создайте постоянный тестовый ключ в кабинете, в разделе «Вебхуки и API-ключи».

Секретный ключ показывается один раз — сохраните его в переменной окружения или менеджере секретов.

Временный тестовый ключ
curl -X POST https://api.nordpay.pro/v1/sandbox/keys \
  -H "Content-Type: application/json" \
  -d '{}'
Ответ · 201
{
  "secret_key": "sk_test_51c8…f2a9",
  "webhook_secret": "a3f9…7c1e",
  "merchant_id": "mch_test_7Hq2",
  "expires_at": "2026-11-09T12:00:00Z"
}

2. Создайте платёж

Отправьте сумму в копейках, описание и номер заказа. Поле method можно не задавать — тогда покупатель выберет СБП, карту или USDT на странице оплаты.

Заголовок Idempotency-Key защищает от двойного платежа, если запрос придётся повторить из-за сетевой ошибки. Подробнее — в разделе «Идемпотентность».

curl -X POST https://api.nordpay.pro/v1/payments \
  -H "Authorization: Bearer $NORDPAY_SECRET_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 499000,
    "currency": "RUB",
    "method": "sbp",
    "description": "Заказ №1042",
    "order_id": "1042",
    "customer": {
      "email": "buyer@example.com"
    },
    "return_url": "https://shop.example/orders/1042",
    "metadata": {
      "cart_id": "c_77"
    }
  }'
Ответ · 201
{
  "id": "pay_2Kq8sD1fVxJ7mN4p",
  "object": "payment",
  "status": "pending",
  "amount": 499000,
  "amount_refunded": 0,
  "currency": "RUB",
  "fee": 17465,
  "net": 481535,
  "method": "sbp",
  "description": "Заказ №1042",
  "order_id": "1042",
  "metadata": {
    "cart_id": "c_77"
  },
  "customer": {
    "email": "buyer@example.com"
  },
  "confirmation": {
    "type": "redirect",
    "url": "https://api.nordpay.pro/checkout/pay_2Kq8sD1fVxJ7mN4p"
  },
  "sbp": {
    "qr_payload": "https://api.nordpay.pro/checkout/pay_2Kq8sD1fVxJ7mN4p",
    "expires_at": "2026-11-08T12:30:00Z"
  },
  "crypto": null,
  "crypto_network": null,
  "card": null,
  "failure": null,
  "livemode": false,
  "created_at": "2026-11-08T12:00:00Z",
  "paid_at": null,
  "expires_at": "2026-11-08T12:30:00Z"
}

3. Перенаправьте покупателя

В ответе есть confirmation.url — страница оплаты на api.nordpay.pro. Отправьте туда покупателя редиректом или кнопкой. После оплаты он вернётся на ваш return_url.

В тестовом режиме на странице оплаты есть плашка «Тестовый режим» и кнопки, которые задают исход платежа.

Перенаправление
res.redirect(303, payment.confirmation.url);

4. Примите вебхук

Укажите адрес обработчика в кабинете или через API. Когда платёж оплачен, придёт событие payment.succeeded. Проверьте подпись из заголовка NordPay-Signature, затем отметьте заказ оплаченным и ответьте кодом 2xx.

Подпись считается от «сырого» тела запроса — не разбирайте JSON до проверки.

Обработчик вебхука
import express from 'express';
import crypto from 'node:crypto';

const app = express();

app.post('/webhooks/nordpay', express.raw({ type: 'application/json' }), (req, res) => {
  const header = req.get('NordPay-Signature') || '';
  const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));
  const expected = crypto
    .createHmac('sha256', process.env.NORDPAY_WEBHOOK_SECRET)
    .update(`${parts.t}.${req.body}`)
    .digest('hex');
  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
  const ok = fresh && parts.v1 && parts.v1.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
  if (!ok) return res.sendStatus(400);

  const event = JSON.parse(req.body);
  if (event.type === 'payment.succeeded') {
    markOrderPaid(event.data.object.order_id);
  }
  res.sendStatus(200);
});

5. Проверьте статус

Если вебхук не дошёл — например, ваш сервер был недоступен, — статус всегда можно запросить напрямую. Платёж в статусе succeeded оплачен.

Дальше: все параметры платежа, подписки и тестовые сценарии.

curl https://api.nordpay.pro/v1/payments/pay_2Kq8sD1fVxJ7mN4p \
  -H "Authorization: Bearer $NORDPAY_SECRET_KEY"
Ответ · 200
{
  "id": "pay_2Kq8sD1fVxJ7mN4p",
  "object": "payment",
  "status": "succeeded",
  "amount": 499000,
  "amount_refunded": 0,
  "currency": "RUB",
  "fee": 17465,
  "net": 481535,
  "method": "sbp",
  "description": "Заказ №1042",
  "order_id": "1042",
  "metadata": {
    "cart_id": "c_77"
  },
  "customer": {
    "email": "buyer@example.com"
  },
  "confirmation": {
    "type": "redirect",
    "url": "https://api.nordpay.pro/checkout/pay_2Kq8sD1fVxJ7mN4p"
  },
  "sbp": {
    "qr_payload": "https://api.nordpay.pro/checkout/pay_2Kq8sD1fVxJ7mN4p",
    "expires_at": "2026-11-08T12:30:00Z"
  },
  "crypto": null,
  "crypto_network": null,
  "card": null,
  "failure": null,
  "livemode": false,
  "created_at": "2026-11-08T12:00:00Z",
  "paid_at": "2026-11-08T12:03:41Z",
  "expires_at": "2026-11-08T12:30:00Z"
}