223 lines
7.2 KiB
Markdown
223 lines
7.2 KiB
Markdown
# 全局公共参数
|
||
|
||
**全局Header参数**
|
||
|
||
| 参数名 | 示例值 | 参数类型 | 是否必填 | 参数描述 |
|
||
| --- | --- | ---- | ---- | ---- |
|
||
| 暂无参数 |
|
||
|
||
**全局Query参数**
|
||
|
||
| 参数名 | 示例值 | 参数类型 | 是否必填 | 参数描述 |
|
||
| --- | --- | ---- | ---- | ---- |
|
||
| 暂无参数 |
|
||
|
||
**全局Body参数**
|
||
|
||
| 参数名 | 示例值 | 参数类型 | 是否必填 | 参数描述 |
|
||
| --- | --- | ---- | ---- | ---- |
|
||
| 暂无参数 |
|
||
|
||
**全局认证方式**
|
||
|
||
> 无需认证
|
||
|
||
# 状态码说明
|
||
|
||
| 状态码 | 中文描述 |
|
||
| --- | ---- |
|
||
| 暂无参数 |
|
||
|
||
# 微信支付
|
||
|
||
> 创建人: 达民
|
||
|
||
> 更新人: 达民
|
||
|
||
> 创建时间: 2025-03-08 08:44:12
|
||
|
||
> 更新时间: 2025-03-08 08:44:12
|
||
|
||
```text
|
||
暂无描述
|
||
```
|
||
|
||
**目录Header参数**
|
||
|
||
| 参数名 | 示例值 | 参数类型 | 是否必填 | 参数描述 |
|
||
| --- | --- | ---- | ---- | ---- |
|
||
| 暂无参数 |
|
||
|
||
**目录Query参数**
|
||
|
||
| 参数名 | 示例值 | 参数类型 | 是否必填 | 参数描述 |
|
||
| --- | --- | ---- | ---- | ---- |
|
||
| 暂无参数 |
|
||
|
||
**目录Body参数**
|
||
|
||
| 参数名 | 示例值 | 参数类型 | 是否必填 | 参数描述 |
|
||
| --- | --- | ---- | ---- | ---- |
|
||
| 暂无参数 |
|
||
|
||
**目录认证信息**
|
||
|
||
> 继承父级
|
||
|
||
**Query**
|
||
|
||
## JS API支付
|
||
|
||
> 创建人: 达民
|
||
|
||
> 更新人: 达民
|
||
|
||
> 创建时间: 2025-03-08 08:49:16
|
||
|
||
> 更新时间: 2025-03-08 15:08:38
|
||
|
||
**在微信内置浏览器里打开目标应用页面(如微信公众号、点击聊天窗口的链接打开页面),根据需要调起微信支付.
|
||
1、openid的获取,参考:https://segmentfault.com/a/1190000013392838 。也可以自己找微信官方文档。
|
||
2、如何调起jsapi支付,参考文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6
|
||
3、支付回调。支付网关根据请求支付传递的notify_url将支付结果通知到业务方
|
||
回调参数**
|
||
|
||
| 参数 | 含义 |
|
||
| --- | --- |
|
||
| client_id | 客户端ID |
|
||
| biz_id | 支付网关为业务方分配的ID |
|
||
| nonce_str | 参与签名的混淆字段 |
|
||
| sign | 签名校验字段值 |
|
||
| sign_type | 签名类型,一般是MD5 |
|
||
| version | 支付网关版本号 |
|
||
| timestamp | 回调时的时间戳,毫秒 |
|
||
| biz_content | 订单的相关数据,以key=value组合并以&拼接在一起的字符串,其中value未做urlencode处理 |
|
||
| 以上参数按照key=value的形式,并对参数值做urlencode,以 & 拼接多个key=value形成一个字符串,以POST的方式调用notify_url时将该字符串提交给业务方。 | |
|
||
|
||
**其中,biz_content包含了以下参数**
|
||
|
||
| 参数 | 含义 |
|
||
| --- | --- |
|
||
| uid | 应用方为人员分配的记录ID,应用方在请求接口时以ucid传递的参数值 |
|
||
| trade_id | 支付网关为本次支付分配的记录ID |
|
||
| total_amount | 本次支付涉及的金额,单位:分 |
|
||
| trade_pay_time | 支付成功的时间,格式:yyyy-MM-dd HH:mm:ss |
|
||
| trade_status | 支付支付状态,成功时值为:SUCCESS |
|
||
| pay_type | 支付方式,jsapi接口调起的支付,本字段值固定为:113 |
|
||
| callback_content | 微信回调给支付网关的原始xml数据,参考https://pay.weixin.qq.com/doc/v2/partner/4011936644 |
|
||
| title | 业务方调接口时传递的title字段值 |
|
||
| biz_order_id | 业务方支付订单的订单号 |
|
||
|
||
**举个例子:
|
||
biz_content=%7B%22uid%22%3A%22102579%22%2C%22trade_id%22%3A%221501822040%22%2C%22total_amount%22%3A83601%2C%22trade_pay_time%22%3A%222025-03-08%2008%3A48%3A35%22%2C%22trade_status%22%3A%22SUCCESS%22%2C%22pay_type%22%3A%22113%22%2C%22callback_content%22%3A%22%3Cxml%3E%E7%95%A5%3C%2Fxml%3E%22%2C%22title%22%3A%22%E4%BA%91%E9%98%9F%E9%95%BF%E5%8C%BB%E8%8D%AF%E8%BF%9E%E9%94%81%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F%22%2C%22biz_order_id%22%3A%2221-364535%22%7D&nonce_str=11961acffe074c7da556a18e8549027f&sign=5ec91e8d3f4feb4b3c273e5512a7d7c3&biz_id=ydrug&sign_type=MD5&version=1.0&client_id=yeshan×tamp=1741394916159,只有通过了签名校验,才应该能被业务方接受并进行业务的下一步处理。业务方应该根据回调数据里的相关参数(如:biz_order_id)找回相应的订单以进行下一步的业务处理。注意:同一个支付订单的支付结果,支付网关可能会多次回调通知业务方,所以业务方要做好幂等处理。签名校验算法如下:**
|
||
|
||
```java
|
||
/**
|
||
* @param appKey 支付网关提供的业务秘钥,与biz_id是配对一起提供的
|
||
* @param sign 支付网关回调参数里的sign字段值
|
||
* @param reqBody 支付网关回调的原始请求body字符串
|
||
*/
|
||
public static boolean checkOpenSign(String appKey, String sign, String reqBody) {
|
||
String[] fields = reqBody.split("&");
|
||
Map<String, String> fieldMap = new HashMap<>();
|
||
for (String field : fields) {
|
||
String[] pair = field.split("=");
|
||
if (pair.length != 2) {
|
||
continue;
|
||
}
|
||
// sign字段不参与校验,空字段不校验
|
||
if (!"sign".equals(pair[0]) && StringUtils.isNotBlank(pair[1])) {
|
||
fieldMap.put(pair[0], pair[1]);
|
||
}
|
||
}
|
||
String generateSign = openSign(appKey, fieldMap);
|
||
return Objects.equals(generateSign, sign);
|
||
}
|
||
|
||
public static String openSign(String appKey, Map<String, String> params) {
|
||
if(MapUtils.isEmpty(params)) {
|
||
params = new HashMap<String, String>(1);
|
||
}
|
||
Map<String, String> sortedParams = new TreeMap<>(params);
|
||
List<String> kvPairList = getKVList(sortedParams);
|
||
String sourceText = StringUtils.join(kvPairList, "&");
|
||
sourceText = sourceText + "&app_key=" + appKey;
|
||
LogUtils.NORMAL.info("sourceText:" + sourceText);
|
||
try {
|
||
return md5(sourceText.getBytes("utf-8"));
|
||
} catch (Exception e) {
|
||
return null;
|
||
}
|
||
}
|
||
```
|
||
|
||
**接口状态**
|
||
|
||
> 开发中
|
||
|
||
**接口URL**
|
||
|
||
> http://localhost:7045/open/trade/wx/jsapi/precreate
|
||
|
||
| 环境 | URL |
|
||
| --- | --- |
|
||
|
||
|
||
**请求方式**
|
||
|
||
> POST
|
||
|
||
**Content-Type**
|
||
|
||
> json
|
||
|
||
**请求Body参数**
|
||
|
||
```javascript
|
||
{
|
||
"ucid": "123", //应用方为人员分配的记录ID,以方便后续排查问题。选填
|
||
"ip": "127.0.0.1", //调用方应用所在服务器的ip。必填
|
||
"openid": "o_xsewew131SGS", //微信用户的openid,参考【设计】模块的【详细说明】。必填
|
||
"biz_order_id": "1234536", //应用方为本次支付订单定义的订单ID,务必确保在业务应用内唯一。必填
|
||
"pay_amount": 1, //支付金额,单位:分。必填
|
||
"title": "测试", //用户在微信支付界面看到订单标题,也就是商品描述。必填
|
||
"notify_url": "http://...", //业务方接收支付结果的异步回调地址。必填
|
||
"biz_id": "abc", //支付网关为业务方分配的业务应用ID。必填
|
||
"extra": "342rewrs" //业务方期望支付网关回调时透传的数据。选填
|
||
}
|
||
```
|
||
|
||
**认证方式**
|
||
|
||
> 继承父级
|
||
|
||
**响应示例**
|
||
|
||
* 成功(200)
|
||
|
||
```javascript
|
||
//成功,使用以下参数调起jsapi支付。
|
||
{
|
||
"appId": "",
|
||
"timeStamp": "",
|
||
"nonceStr": "",
|
||
"package": "",
|
||
"signType": "",
|
||
"paySign": ""
|
||
}
|
||
```
|
||
|
||
* 失败(200)
|
||
|
||
```javascript
|
||
{
|
||
"timestamp": "2025-03-08T01:55:14.480+0000",
|
||
"status": 500,
|
||
"error": "Internal Server Error",
|
||
"message": "第三方返回失败, errorMsg = 第三方返回失败, errorMsg = 无效的openid",
|
||
"path": "/open/trade/wx/jsapi/precreate"
|
||
}
|
||
```
|
||
|
||
**Query**
|