Quick Start

If you just want to complete the first integration, this page is enough: generate signed headers, create a pay-in order, then verify the callback and return a 2xx response.

The examples use pay-in order creation by default. Payout orders use the same signature, request headers, and callback headers; only the endpoint and business payload change.

Production APIhttps://api.uugate.com
Supported assetsTRC20-USDT · BEP20-USDT · BEP20-USDC · SPL-USDC
Callback setupAPI Key + notifyUrl
✓Prepare your Merchant UID.
✓Prepare the API Key beginning with mch_ from the merchant API settings.
✓Prepare a publicly reachable notifyUrl owned by the merchant; it is required when creating orders.
Step 1

Generate Signed Headers

OpenAPI requests use five headers: x-api-key, x-merchant-uid, x-timestamp, x-nonce, and x-signature.

  • Use the same mch_ API Key as both x-api-key and the signing secret.
  • The signature path must be the API path only, for example /openapi/payin/orders, without the domain.
  • The signature payload is Merchant UID, timestamp, nonce, method, path, canonical query, and canonical body.
Minimal Node.js Signature Example
import crypto from 'node:crypto';

const merchantUid = '880001';
const apiKey = 'mch_xxxxxxxxxxxxxxxxxxxx';
const timestamp = String(Date.now());
const nonce = crypto.randomBytes(16).toString('hex');
const method = 'POST';
const path = '/openapi/payin/orders';
const canonicalQuery = '';
const canonicalBody = '{"amount":"100.00","chainCode":"TRON","merchantOrderNo":"M202604170001","notifyUrl":"https://merchant.example.com/api/uugate/payin-notify","tokenSymbol":"USDT"}';

const payload = [
  merchantUid,
  timestamp,
  nonce,
  method,
  path,
  canonicalQuery,
  canonicalBody,
].join('\n');

const signature = crypto.createHmac('sha256', apiKey).update(payload).digest('hex');
Step 2

Create Pay-in Order

After preparing the signed headers, call the create pay-in order API. On success, use orderNo, cashierUrl, and paymentUri.

  • Endpoint: POST /openapi/payin/orders.
  • Use the returned cashierUrl when the merchant frontend needs to redirect to checkout.
  • notifyUrl is required and is passed with the order request. No separate backend callback configuration is needed.
  • For payout, change the path to /openapi/payout/orders and submit the payout parameters.
Node.js Order Creation Example
import { UUGateClient } from 'uugate-openapi-sdk';

const client = new UUGateClient({
  baseUrl: 'https://api.uugate.com',
  merchantUid: '880001',
  apiKey: 'mch_xxxxxxxxxxxxxxxxxxxx',
});

const order = await client.createPayinOrder({
  chainCode: 'TRON',
  tokenSymbol: 'USDT',
  merchantOrderNo: 'M202604170001',
  amount: '100.00',
  notifyUrl: 'https://merchant.example.com/api/uugate/payin-notify',
});

console.log(order.orderNo, order.cashierUrl);
Step 3

Receive and Process Callback

When the platform calls your notifyUrl, verify it with apiKey first, update the business order after verification, then return 200 or another 2xx response.

  • Callback verification uses apiKey, not the OpenAPI x-signature.
  • For pay-in, treat status=completed as the final success state.
  • For payout, focus on status=confirmed and status=failed.
Minimal Callback Handler Example
import express from 'express';
import { verifyCallbackSignature } from 'uugate-openapi-sdk';

const app = express();
app.use(express.json({
  verify: (req, _res, buffer) => {
    req.rawBody = buffer.toString('utf8');
  },
}));

app.post('/merchant/callback', (req, res) => {
  const valid = verifyCallbackSignature({
    apiKey: process.env.UUGATE_API_KEY,
    timestamp: req.header('x-callback-timestamp'),
    nonce: req.header('x-callback-nonce'),
    signature: req.header('x-callback-signature'),
    rawBody: req.rawBody || '',
  });

  if (!valid) {
    return res.status(401).json({ ok: false });
  }

  if (req.body.status === 'completed') {
    // 更新商户订单为成功
  }

  return res.status(200).json({ ok: true });
});

Pay-in and payout share the same signing algorithm and callback headers, so you do not need two authentication flows.

Once this page makes sense, continue down for detailed parameters, response structures, and SDK downloads.