全部开发者教程

企业级在线办公系统

首页 慕课教程 企业级在线办公系统 企业级在线办公系统 10-12 创建支付订单(持久层&业务层)

我们明白了微信支付的一些基础概念,只有先创建好支付订单,然后用户才能付款,所以这节课我们来实现创建支付订单的后端代码。

图片描述
首先你要明白一个概念,支付订单是由商户系统调用微信支付接口创建的,所以写代码之前,我们必须要了解微信支付的API接口规范,需要我们提交什么参数,返回什么结果。

一、创建支付订单的API接口

大家可以用浏览器访问微信支付的API手册(https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1),查阅具体的调用规范。因为其中有很多非必要的参数,所以我整理了一下,我们看下面的表格。

参数 含义 类型 例子
appid 公众号ID String wxd678efh567hg6787
mch_id 商户号ID String 1230000109
nonce_str 随机字符串 String 5K8264ILTKCH16CQ2502SI8ZNMTM67VS
sign 签名 String C380BEC2BFD727A4B6845133519F3AD6
body 商品订单描述 String QQ会员充值
out_trade_no 商品订单号 String 20150806125346
total_fee 订单金额 int 150
spbill_create_ip 终端IP String 123.12.12.123
notify_url 通知地址 String http://140.143.132.225:8000/project-1/doc-110/
trade_type 交易类型 String NATIVE

微信支付平台给我们返回的响应中包含了下面这些参数。

参数 含义 类型 例子
return_code 通信状态码 String SUCCESS
result_code 业务状态码 String SUCCESS
app_id 微信公众账号APPID String wx8888888888888888
mch_id 商户ID String 1900000109
nonce_str 随机字符串 String 5K8264ILTKCH16CQ2502SI8ZNMTM67VS
sign 数字签名 String C380BEC2BFD727A4B6845133519F3AD6
trade_type 交易类型 String NATIVE
prepay_id 支付订单ID String wx201410272009395522657a690389285100

图片描述

二、定义值注入

application.yml文件中,定义值注入内容,这些内容必须都是QQ群里面企业身份的。

wx:
  app-id: 企业身份APPID
  app-secret: 企业身份密钥
  mch-id: 企业身份商户号ID
  key: 企业身份微信支付的密钥
  cert-path: 企业身份微信支付的数字证书路径

然后大家创建com.example.emos.api.wxpay包,把课程GIT上面的微信支付工具类放入这个包。

图片描述

三、编写持久层代码

TbAmectDao.xml文件中,声明SQL语句。

<select id="searchAmectByCondition" parameterType="HashMap" resultType="HashMap">
    SELECT uuid,
           amount,
           prepay_id AS prepayId,
           `status`
    FROM tb_amect
    WHERE id = #{amectId}
    AND user_id = #{userId}
    <if test="status!=null">
        AND `status` = #{status}
    </if>
</select>
<update id="updatePrepayId" parameterType="HashMap">
    UPDATE tb_amect
    SET prepay_id = #{prepayId}
    WHERE id = #{amectId} AND status = 1
</update>

TbAmectDao.java接口中,声明DAO方法。

public interface TbAmectDao {
    ……
    public HashMap searchAmectByCondition(HashMap param);
    public int updatePrepayId(HashMap param);
}

四、编写业务层代码

AmectService.java接口中,定义抽象方法。

public interface AmectService {
    ……
    public String createNativeAmectPayOrder(HashMap param);
}

AmectServiceImpl.java类中,实现抽象方法,创建支付订单。

public class AmectServiceImpl implements AmectService {
    @Autowired
    private MyWXPayConfig myWXPayConfig;
    
    ……
    @Override
    public String createNativeAmectPayOrder(HashMap param) {
        int userId = MapUtil.getInt(param, "userId");
        int amectId = MapUtil.getInt(param, "amectId");
        //根据罚款单ID和用户ID查询罚款单记录
        HashMap map = amectDao.searchAmectByCondition(param);
        if (map != null && map.size() > 0) {
            String amount = new BigDecimal(MapUtil.getStr(map, "amount")).multiply(new BigDecimal("100")).intValue() + "";
            try {
                WXPay wxPay = new WXPay(myWXPayConfig);
                param.clear();
                param.put("nonce_str", WXPayUtil.generateNonceStr()); //随机字符串
                param.put("body", "缴纳罚款");
                param.put("out_trade_no", MapUtil.getStr(map, "uuid"));
                param.put("total_fee", amount);
                param.put("spbill_create_ip", "127.0.0.1");
                param.put("notify_url", "http://s1.nsloop.com:35750/emos-api/amect/recieveMessage");
                param.put("trade_type", "NATIVE");
                String sign = WXPayUtil.generateSignature(param, myWXPayConfig.getKey());
                param.put("sign", sign);
                Map<String, String> result = wxPay.unifiedOrder(param); //创建支付订单
                String prepayId = result.get("prepay_id");  //微信订单ID
                String codeUrl = result.get("code_url");   //支付连接,需要生成二维码让手机扫码
                if (prepayId != null) {
                    param.clear();
                    param.put("prepayId", prepayId);
                    param.put("amectId", amectId);
                    int rows = amectDao.updatePrepayId(param);
                    if (rows != 1) {
                        throw new EmosException("更新罚款单的支付订单ID失败");
                    }

                    //把支付订单的URL生成二维码
                    QrConfig qrConfig = new QrConfig();
                    qrConfig.setWidth(255);
                    qrConfig.setHeight(255);
                    qrConfig.setMargin(2);
                    String qrCodeBase64 = QrCodeUtil.generateAsBase64(codeUrl, qrConfig, "jpg");
                    return qrCodeBase64;
                } else {
                    log.error("创建支付订单失败", result);
                    throw new EmosException("创建支付订单失败");
                }
            } catch (Exception e) {
                log.error("创建支付订单失败", e);
                throw new EmosException("创建支付订单失败");
            }

        } else {
            throw new EmosException("没有找到罚款单");
        }
    }
}