Skip to content

Quick Start

AnonyPay is a cryptocurrency payment gateway for merchants. Through a server-to-server HTTP API it lets you create deposit addresses, receive deposit notifications, and place withdrawal orders, with multi-chain support across TRON / Solana / ETH·BNB / TON today, with Bitcoin reserved and coming soon. Every business request, response, and callback is encrypted with RSA-OAEP, signed with SHA256withRSA, and protected against replay in both directions with a timestamp + nonce scheme. Integration boils down to three things: obtain your credentials and load the official SDK (available in PHP / Python / Node.js / Go / Java), implement the call chain of "get token → encrypt and sign the request → verify and decrypt the response", and implement an endpoint that handles platform callbacks.

Prerequisites

Before writing any code, confirm each of the following:

  1. You have all 4 credentials: APP-ID (merchant ID), the secret used to obtain tokens, the server public key public_t, and the merchant private key private_u. Keys are RSA-2048 in base64(PEM) format; see Credentials & Keys for how to obtain them and the format details. Keep your credentials safe and never expose them.
  2. Your server is NTP-synchronized: the protocol relies on second-precision Unix timestamps with a server-side window of only ±5 minutes; clock drift will directly trigger signatureFailed.
  3. Your egress IP is whitelisted: provide your server's egress IP to the platform for configuration. Requests from non-whitelisted IPs receive the plain-text response Oops (not JSON).
  4. Your runtime is ready: PHP requires the openssl extension; Python requires cryptography; Node.js uses the built-in crypto module (getToken() requires Node ≥ 18); Go / Java use only the standard library. See the SDK Overview for how to get each SDK.

The call flow: three steps

All business endpoints are POST requests against the base URL https://api.anonypay.io/api/merchant/.

①  getToken   ── exchange APP-ID + secret for a token (request body is neither encrypted nor signed;
                 the response, however, is still an encrypted + signed envelope — verify and decrypt it)
②  business   ── OAEP-encrypt the body → generate ts/nonce → SHA256-sign the canonical string
    endpoint     → POST with the 5 headers
③  response   ── check the time window / nonce → verify the signature → decrypt → get the business data
  1. getToken — authenticate with md5 over APP-ID + secret to obtain the ANONY-TOKEN required by all subsequent endpoints; this endpoint's request body is neither encrypted nor signed.
  2. Business request — RSA-OAEP-encrypt the business JSON into a ciphertext body, generate a timestamp and nonce, sign the canonical string with SHA256withRSA, and POST with the full set of ANONY-* request headers.
  3. Handle the response — validate the time window (±5 minutes) and deduplicate the nonce, verify the signature with the platform public key, then OAEP-decrypt data with the merchant private key to obtain the business data.

The getToken response is not a plain-text token

The getToken response is an encrypted + signed envelope just like every other endpoint. Always verify and decrypt it with the SDK before extracting the token field — never use the raw response body as the token.

Minimal examples in five languages

The examples below walk through "get token → create a TRON deposit address → verify and decrypt the response". getToken support varies by language: PHP / Node.js ship a ready-to-use getToken() (HTTP call included); Python / Go / Java provide authHeader() (which computes auth + md5(APP-ID & secret)), leaving the HTTP call to the library of your choice, with the response handled via verifyResponse / verify + decrypt.

php
require 'AnonyV2Client.php';
$client = new AnonyV2Client($appId, $serverPublicKeyB64, $merchantPrivateKeyB64);
$token  = $client->getToken($secret);  // md5 auth + verify/decrypt handled automatically, returns the token
$res = $client->post('createAddress', ['userOrder'=>'A1001','addressType'=>'trx'], $token);
// $res['data'] has already been verified and decrypted
python
from anony_v2 import AnonyV2Client, auth_header
import requests

c = AnonyV2Client(app_id, server_pub_b64, merchant_priv_b64)

# Get the token first: the request is unencrypted, md5 auth only;
# the response still needs signature verification + decryption
tr = requests.post(c.base_url + "getToken",
                   headers={"ANONY-APP-ID": str(app_id), "Authorization": auth_header(app_id, secret)})
tb = tr.json()
token = c.verify_response(tb["data"], tr.headers["ANONY-TIMESTAMP"],
                          tr.headers["ANONY-NONCE"], tr.headers["ANONY-SIGN"])["token"]

req = c.build_request({"userOrder": "A1001", "addressType": "trx"}, token)
r = requests.post(c.base_url + "createAddress", data=req["body"], headers=req["headers"])
body = r.json()
if body["code"] == 10000:
    data = c.verify_response(body["data"], r.headers["ANONY-TIMESTAMP"],
                             r.headers["ANONY-NONCE"], r.headers["ANONY-SIGN"])
js
const { AnonyV2Client } = require('./anony_v2');
const c = new AnonyV2Client(appId, serverPubB64, merchantPrivB64);
const token = await c.getToken(secret); // Node ≥18: md5 auth + verify/decrypt handled automatically, returns the token
const req = c.buildRequest({ userOrder: 'A1001', addressType: 'trx' }, token);
const r = await fetch(c.baseUrl + 'createAddress', { method: 'POST', body: req.body, headers: req.headers });
const body = await r.json();
if (body.code === 10000) {
  const data = c.verifyResponse(body.data, r.headers.get('anony-timestamp'),
    r.headers.get('anony-nonce'), r.headers.get('anony-sign'));
}
go
// The Go SDK (sdk/go/anonyv2.go, standard library only) does not include HTTP calls.
// Exported functions: Encrypt / Decrypt / Sign / Verify / Canonical / NewNonce / AuthHeader.
// JSON serialization and HTTP transport are handled by the library of your choice.
//
// Getting a token: use AuthHeader() to compute the Authorization header
// (auth + md5(APP-ID & secret)), POST to getToken, then process the response
// envelope with Verify + Decrypt and extract the token.
//
// Business requests: Encrypt the body → NewNonce to generate a random string
// → Canonical to build the signing string → Sign → POST with the 5 ANONY-* headers;
// process the response the same way with Verify + Decrypt.
java
// The Java SDK (sdk/java/AnonyV2Client.java, JDK standard library only) does not include HTTP calls.
// Static methods: encrypt / decrypt / sign / verify / canonical / newNonce / buildHeaders / authHeader.
// JSON serialization and HTTP transport are handled by the library of your choice.
//
// Getting a token: use authHeader() to compute the Authorization header
// (auth + md5(APP-ID & secret)), POST to getToken, then process the response
// envelope with verify + decrypt and extract the token.
//
// Business requests: encrypt the body → newNonce to generate a random string
// → canonical to build the signing string → sign → buildHeaders to assemble
// the request headers → POST; process the response the same way with verify + decrypt.

For full usage of the Go / Java SDKs, see Go SDK and Java SDK; for the parameters and response of createAddress, see Create Deposit Address.

TRON USDC deposits are closed: funds are not credited and no callback fires

Do not use the trx-type address created in these examples to receive USDC on TRON — deposits for that asset are closed. Incoming transfers are only recorded: they will not be credited and will not trigger a callback. For deposits on TRON, use TRX / USDT (TRC-20). See the API Reference for the supported asset enums.

Going live is a one-shot switch — once the platform enables it for your merchant ID, every subsequent business request is immediately validated against this protocol. If your SDK has any inconsistency at that point (OAEP hash, canonical string, signature algorithm, etc.), every request will fail and your business will be interrupted. selfcheck is a read-only integration probe that lets you exercise the full pipeline with real keys before enablement:

  • The server runs your request through the complete pipeline — token validation → timestamp/nonce anti-replay → SHA256 signature verification → OAEP decryption — then echoes the content back in the same v2 envelope.
  • A single successful call proves both directions at once: upstream (your encryption + signature is accepted by the server) and downstream (you can verify and decrypt the server's response).
  • The endpoint creates no orders or addresses and changes no state, so you can call it as many times as you like.
  • Once your self-check passes, notify the platform and it will complete the production enablement.

If you run into signatureFailed or decryption failures, work through the Troubleshooting Guide in order: ① is OAEP using SHA-1; ② does the canonical string use \n with the order ts, nonce, body; ③ are the key roles correct (upstream: encrypt with the platform public key, sign with the merchant private key); ④ is your server clock in sync.

Next steps