PayZuDocs
Sandbox

沙盒中的 Webhook

只有在 URL 证明归属之后才开始投递:X-Callback-Challenge 质询、pending、verified 和 failed 状态,以及如何重新验证。

在生产环境,通过 POST /v1/user/webhooks 注册的 webhook 会立即收到投递。在沙盒中,任何人都可以生成凭证并把 webhook 指向任意地址,因此只有在 URL 证明归你所有之后才开始投递:

  1. 注册时,沙盒向该 URL 发送 POST,token 放在 X-Callback-Challenge header 中,body 为 {}
  2. endpoint 返回 2xx 并回显 token,可以是纯文本 body,也可以是 {"challenge":"<token>"}
  3. 在通过之前,webhook 保持 pending,不会发出任何投递。

token 只出现在 header 中,因此把收到的 body 原样返回的服务无法通过:只有主动读取 header 的 endpoint 才能通过。URL 必须是公开 HTTPS;私有地址和重定向会被拒绝。

SandboxPOST + X-Callback-Challenge
你的 endpoint 回显 token
verified开始投递
app.post('/webhook', (req, res) => {
  const challenge = req.get('X-Callback-Challenge');
  if (challenge) return res.status(200).json({ challenge });
  return handleCallback(req, res);
});

注册 webhook

注册带 secret 的 URL,用于测试签名。secret 只在响应中出现一次。

curl -X POST https://pix.sandbox.payzu.dev/v1/user/webhooks \
  -H "Authorization: Bearer $SANDBOX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://sua-app.com.br/webhook","generateSecret":true}'

继续之前,请确认归属已验证:GET /sandbox/webhooks/{id}/challenge 应返回 "status": "verified"

查询并重新验证

当投递没有发生时,查询原因:

curl https://pix.sandbox.payzu.dev/sandbox/webhooks/$WEBHOOK_ID/challenge \
  -H "Authorization: Bearer $SANDBOX_TOKEN"
{
  "webhookId": "cmh2k1x9d0001s6bwjb5bez01",
  "url": "https://sua-app.com.br/webhook",
  "status": "failed",
  "detail": "o endpoint respondeu 2xx sem ecoar o token, no corpo ou em {\"challenge\"}",
  "checkedAt": "2026-08-23T12:00:00.000Z"
}

statuspendingverifiedfailed。修复 endpoint 后,POST /sandbox/webhooks/{id}/challenge 会重新验证。投递的格式和签名与生产一致:见 HMAC 验证

本页内容