Signature
Every request carries two headers: appKey (your Application Key) and sign. The signature is computed over the exact raw request body you send.
sign = base64( HMAC-SHA256( appSecret, rawBody ) )
- Body may be
application/x-www-form-urlencoded(recommended, DeusaPay-compatible) orapplication/json. Sign the bytes exactly as transmitted — do not re-encode or re-order after signing. - GET requests have no body: sign the empty string
"". - The secret is used raw (not hex-decoded, not hashed).
Deposit signature
import { createHmac } from "node:crypto";
const body = new URLSearchParams({
bankId: "FIB", processId: "ORDER-1001", amount: "25000",
userId: "u-42", userName: "ahmed77", name: "Ahmed Al-Jubouri",
}).toString();
const sign = createHmac("sha256", APP_SECRET).update(body).digest("base64");
await fetch("https://api.deuspay.co/v1/transactions/deposit", {
method: "POST",
headers: { appKey: APP_KEY, sign, "content-type": "application/x-www-form-urlencoded" },
body,
});
$body = http_build_query([
'bankId' => 'FIB', 'processId' => 'ORDER-1001', 'amount' => '25000',
'userId' => 'u-42', 'userName' => 'ahmed77', 'name' => 'Ahmed Al-Jubouri',
]);
$sign = base64_encode(hash_hmac('sha256', $body, $APP_SECRET, true));
// POST $body with headers appKey / sign / Content-Type: application/x-www-form-urlencoded
import hmac, hashlib, base64, requests
from urllib.parse import urlencode
body = urlencode({"bankId": "FIB", "processId": "ORDER-1001", "amount": "25000",
"userId": "u-42", "userName": "ahmed77", "name": "Ahmed Al-Jubouri"})
sign = base64.b64encode(hmac.new(APP_SECRET.encode(), body.encode(), hashlib.sha256).digest()).decode()
requests.post("https://api.deuspay.co/v1/transactions/deposit", data=body,
headers={"appKey": APP_KEY, "sign": sign, "Content-Type": "application/x-www-form-urlencoded"})
Withdraw signature
Identical — sign the raw body of the withdraw request (which additionally contains accountName and iban).
Alternative: timestamped signature
If you prefer replay protection on requests, send X-Api-Key, X-Timestamp (unix seconds) and X-Signature = hex( HMAC-SHA256( appSecret, "<timestamp>.<rawBody>" ) ). Requests older than 5 minutes are rejected. Either scheme is accepted; do not mix both in one request.
A wrong signature returns
403 error_invalid_sign. The most common causes: signing a re-serialized body, trailing newline in the secret, or hex instead of base64 output.