KKSU
2023-12-22 63d035d8d2369337dd7938b053ec050a25e1865c
富文本框输入版本变化
9 files modified
1 files added
337 ■■■■ changed files
src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java 1 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/controller/AdminSystemController.java 28 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/controller/ViewSystemController.java 31 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/dto/XcxSettingDto.java 12 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallAppServiceImpl.java 11 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/pay/configure/WxPayConfiguration.java 1 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/pay/controller/XcxPayController.java 24 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/pay/service/impl/xcxCodePayServiceImpl.java 154 ●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/system/xcxSetting.html 49 ●●●●● patch | view | raw | blame | history
src/test/java/cc/mrbird/febs/PayTest.java 26 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java
@@ -29,5 +29,6 @@
        registration.excludePathPatterns("/api/leader/noLoginLeaderTitle");
        registration.excludePathPatterns("/api/xcxPay/wxpayCallback");
        registration.excludePathPatterns("/api/xcxPay/rechargeCallBack");
        registration.excludePathPatterns("/api/xcxPay/xcxCodePayCallBack");
    }
}
src/main/java/cc/mrbird/febs/mall/controller/AdminSystemController.java
@@ -3,6 +3,8 @@
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.enumerates.DataDictionaryEnum;
import cc.mrbird.febs.mall.dto.CashOutSettingDto;
import cc.mrbird.febs.mall.dto.XcxSettingDto;
import cc.mrbird.febs.mall.mapper.DataDictionaryCustomMapper;
import cc.mrbird.febs.mall.service.ICommonService;
import cc.mrbird.febs.mall.service.ISystemService;
import lombok.RequiredArgsConstructor;
@@ -27,6 +29,7 @@
    private ISystemService systemService;
    private final ICommonService commonService;
    private final DataDictionaryCustomMapper dictionaryCustomMapper;
    @PostMapping(value = "/bonusSystemSetting")
    public FebsResponse bonusSystemSetting(@RequestBody Map<String, Object> map) {
@@ -39,4 +42,29 @@
        commonService.addDataDic(DataDictionaryEnum.CASHOUT_SETTING.getType(), DataDictionaryEnum.CASHOUT_SETTING.getCode(), cashOutSettingDto, "提现设置");
        return new FebsResponse().success();
    }
    @PostMapping(value = "/xcxSetting")
    public FebsResponse cashOutSetting(XcxSettingDto xcxSettingDto) {
        dictionaryCustomMapper.updateDicValueByTypeAndCode(
                DataDictionaryEnum.XCX_APP_ID.getType(),
                DataDictionaryEnum.XCX_APP_ID.getCode(),
                xcxSettingDto.getAppId());
        dictionaryCustomMapper.updateDicValueByTypeAndCode(
                DataDictionaryEnum.XCX_MCH_ID.getType(),
                DataDictionaryEnum.XCX_MCH_ID.getCode(),
                xcxSettingDto.getMchId());
        dictionaryCustomMapper.updateDicValueByTypeAndCode(
                DataDictionaryEnum.XCX_MCH_KEY.getType(),
                DataDictionaryEnum.XCX_MCH_KEY.getCode(),
                xcxSettingDto.getMchKey());
        dictionaryCustomMapper.updateDicValueByTypeAndCode(
                DataDictionaryEnum.XCX_MCH_KEY_PATH_P12.getType(),
                DataDictionaryEnum.XCX_MCH_KEY_PATH_P12.getCode(),
                xcxSettingDto.getKeyPath());
        dictionaryCustomMapper.updateDicValueByTypeAndCode(
                DataDictionaryEnum.XCX_NOTICE_URL.getType(),
                DataDictionaryEnum.XCX_NOTICE_URL.getCode(),
                xcxSettingDto.getNotifyUrl());
        return new FebsResponse().success();
    }
}
src/main/java/cc/mrbird/febs/mall/controller/ViewSystemController.java
@@ -5,6 +5,7 @@
import cc.mrbird.febs.common.utils.FebsUtil;
import cc.mrbird.febs.mall.dto.CashOutSettingDto;
import cc.mrbird.febs.mall.dto.ScoreSettingDto;
import cc.mrbird.febs.mall.dto.XcxSettingDto;
import cc.mrbird.febs.mall.entity.DataDictionaryCustom;
import cc.mrbird.febs.mall.mapper.DataDictionaryCustomMapper;
import com.alibaba.fastjson.JSONObject;
@@ -40,7 +41,35 @@
    @GetMapping("xcxSetting")
    public String xcxSetting() {
    @RequiresPermissions("xcxSetting:update")
    public String xcxSetting(Model model) {
        String appId = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                DataDictionaryEnum.XCX_APP_ID.getType(),
                DataDictionaryEnum.XCX_APP_ID.getCode()
        ).getValue();
        String mchId = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                DataDictionaryEnum.XCX_MCH_ID.getType(),
                DataDictionaryEnum.XCX_MCH_ID.getCode()
        ).getValue();
        String mchKey = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                DataDictionaryEnum.XCX_MCH_KEY.getType(),
                DataDictionaryEnum.XCX_MCH_KEY.getCode()
        ).getValue();
        String keyPath = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                DataDictionaryEnum.XCX_MCH_KEY_PATH_P12.getType(),
                DataDictionaryEnum.XCX_MCH_KEY_PATH_P12.getCode()
        ).getValue();
        String notifyUrl = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                DataDictionaryEnum.XCX_NOTICE_URL.getType(),
                DataDictionaryEnum.XCX_NOTICE_URL.getCode()
        ).getValue();
        XcxSettingDto xcxSettingDto = new XcxSettingDto();
        xcxSettingDto.setAppId(appId);
        xcxSettingDto.setMchId(mchId);
        xcxSettingDto.setMchKey(mchKey);
        xcxSettingDto.setKeyPath(keyPath);
        xcxSettingDto.setNotifyUrl(notifyUrl);
        model.addAttribute("xcxSetting", xcxSettingDto);
        return FebsUtil.view("modules/system/xcxSetting");
    }
}
src/main/java/cc/mrbird/febs/mall/dto/XcxSettingDto.java
New file
@@ -0,0 +1,12 @@
package cc.mrbird.febs.mall.dto;
import lombok.Data;
@Data
public class XcxSettingDto {
    private String appId;
    private String mchId;
    private String mchKey;
    private String notifyUrl;
    private String keyPath;
}
src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallAppServiceImpl.java
@@ -324,8 +324,17 @@
    @Override
    public FebsResponse wxCodePay(ApiWxCodePayDto wxCodePayDto) {
        Long orderId = wxCodePayDto.getOrderId();
        MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectById(orderId);
        String wxPayCode = wxCodePayDto.getWxPayCode();
        /**
         * auth_code 扫码支付付款码 微信付款码规则:18位纯数字,前缀以10、11、12、13、14、15开头
         */
        String regex = "^(10|11|12|13|14|15)\\d{16}$";
        boolean flag = wxPayCode.matches(regex);
        if(!flag){
            throw new FebsException("请打开微信付款码!");
        }
        MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectById(orderId);
        mallOrderInfo.setTakeCode(wxPayCode);
        List<ApiGetOrderOrderItemVo> appOrderItemByOrderId = mallOrderItemMapper.getAppOrderItemByOrderId(orderId);
        if(CollUtil.isEmpty(appOrderItemByOrderId)){
src/main/java/cc/mrbird/febs/pay/configure/WxPayConfiguration.java
@@ -1,7 +1,6 @@
package cc.mrbird.febs.pay.configure;
import cc.mrbird.febs.common.enumerates.DataDictionaryEnum;
import cc.mrbird.febs.mall.entity.DataDictionaryCustom;
import cc.mrbird.febs.mall.mapper.DataDictionaryCustomMapper;
import cn.hutool.core.util.StrUtil;
import com.github.binarywang.wxpay.config.WxPayConfig;
src/main/java/cc/mrbird/febs/pay/controller/XcxPayController.java
@@ -73,11 +73,11 @@
    @Autowired
    private IApiMallMemberWalletService memberWalletService;
    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private IXcxCodePayService xcxCodePayService;
//    @Autowired
//    private WxPayService wxPayService;
//
//    @Autowired
//    private IXcxCodePayService xcxCodePayService;
    @Autowired
    private IXcxPayService iXcxPayService;
@@ -299,13 +299,13 @@
    }
    @PostMapping(value = "/xcxCodePayCallBack")
    public String xcxCodePayCallBack(@RequestBody String xmlData) throws WxPayException {
        log.info("=======微信支付码付款回调:{}========", xmlData);
        WxPayOrderNotifyResult notifyResult = this.wxPayService.parseOrderNotifyResult(xmlData);
        xcxCodePayService.payCallback(notifyResult.toMap());
        return WxPayNotifyResponse.success("成功");
    }
//    @PostMapping(value = "/xcxCodePayCallBack")
//    public String xcxCodePayCallBack(@RequestBody String xmlData) throws WxPayException {
//        log.info("=======微信支付码付款回调:{}========", xmlData);
//        WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
//        xcxCodePayService.payCallback(notifyResult.toMap());
//        return WxPayNotifyResponse.success("成功");
//    }
}
src/main/java/cc/mrbird/febs/pay/service/impl/xcxCodePayServiceImpl.java
@@ -1,33 +1,39 @@
package cc.mrbird.febs.pay.service.impl;
import cc.mrbird.febs.common.enumerates.DataDictionaryEnum;
import cc.mrbird.febs.common.enumerates.OrderStatusEnum;
import cc.mrbird.febs.common.exception.FebsException;
import cc.mrbird.febs.mall.entity.MallMember;
import cc.mrbird.febs.mall.entity.MallOrderInfo;
import cc.mrbird.febs.mall.mapper.DataDictionaryCustomMapper;
import cc.mrbird.febs.mall.mapper.MallOrderInfoMapper;
import cc.mrbird.febs.pay.model.BrandWCPayRequestData;
import cc.mrbird.febs.pay.model.JsApiPayBusiness;
import cc.mrbird.febs.pay.model.JsApiPayReqData;
import cc.mrbird.febs.pay.model.JsApiPayResData;
import cc.mrbird.febs.pay.service.IXcxCodePayService;
import cc.mrbird.febs.pay.util.RandomStringGenerator;
import cc.mrbird.febs.pay.util.Signature;
import cc.mrbird.febs.pay.util.WebUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DatePattern;
import cc.mrbird.febs.pay.util.WeixinServiceUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.request.WxPayOrderQueryRequest;
import com.github.binarywang.wxpay.bean.result.WxPayMicropayResult;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@@ -36,37 +42,121 @@
public class xcxCodePayServiceImpl implements IXcxCodePayService {
    private final MallOrderInfoMapper mallOrderInfoMapper;
    private final WxPayService wxService;
    private final DataDictionaryCustomMapper dataDictionaryCustomMapper;
    private final WeixinServiceUtil weixinServiceUtil;
    private static final String PAY_SUCCESS = "SUCCESS";
    private static final String PAY_USERPAYING = "USERPAYING";
    @Override
    public String pay(MallOrderInfo mallOrderInfo) {
        WxPayMicropayRequest request = new WxPayMicropayRequest();
        request
        request.setAppid(wxPayProperties.getAppId());
        request.setMchId(wxPayProperties.getMchId());
        request.setNotifyUrl(wxPayProperties.getNoticeUrl());
        request.setBody(orderInfo.getName());
        request.setOutTradeNo(orderInfo.getOrderNo());
        request.setTimeExpire(DateUtil.format(DateUtil.offset(new Date(), DateField.MINUTE, 15), DatePattern.PURE_DATETIME_PATTERN));
        request.setSpbillCreateIp("127.0.0.1");
        request.setTradeType("APP");
//        if ("dev".equals(active) || "test".equals(active)) {
        if ("dev".equals(active)) {
            request.setTotalFee(1);
        } else {
            request.setTotalFee(orderInfo.getAmount().add(orderInfo.getCarriage()).multiply(new BigDecimal(100)).intValue());
        }
        String appId = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                DataDictionaryEnum.XCX_APP_ID.getType(),
                DataDictionaryEnum.XCX_APP_ID.getCode()
        ).getValue();
        String mchId = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                DataDictionaryEnum.XCX_MCH_ID.getType(),
                DataDictionaryEnum.XCX_MCH_ID.getCode()
        ).getValue();
        String paySecret = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                DataDictionaryEnum.XCX_MCH_KEY.getType(),
                DataDictionaryEnum.XCX_MCH_KEY.getCode()
        ).getValue();
        String keyPath = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                DataDictionaryEnum.XCX_MCH_KEY_PATH_P12.getType(),
                DataDictionaryEnum.XCX_MCH_KEY_PATH_P12.getCode()
        ).getValue();
        String notifyUrl = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                DataDictionaryEnum.XCX_NOTICE_URL.getType(),
                DataDictionaryEnum.XCX_NOTICE_URL.getCode()
        ).getValue();
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setAppId(StrUtil.trim(appId));
        payConfig.setMchId(StrUtil.trim(mchId));
        payConfig.setMchKey(StrUtil.trim(paySecret));
        payConfig.setKeyPath(StrUtil.trim(keyPath));
        payConfig.setNotifyUrl(StrUtil.trim(notifyUrl));
        // 可以指定是否使用沙箱环境
        payConfig.setUseSandboxEnv(false);
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);
        WxPayMicropayRequest request = new WxPayMicropayRequest();
        /**
         *
         Map<String, String> map = new HashMap<>(16);
         map.put("attach", "订单额外描述");
         map.put("auth_code", auth_code);
         map.put("body", "付款码支付测试");
         map.put("device_info", "1000");
         map.put("nonce_str", WXPayUtil.generateNonceStr());
         map.put("out_trade_no", out_trade_no);
         map.put("spbill_create_ip", "14.17.22.52");
         map.put("total_fee", "2");
         //生成签名
         String sign = WXPayUtil.generateSignature(map, config.getKey());
         map.put("sign", sign);
         */
        request.setAppid(appId);
        request.setMchId(mchId);
        request.setNonceStr(RandomStringGenerator.getRandomStringByLength(32));
        request.setBody(mallOrderInfo.getName());
        request.setOutTradeNo(mallOrderInfo.getOrderNo());
        int totalFee = mallOrderInfo.getAmount().subtract(mallOrderInfo.getCarriage()).multiply(new BigDecimal(100)).intValue();
        request.setTotalFee(totalFee);
        request.setSpbillCreateIp(weixinServiceUtil.getIpAddr(WebUtil.getRequest()));
        request.setAuthCode(mallOrderInfo.getTakeCode());
        try {
            WxPayMicropayResult micropay = wxService.micropay(request);
            return JSONObject.toJSONString(micropay);
            request.setSign(Signature.getSign(request,paySecret));
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            throw new FebsException("签名异常");
        }
        try {
            WxPayMicropayResult micropay = wxPayService.micropay(request);
            String returnCode = micropay.getReturnCode();
            String resultCode = micropay.getResultCode();
            String errCode = micropay.getErrCode();
            String outTradeNo = micropay.getOutTradeNo();
            String errCodeDes = micropay.getErrCodeDes();
            /**
             * 交易成功判断条件:return_code和result_code都为SUCCESS且trade_type为MICROPAY
             */
            if(PAY_SUCCESS.equals(returnCode) && PAY_SUCCESS.equals(resultCode)){
                log.info("微信免密支付成功");
                return PAY_SUCCESS;
            } else if (PAY_USERPAYING.equals(errCode)){//等待用户输入密码
                for(int i = 0; i < 4; i++){
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //调用微信的查询接口
                    /**
                     * 交易成功判断条件: return_code、result_code和trade_state都为SUCCESS
                     */
                    WxPayOrderQueryRequest wxPayOrderQueryRequest = new WxPayOrderQueryRequest();
                    wxPayOrderQueryRequest.setOutTradeNo(outTradeNo);
                    WxPayOrderQueryResult wxPayOrderQueryResult = wxPayService.queryOrder(wxPayOrderQueryRequest);
                    String returnCodePaying = wxPayOrderQueryResult.getReturnCode();
                    String resultCodePaying = wxPayOrderQueryResult.getResultCode();
                    String tradeTypePaying = wxPayOrderQueryResult.getTradeType();
                    if(PAY_SUCCESS.equals(tradeTypePaying)&& PAY_SUCCESS.equals(returnCodePaying)&& PAY_SUCCESS.equals(resultCodePaying)){
                        log.info("微信加密支付成功!");
                        return PAY_SUCCESS;
                    }
                    log.info("正在支付" + wxPayOrderQueryResult.getDetail());
                }
            }
            log.error("微信支付失败!");
            return errCodeDes;
        } catch (WxPayException e) {
            e.printStackTrace();
            throw new FebsException("支付异常, 请检查");
            throw new FebsException("支付异常");
        }
        return null;
    }
    @Override
src/main/resources/templates/febs/views/modules/system/xcxSetting.html
@@ -1,36 +1,40 @@
<div class="layui-fluid layui-anim febs-anim" id="xcx-setting" lay-title="小程序设置">
<div class="layui-fluid layui-anim febs-anim" id="xcx-setting" lay-title="微信收款码支付设置">
    <div class="layui-row layui-col-space8 febs-container">
        <form class="layui-form" action="" lay-filter="xcx-setting-form">
            <div class="layui-card">
                <div class="layui-card-body">
                    <div class="layui-form-item">
                        <label class="layui-form-label ">每次最小提现金额:</label>
                        <label class="layui-form-label ">APPID:</label>
                        <div class="layui-input-block">
                            <input type="text" name="minCashOut" data-th-id="${cashout.minCashOut}"
                                   lay-verify="number" autocomplete="off" class="layui-input" >
                            <input type="text" name="appId"  lay-verify="text" autocomplete="off" class="layui-input" >
                        </div>
                    </div>
                    <div class="layui-form-item">
                        <label class="layui-form-label ">每日提现上限:</label>
                        <label class="layui-form-label ">MCHID:</label>
                        <div class="layui-input-block">
                            <input type="text" name="allCashOut" data-th-id="${cashout.allCashOut}"
                                   lay-verify="number" autocomplete="off" class="layui-input" >
                            <input type="text" name="mchId" lay-verify="text" autocomplete="off" class="layui-input" >
                        </div>
                        <div class="layui-word-aux" style="margin-left: 150px;">商户号</div>
                    </div>
                    <div class="layui-form-item">
                        <label class="layui-form-label ">提现手续费:</label>
                        <label class="layui-form-label ">MCHKEY:</label>
                        <div class="layui-input-block">
                            <input type="text" name="serviceFee" data-th-id="${cashout.serviceFee}"
                                   lay-verify="text" autocomplete="off" class="layui-input" >
                            <input type="text" name="mchKey" lay-verify="text" autocomplete="off" class="layui-input" >
                        </div>
                        <div class="layui-word-aux" style="margin-left: 150px;">提现手续费:直接输入百分比,例如25%,直接输入25</div>
                        <div class="layui-word-aux" style="margin-left: 150px;">商户支付密钥</div>
                    </div>
                    <div class="layui-form-item">
                        <label class="layui-form-label">提现时间:</label>
                        <label class="layui-form-label">证书地址:</label>
                        <div class="layui-input-block">
                            <input type="radio" name="workingDays" value="1" title="工作日">
                            <input type="radio" name="workingDays" value="2" title="每一天">
                            <input type="text" name="keyPath" lay-verify="text" autocomplete="off" class="layui-input" >
                        </div>
                        <div class="layui-word-aux" style="margin-left: 150px;">证书地址p12,服务器路径</div>
                    </div>
                    <div class="layui-form-item">
                        <label class="layui-form-label">回调地址:</label>
                        <div class="layui-input-block">
                            <input type="text" name="notifyUrl" lay-verify="text" autocomplete="off" class="layui-input" >
                        </div>
                    </div>
                </div>
@@ -60,28 +64,29 @@
        var $ = layui.jquery,
            febs = layui.febs,
            form = layui.form,
            cashout = [[${cashout}]],
            xcxSetting = [[${xcxSetting}]],
            validate = layui.validate,
            $view = $('#xcx-setting');
        form.verify(validate);
        initCashoutValue();
        xcxSettingValue();
        form.render();
        function initCashoutValue() {
        function xcxSettingValue() {
            form.val("xcx-setting-form", {
                "minCashOut": cashout.minCashOut,
                "allCashOut": cashout.allCashOut,
                "serviceFee": cashout.serviceFee,
                "workingDays": cashout.workingDays
                "appId": xcxSetting.appId,
                "mchId": xcxSetting.mchId,
                "mchKey": xcxSetting.mchKey,
                "keyPath": xcxSetting.keyPath,
                "notifyUrl": xcxSetting.notifyUrl
            });
        }
        form.on('submit(xcx-setting-form-submit)', function (data) {
            console.log(data);
            febs.post(ctx + 'admin/system/cashOutSetting', data.field, function (res) {
            febs.post(ctx + 'admin/system/xcxSetting', data.field, function (res) {
                febs.alert.success('设置成功');
            });
            window.location.reload();
src/test/java/cc/mrbird/febs/PayTest.java
@@ -17,17 +17,17 @@
@SpringBootTest
public class PayTest {
    @Test
    public void aliPay() throws AlipayApiException {
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody("这是测试用");
        model.setSubject("支付测试用的");
        model.setOutTradeNo("2021092712215802974");
        model.setTimeoutExpress("15m");
        model.setTotalAmount("0.01");
        model.setPassbackParams("callback params");
        model.setProductCode("QUICK_MSECURITY_PAY");
        AlipayTradeAppPayResponse resp = AliPayApi.appPayToResponse(model, "");
        log.info("=====>>>{}", JSONObject.toJSONString(resp));
    }
//    @Test
//    public void aliPay() throws AlipayApiException {
//        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
//        model.setBody("这是测试用");
//        model.setSubject("支付测试用的");
//        model.setOutTradeNo("2021092712215802974");
//        model.setTimeoutExpress("15m");
//        model.setTotalAmount("0.01");
//        model.setPassbackParams("callback params");
//        model.setProductCode("QUICK_MSECURITY_PAY");
//        AlipayTradeAppPayResponse resp = AliPayApi.appPayToResponse(model, "");
//        log.info("=====>>>{}", JSONObject.toJSONString(resp));
//    }
}