Callback de cobro

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 solicitud de creación de orden de pago body

Encabezados

CampoTipoObligatorioDescripción
content-typeapplication/jsonSíSiempre aplicación/json.
x-callback-timestampstringSíDevolución de llamada timestamp en milisegundos.
x-callback-noncestringSíDevolución de llamada nonce.
x-callback-signaturestringSíHMAC-SHA256(apiKey, timestamp + "." + nonce + "." + rawBody)。
x-callback-signature-algorithmstringSíSiempre HMAC-SHA256.
x-callback-signature-versionstringSíSiempre v1.

Parámetros

CampoTipoObligatorioDescripción
merchantUidstringSíMerchant UID.
orderNostringSíNúmero de pedido de la plataforma.
merchantOrderNostring | nullSíNúmero de pedido del comerciante.
bindKeystring | nullSíClave vinculante para recarga de socios. Generalmente vacío para órdenes de pago compartido.
expectedAmountstringSíImporte del pedido.
paidAmountstringSíMonto real pagado.
chainCodestringSíCódigo de cadena.
tokenSymbolstringSíSímbolo simbólico.
txHashstringSíHash de transacciones en cadena.
fromAddressstring | nullSíDirección del remitente.
statusstringSíFinal successful pay-in status; always completed.

Ejemplo de solicitud

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

Campos de respuesta

CampoTipoObligatorioDescripción
HTTP Status200-299SíCualquier respuesta 2xx se considera exitosa.
Response Bodystring | jsonNoLa respuesta body se puede personalizar.

Ejemplo de respuesta

HTTP/1.1 200 OK
Content-Type: application/json

{
  "ok": true
}

Ejemplos de código

Node.js Ejemplo de verificación de devolución de llamada
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 });
});

Notas

  • La verificación de devolución de llamada utiliza apiKey, no el encabezado de solicitud de firma x OpenAPI.
  • Tras verificar, comprueba comerciante, pedido, activo, red e importe. Guarda pago y resultado en una transacción idempotente por pedido de plataforma antes de responder 2xx; los duplicados no deben repetir abonos o entregas.
  • Para la recarga de miembros, utilice bindKey directamente como identificador de miembro para que no necesite una tabla de asignación adicional de orderNo a miembro.