Главная / Разработчикам
Документация по интеграции для мерчантов

API приёма и выплат: подключение в несколько шагов

Единый интерфейс HTTP + JSON, подпись и проверка по SHA-256, асинхронные уведомления и самостоятельный запрос статуса заказа. В этом документе описаны правила подписи, все поля API и примеры запросов.

Обзор

India Payme предоставляет мерчантам два ключевых типа операций: приём платежей (Payin) — получение средств от конечных пользователей от имени мерчанта; выплаты (Payout) — перевод средств на указанный счёт от имени мерчанта. Все внешние методы работают по протоколу POST + JSON и обязательно требуют API-подписи. После обработки платформа уведомляет мерчанта через асинхронное уведомление, а также поддерживает самостоятельный запрос статуса заказа.

ВозможностьМетодПуть
Создание платежа (приём)POST/transaction/payin/v1/apply
Запрос статуса платежа (приём)POST/transaction/payin/v1/query
Создание выплатыPOST/transaction/payout/v1/apply
Запрос статуса выплатыPOST/transaction/payout/v1/query
Запрос балансаPOST/transaction/payout/v1/balance

Базовый адрес (домен продуктивного шлюза предоставляется платформой после открытия счёта):

https://{домен_шлюза}

Подготовка к интеграции

Войдите в личный кабинет мерчанта → раздел «Ключи приложения»: у каждого приложения есть пара учётных данных — appKey и appSecret. При этом appKey используется как заголовок запроса appId; appSecret — это ключ подписи, который применяется только для локального вычисления подписи и никогда не передаётся по сети.

Все запросы должны содержать следующие HTTP-заголовки, Content-Typeapplication/json:

HeaderОбязательноОписание
appIdДаID приложения мерчанта (то есть appKey)
timestampДаUnix-время в миллисекундах
nonceДаСлучайная строка, ≥10 символов, одноразовая, повторное использование запрещено
signДаПодпись, рассчитанная по правилам из следующего раздела

Правила подписи

Алгоритм подписи — чистый SHA-256 (в нижнем регистре, шестнадцатеричный), а не HMAC. appSecret добавляется непосредственно в конец подписываемой строки, после чего вычисляется SHA-256. Шаги:

  1. Возьмите поля верхнего уровня тела запроса (только непустые) и объедините их с заголовками подписи appId, timestamp, nonce в единый Map (сам sign в этом не участвует);
  2. отсортируйте по именам параметров в порядке возрастания ASCII и соберите строку вида key1=value1&key2=value2…;
  3. в конец строки без разделителя добавьте appSecret и вычислите SHA-256 всей строки (в нижнем регистре, шестнадцатеричный) — это и есть sign.
# строка для подписи signString = "key1=value1&key2=value2…&keyN=valueN" + appSecret sign = SHA256_HEX(signString) // нижний регистр, hex

Срок действия и защита от повторов:

  • Срок действия временной метки — 30 секунд: |время сервера − timestamp| ≤ 30s, при превышении возвращается timestamp has expired. Убедитесь, что часы клиента и шлюза синхронизированы (NTP).
  • Защита от повторов по nonce: один и тот же nonce можно использовать только один раз, при повторе возвращается ошибка nonce has been used (код ошибки 900).
  • Пустые поля не участвуют в подписи — набор полей, участвующих в подписи, должен полностью совпадать с фактически отправляемыми полями JSON.

Пример подписи на Node.js:

const crypto = require('crypto'); function buildSign(appId, appSecret, timestamp, nonce, body) { const params = { ...body, appId, timestamp, nonce }; const signString = Object.keys(params) .filter(k => params[k] !== null && params[k] !== undefined) .sort() .map(k => `${k}=${params[k]}`) .join('&') + appSecret; return crypto.createHash('sha256').update(signString, 'utf8').digest('hex'); }

Создание платежа (приём) POST

POST /transaction/payin/v1/apply —— создаёт заказ на приём платежа и возвращает ссылку на кассу payUrl, по которой пользователь завершает оплату.

ПолеТипОбязательноОписание
merchantOrderNostringДаНомер заказа мерчанта, не должен повторяться
amountnumberДаСумма заказа, десятичное число (например, 100.02)
namestringДаИмя пользователя. Только латиница, ≥3 буквы, пробелы допускаются, без символов и цифр
phonestringДаНомер телефона
emailstringДаEmail
currencystringДаВалюта: INR / PKR / USDT / BDT
productstringДаКод платёжного продукта, предоставляется платформой согласно договору
notifyUrlstringНетАдрес асинхронных уведомлений; если не указан, используется адрес по умолчанию для мерчанта
returnUrlstringНетСтраница перенаправления после успешной оплаты
payTypestringНетСпособ прямой оплаты через кошелёк: JAZZCASH / EASYPAISA / BKASH / NAGAD
POST /transaction/payin/v1/apply { "merchantOrderNo": "ORD1751731200123", "amount": "600.00", "currency": "INR", "product": "{код_продукта}", "name": "John Doe", "phone": "9910099100", "email": "john@example.com", "notifyUrl": "https://shop.example/pay/notify" }
// ответ { "code": 0, "msg": "Success", "data": { "orderNo": "P1751731200999", "merchantOrderNo": "ORD1751731200123", "amount": 600, "currency": "INR", "payUrl": "https://{домен_кассы}/cashier/xxxx", "payStatus": 0 } }

После получения payUrl перенаправьте пользователя для оплаты; окончательный результат определяется асинхронным уведомлением.

Создание выплаты POST

POST /transaction/payout/v1/apply —— инициирует выплату на указанный счёт. Асинхронная обработка: сначала выполняется проверка счёта и блокировка средств, затем платформа асинхронно подбирает канал для выплаты; в ответе обычно возвращается payStatus=0 (заявка принята), а итоговый статус определяется по запросу или уведомлению.

ПолеТипОбязательноОписание
merchantOrderNostringДаНомер заказа мерчанта
amountnumberДаСумма выплаты, минимум 100.00
accountNamestringДаИмя получателя. Только латиница, ≥3 буквы, пробелы допускаются
accountstringДаНомер счёта получателя
phonestringДаНомер телефона
emailstringДаEmail
currencystringДаВалюта: INR / PKR / USDT / BDT
bizCodestringДаТип операции выплаты: IMPS / UPI / BANK / JAZZCASH / EASYPAISA / BKASH / NAGAD / ECARD
payCodestringДаСпособ выплаты: CARD / WALLET / NBK / ITT / VC
branchCodestringДаКлиринговый код: для Индии — IFSC; для Пакистана — bankcode; для Бангладеш — согласно bizCode
productstringДаКод платёжного продукта для выплаты, предоставляется платформой
bankNamestringНетНазвание банка
swiftCodestringНетSWIFT-код (используется при международном переводе ITT)
POST /transaction/payout/v1/apply { "merchantOrderNo": "PO1751731200123", "amount": "1500.00", "currency": "INR", "product": "{код_продукта}", "accountName": "John Doe", "account": "1234567890", "bizCode": "IMPS", "payCode": "NBK", "branchCode": "HDFC0000001", "bankName": "HDFC", "phone": "9910099100", "email": "john@example.com" }

Запрос статуса заказа POST

Для приёма — POST /transaction/payin/v1/query, для выплат — POST /transaction/payout/v1/query. Заказ определяется по merchantOrderNo или orderNo. Ограничение: 5 запросов в секунду.

POST /transaction/payin/v1/query { "merchantOrderNo": "ORD1751731200123" }
// возвращаемые данные (data) { "orderNo": "P1751731200999", "merchantOrderNo": "ORD1751731200123", "amount": 600, "realAmount": 600, "currency": "INR", "payStatus": 1 // 0 — в обработке / 1 — оплачено / -1 — отменено }

Запрос баланса POST

POST /transaction/payout/v1/balance —— запрос баланса счёта мерчанта. Ограничение: 5 запросов в секунду.

POST /transaction/payout/v1/balance { "currency": "INR" }
// возвращаемые данные (data) { "accountNo": "ACC0001", "currency": "INR", "balance": 100000.00, // общий баланс "balanceActive": 98500.00, // доступный баланс "balanceFreeze": 1500.00 // заблокированный баланс }

Асинхронные уведомления

Когда заказ переходит в конечный статус, платформа отправляет POST-уведомление (JSON) на notifyUrl мерчанта (если не указан — используется адрес по умолчанию), вместе с теми же заголовками подписи (appId/timestamp/nonce/sign). Мерчант должен пересчитать подпись по тем же правилам с использованием собственного appSecret и сверить её, чтобы подтвердить подлинность уведомления.

Уведомление о приёме платежа содержит: merchantOrderNo, orderNo, currency, product, amount, realAmount, status (значение "1" означает успешный приём). Уведомление о выплате дополнительно содержит utr (номер банковской транзакции) и statusDes (описание статуса); status принимает значения "1" — успех / "2" — ошибка.

// пример тела уведомления о приёме платежа { "merchantOrderNo": "ORD1751731200123", "orderNo": "P1751731200999", "currency": "INR", "product": "{код_продукта}", "amount": "600.00", "realAmount": "600.00", "status": "1" }

Мерчант обязан вернуть простой текст OK или success (без учёта регистра). В противном случае платформа поставит уведомление в очередь повторной отправки: не более 5 попыток с увеличивающимся интервалом в минутах (1 / 2 / 5 / 10 / 30 / 60 / 120). Поэтому обработчик на стороне мерчанта должен быть идемпотентным (один и тот же orderNo может быть отправлен повторно).

Статусы заказа

При интеграции ориентируйтесь на приведённые ниже внешние статусы (внутренняя логика статусов более детализирована и напрямую не раскрывается):

СценарийПолеЗначения
Ответ на создание заказаpayStatus0 создан / 1 успех / 2 ошибка / 3 отменён
Запрос статуса приёмаpayStatus0 в обработке / 1 оплачено / -1 отменено
Запрос статуса выплатыpayStatus0 ожидает выплаты / 1 выплачено / -1 отменено
Асинхронное уведомлениеstatusприём — успех "1"; выплата — "1" успех / "2" ошибка

Коды ошибок

Если в теле ответа code != 0, запрос завершился ошибкой, а msg содержит пояснение. Часто встречающиеся коды ошибок:

codeОписание
0Успех
400Ошибка параметров / ошибка проверки подписи (Sign invalid)
900Повторный запрос / повтор nonce
10000 / 10001Приложение не найдено / приложение недоступно
10002Валюта не поддерживается
10003 / 10007Мерчант недоступен / счёт мерчанта недоступен
10004Продукт не подключён либо истёк срок договора
10005 / 10009Нет доступных каналов / канал временно недоступен
10008Недостаточно средств на счёте
10010IP-адрес отсутствует в белом списке
10011 / 10012Недействительный продукт / недействительный способ оплаты
10020Номер заказа мерчанта уже используется
30001 / 30002Неверный номер заказа / неверная валюта либо счёт не активирован

Полный процесс интеграции

На примере приёма платежа:

  1. Сформируйте тело запроса (см. поля раздела «Создание платежа (приём)»).
  2. Сгенерируйте timestamp (в миллисекундах) и nonce (случайная строка ≥10 символов).
  3. Рассчитайте sign согласно разделу «Правила подписи».
  4. Отправьте POST /transaction/payin/v1/apply с 4 заголовками подписи и телом JSON.
  5. Если code==0, возьмите data.payUrl и перенаправьте пользователя для оплаты.
  6. Ожидайте асинхронное уведомление; также можно самостоятельно запросить статус заказа для сверки итогового результата.
  7. После получения уведомления проверьте подпись, обработайте бизнес-логику и верните простой текст OK.

Примечание: пути методов, поля и коды статусов в этом документе соответствуют продуктивной реализации; домен продуктивного шлюза, доступные коды продуктов product и политика белого списка IP предоставляются платформой после открытия счёта.

Получите ключи и начните разработку

Откройте счёт онлайн, чтобы получить тестовые учётные данные и коды продуктов; после успешного тестирования в песочнице переключение на продуктив выполняется одним действием.