Callback de paiement sortant

Les rappels de paiement utilisent les mêmes en-têtes de signature et le même mécanisme de nouvelle tentative que les rappels de paiement.

The platform calls back only when a payout reaches the confirmed or failed final state.

POSTnotifyUrl de la demande de création d'ordre de paiement body

En-têtes

ChampTypeObligatoireDescription
content-typeapplication/jsonOuiToujours application/json.
x-callback-timestampstringOuiRappel timestamp en millisecondes.
x-callback-noncestringOuiRappel nonce.
x-callback-signaturestringOuiHMAC-SHA256(apiKey, timestamp + "." + nonce + "." + rawBody)。
x-callback-signature-algorithmstringOuiToujours HMAC-SHA256.
x-callback-signature-versionstringOuiToujours v1.

Paramètres

ChampTypeObligatoireDescription
merchantUidstringOuiMerchant UID.
orderNostringOuiNuméro d’ordre de paiement de la plateforme.
merchantOrderNostring | nullOuiNuméro de commande du commerçant.
chainCodestringOuiCode de chaîne.
tokenSymbolstringOuiSymbole de jeton.
fromAddressstring | nullOuiAdresse de l'expéditeur.
toAddressstringOuiAdresse de réception.
txHashstring | nullNonHachage en chaîne.
amountstringOuiMontant du paiement.
statusstringOuiFinal payout state: confirmed or failed.
failedStagestringNonReturned only when status=failed.

Exemple de requête

{
  "merchantUid": "880001",
  "orderNo": "PO1776193200A1B2C3D4",
  "merchantOrderNo": "PO202604150001",
  "chainCode": "TRON",
  "tokenSymbol": "USDT",
  "fromAddress": "TNjBrNq2a9FK2vwu4W9C1QdLKSZ42Yx5YY",
  "toAddress": "TS7b7iD8G2PaPqK1TqSmLJ9nrrYH4oKX1S",
  "txHash": "b3d4fb0cb11eb86bb906d1e0ee3b84e17f40d5441d1e4c651ea46920a48a9a01",
  "amount": "35.500000",
  "status": "confirmed"
}

Champs de réponse

ChampTypeObligatoireDescription
HTTP Status200-299OuiToute réponse 2xx est considérée comme un succès.
Response Bodystring | jsonNonLa réponse body peut être personnalisée.

Exemple de réponse

HTTP/1.1 200 OK
Content-Type: text/plain

success

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

Notes

  • Handle callbacks idempotently by orderNo; only confirmed or failed final states are sent automatically.
  • Ce code vérifie uniquement les callbacks. Transmettez le corps brut à l’entrée standard et mappez les en-têtes vers UUGATE_CALLBACK_TIMESTAMP, UUGATE_CALLBACK_NONCE et UUGATE_CALLBACK_SIGNATURE. UUGATE_API_KEY doit être la clé utilisée pour créer la commande. Validez ensuite la commande et persistez-la de façon idempotente dans une transaction avant de renvoyer HTTP 2xx.