Ir para a navegação

Webhook Eventos e avisos de liquidação

Tipos de eventos do comerciante Webhook, identidades de idempotência, campos de aviso de liquidação e exemplos de resultados de fundos.

Ver como Markdown

Esta página segue Agent Java SDK WEBHOOKS.md no commit fa6c7b6. Esta é uma atualização apenas de documentação; nenhum novo artefato SDK contendo métodos auxiliares de aviso foi lançado.

Todos os quatro tipos de eventos usam o retorno de chamada configurado único do comerciante URL (agents.webhook_url). Despacho no corpo event; nenhum aviso separado URL é necessário. Os exemplos mostram a estrutura da carga útil e não devem ser usados ​​para injetar dados em um ambiente de teste.

Eventos e idempotência

eventSignificadotargetStatus / chave de desduplicação
transfer.completedTransferir o estado terminal, incluindo uma atualização do pedido original após a reversão; não necessariamente bem sucedidoSUCCESS / FAILED / REVERSED; orderType:orderId:targetStatus
reverse.completedEstado terminal da ordem de reversãoSUCCESS / FAILED; orderType:orderId:targetStatus
transfer.deadO estado final do pedido de fundos permanece não confirmado após novas tentativas e precisa de reconciliação manual; não é uma falha confirmadaDEAD; orderType:orderId:targetStatus
liquidation.warningAviso de risco de liquidação, sem campos de estado terminal do pedidoliquidation.warning:notificationId

O evento de aviso do comerciante é liquidation.warning; o usuário WebSocket data.event permanece LIQUIDATION_WARNING. Mantenha os dois canais distintos.

Notificações históricas do comerciante usadas LIQUIDATION_WARNING. As cargas congeladas mantêm seu corpo original nas novas tentativas, portanto, os receptores devem reconhecer ambos os nomes. Se os registros comerciais existentes usarem um prefixo de chave de aviso em letras maiúsculas, retenha a chave original ou verifique ambas as chaves durante a migração para evitar processar a notificação novamente.

O WebhookVerifier.idempotencyKey atual apenas extrai orderType:orderId:targetStatus para eventos de fundos e retorna uma string vazia para cargas úteis de aviso. Nenhum novo artefato SDK contendo métodos auxiliares de aviso foi lançado com esta atualização de documentação. Continue usando o método verify existente para verificar o corpo do aviso bruto. Após as verificações de assinatura e propriedade, o código comercial do comerciante deve reconhecer ambos os nomes de eventos, validar se notificationId é uma string de número inteiro decimal positivo e construir liquidation.warning:<notificationId>. Nunca use uma chave de desduplicação vazia ou exija que avisos contenham campos de pedidos de fundos.

Persista a desduplicação no escopo do comerciante e environment e confirme-a atomicamente com o processamento de negócios. Notificações FIRST / UPGRADE / REMINDER com valores notificationId diferentes são independentes; não os descarte agrupando-os por usuário, episódio ou eventType. Uma chave vazia significa que uma identidade válida não pôde ser extraída. O SDK retorna apenas uma chave auxiliar; ele não persiste registros nem executa processamento comercial. Registrar a mesma identidade com corpo diferente como conflito; não substitua o corpo processado.

Campos de aviso de liquidação e exemplo

CampoTipo/descrição
notificationIdString de número inteiro decimal positivo; ID de notificação exclusivo. Não o converta em um número de ponto flutuante.
eventTypeFIRST: primeiro aviso no episódio atual; UPGRADE: risco normal elevado a alto risco neste episódio; REMINDER: outro lembrete do risco contínuo.
severityNORMAL / HIGH. FIRST já pode ser HIGH; UPGRADE é HIGH; REMINDER pode ser NORMAL ou HIGH.
occurredAtJSON número; Milissegundos Unix quando o aviso foi acionado, não quando a entrega HTTP chegou.
objecttype=CROSS: conta de margem cruzada, com strings vazias para symbol, side e positionId. ISOLATED: posição com margem isolada, contendo o correspondente contrato, lado e ID da posição.
episodeCorda; episódio de aviso atual. FIRST não significa o primeiro aviso do usuário.
stateVersion / configVersionCordas; estado upstream/versão de configuração. Não descarte notificações de forma independente com base nesses campos.
riskRatio / minLargePositionValue / liquidationHighRiskThresholdSequências decimais para a taxa de risco, limite de aviso normal e limite de alto risco. Preservar a precisão; upstream calcula as regras de limite.
environmentPRODUCTION / SIMULATED; isolado pelo ambiente de fundos configurado, não pelo nome do servidor.
agentId / agentCode / agentUserIdCordas; ID do agente, código do agente e ID do usuário do comerciante.
platformUserIdCorda; ID de usuário da plataforma pública correspondente ao resultado da ligação, não ao user_id interno do serviço.
{
"event": "liquidation.warning",
"notificationId": "68460336",
"eventType": "FIRST",
"severity": "NORMAL",
"occurredAt": 1791875870804,
"object": {
"type": "CROSS",
"symbol": "",
"side": "",
"positionId": ""
},
"episode": "3",
"stateVersion": "9",
"riskRatio": "0.29133109",
"minLargePositionValue": "0.20000000",
"liquidationHighRiskThreshold": "0.40000000",
"configVersion": "8",
"environment": "PRODUCTION",
"agentId": "16",
"agentCode": "DEMO",
"agentUserId": "merchant-user-001",
"platformUserId": "6054354872"
}

Exemplo de resultado de transferência

Os retornos de chamada de fundos mantêm seus tipos existentes: orderId e agentId são números JSON; amount e platformUserId são strings. Não aplique a convenção de string agentId do aviso para retornos de chamada de fundos. Leia números inteiros grandes sem perda de precisão usando tipos inteiros/decimais. completedAt é UTC RFC3339; ts são segundos Unix.

{
"environment": "PRODUCTION",
"event": "transfer.completed",
"orderType": "transfer",
"orderId": 10001,
"orderNo": "merchant-order-001",
"targetStatus": "SUCCESS",
"agentId": 16,
"agentCode": "DEMO",
"currency": "USDT",
"amount": "10.00",
"direction": "IN",
"transferMode": "FIXED_AMOUNT",
"agentUserId": "merchant-user-001",
"platformUserId": "6054354872",
"rejectCode": 0,
"rejectMessage": "",
"failReason": "",
"completedAt": "2026-10-13T07:17:50Z",
"ts": 1791875870
}

Exemplo de resultado de reversão

{
"environment": "PRODUCTION",
"event": "reverse.completed",
"orderType": "transfer",
"orderId": 10002,
"orderNo": "merchant-reverse-001",
"targetStatus": "SUCCESS",
"agentId": 16,
"agentCode": "DEMO",
"currency": "USDT",
"amount": "10.00",
"direction": "IN",
"transferMode": "FIXED_AMOUNT",
"agentUserId": "merchant-user-001",
"platformUserId": "6054354872",
"rejectCode": 0,
"rejectMessage": "",
"failReason": "",
"completedAt": "2026-10-13T07:17:50Z",
"ts": 1791875870
}

Exemplo de estado morto de pedido de fundos

{
"environment": "PRODUCTION",
"event": "transfer.dead",
"orderType": "transfer",
"orderId": 10003,
"orderNo": "merchant-order-002",
"targetStatus": "DEAD",
"agentId": 16,
"agentCode": "DEMO",
"currency": "USDT",
"amount": "10.00",
"direction": "IN",
"transferMode": "FIXED_AMOUNT",
"agentUserId": "merchant-user-001",
"platformUserId": "6054354872",
"rejectCode": 0,
"rejectMessage": "",
"failReason": "order dead",
"completedAt": "2026-10-13T07:17:50Z",
"ts": 1791875870
}

Estes exemplos mostram apenas o protocolo. Para FAILED, rejectCode, rejectMessage e failReason refletem a rejeição real. O nome do evento por si só não prova que os fundos foram creditados.

Verificação de assinatura, respostas e novas tentativas