Callback d’encaissement

The merchant server is called only after a pay-in completes successfully; the callback status is always completed.

Only final payment results are sent. Any HTTP 2xx response stops delivery immediately. After the first failure, the platform retries in 1 minute; after another failure, it makes a final retry in 5 minutes, for up to 3 attempts total. Callback business times use Beijing time in YYYY/MM/DD HH:mm:ss format.

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 de commande de la plateforme.
merchantOrderNostring | nullOuiNuméro de commande du commerçant.
bindKeystring | nullOuiClé de liaison pour la recharge des membres. Généralement vide pour les ordres de paiement partagés.
expectedAmountstringOuiMontant de la commande.
paidAmountstringOuiMontant réel payé.
chainCodestringOuiCode de chaîne.
tokenSymbolstringOuiSymbole de jeton.
txHashstringOuiHachage de transaction en chaîne.
fromAddressstring | nullOuiAdresse de l'expéditeur.
statusstringOuiFinal successful pay-in status; always completed.

Exemple de requête

{
  "merchantUid": "880001",
  "orderNo": "PI1776193200123ABCD1234",
  "merchantOrderNo": "M202604150001",
  "bindKey": "USER_90001",
  "expectedAmount": "100.000000",
  "paidAmount": "100.000000",
  "chainCode": "TRON",
  "tokenSymbol": "USDT",
  "txHash": "f7f17891f52c35d0c93170f0d12bb347ac16ab34853b4bc8dcf7fd0a8c9aa321",
  "fromAddress": "TS7b7iD8G2PaPqK1TqSmLJ9nrrYH4oKX1S",
  "status": "completed"
}

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: application/json

{
  "ok": true
}

Exemples de code

Node.js Exemple de vérification de rappel
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 });
  }

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

Notes

  • La vérification du rappel utilise apiKey, et non l'en-tête de demande de signature x OpenAPI.
  • Après vérification, contrôlez marchand, commande, actif, réseau et montant. Enregistrez paiement et résultat dans une transaction idempotente par commande avant de répondre 2xx ; aucun double crédit ou livraison.
  • Pour le rechargement des membres, utilisez bindKey directement comme identifiant de membre afin de ne pas avoir besoin d'une table de mappage orderNo supplémentaire vers le membre.