Inicio rápido

Si solo desea completar la primera integración, esta página es suficiente: genere encabezados firmados, cree una orden de pago, luego verifique la devolución de llamada y devuelva una respuesta 2xx.

Los ejemplos utilizan la creación de órdenes de pago de forma predeterminada. Las órdenes de pago utilizan la misma firma, encabezados de solicitud y encabezados de devolución de llamada; solo cambian el punto final y la carga útil empresarial.

API de producciónhttps://api.uugate.com
Activos compatiblesTRC20-USDT · BEP20-USDT · BEP20-USDC · SPL-USDC
Configuración de callbackAPI Key + notifyUrl
✓Merchant UID es la identidad comercial única asignada por la plataforma. Se utiliza en x-merchant-uid y cargas útiles de devolución de llamada.
✓Prepare el API Key comenzando con mch_ de la configuración del comerciante API.
✓Prepare un notifyUrl accesible públicamente propiedad del comerciante; es necesario al crear pedidos.
Step 1

Generar encabezados firmados

Las solicitudes OpenAPI utilizan cinco encabezados: x-api-key, x-merchant-uid, x-timestamp, x-nonce y x-signature.

  • Utilice el mismo mch_ API Key como x-api-key y como secreto de firma.
  • La ruta de la firma debe ser únicamente la ruta API, por ejemplo /openapi/payin/orders, sin el dominio.
  • La carga útil de la firma es Merchant UID, timestamp, nonce, método, ruta, canónico query y canónico body.
Node.js
import { createHmac, randomBytes } from 'node:crypto';

function required(name) {
  const value = process.env[name]?.trim();
  if (!value) throw new Error(name + ' is required');
  return value;
}
const uid = "880001", key = "mch_xxxxxxxxxxxxxxxxxxxx";
const timestamp = "1776193200000", nonce = "2f5c7b147c3748f0a8b3d9bb38aa91a4";
const method = 'POST', path = '/openapi/payin/orders';
const canonicalQuery = '', canonicalBody = "{\"amount\":\"100.00\",\"chainCode\":\"TRON\",\"merchantOrderNo\":\"M202604150001\",\"notifyUrl\":\"https://merchant.example.com/api/uugate/payin-notify\",\"tokenSymbol\":\"USDT\"}";
const payload = [uid, timestamp, nonce, method, path, canonicalQuery, canonicalBody].join('\n');
const signature = createHmac('sha256', key).update(payload, 'utf8').digest('hex');
console.log(signature);
Step 2

Crear pedido de cobro

Después de preparar los encabezados firmados, llame a la orden de pago de creación API. En caso de éxito, utilice orderNo, cashierUrl y paymentUri.

  • Punto final: POST /openapi/payin/orders.
  • Utilice el cashierUrl devuelto cuando la interfaz del comerciante necesite redirigir al pago.
  • notifyUrl es obligatorio y se pasa con la solicitud de pedido. No se necesita una configuración de devolución de llamada de backend por separado.
Node.js
import { createHmac, randomBytes } from 'node:crypto';

function required(name) {
  const value = process.env[name]?.trim();
  if (!value) throw new Error(name + ' is required');
  return value;
}
const uid = required("UUGATE_MERCHANT_UID"), key = required("UUGATE_API_KEY");
const timestamp = String(Date.now()), nonce = randomBytes(16).toString("hex");
const method = 'POST', path = '/openapi/payin/orders';
const canonicalQuery = '', canonicalBody = "{\"amount\":\"100.00\",\"chainCode\":\"TRON\",\"merchantOrderNo\":\"M202604150001\",\"notifyUrl\":\"https://merchant.example.com/api/uugate/payin-notify\",\"tokenSymbol\":\"USDT\"}";
const payload = [uid, timestamp, nonce, method, path, canonicalQuery, canonicalBody].join('\n');
const signature = createHmac('sha256', key).update(payload, 'utf8').digest('hex');
const base = (process.env.UUGATE_BASE_URL || 'https://api.uugate.com').replace(/\/+$/, '');
const response = await fetch(base + path, {
  method, redirect: 'error', signal: AbortSignal.timeout(30000),
  headers: { 'Content-Type': 'application/json', 'x-api-key': key, 'x-merchant-uid': uid,
    'x-timestamp': timestamp, 'x-nonce': nonce, 'x-signature': signature },
  ...(canonicalBody ? { body: canonicalBody } : {}),
});
const raw = await response.text();
if (!response.ok) throw new Error('HTTP ' + response.status + ': ' + (raw || 'empty response body'));
JSON.parse(raw);
console.log(raw);
Step 3

Recibir y procesar devolución de llamada

Cuando la plataforma llame a su notifyUrl, verifíquelo primero con apiKey, actualice la orden comercial después de la verificación y luego devuelva 200 u otra respuesta 2xx.

  • La verificación de devolución de llamada utiliza apiKey, no la firma x OpenAPI.
  • Para el pago, trate status=completed como el estado de éxito final.
  • Este código solo verifica callbacks. Usa el cuerpo original como entrada estándar y asigna los encabezados a UUGATE_CALLBACK_TIMESTAMP, UUGATE_CALLBACK_NONCE y UUGATE_CALLBACK_SIGNATURE. UUGATE_API_KEY debe ser la clave de creación del pedido. Después valida el pedido y persiste con idempotencia transaccional antes de devolver HTTP 2xx.
Node.js
import { createHmac, timingSafeEqual } from 'node:crypto';

function required(name) {
  const value = process.env[name]?.trim();
  if (!value) throw new Error(name + ' is required');
  return value;
}
const key = required('UUGATE_API_KEY');
const timestamp = required('UUGATE_CALLBACK_TIMESTAMP'), nonce = required('UUGATE_CALLBACK_NONCE');
const signature = required('UUGATE_CALLBACK_SIGNATURE');
const chunks = [];
for await (const chunk of process.stdin) chunks.push(chunk);
const rawBody = Buffer.concat(chunks);
const expected = createHmac('sha256', key).update(timestamp + '.' + nonce + '.', 'utf8').update(rawBody).digest();
const actual = Buffer.from(signature, 'hex');
if (!/^[a-fA-F0-9]{64}$/.test(signature) || actual.length !== expected.length || !timingSafeEqual(expected, actual))
  throw new Error('Invalid callback signature');
console.log('VERIFIED');

El timestamp, nonce y las credenciales fijos son valores de prueba de firma sin conexión. Para solicitudes reales, usa el timestamp actual en milisegundos y un nonce aleatorio nuevo. Las rutas API no tienen prefijo de versión; v1 solo identifica la firma de callbacks.

Ejecución: guarda Java como UUGateExample.java (UUGateCallback.java para callbacks) y usa java nombre de archivo; PHP: php example.php; Go: go run example.go; Node.js: node example.mjs. La verificación de callbacks lee el cuerpo original desde la entrada estándar.

El pago y el pago comparten el mismo algoritmo de firma y encabezados de devolución de llamada, por lo que no necesita dos flujos de autenticación.

Una vez que esta página tenga sentido, continúe hacia abajo para obtener parámetros detallados, estructuras de respuesta y descargas SDK.