电商项目日总结(第十八天微信支付)

一、业务逻辑

1.续接昨天的,当在getOrderInfo.html页面点击提交订单后,昨天是生成了一个order订单和order_item订单商品(订单明细),在昨天的基础上还要生成一个pay_log支付订单,这个支付订单不仅要保存到数据库中,还要把pay_log这个对象保存在redis中,如果生成订单成功后,跳转支付页面pay.html

2.一跳转到支付页面pay.html,就要生成微信二维码,生成二维码需要两个参数:通过用户id(userId)在redis中获取pay_log对象,进而获取支付订单号out_trade_no和支付金额total_fee这两个参数.

3.拿着这两个参数,就可以在service层通过HttpClient去请求对接微信的接口,请求中传递一个携带商品信息的xml类型的字符串(我们先将需要必要的信息封装到一个map集合中,然后通过提供一个签名信息给微信的工具类将map集合生成一个xml类型的字符串);然后微信端给我们返回来的也是一个xml类型的字符串,我们通过微信的工具类将其转为一个map类型,经过我们重新封装一个map返回给页面,这个封装后的map携带三个参数:返回支付二维码的url,页面要显示的订单号,页面要显示的总金额,代码如下:

/**
 * 生成微信二维码
 *
 * @param out_trade_no 支付单号(一个用户只有一个支付单号,一个支付单号上可以有很多订单号)
 * @param total_fee    总金额
 * @return
 */
@Override
public Map createNative(String out_trade_no, String total_fee) {
    try {
        //通过HttpClient来给微信的接口连接发送请求
        HttpClientUtil httpClient = new HttpClientUtil("https://api.mch.weixin.qq.com/pay/unifiedorder");
        //因为访问微信的接口需要很多必要的参数信息,所以封装成一个map集合
        Map requestMap = new HashMap();
        requestMap.put("appid", appid);//公众号id
        requestMap.put("mch_id", mch_id);//商户号id
        requestMap.put("nonce_str", WXPayUtil.generateUUID());//生成一个随机字符串加密用
        requestMap.put("body", "品优购商品");//商品描述
        requestMap.put("out_trade_no", out_trade_no);//支付单号
        requestMap.put("total_fee",total_fee);//总金额(单位:分)
        requestMap.put("spbill_create_ip","127.0.0.1");//终端ip(一般是手机上给传过来的)
        requestMap.put("notify_url",notifyurl);//通知地址
        requestMap.put("trade_type","NATIVE");//交易类型
        //将请求参数封装的Map集合转成XML类型的,需要携带签名信息
        String requestXML = WXPayUtil.generateSignedXml(requestMap, partnerkey);
        //微信只接受XML类型的参数
        httpClient.setXmlParam(requestXML);
        //因为微信给的接口的连接是https,所以需要设置请求的协议
        httpClient.setHttps(true);
        //发送请求
        httpClient.post();
        //接收响应内容(因为微信响应回来的是XML类型的)
        String responseXML = httpClient.getContent();
        //将XML类型的响应内容转成map类型的
        Map responseMap = WXPayUtil.xmlToMap(responseXML);
        //将结果重新封装为了去除不要的信息
        Map resultMap=new HashMap();
        //通过返回结果result_code判断是否成功
        if("SUCCESS".equals(responseMap.get("result_code"))){
            resultMap.put("code_url",responseMap.get("code_url"));//返回的支付二维码
            resultMap.put("out_trade_no",out_trade_no);//为了页面显示订单号
            resultMap.put("total_fee",total_fee);//为了页面显示总金额
        }
        return resultMap;
    } catch (Exception e) {
        e.printStackTrace();
        return new HashMap();
    }
}

4.前端部分通过接收一个map集合,获取map集合中的url通过qrious(二维码生成插件)来在页面生成二维码

5.一生成二维码就要去后端查询订单状态,还是去对接微信查询订单的接口,通过发送HttpClient请求给微信的接口,需要前端页面返还一个订单号,响应回一个map,这次不用重新封装,直接返回就行

前端controller部分

重点是后端controller层的业务逻辑

@RequestMapping("/queryPayStatus")
public Result queryPayStatus(String out_trade_no) {
    //新建一个返回结果
    Result result = null;
    //
    int count = 1;
    while (true) {
        //返回包含支付状态trade_state的map
        Map map = wxPayService.queryPayStatus(out_trade_no);
        //支付出错
        if (map == null) {
            result = new Result(false, "支付异常");
            break;
        }
        //支付成功
        if ("SUCCESS".equals(map.get("trade_state"))) {
            result = new Result(true, "支付成功");
            //支付成功,修改订单状态
            wxPayService.updateOrderStatus(out_trade_no,map.get("transaction_id").toString());
            break;
        }
        //请求超时
        if (count >= 6) {
            System.out.println("超时======================");
            result = new Result(false, "timeout");
            break;
        }
        try {
            //等待3s,做一次支付单查询
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //查询支付单次数加一
        count++;
    }
    return result;
}

支付成功后,别忘了修改支付订单payLog和订单order的状态,并且清空支付订单pay_log在redis中的缓存,代码如下

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值