Перейти к содержанию

Коллбэки (callbacks)#

Для уведомлений мерчанта о финальных статусах ордера в платёжной системе предусмотрен механизм коллбэков (вебхуков).

Структура запроса#

Если при создании ордера мерчант указал поле callbackURL, на указанный URL будет отправлен POST-запрос в момент перехода ордера в один из триггерных статусов.

Заголовки:

  • Content-Type: application/json
  • X-Api-Version: v3 - пометка версии формата
  • X-Signature: <SIGNATURE> - подпись тела запроса. См. ниже раздел "Верификация"

Тело запроса - модель ордера OrderOut (см. "Общая информация"); для P2P - с блоком реквизитов paymentDetails:

{
  "id": "9c37e448-84b5-4639-9ffa-29558f8f2567",
  "createdAt": "2026-08-31T16:08:06.310479Z",
  "updatedAt": "2026-08-31T16:12:41.825346Z",
  "type": "PayIn",
  "direction": "PayIn",
  "status": "succeeded",
  "merchantOrderID": "TX-1",
  "clientID": "C1",
  "methodID": 9,
  "paymentDetails": {
    "requisiteTypeCode": "card",
    "recipientName": "Ivan Ivanov",
    "recipientNumber": "7777777777777777",
    "recipientBank": "SBER"
  },
  "currencyCode": "AZN",
  "amount": 10,
  "merchantCommission": 0.5,
  "amountUSDT": 5.617978,
  "merchantCommissionUSDT": 0.280899,
  "exchangeRate": 1.78,
  "trafficType": "mixed"
}

Статусы-триггеры#

Вебхук отправляется при переходе ордера в один из статусов:

  1. succeeded
  2. expired
  3. succeeded_by_appeal
  4. failed_by_appeal
  5. failed_by_terminal
  6. all_terminals_failed

Верификация#

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

Алгоритм получения подписи:

  1. Вычислить SHA256 хэш от тела запроса
  2. Подписать приватным RSA (PKCS #1 v1.5) ключом
  3. Закодировать в base64 std encoding

Полученная подпись передаётся в заголовке X-Signature.

Алгоритм верификации#

При получении запроса на webhook endpoint необходимо верифицировать его подпись по следующему алгоритму:

  1. Декодировать из base64 значение заголовка X-Signature
  2. Вычислить SHA256 хэш от полученного тела запроса
  3. Верифицировать подпись при помощи публичного ключа RSA
Пример реализации на Go
package main

import (
    "crypto"
    "crypto/rsa"
    "crypto/sha256"
    "crypto/x509"
    "encoding/base64"
    "encoding/pem"
    "fmt"
)

func VerifyRSASignature(publicKey *rsa.PublicKey, data []byte, signatureBase64 string) error {
    signature, err := base64.StdEncoding.DecodeString(signatureBase64)
    if err != nil {
        return err
    }

    hash := sha256.Sum256(data)

    err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hash[:], signature)
    if err != nil {
        return err
    }

    return nil
}

func main() {
    data := []byte(`<HTTP-REQUEST-BODY>`)
    signature := "<X-SIGNATURE-HEADER-VALUE>"
    pubKeyPEM := `<PUBLIC-KEY>`

    block, _ := pem.Decode([]byte(pubKeyPEM))
    if block == nil || block.Type != "PUBLIC KEY" {
        panic("не удалось декодировать публичный ключ")
    }

    pubKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
    if err != nil {
        panic(err)
    }

    pubKey, ok := pubKeyInterface.(*rsa.PublicKey)
    if !ok {
        panic("не удалось привести ключ к *rsa.PublicKey")
    }

    err = VerifyRSASignature(pubKey, data, signature)
    if err != nil {
        fmt.Println("Подпись недействительна:", err)
    } else {
        fmt.Println("Подпись верна!")
    }
}

Публичные RSA ключи#

Публичные ключи для проверки подписей предоставляются тех. специалистами платёжной системы при интеграции - отдельно для stage и prod контуров. См. страницу "Процесс интеграции".