Skip to main content
这一页是配置项的参考手册。想先跑通一笔支付,看 快速开始;想知道代码怎么写,看 Hosted Checkout 接入

环境

Clink 分沙盒和生产两套环境。沙盒就是通常说的测试环境。
两套环境是两个独立的后台地址。沙盒中的支付域资源和环境配置不会复制到生产环境,包括产品、客户、订单、API 密钥、Webhook 端点、签名密钥以及认证申请和资料。首次进入生产环境时,系统会同步生产访问所需的租户、商户、用户登录凭据和角色授权信息。请在沙盒完整验证后再部署到生产,也不要在沙盒使用真实客户信息。

API 密钥

Clink 的 API 通过请求头认证,需要两个头:
X-Timestamp 是毫秒级时间戳。生产环境只接受与平台时间相差 2 分钟以内的请求,超前和滞后同样处理。每次请求现算,不要写死或缓存。
沙盒的容差要宽得多,目前是 ±24 小时。它只是为了方便测试,不构成接口承诺,随时可能收紧。因此沙盒验证通过不代表生产可用。缓存的时间戳、写死的时间戳、未校准的服务器时钟,在沙盒都能通过,切到生产后会集中出现认证失败。实现时应在发起请求的那一刻取当前时间,并用 NTP 校准服务器时钟。
这个容差是配置中心的热更新项,两边的值都可能调整。

初始化密钥

进入 开发者 页面,点击初始化密钥。Secret Key 只显示一次,务必复制保存。
key

两种密钥

Secret Keysk_)用于服务端调用 API。默认不受限制,可以执行任何 API 请求,包括收款和退款。
Secret Key 只能放在服务器上。不要写进前端代码、不要提交到版本库、不要打进 App 安装包。
Publishable Keypk_)用于浏览器端。它只能访问客户端 SDK 需要的两个接口:
  • /api/sdk/bootstrap
  • /api/checkout/session/verify-merchant
其余 /api/** 接口一律要求 Secret Key。因此 Publishable Key 无法创建 Checkout Session、查询订单或发起退款,这些操作只能在服务端完成。

轮换密钥

轮换会作废当前密钥并生成一个替代密钥。旧密钥可以立即失效,也可以设定一个过期时间以便平滑切换。
1

打开 API 密钥页面

进入 开发者 页面。
2

选择轮换

在要轮换的密钥行点击更多按钮(⋮),选择轮换密钥
3

设置失效时间

失效时间下拉菜单选择旧密钥的过期期限。生产环境建议留一段重叠时间,等新密钥部署完成再让旧的失效。
4

保存新密钥

复制对话框里的新密钥值。这个值之后无法再次查看。

删除密钥

删除后该密钥立即无法调用 API。如果某个密钥是账户里最后一个有效密钥,则不能删除。 删除前应先轮换出新密钥、更新代码并确认线上已全部切换,再删除旧密钥。

限制 IP

只有 Secret Key 支持 IP 限制。可以限制到若干个具体 IP,也可以用 CIDR 限制一个网段。 在密钥行点击更多按钮(⋮),选择管理 IP 限制,开启限制使用特定 IP 地址,然后逐条添加 IP 或 CIDR 范围。
服务器出口 IP 变更后需同步更新,否则所有 API 请求都会被拒绝。

Webhook

Webhook 是 Clink 主动推送结果的通道。付款成功、退款处理完成、订阅续费等结果都通过它送达商户服务端。

注册

在后台注册:进入 开发者 > Webhooks,点击新增,填入 HTTPS 地址并勾选要订阅的事件。 用 API 注册:调 PUT /webhook/endpoints/ensure,传 urlevents。这个接口以 URL 作为幂等键,同一个 URL 重复调用会更新而不是新建,适合放进部署脚本。 用 CLI 注册clink-integ-cli 把注册和密钥同步合成了一步:
不要用 --events core 它订阅的是 session.completeorder.succeededorder.failedrefund.succeededsubscription.createdinvoice.paid 这六个,不含 order.createdorder.next_action少了 order.created,就拿不到判断支付尝试先后顺序的唯一依据;少了 order.next_action,需要客户额外验证的订单会一直卡在待定状态。Hosted Checkout 接入 那套多支付尝试模型靠 core 是撑不起来的。所以上面显式列出了九个事件名。等 clink-integ-cli 发布 checkoutcommerce 这类预设之后,可以换成 --events checkout
--save-secret 将返回的签名密钥存入 CLI 配置,--sync-env-file 同时写入指定的 env 文件。写入后仍需重启或重新部署,服务才会加载新密钥。Webhook 地址变更后重跑一次,重新同步并重启。 这个工具随 clink-integ-skills 分发,不是 npm 上的 @clink-ai/clink-cli——后者是客户钱包 CLI,两者命令名都以 clink 开头,别装错。
Webhook 地址必须是公网可达的 HTTPS。localhost、回环地址、内网 IP、链路本地地址和组播地址都会被拒绝。
GET /webhook/events 可以查当前支持的事件名。注册时用事件名,不要用数字 code。 接口返回或轮换出 signingSecret 之后,将其存入服务端的密钥管理,再重启或重新部署。

验证签名

Clink 用 HMAC SHA-256 为每个事件签名,签名密钥在注册 Webhook 后生成。 请求头里有三个字段: 验签步骤,顺序不能换:
1

确认签名类型

X-Clink-SignType 必须是 SHA256。不是就直接拒绝,别往下算。
2

校验时间戳新鲜度

X-Clink-Timestamp 是 Unix 毫秒时间戳。要求 abs(当前时间 - 时间戳) <= 5 分钟超出窗口、格式不是数字、或服务器时钟本身偏得太多,一律拒绝。服务器请用 NTP 校时。
3

拼接待签字符串

时间戳(字符串形式)+ 字符 . + 收到的原始请求体。
4

计算 HMAC

用签名密钥和 SHA256 计算 HMAC,结果编码成 hex 字符串。
5

恒定时间比对

X-Clink-Signature 比较,一致才处理这个事件。必须用恒定时间比较(Node 里是 crypto.timingSafeEqual),普通的 === 会泄露逐字节的比较进度。
时间校验和 HMAC 都要在解析 JSON 之前完成,用的是原始请求体。 先解析再重新序列化,字段顺序和空格会变,签名一定对不上。另外,时间窗口只能防重放,挡不住重复投递——Clink 自己的重试也在窗口内。重复必须另外按 event.id 原子去重,见 Hosted Checkout 接入
可以直接抄的验签代码见 Hosted Checkout 接入 的「验签」一节。

投递规则

返回非 2xx 或超时都算投递失败。首次投递失败后会进行指数退避重试。 当前策略下,失败后的等待间隔依次约为 2、4、8、16、32、64、128、256 和 512 分钟,共执行最多 10 次 HTTP 投递(包含首次投递)。持续失败的话,最后一次实际 HTTP 投递约发生在首次投递后的 17 小时,随后进入死信队列。 九段等待合计 1022 分钟,约 17 小时 2 分。实际时间会因队列调度产生少量偏差。
重试间隔属于平台配置,可能调整,不要写死进业务逻辑、告警阈值或补偿任务的调度,也不要按分钟级精度做判断。需要兜底时,把主动回查安排在自动重试窗口结束之后——例如首次事件约 18 小时后仍未收到,就用 GET /order/{orderId} 之类的接口自行补齐状态。
是否耗尽自动重试应按单个事件判断,而不是只看总停机时长。 当恢复时间距某个事件的首次投递已达到约 17 小时时,该事件才可能已经耗尽全部自动投递;临近恢复时才首次投递的事件仍可能处于重试窗口。 举个例子:停机 20 小时,停机刚开始时首次投递的事件早已耗尽重试,而停机结束前一小时才首次投递的事件还会继续重投——同一次停机里,两者的处境完全不同。 恢复后对整个停机区间执行主动对账,仍是更稳妥的运维策略。核对区间内的 Order、Invoice、Subscription、Refund 等关键对象,用服务端查询或列表接口拉一遍,别假设推送会把缺口补上。运维规则需要一个整点兜底值的话,可以保守按 18 小时——这是覆盖 17 小时 2 分钟投递窗口的取整,不是平台的另一个阈值。 单条事件可以在后台手动补发:进入交易详情的 Webhook delivery 列表,对指定 endpoint 重发。这是按条操作,没有批量重放入口。 事件不保证按发生顺序到达。 处理逻辑不能依赖顺序,也不能让先发生的事件覆盖后发生的状态。 因为存在重试,同一个事件会送达多次,需按事件的 id 字段去重。

常用事件

Hosted Checkout 必须显式分派两个 Session 终态事件。session.complete 只把 Session 生命周期更新为 completedsession.expired 只更新为 expired。外层 event.created 要保存为 Session 生命周期版本:较旧终态不能覆盖较新终态,同一毫秒出现不同终态时必须持久化人工对账。两者都不能证明某个 Order 成功或失败,因此支付、退款、履约和 Payment Attempt 状态仍须分开维护。 事件体结构和字段说明见 Webhook 参考。端点的增删改查见 Webhook 端点管理

轮换签名密钥

POST /webhook/endpoints/{id}/rotate-secret 轮换。 轮换之后必须同步更新服务端的签名密钥并重启,否则新推送的事件会全部验签失败。

商户后台

日常运营在后台完成:

商户

业务运行主体。

用户

可以登录商户后台的用户。

产品与价格

售卖的产品和定价配置。

余额

账户余额和费用信息。