Crear cartera exclusiva

Crea una dirección de recepción exclusiva para un bindKey. Los depósitos futuros a esta dirección pertenecen permanentemente a ese bindKey.

Si se proporciona notifyUrl, las futuras órdenes de recarga creadas automáticamente para esta dirección exclusiva devolverán la llamada a ese URL primero. Esto es útil cuando cada sitio o aplicación recibe sus propias notificaciones de recarga para miembros.

POST/openapi/payin/exclusive-bindings

Encabezados

CampoTipoObligatorioDescripción
x-api-keystringSíComerciante API Key. Utilice el valor que comienza con mch_ de la página de configuración del comerciante API.
x-merchant-uidstringSíMerchant UID.
x-timestampstringSíMilisegundo de 13 dígitos timestamp. La desviación del reloj permitida por defecto es de 5 minutos.
x-noncestringSíCadena aleatoria única para cada solicitud, hasta 128 caracteres. Se rechaza la reutilización.
x-signaturestringSíFirma hexadecimal generada con HMAC-SHA256. La carga útil contiene Merchant UID, timestamp, nonce, método, ruta, query canónico y body canónico.

Parámetros

CampoTipoObligatorioDescripción
chainCodestringSíCódigo de cadena. Valores admitidos: TRON / BSC / SOL.
tokenSymbolstringSíSímbolo simbólico.
bindKeystringSíClave vinculante única en el lado del comerciante. Máximo 128 caracteres.
labelstringNoObservación vinculante. Máximo 100 caracteres.
notifyUrlstringNoDevolución de llamada independiente URL para esta dirección exclusiva. Las órdenes creadas automáticamente a partir de depósitos futuros se devolverán aquí primero. Máximo 500 caracteres; destinos privados, loopback o inseguros están prohibidos.

Ejemplo de solicitud

{
  "chainCode": "TRON",
  "tokenSymbol": "USDT",
  "bindKey": "USER_90001",
  "label": "VIP User 90001",
  "notifyUrl": "https://merchant.example.com/api/uugate/member-topup-notify"
}

Campos de respuesta

CampoTipoObligatorioDescripción
bindingIdnumberSíID de registro vinculante.
chainCodestringSíCódigo de cadena.
tokenSymbolstringSíSímbolo simbólico.
bindKeystringSíClave de encuadernación.
addressIdnumberSíIdentificación de dirección.
addressstringSíDirección de recepción exclusiva.
addressTypestringSíSiempre exclusivo.
notifyUrlstring | nullSíDevolución de llamada exclusiva URL utilizada por este enlace.
statusstringSíEncuadernación status.

Ejemplo de respuesta

{
  "bindingId": 70031,
  "chainCode": "TRON",
  "tokenSymbol": "USDT",
  "bindKey": "USER_90001",
  "addressId": 31088,
  "address": "TQ3sCY8k9h7G9UsApY3JPt5VDpNKr2kJ1E",
  "addressType": "exclusive",
  "notifyUrl": "https://merchant.example.com/api/uugate/member-topup-notify",
  "status": "active"
}

Ejemplos de código

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.

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/exclusive-bindings';
const canonicalQuery = '', canonicalBody = "{\"bindKey\":\"USER_90001\",\"chainCode\":\"TRON\",\"label\":\"VIP User 90001\",\"notifyUrl\":\"https://merchant.example.com/api/uugate/member-topup-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);

Notas

  • Si se vuelve a crear el mismo bindKey, la plataforma devuelve de forma idempotente el enlace y la dirección existentes, lo que funciona bien para un flujo de obtención o creación.
  • Para recarga de miembros, pase notifyUrl en el momento vinculante para que los depósitos de cualquier monto en la dirección exclusiva devuelvan la llamada directamente al sitio o aplicación correspondiente.
  • Los cuatro lenguajes comparten rutas, parámetros y respuestas. Las credenciales se leen de UUGATE_MERCHANT_UID y UUGATE_API_KEY; UUGATE_BASE_URL usa https://api.uugate.com por defecto.
  • canonicalBody es JSON compacto con claves ordenadas. Al modificar parámetros, ordena objetos recursivamente, conserva el orden de arrays y usa UTF-8 sin escapes adicionales de barras ni Unicode. Los importes son cadenas y los booleanos true / false.
  • El éxito devuelve directamente el objeto de negocio, sin envoltorio code / data. Comprueba primero el estado HTTP. Los errores devuelven code, message, data y requestId; un rechazo de seguridad puede ser solo HTTP 401 / 403 sin cuerpo.
  • Tras un timeout o HTTP 5xx, consulta el pedido antes de repetir su creación o envío. Genera un timestamp, nonce y firma nuevos en cada solicitud.