Callbacks

When the status changes, the platform sends a POST request identical to the response received when creating a deal.

The callback URL can be set in two ways:

  1. In the personal account
  2. When creating a deal, you can specify callback_url

If both values are present, priority will be given to the callback_url from the request.

Regardless of how the URL is set, a POST request identical to the response received when creating a deal will be sent to this address.

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "order_id": "ext-123",
  "merchant_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "state": "pending",
  "kind": "deposit",
  "amount_cents": 1000,
  "amount_currency": "USD",
  "percent": 1.5,
  "exchange_rate": 1.0,
  "payment_data": {
    "name": "Dan Shnider",
    "number": "4242 4242 4242 4242",
    "bank_name": "Bank Example"
  },
  "url": "https://pay.example.com/payment/3fa85f64"
}

Callback Signature Verification

Each callback contains a Signature header — HMAC-SHA256 signature of the request body.

How to verify

  1. Take the raw body of the request (before JSON parsing)
  2. Compute the HMAC-SHA256 of the body using your secret_key
  3. Compare the result with the Signature header

PHP

$signature = hash_hmac('sha256', file_get_contents('php://input'), $secretKey);
$isValid = hash_equals($signature, $request->header('Signature'));

Python

import hmac, hashlib
signature = hmac.new(secret_key.encode(), raw_body, hashlib.sha256).hexdigest()
is_valid = hmac.compare_digest(signature, request.headers['Signature'])

Node.js

const crypto = require('crypto');
const signature = crypto.createHmac('sha256', secretKey).update(rawBody).digest('hex');
const isValid = crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(req.headers['signature']));