# 全局公共参数

**全局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&timestamp=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**