一个真实可用的商家集成,你可以阅读也可以运行——涵盖一次性购买与订阅,并包含 Webhook 验证。
这些指南里的内容都是片段。这里是完整的、实际运行的全貌:
github.com/paygatehq/paygate-example
一个小店,用两种方式出售同一件商品——一次性购买和订阅。它会把客户跳转到托管页面、接收 Webhook,并验证其签名。它是一个真实的集成而不是一段脚本,并且停在真实集成会停下的地方:授权网址。签署扣款授权是一笔从客户自己的钱包发起的交易,服务器上的任何东西都无法替客户完成。
src/env.ts configuration, checked at boot — refuses rather than guesses
src/paygate.ts the whole API client: fetch, a bearer token, idempotency keys
src/catalogue.ts product + price + webhook endpoint, created once
src/webhook.ts signature verification, and why it is shaped that way
src/server.ts the merchant app: /buy, /subscribe, /webhooks/paygate
src/views.ts server-rendered HTML, no framework
没有运行时依赖,也没有框架。Node ≥ 22.6 可以直接运行 TypeScript。这是刻意为之:如果一个示例把有意思的部分都藏在 SDK 后面,它教会你的只是那个 SDK。paygate.ts 大约八十行,展示了本 API 对客户端仅有的三项要求——Bearer 令牌、写操作上的 Idempotency-Key,以及可据以分支处理的错误结构。
src/webhook.ts。签名验证是集成中唯一一个出了错却没有任何东西会提醒你的环节:一个总是通过的校验,看起来和一个真正有效的校验一模一样,直到有人向你发送一笔从未发生过的付款。它基于到达时的原始字节进行验证,以常量时间比较,并强制执行时间戳容差——每一处旁边都写明了理由。
README 中有完整的配置说明,包括让网关能够把 Webhook 投递到 localhost 的两个仅限开发环境的设置,以及为什么这两个设置都不能与正式模式同时使用。