Webhooks
Atualizado:
Em vez de fazer consultas, você pode receber os eventos de um pedido em seu endpoint HTTPS. Os webhooks transmitem os mesmos eventos que Ordem dos eventos. O log de eventos permanece disponível com ou sem webhooks, portanto, você sempre pode recorrer à consulta periódica.
Configuração
Aprovado
callback_urlem Fazer um pedido, ou defina isso mais tarde com Ordem de atualização.A resposta retorna
webhook_secret(whsec_…) uma vez. Salve-o: ele assina todos os webhooks.Alteração
callback_urlemite um novo segredo. O segredo anterior continua assinando os webhooks por 24 horas: durante esse períodoX-PS-Signaturepossui duas assinaturas.
Solicitação
Propriedade | Valor |
|---|---|
Método |
|
Títulos |
|
Corpo do texto | Um evento, como em Ordem dos eventos; |
Sucesso | Qualquer |
Entrega | Pelo menos uma vez, sem ordem específica. Remova duplicatas por |
POST /hooks/proxy HTTP/1.1
Host: agent.example.com
Content-Type: application/json; charset=utf-8
User-Agent: ProxySeller-Webhooks/1
X-PS-Timestamp: 1762077838
X-PS-Signature: v1=5f0c2a…9e
{"event_id":"evt_01JZ8QA2C4E6G8J0K2M4P6R8T0","type":"order.active","created_at":"2026-11-02T10:03:58Z","api_version":"v1","order_id":"ord_01JZ8Q7K5N2R4T6V8X0Z2B4D6F","wallet":"0x857b06519e91e3a54538791bdbb0e22373e36b66","attempt":1,"data":{"lines":[{"line_id":"1","status":"active","delivered":2,"qty":2}],"expires_at":"2026-12-02T23:59:59Z"}}Verifique a assinatura
X-PS-Signature: v1=hex(HMAC-SHA256(key, timestamp + "." + raw_body))
key— os bytes (UTF-8) do todowebhook_secretstring, incluindo owhsec_prefixo.timestamp— o valor deX-PS-Timestamp, segundos Unix.raw_body— o corpo exatamente como recebido, antes de qualquer análise JSON.Durante 24 horas após uma alteração secreta, o cabeçalho fica
v1=<current>,v1=<previous>: aceite a solicitação se alguma delas corresponder.Rejeite solicitações cuja data e hora difiram do seu relógio em mais de 300 segundos.
Python
import hashlib
import hmac
import time
def verify(secret: str, timestamp: str, signature_header: str, raw_body: bytes, tolerance: int = 300) -> bool:
if abs(time.time() - int(timestamp)) > tolerance:
return False
expected = hmac.new(secret.encode(), timestamp.encode() + b"." + raw_body, hashlib.sha256).hexdigest()
candidates = [part.strip()[3:] for part in signature_header.split(",") if part.strip().startswith("v1=")]
return any(hmac.compare_digest(expected, candidate) for candidate in candidates)Node.js
import crypto from 'node:crypto';
function verify(secret, timestamp, signatureHeader, rawBody, toleranceSeconds = 300) {
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > toleranceSeconds) return false;
const expected = crypto.createHmac('sha256', secret).update(`${timestamp}.`).update(rawBody).digest('hex');
return signatureHeader.split(',').map((s) => s.trim()).filter((s) => s.startsWith('v1='))
.some((s) => s.length === expected.length + 3
&& crypto.timingSafeEqual(Buffer.from(s.slice(3)), Buffer.from(expected)));
}Novas tentativas
Regra | Valor |
|---|---|
Primeira tentativa | Não antes de 30 segundos após o evento |
Novas tentativas | Após 1 min, 5 min, 30 min, 2 h, 6 h, 12 h e 24 h: 8 tentativas em cerca de 44,6 horas |
Muito antigo | Um evento com mais de aproximadamente 45,6 horas não é mais enviado |
Disjuntor | Após três falhas consecutivas, os demais eventos da ordem aguardam a próxima tentativa |
Desativação | Se a última tentativa de um evento falhar e a URL não tiver aceitado nenhum webhook desde que esse evento foi criado, a entrega para a URL será desativada. O pedido em si não é afetado |
Para habilitar uma URL desativada, envie-a novamente com Ordem de atualização: o mesmo URL no máximo uma vez por hora; um novo URL a qualquer momento. Eventos perdidos estão sempre em Ordem dos eventos.
regras do callback_url
Verificado quando o orçamento for emitido e em PATCH. Uma violação resulta em 400 invalid_request:
Regra | detalhe |
|---|---|
ASCII imprimível, até 2.048 caracteres |
|
|
|
Não inclua login nem senha na URL |
|
Sem fragmento |
|
Apenas porta 443 |
|
Um nome DNS público, um endereço IPv4 canônico ou um endereço IPv6 entre colchetes |
|
Todos os endereços do servidor são públicos |
|
Não é um provedor do próprio serviço |
|
O DNS é verificado novamente antes de cada envio; a solicitação é enviada apenas para os endereços verificados.