配置多个接收地址、按事件类型订阅,以及安全地轮换签名密钥。
POST /api/v1/webhook_endpoints
GET /api/v1/webhook_endpoints
GET /api/v1/webhook_endpoints/{endpoint_id}
POST /api/v1/webhook_endpoints/{endpoint_id}
DELETE /api/v1/webhook_endpoints/{endpoint_id}
POST /api/v1/webhook_endpoints/{endpoint_id}/rotate_secret事件格式与验签见 Webhook。这里只讲端点管理。
每个环境最多配置 5 个端点,各自有独立的签名密钥和事件订阅。端点按环境隔离——沙箱端点永远收不到正式事件。
curl -X POST "https://web.kukopay.com/api/v1/webhook_endpoints" \
-H "X-Api-Key: kuko_live_你的密钥" \
-H "Content-Type: application/json" \
-d '{
"url": "https://api.yourshop.com/hooks/kukopay",
"description": "订单履约服务",
"enabled_events": ["payment.succeeded", "refund.succeeded"]
}'| 参数 | 必填 | 说明 |
|---|---|---|
url | ✅ | 正式环境必须是可公网访问的 HTTPS 地址 |
description | 备注,便于在控制台区分多个端点 | |
enabled_events | 订阅的事件类型,省略为全部 |
enabled_events 传 ["*"] 表示订阅全部,并且会自动包含之后新增的事件类型。
{
"object": "webhook_endpoint",
"endpoint_id": "whe_8c2f41ab9d0e7635",
"url": "https://api.yourshop.com/hooks/kukopay",
"enabled_events": ["payment.succeeded", "refund.succeeded"],
"status": "enabled",
"secret": "whsec_4f81a2c9...",
"secret_notice": "请立即保存该签名密钥,它不会再次以明文返回。"
}secret 只在创建和轮换时返回这一次。它加密存储,之后无法再读回明文——这正是设计目的:控制台被人看到也拿不到密钥。没保存就只能轮换一把新的。
curl -X POST "https://web.kukopay.com/api/v1/webhook_endpoints/whe_8c2f41ab9d0e7635" \
-H "X-Api-Key: kuko_live_你的密钥" \
-H "Content-Type: application/json" \
-d '{ "status": "disabled" }'想暂停接收时建议改成 disabled 而不是删除:投递历史挂在端点上,删掉之后就查不到这段时间漏了什么。
curl -X POST "https://web.kukopay.com/api/v1/webhook_endpoints/whe_8c2f41ab9d0e7635/rotate_secret" \
-H "X-Api-Key: kuko_live_你的密钥"签发新密钥,旧密钥在 24 小时内继续并行签名。两个签名出现在同一个 X-KukoPay-Signature 头里(多个 v1=),任意一个验签通过即为合法请求。
X-KukoPay-Signature: t=1758268800,v1=9c1f...,v1=3ea7...
新密钥 旧密钥所以你可以在窗口期内任意时刻更新配置,不必和平台同步切换。
轮换前请先确认你的验签代码能处理多个 v1=。只取第一个或用 Object.fromEntries 之类只保留最后一个的写法,会在窗口期内验签全部失败。Webhook 页 有三种语言的正确实现。
| 情况 | 事件发往 |
|---|---|
下单时传了 notify_url | 只发这个地址,不发给已配置端点 |
没传 notify_url | 所有订阅了该事件类型的端点 |
| 两者都没有 | 开发者中心配置的单一地址(兜底) |
多个端点各自独立重试,一个端点故障不会拖住其它端点。