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}'

201 响应会返回创建的 webhook。请保存 id:challenge 路由中的 {id} 就是它,而 secret 不会在其他任何响应中再次出现。

{
  "id": "cmh2k1x9d0001s6bwjb5bez01",
  "url": "https://sua-app.com.br/webhook",
  "active": true,
  "events": [],
  "hasSecret": true,
  "createdAt": "2026-08-23T12:00:00.000Z",
  "updatedAt": "2026-08-23T12:00:00.000Z",
  "secret": "EOvBvLmIqjcIg13T2_cf8NXn7K5txbakb053ZY8sPrA"
}

如果丢失了 id,用 GET /v1/user/webhooks 列出该凭证的 webhook。这里没有 secret,只有 hasSecret:

curl -X GET https://pix.sandbox.payzu.dev/v1/user/webhooks \
  -H "Authorization: Bearer $SANDBOX_TOKEN"

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

查询并重新验证

当投递没有发生时,用 GET /sandbox/webhooks/{id}/challenge 查询原因:

curl -X GET 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"
}

status 为 pending、verified 或 failed。修复 endpoint 后,用 POST /sandbox/webhooks/{id}/challenge 重新验证,同一路由,无请求体:

curl -X POST https://pix.sandbox.payzu.dev/sandbox/webhooks/$WEBHOOK_ID/challenge \
  -H "Authorization: Bearer $SANDBOX_TOKEN"

投递的格式和签名与生产一致:见 HMAC 验证。

本页内容