http://your-domain:8080生成微信支付二维码,用户扫码后完成支付。
POST/api/pay/wechat/nativeapplication/json| 参数名 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| bizOrderId | String | 是 | 业务订单号(唯一标识) | "ORDER20251123001" |
| amount | Integer | 是 | 支付金额(单位:分) | 10000 (表示100元) |
| subject | String | 是 | 订单标题 | "商品订单支付" |
| description | String | 否 | 订单描述 | "购买商品A×1" |
| callbackUrl | String | 是 | 业务回调地址(支付成功后通知) | "https://your-domain.com/notify" |
{
"bizOrderId": "ORDER20251123001",
"amount": 10000,
"subject": "商品订单支付",
"description": "购买商品A×1",
"callbackUrl": "https://your-domain.com/notify"
}
| 参数名 | 类型 | 说明 |
|---|---|---|
| code | Integer | 响应码,200表示成功 |
| msg | String | 响应消息 |
| data | Object | 响应数据 |
| data.orderId | Long | 支付订单ID |
| data.transactionId | Long | 交易流水ID |
| data.status | String | 订单状态(PENDING-待支付) |
| data.qrBase64 | String | 二维码图片Base64编码 |
| data.expireAt | String | 过期时间(2小时) |
{
"code": 200,
"msg": "操作成功",
"data": {
"orderId": 1234567890,
"transactionId": 9876543210,
"status": "PENDING",
"qrBase64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
"expireAt": "2025-11-23 14:00:00"
}
}
qrBase64<img src="{qrBase64}" />callbackUrl 通知结果生成支付宝支付二维码,用户扫码后完成支付。
POST/api/pay/alipay/precreateapplication/json与微信支付相同,参考上方表格。
{
"bizOrderId": "ORDER20251123002",
"amount": 10000,
"subject": "商品订单支付",
"description": "购买商品B×1",
"callbackUrl": "https://your-domain.com/notify"
}
{
"code": 200,
"msg": "操作成功",
"data": {
"orderId": 1234567891,
"transactionId": 9876543211,
"status": "PENDING",
"qrBase64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
"expireAt": "2025-11-23 14:00:00"
}
}
查询支付订单的当前状态。
GET/api/pay/orders/{orderId}| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| orderId | Long | 是 | 支付订单ID |
GET /api/pay/orders/1234567890
| 参数名 | 类型 | 说明 |
|---|---|---|
| code | Integer | 响应码 |
| msg | String | 响应消息 |
| data | Object | 订单详情 |
| data.id | Long | 订单ID |
| data.bizOrderId | String | 业务订单号 |
| data.amount | Integer | 金额(分) |
| data.currency | String | 币种(CNY) |
| data.channel | String | 支付渠道(WECHAT/ALIPAY) |
| data.status | String | 订单状态 |
| data.subject | String | 订单标题 |
| data.channelTradeNo | String | 渠道交易号 |
| data.paidAt | String | 支付完成时间 |
| data.expireAt | String | 过期时间 |
| data.createdAt | String | 创建时间 |
| 状态码 | 说明 |
|---|---|
| INIT | 初始化 |
| PENDING | 待支付 |
| SUCCEEDED | 支付成功 |
| FAILED | 支付失败 |
| CANCELED | 已关闭 |
| EXPIRED | 已过期 |
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 1234567890,
"bizOrderId": "ORDER20251123001",
"amount": 10000,
"currency": "CNY",
"channel": "WECHAT",
"status": "SUCCEEDED",
"subject": "商品订单支付",
"channelTradeNo": "4200001234567890",
"paidAt": "2025-11-23 12:30:00",
"expireAt": "2025-11-23 14:00:00",
"createdAt": "2025-11-23 12:00:00"
}
}
查询订单的最新交易记录(包含二维码)。
GET/api/pay/orders/{orderId}/transactions/latestGET /api/pay/orders/1234567890/transactions/latest
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 9876543210,
"orderId": 1234567890,
"channel": "WECHAT",
"clientType": "NATIVE",
"status": "PENDING",
"qrBase64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
"createdAt": "2025-11-23 12:00:00"
}
}
当支付成功后,系统会主动调用您在发起支付时提供的 callbackUrl,通知支付结果。
POSTapplication/jsoncallbackUrl| 参数名 | 说明 |
|---|---|
| Content-Type | application/json |
| X-Signature | HMAC-SHA256签名,用于验证请求来源 |
| X-Nonce | 随机字符串 |
| X-Timestamp | 时间戳(毫秒) |
| 参数名 | 类型 | 说明 |
|---|---|---|
| tradeId | Long | 交易ID |
| orderId | Long | 订单ID |
| bizOrderId | String | 业务订单号 |
| channel | String | 支付渠道(WECHAT/ALIPAY) |
| amount | Integer | 金额(分) |
| currency | String | 币种(CNY) |
| status | String | 订单状态(SUCCEEDED) |
| channelTradeNo | String | 渠道交易号 |
| paidAt | String | 支付完成时间 |
| subject | String | 订单标题 |
| description | String | 订单描述 |
{
"tradeId": 9876543210,
"orderId": 1234567890,
"bizOrderId": "ORDER20251123001",
"channel": "WECHAT",
"amount": 10000,
"currency": "CNY",
"status": "SUCCEEDED",
"channelTradeNo": "4200001234567890",
"paidAt": "2025-11-23 12:30:00",
"subject": "商品订单支付",
"description": "购买商品A×1"
}
签名算法: HMAC-SHA256
签名数据: payload + nonce + timestamp
验证步骤:
1. 获取请求头中的 X-Signature、X-Nonce、X-Timestamp
2. 获取请求体 JSON 字符串 payload
3. 拼接字符串:signData = payload + nonce + timestamp
4. 使用配置的 callbackSignSecret 计算 HMAC-SHA256
5. 对比计算结果与 X-Signature 是否一致
Java示例代码:
```java
String payload = "请求体JSON字符串";
String nonce = request.getHeader("X-Nonce");
String timestamp = request.getHeader("X-Timestamp");
String signature = request.getHeader("X-Signature");
String signData = payload + nonce + timestamp;
String calculated = SignUtil.hmacSha256(signData, callbackSignSecret);
if (signature.equals(calculated)) {
// 签名验证通过
}
```
您的回调接口应返回:
- 成功: HTTP 状态码 200-299
- 失败: 其他状态码(系统会自动重试)
如果回调失败,系统会按以下间隔自动重试(最多10次):
- 立即重试
- 1分钟后
- 5分钟后
- 15分钟后
- 60分钟后
检查服务是否正常运行。
GET/api/health{
"code": 200,
"msg": "操作成功",
"data": {
"status": "UP",
"service": "dryad-payment",
"time": "2025-11-23 12:00:00",
"message": "支付模块服务运行正常"
}
}
| 错误码 | 说明 |
|---|---|
| 200 | 成功 |
| 500 | 服务器内部错误 |
| 400 | 请求参数错误 |
| 404 | 资源不存在 |
{
"code": 500,
"msg": "支付创建失败: 微信下单失败",
"data": null
}
发起微信支付:bash curl -X POST http://localhost:8080/api/pay/wechat/native \ -H "Content-Type: application/json" \ -d '{ "bizOrderId": "ORDER20251123001", "amount": 10000, "subject": "商品订单支付", "description": "购买商品A×1", "callbackUrl": "https://your-domain.com/notify" }'
查询订单:bash curl http://localhost:8080/api/pay/orders/1234567890
// 发起支付
async function createPayment() {
const response = await fetch('http://localhost:8080/api/pay/wechat/native', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
bizOrderId: 'ORDER20251123001',
amount: 10000,
subject: '商品订单支付',
description: '购买商品A×1',
callbackUrl: 'https://your-domain.com/notify'
})
});
const result = await response.json();
if (result.code === 200) {
// 显示二维码
document.getElementById('qrcode').src = result.data.qrBase64;
}
}
// 查询订单状态
async function queryOrder(orderId) {
const response = await fetch(`http://localhost:8080/api/pay/orders/${orderId}`);
const result = await response.json();
return result.data.status;
}
// 发起支付
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8080/api/pay/wechat/native";
Map<String, Object> request = new HashMap<>();
request.put("bizOrderId", "ORDER20251123001");
request.put("amount", 10000);
request.put("subject", "商品订单支付");
request.put("callbackUrl", "https://your-domain.com/notify");
ResponseEntity<Map> response = restTemplate.postForEntity(url, request, Map.class);
Map<String, Object> data = (Map<String, Object>) response.getBody().get("data");
String qrBase64 = (String) data.get("qrBase64");
bizOrderId + channel 重复请求会返回同一订单和二维码如有问题,请联系技术支持团队。