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.
En-têtes
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
| content-type | application/json | Oui | Toujours application/json. |
| x-callback-timestamp | string | Oui | Rappel timestamp en millisecondes. |
| x-callback-nonce | string | Oui | Rappel nonce. |
| x-callback-signature | string | Oui | HMAC-SHA256(apiKey, timestamp + "." + nonce + "." + rawBody)。 |
| x-callback-signature-algorithm | string | Oui | Toujours HMAC-SHA256. |
| x-callback-signature-version | string | Oui | Toujours v1. |
Paramètres
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
| merchantUid | string | Oui | Merchant UID. |
| orderNo | string | Oui | Numéro de commande de la plateforme. |
| merchantOrderNo | string | null | Oui | Numéro de commande du commerçant. |
| bindKey | string | null | Oui | Clé de liaison pour la recharge des membres. Généralement vide pour les ordres de paiement partagés. |
| expectedAmount | string | Oui | Montant de la commande. |
| paidAmount | string | Oui | Montant réel payé. |
| chainCode | string | Oui | Code de chaîne. |
| tokenSymbol | string | Oui | Symbole de jeton. |
| txHash | string | Oui | Hachage de transaction en chaîne. |
| fromAddress | string | null | Oui | Adresse de l'expéditeur. |
| status | string | Oui | Final 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
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
| HTTP Status | 200-299 | Oui | Toute réponse 2xx est considérée comme un succès. |
| Response Body | string | json | Non | La 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.