S
docs.syncra.money
API ReferenceMerchant API

Примеры SDK и Кода

Примеры использования Syncra Merchant API V2 на различных языках программирования

Примеры интеграции и использования SDK

В этом разделе представлены готовые к использованию примеры кода для интеграции с Syncra Merchant API V2 на четырех языках программирования: curl (HTTP), Python, Node.js и PHP.


1. Быстрый старт (Quick Start)

Создание простой платежной ссылки для приема оплаты.

curl -X POST https://api.syncra.money/api/v1/p2p/merchant/deals/payin \
  -H "X-Merchant-Token: your_merchant_token" \
  -H "X-Timestamp: 1783856120" \
  -H "X-Signature: t=1783856120,v1=9e87d0c3c8801d0a5198d023b6b19a16f2c8d2037920ab3e09819cd8e412cfab" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 150000,
    "currency": "RUB",
    "idempotency_key": "quickstart_order_001"
  }'
import requests
import time
import hmac
import hashlib
import json

token = "your_merchant_token"
secret = "your_webhook_secret"
timestamp = str(int(time.time()))

body = json.dumps({
    "amount": 150000,
    "currency": "RUB",
    "idempotency_key": "quickstart_order_001"
})

payload = f"{timestamp}.{body}"
signature = hmac.new(secret.encode(), payload.encode(), hashlib.sha256).hexdigest()

headers = {
    "X-Merchant-Token": token,
    "X-Timestamp": timestamp,
    "X-Signature": f"t={timestamp},v1={signature}",
    "Content-Type": "application/json"
}

response = requests.post(
    "https://api.syncra.money/api/v1/p2p/merchant/deals/payin",
    headers=headers,
    data=body
)
print(response.json())
const crypto = require('crypto');

const token = 'your_merchant_token';
const secret = 'your_webhook_secret';
const timestamp = Math.floor(Date.now() / 1000).toString();

const body = JSON.stringify({
  amount: 150000,
  currency: 'RUB',
  idempotency_key: 'quickstart_order_001'
});

const payload = `${timestamp}.${body}`;
const signature = crypto
  .createHmac('sha256', secret)
  .update(payload)
  .digest('hex');

fetch('https://api.syncra.money/api/v1/p2p/merchant/deals/payin', {
  method: 'POST',
  headers: {
    'X-Merchant-Token': token,
    'X-Timestamp': timestamp,
    'X-Signature': `t=${timestamp},v1=${signature}`,
    'Content-Type': 'application/json'
  },
  body: body
})
.then(res => res.json())
.then(console.log);
<?php
$token = "your_merchant_token";
$secret = "your_webhook_secret";
$timestamp = (string)time();

$body = json_encode([
    "amount" => 150000,
    "currency" => "RUB",
    "idempotency_key" => "quickstart_order_001"
]);

$payload = $timestamp . '.' . $body;
$signature = hash_hmac('sha256', $payload, $secret);

$ch = curl_init("https://api.syncra.money/api/v1/p2p/merchant/deals/payin");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "X-Merchant-Token: {$token}",
    "X-Timestamp: {$timestamp}",
    "X-Signature: t={$timestamp},v1={$signature}",
    "Content-Type: application/json"
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
echo $response;
?>

2. Инициализация и Хелпер Аутентификации (Auth Setup)

Класс-хелпер для формирования заголовков подписи HMAC-SHA256.

import time
import hmac
import hashlib

class SyncraAuth:
    def __init__(self, token: str, secret: str):
        self.token = token
        self.secret = secret

    def get_headers(self, body_str: str) -> dict:
        timestamp = str(int(time.time()))
        payload = f"{timestamp}.{body_str}"
        signature = hmac.new(
            self.secret.encode('utf-8'),
            payload.encode('utf-8'),
            hashlib.sha256
        ).hexdigest()
        
        return {
            "X-Merchant-Token": self.token,
            "X-Timestamp": timestamp,
            "X-Signature": f"t={timestamp},v1={signature}",
            "Content-Type": "application/json"
        }
const crypto = require('crypto');

class SyncraAuth {
  constructor(token, secret) {
    this.token = token;
    this.secret = secret;
  }

  getHeaders(body) {
    const timestamp = Math.floor(Date.now() / 1000).toString();
    const payload = `${timestamp}.${body}`;
    const signature = crypto
      .createHmac('sha256', this.secret)
      .update(payload)
      .digest('hex');

    return {
      'X-Merchant-Token': this.token,
      'X-Timestamp': timestamp,
      'X-Signature': `t=${timestamp},v1=${signature}`,
      'Content-Type': 'application/json'
    };
  }
}
<?php
class SyncraAuth {
    private $token;
    private $secret;

    public function __construct($token, $secret) {
        $this->token = $token;
        $this->secret = $secret;
    }

    public function getHeaders($bodyStr) {
        $timestamp = (string)time();
        $payload = $timestamp . '.' . $bodyStr;
        $signature = hash_hmac('sha256', $payload, $this->secret);

        return [
            "X-Merchant-Token: {$this->token}",
            "X-Timestamp: {$timestamp}",
            "X-Signature: t={$timestamp},v1={$signature}",
            "Content-Type: application/json"
        ];
    }
}
?>

3. Прием платежей (Create PayIn)

Создание платежной сессии для клиента.

curl -X POST https://api.syncra.money/api/v1/p2p/merchant/deals/payin \
  -H "X-Merchant-Token: your_token" \
  -H "X-Timestamp: 1783856120" \
  -H "X-Signature: t=1783856120,v1=9e87d0c3c8801d0a5198d023b6b19a16f2c8d2037920ab3e09819cd8e412cfab" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 250000,
    "currency": "RUB",
    "payment_method": "sbp",
    "idempotency_key": "unique_order_99812",
    "callback_url": "https://yourserver.com/callback",
    "success_url": "https://yourserver.com/success",
    "failed_url": "https://yourserver.com/failed"
  }'
# Использование класса хелпера SyncraAuth из раздела 2
auth = SyncraAuth("your_token", "your_secret")
body = json.dumps({
    "amount": 250000,
    "currency": "RUB",
    "payment_method": "sbp",
    "idempotency_key": "unique_order_99812",
    "callback_url": "https://yourserver.com/callback",
    "success_url": "https://yourserver.com/success",
    "failed_url": "https://yourserver.com/failed"
})
headers = auth.get_headers(body)
res = requests.post("https://api.syncra.money/api/v1/p2p/merchant/deals/payin", headers=headers, data=body)
print(res.json())
const auth = new SyncraAuth('your_token', 'your_secret');
const body = JSON.stringify({
  amount: 250000,
  currency: 'RUB',
  payment_method: 'sbp',
  idempotency_key: 'unique_order_99812',
  callback_url: 'https://yourserver.com/callback',
  success_url: 'https://yourserver.com/success',
  failed_url: 'https://yourserver.com/failed'
});
const headers = auth.getHeaders(body);
fetch('https://api.syncra.money/api/v1/p2p/merchant/deals/payin', {
  method: 'POST',
  headers: headers,
  body: body
})
.then(res => res.json())
.then(console.log);
<?php
$auth = new SyncraAuth("your_token", "your_secret");
$body = json_encode([
    "amount" => 250000,
    "currency" => "RUB",
    "payment_method" => "sbp",
    "idempotency_key" => "unique_order_99812",
    "callback_url" => "https://yourserver.com/callback",
    "success_url" => "https://yourserver.com/success",
    "failed_url" => "https://yourserver.com/failed"
]);

$ch = curl_init("https://api.syncra.money/api/v1/p2p/merchant/deals/payin");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_HTTPHEADER, $auth->getHeaders($body));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
echo $response;
?>

4. Выплаты клиентам (Create PayOut)

Выполнение P2P выплат на банковские карты физических лиц.

curl -X POST https://api.syncra.money/api/v1/p2p/merchant/deals/payout \
  -H "X-Merchant-Token: your_token" \
  -H "X-Timestamp: 1783856120" \
  -H "X-Signature: t=1783856120,v1=9e87d0c3c8801d0a5198d023b6b19a16f2c8d2037920ab3e09819cd8e412cfab" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 500000,
    "currency": "RUB",
    "wallet_id": "8f870a31-b88d-4cb0-a882-628d08cbda88",
    "target_requisite": "2202201234567890",
    "target_name": "Иван И.",
    "idempotency_key": "unique_payout_1291"
  }'
auth = SyncraAuth("your_token", "your_secret")
body = json.dumps({
    "amount": 500000,
    "currency": "RUB",
    "wallet_id": "8f870a31-b88d-4cb0-a882-628d08cbda88",
    "target_requisite": "2202201234567890",
    "target_name": "Иван И.",
    "idempotency_key": "unique_payout_1291"
})
headers = auth.get_headers(body)
res = requests.post("https://api.syncra.money/api/v1/p2p/merchant/deals/payout", headers=headers, data=body)
print(res.json())
const auth = new SyncraAuth('your_token', 'your_secret');
const body = JSON.stringify({
  amount: 500000,
  currency: 'RUB',
  wallet_id: '8f870a31-b88d-4cb0-a882-628d08cbda88',
  target_requisite: '2202201234567890',
  target_name: 'Иван И.',
  idempotency_key: 'unique_payout_1291'
});
const headers = auth.getHeaders(body);
fetch('https://api.syncra.money/api/v1/p2p/merchant/deals/payout', {
  method: 'POST',
  headers: headers,
  body: body
})
.then(res => res.json())
.then(console.log);
<?php
$auth = new SyncraAuth("your_token", "your_secret");
$body = json_encode([
    "amount" => 500000,
    "currency" => "RUB",
    "wallet_id" => "8f870a31-b88d-4cb0-a882-628d08cbda88",
    "target_requisite" => "2202201234567890",
    "target_name" => "Иван И.",
    "idempotency_key" => "unique_payout_1291"
]);

$ch = curl_init("https://api.syncra.money/api/v1/p2p/merchant/deals/payout");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_HTTPHEADER, $auth->getHeaders($body));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
echo $response;
?>

5. Верификация Вебхуков (Verify Callback)

Проверка входящих запросов на ваш обработчик вебхуков.

import hmac
import hashlib

def verify_syncra_webhook(raw_body: str, signature_header: str, secret: str) -> bool:
    parts = signature_header.split(',')
    t_val = [p for p in parts if p.startswith('t=')][0][2:]
    v1_val = [p for p in parts if p.startswith('v1=')][0][3:]
    
    payload = f"{t_val}.{raw_body}"
    expected = hmac.new(secret.encode(), payload.encode(), hashlib.sha256).hexdigest()
    
    return hmac.compare_digest(v1_val, expected)
const crypto = require('crypto');

function verifySyncraWebhook(rawBody, signatureHeader, secret) {
  const parts = signatureHeader.split(',');
  const t = parts.find(p => p.startsWith('t=')).substring(2);
  const v1 = parts.find(p => p.startsWith('v1=')).substring(3);

  const payload = `${t}.${rawBody}`;
  const expected = crypto.createHmac('sha256', secret).update(payload).digest('hex');

  return crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}
<?php
function verifySyncraWebhook($rawBody, $signatureHeader, $secret) {
    $parts = explode(',', $signatureHeader);
    $t = '';
    $v1 = '';
    foreach ($parts as $part) {
        if (strpos($part, 't=') === 0) $t = substr($part, 2);
        if (strpos($part, 'v1=') === 0) $v1 = substr($part, 3);
    }
    
    $payload = $t . '.' . $rawBody;
    $expected = hash_hmac('sha256', $payload, $secret);
    
    return hash_equals($v1, $expected);
}
?>

6. История Сделок (List Orders)

Постраничный запрос списка сделок мерчанта с фильтрами.

curl -X POST https://api.syncra.money/api/v1/p2p/merchant/deals/list \
  -H "X-Merchant-Token: your_token" \
  -H "X-Timestamp: 1783856120" \
  -H "X-Signature: t=1783856120,v1=9e87d0c3c8801d0a5198d023b6b19a16f2c8d2037920ab3e09819cd8e412cfab" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "PAYIN",
    "statuses": ["PAID"],
    "page_size": 20
  }'
auth = SyncraAuth("your_token", "your_secret")
body = json.dumps({
    "type": "PAYIN",
    "statuses": ["PAID"],
    "page_size": 20
})
headers = auth.get_headers(body)
res = requests.post("https://api.syncra.money/api/v1/p2p/merchant/deals/list", headers=headers, data=body)
print(res.json())
const auth = new SyncraAuth('your_token', 'your_secret');
const body = JSON.stringify({
  type: 'PAYIN',
  statuses: ['PAID'],
  page_size: 20
});
const headers = auth.getHeaders(body);
fetch('https://api.syncra.money/api/v1/p2p/merchant/deals/list', {
  method: 'POST',
  headers: headers,
  body: body
})
.then(res => res.json())
.then(console.log);
<?php
$auth = new SyncraAuth("your_token", "your_secret");
$body = json_encode([
    "type" => "PAYIN",
    "statuses" => ["PAID"],
    "page_size" => 20
]);

$ch = curl_init("https://api.syncra.money/api/v1/p2p/merchant/deals/list");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_HTTPHEADER, $auth->getHeaders($body));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
echo $response;
?>

7. Разрешение Диспутов (Handle Disputes)

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

curl -X POST https://api.syncra.money/api/v1/p2p/merchant/appeals \
  -H "X-Merchant-Token: your_token" \
  -H "X-Timestamp: 1783856120" \
  -H "X-Signature: t=1783856120,v1=9e87d0c3c8801d0a5198d023b6b19a16f2c8d2037920ab3e09819cd8e412cfab" \
  -H "Content-Type: application/json" \
  -d '{
    "deal_id": "7ac148fe-19a3-45bb-b992-019fac55b721",
    "reason": "Клиент перевёл средства, но платёж не зачислен",
    "file_ids": ["f3a1b2c3-4d5e-6f7a-8b9c-0d1e2f3a4b5c"]
  }'
auth = SyncraAuth("your_token", "your_secret")
body = json.dumps({
    "deal_id": "7ac148fe-19a3-45bb-b992-019fac55b721",
    "reason": "Клиент перевёл средства, но платёж не зачислен",
    "file_ids": ["f3a1b2c3-4d5e-6f7a-8b9c-0d1e2f3a4b5c"]
})
headers = auth.get_headers(body)
res = requests.post("https://api.syncra.money/api/v1/p2p/merchant/appeals", headers=headers, data=body)
print(res.json())
const auth = new SyncraAuth('your_token', 'your_secret');
const body = JSON.stringify({
  deal_id: '7ac148fe-19a3-45bb-b992-019fac55b721',
  reason: 'Клиент перевёл средства, но платёж не зачислен',
  file_ids: ['f3a1b2c3-4d5e-6f7a-8b9c-0d1e2f3a4b5c']
});
const headers = auth.getHeaders(body);
fetch('https://api.syncra.money/api/v1/p2p/merchant/appeals', {
  method: 'POST',
  headers: headers,
  body: body
})
.then(res => res.json())
.then(console.log);
<?php
$auth = new SyncraAuth("your_token", "your_secret");
$body = json_encode([
    "deal_id" => "7ac148fe-19a3-45bb-b992-019fac55b721",
    "reason" => "Клиент перевёл средства, но платёж не зачислен",
    "file_ids" => ["f3a1b2c3-4d5e-6f7a-8b9c-0d1e2f3a4b5c"]
]);

$ch = curl_init("https://api.syncra.money/api/v1/p2p/merchant/appeals");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_HTTPHEADER, $auth->getHeaders($body));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
echo $response;
?>

8. Криптовалютный Вывод (Crypto Withdrawal)

Вывод баланса мерчанта в Tether (USDT) на внешний кошелек.

curl -X POST https://api.syncra.money/api/v1/p2p/merchant/wallet/withdraw \
  -H "X-Merchant-Token: your_token" \
  -H "X-Timestamp: 1783856120" \
  -H "X-Signature: t=1783856120,v1=9e87d0c3c8801d0a5198d023b6b19a16f2c8d2037920ab3e09819cd8e412cfab" \
  -H "Content-Type: application/json" \
  -d '{
    "amount_usdt": 1000000,
    "blockchain": "TRC20",
    "address": "TYHCiW3XN5sP9cWJ5T4Dfs9Y18h46t9w1a"
  }'
auth = SyncraAuth("your_token", "your_secret")
body = json.dumps({
    "amount_usdt": 1000000,
    "blockchain": "TRC20",
    "address": "TYHCiW3XN5sP9cWJ5T4Dfs9Y18h46t9w1a"
})
headers = auth.get_headers(body)
res = requests.post("https://api.syncra.money/api/v1/p2p/merchant/wallet/withdraw", headers=headers, data=body)
print(res.json())
const auth = new SyncraAuth('your_token', 'your_secret');
const body = JSON.stringify({
  amount_usdt: 1000000,
  blockchain: 'TRC20',
  address: 'TYHCiW3XN5sP9cWJ5T4Dfs9Y18h46t9w1a'
});
const headers = auth.getHeaders(body);
fetch('https://api.syncra.money/api/v1/p2p/merchant/wallet/withdraw', {
  method: 'POST',
  headers: headers,
  body: body
})
.then(res => res.json())
.then(console.log);
<?php
$auth = new SyncraAuth("your_token", "your_secret");
$body = json_encode([
    "amount_usdt" => 1000000,
    "blockchain" => "TRC20",
    "address" => "TYHCiW3XN5sP9cWJ5T4Dfs9Y18h46t9w1a"
]);

$ch = curl_init("https://api.syncra.money/api/v1/p2p/merchant/wallet/withdraw");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_HTTPHEADER, $auth->getHeaders($body));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
echo $response;
?>

On this page