快速开始
对接流程
- 创建支付应用 → 获取 Payment ID 和 Secret Key
- 用户下单 → 调用发起支付接口
- 跳转支付 → 用户在 NodeLoc 登录并支付
- 接收回调 → 浏览器跳转到你的回调地址
- 查询状态(可选)→ 主动查询支付结果
创建支付应用
访问管理页面
填写应用信息
| 字段 | 说明 | 示例 |
|---|---|---|
| 应用名称 | 你的网站/商店名称 | ”我的在线商店” |
| 网站地址 | 你的网站主页 | https://example.com |
| 回调地址 | 接收支付通知的URL | https://example.com/payment/callback |
| 描述 | 应用说明(可选) | “在线商店支付集成” |
保存密钥
创建成功后会显示:- Payment ID:
pay_xxxxxxxxxxxxxxxxxx - Secret Key:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
发起支付
API 接口
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
amount | Integer | 是 | 支付金额(积分) |
description | String | 是 | 交易描述 |
order_id | String | 是 | 你的订单号(唯一标识) |
signature | String | 是 | HMAC-SHA256 签名 |
签名算法
- 准备参数:
amount,description,order_id - 按键名排序: 字母顺序排列参数
- 拼接字符串: 格式
key1=value1&key2=value2&key3=value3 - 计算密钥:
token_hash = SHA256(your_token)// 你的 token 是 tk_xxx 格式 - 生成签名:
signature = HMAC-SHA256(token_hash, param_string)
your_token是申请时获得的 token(格式:tk_xxx...)token_hash是 token 的 SHA256 哈希(64位十六进制字符串)- 不要直接用 token 作为 HMAC 密钥!
响应数据
成功时返回:跳转支付
将用户重定向到响应中的payment_url,用户会:
- 自动跳转到登录页(如未登录)
- 登录后返回支付页面
- 确认订单并完成支付
- 支付成功后跳转到你的回调地址
处理回调
回调方式
支付成功后,用户浏览器会跳转到你设置的回调地址,所有参数以查询字符串形式传递。回调参数(URL 查询参数)
| 参数 | 类型 | 说明 |
|---|---|---|
transaction_id | String | 交易ID |
external_reference | String | 你的订单号(即 order_id) |
amount | Integer | 支付金额(积分) |
platform_fee | Integer | 平台手续费(积分) |
merchant_points | Integer | 商家实际收到的积分 |
status | String | 交易状态(completed) |
paid_at | DateTime | 支付时间(ISO 8601) |
signature | String | 回调签名(用于验证) |
回调 URL 示例
验证签名
验证步骤:- 提取签名参数: 从 URL 中获取
signature - 提取其他参数: 所有参数除了
signature本身 - 按键名排序: 字母顺序排列
- 拼接字符串: 格式
key1=value1&key2=value2... - 计算签名:
HMAC-SHA256(secret_key, param_string) - 比对签名: 计算出的签名与接收到的签名必须完全一致
处理订单
验证签名通过后:- ✅ 检查幂等性: 确保订单未被重复处理
- ✅ 验证金额: 确认
amount与订单金额一致 - ✅ 更新订单状态: 标记为已支付
- ✅ 执行业务逻辑: 发货、开通服务等
- ✅ 显示确认页面: 向用户展示支付成功信息
查询状态
如果回调失败或需要主动确认支付状态,可以使用查询接口。API 接口
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
transaction_id | String | 是 | 交易ID |
signature | String | 是 | HMAC-SHA256 签名 |
签名算法
与发起支付相同:- 参数:
transaction_id - 拼接:
transaction_id=txn_xxx - 签名:
HMAC-SHA256(secret_key, param_string)
响应数据
交易状态
| 状态 | 说明 |
|---|---|
pending | 等待用户支付 |
processing | 支付处理中 |
completed | 支付成功 |
failed | 支付失败 |
cancelled | 已取消 |
refunded | 已退款 |
建议使用场景
- 定时任务检查待支付订单状态
- 用户主动查询订单状态
- 回调失败后的补救措施
安全建议
1. 保护密钥
- ❌ 不要硬编码在代码中
- ✅ 使用环境变量或密钥管理服务
2. 使用 HTTPS
- ✅ 生产环境必须使用 HTTPS
- ✅ 回调 URL 必须是 HTTPS 地址
3. 验证签名
- ✅ 所有回调请求必须验证签名
- ✅ 签名不匹配时拒绝请求
4. 防止重复处理
- ✅ 检查订单状态,防止重复处理
- ✅ 使用数据库事务确保原子性
5. 验证金额
- ✅ 验证回调金额与订单金额一致
- ✅ 金额不匹配时记录日志并告警
6. 日志记录
- ✅ 记录所有支付相关操作
- ✅ 记录所有回调请求(包括签名验证失败的)
常见问题
Q: 签名验证失败?
Q: 签名验证失败?
检查以下几点:
- 参数是否按键名字母顺序排序
- 参数拼接格式是否为
key=value&key=value - Secret Key 是否正确
- 验证时是否排除了
signature参数本身 - 字符编码是否一致(UTF-8)
Q: 回调没有收到?
Q: 回调没有收到?
可能原因:
- 回调 URL 设置错误
- 用户关闭了浏览器窗口
- 网络问题导致跳转失败
Q: 如何测试?
Q: 如何测试?
开发环境测试:
- 使用 ngrok 等工具暴露本地服务器
- 在 NodeLoc 创建测试应用
- 设置回调 URL 为 ngrok 地址
- 创建小金额订单测试
Q: 支持退款吗?
Q: 支持退款吗?
目前不支持自动退款,需要联系管理员手动处理。
Q: 订单会过期吗?
Q: 订单会过期吗?
是的,默认 30 分钟未支付会自动过期。
API 参考
发起支付
- URL:
POST /payment/pay/:payment_id/process - 认证: 签名验证
- 请求:
amount,description,order_id,signature - 响应:
payment_url,transaction_id,status,amount
查询状态
- URL:
POST /payment/query/:payment_id - 认证: 签名验证
- 请求:
transaction_id,signature - 响应: 完整交易信息(见上文)
支付回调
- 方式: 浏览器 GET 跳转
- URL: 你设置的
callback_url - 认证: 签名验证
- 参数:
transaction_id,external_reference,amount,platform_fee,merchant_points,status,paid_at,signature
祝对接顺利! 🚀