Callbacks#
A callback (webhook) mechanism is provided for notifying merchants about final order statuses in the payment system.
Request Structure#
If the merchant specified the callbackURL field when creating the order, a POST
request is sent to the specified URL at the moment the order transitions to one of the
trigger statuses.
Headers:
Content-Type: application/jsonX-Api-Version: v3- format version markerX-Signature: <SIGNATURE>- request body signature. See the "Verification" section below
The request body is the OrderOut order model (see "General Information");
for P2P it includes the paymentDetails block:
{
"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"
}
Trigger Statuses#
The webhook is sent when the order transitions to one of the statuses:
succeededexpiredsucceeded_by_appealfailed_by_appealfailed_by_terminalall_terminals_failed
Verification#
A body signature is sent with each request so that the merchant can verify its authenticity.
Signature algorithm:
- Compute the
SHA256hash of the request body - Sign it with the private
RSA (PKCS #1 v1.5)key - Encode with
base64 std encoding
The resulting signature is sent in the X-Signature header.
Verification Algorithm#
Upon receiving a request on the webhook endpoint, verify its signature using the following algorithm:
- Decode the
X-Signatureheader value frombase64 - Compute the
SHA256hash of the received request body - Verify the signature with the RSA public key
Go implementation example
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("failed to decode public key")
}
pubKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
panic(err)
}
pubKey, ok := pubKeyInterface.(*rsa.PublicKey)
if !ok {
panic("failed to cast key to *rsa.PublicKey")
}
err = VerifyRSASignature(pubKey, data, signature)
if err != nil {
fmt.Println("Signature is invalid:", err)
} else {
fmt.Println("Signature is valid!")
}
}
Public RSA Keys#
Public keys for signature verification are provided by the payment system technical specialists during integration - separately for the stage and prod environments. See the "Integration Process" page.