接入指南
本文面向业务系统开发者,说明如何将 EasyIT Pay 集成到现有项目中。
整体流程
┌─────────────┐ ①创建订单 ┌─────────────┐ ②跳转 ┌─────────────┐
│ 业务系统 │ ──────────────▶ │ 支付平台 │ ──────────▶ │ 收银台 │
│ │ ◀────────────── │ │ ◀────────── │ │
└─────────────┘ ④异步通知 └─────────────┘ ③用户支付 └─────────────┘
▲
└── ⑤ return_url 同步回跳
第一步:获取凭证
- 登录 管理后台
- 进入 接入应用 → 创建应用
- 记录返回的
app_id和app_secret(密钥仅展示一次,请妥善保存)
app_secret用于 API 签名,切勿暴露在前端代码或公开仓库中。
第二步:配置回调地址
创建订单时需传入两个 URL:
| 字段 | 用途 | 要求 |
|---|---|---|
notify_url | 支付成功后平台服务端 POST 回调 | 必须公网可访问(开发可用内网穿透) |
return_url | 支付完成后用户浏览器跳转 | 可为业务前端页面 |
业务系统需在 notify_url 接口中:
- 验证签名(平台回调携带 HMAC 签名)
- 幂等处理(同一订单可能重复通知)
- 返回
success字符串表示接收成功
第三步:创建订单
调用 POST /api/v1/orders,详见 Open API 文档。
请求成功后返回:
{
"code": 0,
"data": {
"order_no": "P202505300001",
"pay_url": "http://127.0.0.1:8010/pay/abc123token",
"expire_at": "2025-05-30T12:30:00Z"
}
}
将用户浏览器重定向至 pay_url 即可进入收银台。
第四步:处理支付结果
异步通知(推荐)
平台向 notify_url POST JSON,包含订单号、金额、支付状态等。业务系统更新本地订单状态后返回 success。
同步回跳
用户支付完成后跳转 return_url,可携带订单号等参数。注意:同步回跳不能作为最终支付凭证,务必以异步通知为准。
主动查询
若长时间未收到回调,可调用 GET /api/v1/orders/{out_trade_no} 主动查询订单状态。
签名规则
所有 Open API 请求需携带 HMAC-SHA256 签名:
- 取除
sign外所有字段 - 按 key 字母序排列,拼接为
key1=value1&key2=value2&... - 使用
app_secret作为密钥,计算 HMAC-SHA256 十六进制字符串 - 将结果填入
sign字段
空值字段不参与签名;timestamp 与服务器时间差不超过 5 分钟。
注意事项
out_trade_no在同一app_id下必须唯一- 金额单位为 分(整数),如 1 元 =
100 - 订单默认 30 分钟过期,过期后需重新创建
- 生产环境请关闭演示模式,配置真实商户密钥
示例代码思路(伪代码)
import hmac, hashlib, time, uuid, requests
def sign(params: dict, secret: str) -> str:
items = sorted((k, v) for k, v in params.items() if k != "sign" and v is not None)
raw = "&".join(f"{k}={v}" for k, v in items)
return hmac.new(secret.encode(), raw.encode(), hashlib.sha256).hexdigest()
payload = {
"app_id": "app_xxx",
"out_trade_no": "ORDER001",
"amount": 100,
"subject": "测试商品",
"notify_url": "https://biz.example.com/pay/notify",
"return_url": "https://biz.example.com/pay/return",
"timestamp": int(time.time()),
"nonce": uuid.uuid4().hex,
}
payload["sign"] = sign(payload, APP_SECRET)
resp = requests.post(f"{PAY_BASE}/api/v1/orders", json=payload)
pay_url = resp.json()["data"]["pay_url"]
# redirect user to pay_url