Créer un portefeuille exclusif

Crée une adresse de réception exclusive pour un bindKey. Les futurs dépôts à cette adresse appartiennent en permanence à ce bindKey.

Si notifyUrl est fourni, les futures commandes de recharge créées automatiquement pour cette adresse exclusive rappelleront d'abord ce URL. Ceci est utile lorsque chaque site ou application reçoit ses propres notifications de recharge de membres.

POST/openapi/payin/exclusive-bindings

En-têtes

ChampTypeObligatoireDescription
x-api-keystringOuiMarchand API Key. Utilisez la valeur commençant par mch_ de la page des paramètres API du marchand.
x-merchant-uidstringOuiMerchant UID.
x-timestampstringOuiMilliseconde à 13 chiffres timestamp. La dérive d'horloge autorisée par défaut est de 5 minutes.
x-noncestringOuiChaîne aléatoire unique pour chaque requête, jusqu'à 128 caractères. La réutilisation est rejetée.
x-signaturestringOuiSignature hexadécimale générée avec HMAC-SHA256. La charge utile contient Merchant UID, timestamp, nonce, la méthode, le chemin, le query canonique et le body canonique.

Paramètres

ChampTypeObligatoireDescription
chainCodestringOuiCode de chaîne. Valeurs prises en charge : TRON / BSC / SOL.
tokenSymbolstringOuiSymbole de jeton.
bindKeystringOuiClé de liaison unique côté commerçant. Maximum 128 caractères.
labelstringNonRemarque contraignante. Maximum 100 caractères.
notifyUrlstringNonRappel indépendant URL pour cette adresse exclusive. Les commandes créées automatiquement à partir des dépôts futurs seront rappelées ici en premier. Maximum 500 caractères ; les destinations privées, loopback ou non sécurisées sont interdites.

Exemple de requête

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

Champs de réponse

ChampTypeObligatoireDescription
bindingIdnumberOuiID d’enregistrement de liaison.
chainCodestringOuiCode de chaîne.
tokenSymbolstringOuiSymbole de jeton.
bindKeystringOuiClé de liaison.
addressIdnumberOuiIdentifiant d'adresse.
addressstringOuiAdresse de réception exclusive.
addressTypestringOuiToujours exclusif.
notifyUrlstring | nullOuiRappel exclusif URL utilisé par cette liaison.
statusstringOuiReliure status.

Exemple de réponse

{
  "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"
}

Exemples de code

Exécution : enregistrez Java sous UUGateExample.java (UUGateCallback.java pour les callbacks), puis utilisez java nom du fichier ; PHP : php example.php ; Go : go run example.go ; Node.js : node example.mjs. Les vérificateurs de callback lisent le corps brut sur l’entrée standard.

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);

Notes

  • Si le même bindKey est créé à nouveau, la plateforme renvoie de manière idempotente la liaison et l'adresse existantes, ce qui fonctionne bien pour un flux get-or-create.
  • Pour la recharge des membres, transmettez notifyUrl au moment de la liaison afin que les dépôts de n'importe quel montant à l'adresse exclusive soient rappelés directement sur le site ou l'application correspondant.
  • Les quatre langages utilisent les mêmes chemins, paramètres et réponses. Les identifiants proviennent de UUGATE_MERCHANT_UID et UUGATE_API_KEY ; UUGATE_BASE_URL vaut https://api.uugate.com par défaut.
  • canonicalBody est un JSON compact aux clés triées. Après modification, triez les objets récursivement, conservez l’ordre des tableaux et utilisez UTF-8 sans échappement supplémentaire des barres obliques ou Unicode. Les montants sont des chaînes, les booléens true / false.
  • Une réponse réussie renvoie directement l’objet métier, sans enveloppe code / data. Vérifiez d’abord le statut HTTP. Les erreurs métier renvoient code, message, data et requestId ; les refus de sécurité peuvent se limiter à HTTP 401 / 403 avec un corps vide.
  • Après un timeout ou HTTP 5xx, consultez la commande avant de répéter sa création ou son envoi. Générez un nouveau timestamp, nonce et une nouvelle signature pour chaque requête.