Интеграция с сервисом 1cent
Схема работы
Создать заявку
Все запросы идут на base url, слеш в конце пути обязателен. Ответ приходит в виде { success, data } или { success: false, error } — проверяйте поле success, а не только HTTP-статус. Сохраните uid, secret и _id из ответа: они нужны для order/get, update-status и проверки IPN.
1POST https://www.1cent.io/service/api/v1/public/exchanger/order/create/2Content-Type: application/json3Lang: ru45{6 "routeId": "64a1f3c2...",7 "amount": 1000,8 "fromValues": [],9 "toValues": [{ "key": "5f1c...", "value": "4441111122223333" }],10 "routeValues": [{ "key": "5f2a...", "value": "client@example.com" }],11 "email": "client@example.com",12 "agreement": true,13 "lang": "ru",14 "captcha": "03AFcWeA...",15 "ipnUrl": "https://your-merchant-site.com/ipn",16 "ipnSecret": "random-string-per-order"17}
1{2 "success": true,3 "data": {4 "_id": "6ace4b450534cc05e1c20af9",5 "uid": 37082,6 "rid": "2P8CCGG6C2I",7 "secret": "QrON4NsRGRGWKsIN9dfXCmep",8 "route": {9 "from": { "name": "Tether TRC20", "symbol": "USDT" },10 "to": { "name": "Наличные Cherkasy", "symbol": "USD" }11 },12 "inAmount": "5000",13 "outAmount": "5000"14 }15}
Получить заявку
1GET https://www.1cent.io/service/api/v1/public/exchanger/order/get/2 ?orderUID=362813 &orderSecret=Hj4sT9aQ...4 &type=order
1{2 "success": true,3 "data": {4 "order": {5 "_id": "6ace462b0534cc05e1c209f2",6 "uid": 36281,7 "status": "waitPayment",8 "inAmount": 1111,9 "outAmount": 51106,10 "rate": 46,11 "expiresAt": "2026-10-13T15:54:35.376Z",12 "comment": "",13 "routeValues": [14 { "field": "69693d5613ef113ff3519ef1", "name": "IBAN", "value": "UA2132..." }15 ],16 "route": {17 "from": { "name": "Tether TRC20", "symbol": "USDT", "paymentDetails": { ... } },18 "to": { "name": "Счет компании", "symbol": "UAH" }19 }20 },21 "verifications": {22 "verificationCurrency": null,23 "verificationCurrencyPayout": null,24 "verificationUser": null25 }26 }27}
Обновить статус заявки
Подтверждает заявку, отмечает оплату или отменяет её. Без skipPreview заявка создаётся в статусе new, и её нужно подтвердить переводом в waitPayment. После ручной оплаты клиентом заявку переводят в inProgress.
1PUT https://www.1cent.io/service/api/v1/public/exchanger/order/update-status/2Content-Type: application/json34{5 "orderUID": 36281,6 "orderSecret": "Hj4sT9aQ...",7 "status": "inProgress"8}
1{2 "success": true,3 "data": { ... }4}5// после смены статуса перечитайте заявку через order/get
Оплата
Вы можете использовать /payment/ для отображения страницы оплаты.
Также вы можете просто дать ссылку на биржу так, как ее видят все клиенты по той же схеме, что и в первом варианте, кроме /payment/ следует заменить на /order/.
Чтобы показать реквизиты для оплаты на своём сайте, возьмите их из order.route.from.paymentDetails в ответе order/get: адрес кошелька при автоматическом зачислении, текст с реквизитами или пошаговую инструкцию.
1https://www.1cent.io/en/payment/1409/dGqwF2M2eBPaSN1G5ljMS1cb
1HTTP/1.1 200 OK2Content-Type: text/html34<!-- Payment page for order #1409 -->
IPN
Уведомление об изменении статуса платежного запросаЧтобы получать уведомления об изменении статуса заявки, при её создании передайте параметры ipnUrl и ipnSecret. При изменении статуса сервер отправит POST-запрос на ваш ipnUrl со следующими данными:
1POST https://www.1cent.io/service/api/v1/public/exchanger/order/create/2Content-Type: application/json34{5 "routeId": "64a1f3c2...",6 "amount": 1000,7 "fromValues": [],8 "toValues": [{ "key": "5f1c...", "value": "4441111122223333" }],9 "routeValues": [],10 "agreement": true,11 "lang": "ru",12 "ipnUrl": "https://your-merchant-site.com/ipn",13 "ipnSecret": "random-string-per-order"14}
1POST https://your-merchant-site.com/ipn2Content-Type: application/x-www-form-urlencoded3User-Agent: Webhook (www.1cent.io)45orderUID=370826&orderId=6ace4b450534cc05e1c20af97&newStatus=done8&oldStatus=inProgress9&inAmount=500010&outAmount=500011&xml_from=USDTTRC2012&xml_to=CASHUSD_C_CHERK13×tamp=179190465988214&hash=f9a11f8f94847ecdbb36911f38bf25f18eeae0d4676ba2045ebab74666d1ebc9
Верификация контрольной суммы запроса (IPN)
1sha256(orderId:newStatus:inAmount:outAmount:xml_from:xml_to:timestamp:ipnSecret)
1// значения берутся ровно в том виде, в каком пришли в форме (строки)2const stringForHash = [orderId, newStatus, inAmount, outAmount, xml_from, xml_to, timestamp, ipnSecret].join(":");3// example string for hash 5d8e6002b80b7b4cd75a6424:inProgress:2:317.42:ETH:WMZ:1571328406072:SECRET12345const expected = crypto.createHash('sha256').update(stringForHash).digest('hex')6// example hash af3acf947e6f0e0f2c267e300b8582e504dba12d1f2d058652b7414163c09f4878// hash приходит полем формы; сравнивайте за постоянное время9const valid =10 String(hash).length === expected.length &&11 crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(String(hash)))
Список статусов
Контроль платежей
Храните uid и secret каждой заявки на своём сервере: по ним через order/get можно в любой момент проверить статус заявки, даже если IPN не дошёл.
Вы можете сохранить UID запроса и секрет и вручную перейти к запросу, указав эти данные в адресной строке.