User Manual
Overview
Get Balances
Balance History
Create Deposit Order
Get Deposit Order Detail
Cancel Deposit Order
Create Withdraw Order
Get Withdraw Order Detail
Cancel Withdraw Order
Create Exchange Order
Get Exchange Order Detail
Upload File
Customer Rate
Home/Overview

Overview

Last Updated: 2026-05-29

Base Information

Base Path
/v1
All external API endpoints in this reference are served under /v1.
Scope
External v1 API
This page documents the external API serving the /v1 business endpoints.
Authentication
Signed API key
Protected business endpoints use signed API key authentication instead of the previous token login flow.
Time Fields
Unix timestamp
Time fields returned by business APIs are Unix timestamps in seconds.
Amounts
Decimal strings
Monetary values are returned as decimal strings (never floats) to preserve precision — parse them with a decimal type.
Replay Protection
recvWindow
Signed requests must reach the server within recvWindow of their timestamp (default 5s, max 60s), otherwise they are rejected as expired.

Authentication

  • Header X-MBX-APIKEY: <ACCESS_ID> is required for every protected request. x-access-id is also accepted by the backend.
  • Signed parameter timestamp is required (milliseconds since epoch; microseconds are also accepted and normalized). A timestamp more than ~1s in the future is rejected.
  • Signed parameter recvWindow is optional (default 5000 ms, maximum 60000 ms). A request is rejected as expired once serverTime - timestamp exceeds recvWindow.
  • Signed parameter signature is required for all protected requests.

Signing Rules

  • Place all signed parameters in exactly one location: query string or request body. Do not split them across both.
  • signature itself is not part of the payload string being signed.
  • Parameters are signed in the exact order they are sent by the client.
  • Each key and value is URL-encoded with the safe character set -_.~ before joining as key=value.
  • For POST /v1/deposit/order, POST /v1/withdraw/order, and POST /v1/exchange/order, sign the JSON body fields excluding signature, then include the generated signature in that same JSON body.
Payload
key1=value1&key2=value2&timestamp=1717200000000&recvWindow=5000
HMAC-SHA256
import crypto from "crypto";

function buildSignedPayload(params) {
  return Object.entries(params)
    .filter(([, value]) => value !== undefined && value !== null && value !== "")
    .map(([key, value]) => {
      const encodedKey = encodeURIComponent(String(key))
        .replace(/[!'()*]/g, c => "%" + c.charCodeAt(0).toString(16).toUpperCase());
      const encodedValue = encodeURIComponent(String(value))
        .replace(/[!'()*]/g, c => "%" + c.charCodeAt(0).toString(16).toUpperCase());
      return `${encodedKey}=${encodedValue}`;
    })
    .join("&");
}

function signPayload(payload, secretKey) {
  return crypto.createHmac("sha256", secretKey).update(payload, "utf8").digest("hex");
}

const params = {
  currency: "NGN",
  timestamp: Date.now(),
  recvWindow: 5000
};

const payload = buildSignedPayload(params);
const signature = signPayload(payload, process.env.PAYANY_SECRET_KEY);

Permissions

EndpointPermissions
GET /v1/balanceUserData
GET /v1/balance/historyUserData
GET /v1/rateUserData
POST /v1/deposit/orderDeposit
GET /v1/deposit/order/{id}UserData
DELETE /v1/deposit/order/{id}Deposit
POST /v1/withdraw/orderWithdrawal
GET /v1/withdraw/order/{id}UserData
DELETE /v1/withdraw/order/{id}Withdrawal
POST /v1/exchange/orderTrade
GET /v1/exchange/order/{id}UserData
POST /v1/fileValid signed API key required

Response Example

{
  "code": 0,
  "data": {},
  "message": "Success"
}

{
  "code": 7012,
  "data": {},
  "message": "Invalid signature"
}

Client Examples

Java
LinkedHashMap<String, String> params = new LinkedHashMap<>();
params.put("currency", "NGN");
params.put("timestamp", String.valueOf(System.currentTimeMillis()));
params.put("recvWindow", "5000");

String payload = buildPayload(params);
String signature = sign(payload, secretKey);
String url = domain + "/v1/balance?" + payload + "&signature=" + signature;
JavaScript
const params = {
  currency: "NGN",
  timestamp: Date.now(),
  recvWindow: 5000
};

const payload = buildPayload(params);
const signature = sign(payload, secretKey);
const url = `${domain}/v1/balance?${payload}&signature=${signature}`;
Go
params := [][2]string{
  {"currency", "NGN"},
  {"timestamp", fmt.Sprintf("%d", time.Now().UnixMilli())},
  {"recvWindow", "5000"},
}

payload := buildPayload(params)
signature := sign(payload, secretKey)
Python
params = [
    ("currency", "NGN"),
    ("timestamp", int(time.time() * 1000)),
    ("recvWindow", 5000),
]

payload = build_payload(params)
signature = hmac.new(
    SECRET_KEY.encode("utf-8"),
    payload.encode("utf-8"),
    hashlib.sha256,
).hexdigest()
PHP
$params = [
    'currency' => 'NGN',
    'timestamp' => (string) round(microtime(true) * 1000),
    'recvWindow' => '5000',
];

$payload = build_payload($params);
$signature = hash_hmac('sha256', $payload, $secretKey);
Notes
  • If a request is initiated from a browser app, do not expose the secret key in browser code. Generate signatures on a trusted backend or server-side integration service.
  • file_ids in deposit and withdraw are currently stringified JSON arrays, not native JSON arrays.
  • deposit and withdraw orders are single-currency — one currency + amount (no price/rate); only exchange converts between two currencies.
  • The backend also supports RSA and Ed25519 signature verification when the API key is provisioned with that key type, but HMAC-SHA256 is the default client integration path documented here.
About
  • About Us
  • Terms of Service
  • Privacy Policy
Products
  • Deposit
  • Withdrawal
  • Exchange
Developers
  • API Docs
  • API Management
Support
  • Help Center
Community
Theme
    • About Us
    • Terms of Service
    • Privacy Policy
    • Deposit
    • Withdrawal
    • Exchange
    • API Docs
    • API Management
    • Help Center
© 2020-2026 PayAny.com. All rights reserved.