haopay-developer-starter
v0.1.0
Published
Server-side Node.js and TypeScript starter for HaoPay Orders API and webhooks
Readme
HaoPay 开发者接入
这个仓库提供服务端 Node.js/TypeScript SDK、Webhook 验签、OpenAPI 和电商平台接入 starter。HaoPay 通过链上支付把资金直接结算到商户配置的钱包;这个仓库不包含 HaoPay 生产后端、数据库、管理系统或密钥。
完整流程:创建订单 → 跳转 Hosted Checkout → 验证 Webhook → 更新你自己的业务订单。
接入前准备
- 注册 HaoPay 商户账号;
- 在对应环境配置结算钱包;
- 服务端使用 Node.js 20 或更高版本;
- 准备一个可以接收 HTTPS Webhook 的服务端地址。
请先使用 Test:
| 环境 | API 地址 | Key 前缀 | 资金 |
|---|---|---|---|
| Test | https://test-api.haopay.xyz | hp_test_ | 仅测试代币 |
| Live | https://api.haopay.xyz | hp_live_ | 真实稳定币 |
1. 申请 Test API Key
登录 HaoPay 商户后台,切换到 Test,进入 开发者 页面创建 API Key。完整 Key 只显示一次,并以 hp_test_ 开头。
API Key 只能保存在服务端密钥系统中。不要放进浏览器、手机 App、公开仓库、日志或统计工具。
发送请求前可以检查 Test API:
curl -i https://test-api.haopay.xyz/api/ready只有返回 HTTP 200 和 {"status":"ready"} 时才继续发送订单请求。
2. 安装 SDK
npm install haopay-developer-starter克隆本仓库后运行示例:
npm install
export HAOPAY_TEST_KEY=hp_test_REPLACE_ME
npx tsx examples/create-order.ts3. 创建订单
订单必须由你的服务端创建。merchantReference 用来关联你自己的业务订单;Idempotency-Key 必须稳定,网络重试时重复使用同一个值,避免产生第二个支付订单。
import { HaoPayClient } from "haopay-developer-starter";
const haopay = new HaoPayClient({
apiKey: process.env.HAOPAY_TEST_KEY!,
environment: "test",
});
const order = await haopay.createOrder(
{
amount: 19.99,
description: "服务账单",
merchantReference: "INV-1042",
successUrl: "https://merchant.example/payment/success",
cancelUrl: "https://merchant.example/payment/cancel",
},
{ idempotencyKey: "invoice-1042" },
);不使用 SDK 也可以直接调用:
curl -sS -X POST "https://test-api.haopay.xyz/api/orders/create" \
-H "X-API-Key: $HAOPAY_TEST_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: invoice-1042" \
-d '{"amount":19.99,"description":"服务账单","merchantReference":"INV-1042"}'响应会返回 HaoPay orderId 和 payUrl。请把 orderId 保存到你自己的订单记录中。
4. 跳转 Hosted Checkout
把客户浏览器跳转到接口原样返回的 payUrl:
response.redirect(303, order.payUrl);不要自己拼接支付页 URL。客户会在 Hosted Checkout 连接钱包、选择支持的链和币种并确认支付。
不要仅根据浏览器成功跳转把业务订单标记为已支付。浏览器回调可能被中断或伪造,最终状态应以通过验签的 Webhook 和你的幂等更新为准。
5. 验证 Webhook
在 HaoPay 开发者页面配置 Test Webhook 地址并保存 Secret。服务端必须先读取原始请求体,再解析 JSON。
import { verifyHaoPayWebhook } from "haopay-developer-starter";
const result = verifyHaoPayWebhook({
rawBody,
headers: request.headers,
currentSecret: process.env.HAOPAY_WEBHOOK_SECRET!,
});
if (!result.valid) {
return response.status(401).end();
}
const event = JSON.parse(rawBody.toString("utf8"));
if (event.event === "order.paid") {
await markOrderPaidOnce(event.orderId, event.txHash);
}
return response.status(204).end();验证器使用 X-HaoPay-Signature-V2,对 <timestamp>.<原始请求体> 计算 HMAC-SHA256;默认拒绝超过 300 秒的请求,并支持密钥轮换期间的 previous secret。
Webhook 可能重复投递。你的数据库更新必须以 HaoPay orderId 为幂等键,不能重复发货、重复充值或重复开通服务。
6. 切换到 Live
完成以下 Test 验收后再切换:
- 能创建订单并得到有效
payUrl; - 能在 Hosted Checkout 完成测试代币支付;
- 服务端能用原始请求体验证
order.paid; - 同一个 Webhook 重复发送不会重复处理;
- 你能从业务记录中排查失败投递和订单状态。
然后在 HaoPay 后台切换到 Live,配置 Live 结算地址,创建 hp_live_ API Key,配置独立的 Live Webhook 和 Secret,并把客户端改为 environment: "live"。
Test Key 不能调用 Live,Live Key 也不能调用 Test。Live 会转移真实稳定币,不要让浏览器参数决定服务端使用哪个环境。
电商和其他接入
- Shopify starter
- SHOPLINE starter
- WooCommerce starter
- 独立站、SaaS、AI 服务和无人设备都使用同一条服务端流程:创建订单、保存
orderId、跳转payUrl、验证order.paid。
这些目录是接入 starter,不是平台官方认证应用。平台授权、权限范围、Webhook 订阅、结账 UI、测试和应用市场审核仍由接入方完成。
更多内容请查看 OpenAPI、Webhook 说明和安全策略。
