Introduction & Authentication
Welcome to the API documentation for merchant integration. Our API allows you to automate the creation of deposit (PayIn) and withdrawal (PayOut) requests, retrieve statistics, and manage your balance and disputes.
Authentication & Global Requirements
All API endpoints are accessible via the base URL of our service (e.g., https://{host}/). Every POST request to the API (except for public methods) must meet the following requirements:
- Method:
POST - Content-Type:
application/json - Accept:
application/json, text/plain
Additionally, each request must contain the following mandatory authentication headers:
X-App-Token— The merchant's public token (PublicToken).X-App-Access-Ts— Current Unix Timestamp (in seconds). The lifetime of the timestamp is limited.X-App-Access-Sig— Digital signature of the request in HMAC-SHA256 format (lowercase result).
Creating the Signature (X-App-Access-Sig)
To create the digital signature, use your secret key (SecretToken) and the email associated with your merchant account. Note: The timestamp and email strings must be concatenated directly, without any spaces or separators.
signStr = "{X-App-Access-Ts}{Email}"
X-App-Access-Sig = hex(HMAC_SHA256(signStr, SecretToken))
C# Example:
using System.Security.Cryptography;
using System.Text;
string time = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
string signStr = $"{time}{email}";
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secretToken));
byte[] hashValue = hmac.ComputeHash(Encoding.UTF8.GetBytes(signStr));
string signature = BitConverter.ToString(hashValue).Replace("-", "").ToLower();
Python Example:
import hmac
import hashlib
import time
unix_time = str(int(time.time()))
sign_str = f"{unix_time}{email}"
signature = hmac.new(
secret_token.encode('utf-8'),
sign_str.encode('utf-8'),
hashlib.sha256
).hexdigest()
Java Example:
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.time.Instant;
String time = String.valueOf(Instant.now().getEpochSecond());
String signStr = time + email;
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(secretToken.getBytes("UTF-8"), "HmacSHA256");
sha256_HMAC.init(secret_key);
byte[] hashValue = sha256_HMAC.doFinal(signStr.getBytes("UTF-8"));
StringBuilder signature = new StringBuilder();
for (byte b : hashValue) {
signature.append(String.format("%02x", b));
}
String result = signature.toString();
Webhook Authentication
To verify the authenticity of incoming callbacks to your server, we send a signature in the X-App-Access-Sig header.
CallBackToken — not the SecretToken you use to sign your own outgoing requests to our API. The two are independent fields of your merchant profile and are typically different values. Using SecretToken to verify a callback will always fail.
Verification Algorithm:
signStr = raw UTF-8 bytes of the HTTP request body (compact JSON, no whitespace)
X-App-Access-Sig = hex(HMAC_SHA256(signStr, CallBackToken)) // lowercase hex
Warning: Compute HMAC over the raw request body bytes as received, before any JSON deserialization. Re-serializing the parsed object will change whitespace, key order or escape casing and the signature will diverge.
No signature header? If your merchant profile has an empty CallBackToken, the system sends the callback without the X-App-Access-Sig header at all (the header is omitted, not empty). Either accept unsigned callbacks (if agreed with us) or reject them; in the latter case request a CallBackToken to be set on your account.
Comparison: Use a constant-time comparison (e.g., crypto.timingSafeEqual in Node.js, hmac.compare_digest in Python, CryptographicOperations.FixedTimeEquals in .NET) and compare in lowercase.