微信扫码支付

来源:互联网 发布:vue.js 动态添加dom 编辑:程序博客网 时间:2024/06/05 00:20

最近公司需要做一个微信扫码支付的功能,已完成用户扫描二维码完成付款,通过查询微信的开发文档,已完成上述功能,接下来我会进行分享并进行讲解有关微信扫支付的相关信息

项目需求:用户下单后,处理完订单,将订单状态改变后,给用户端生成二维码,用户通过扫描二维码完成付款

下面我会针对我写的代码逐一解释(链接我都会以xxx代替,只需要换成你的具体名称即可)

@RequestMapping("/xxx.do")

@ResponseBody

public Map<String, Object> weChatSweepPay(

           @RequestParam(value="orderId",required=false) final Integer orderId,//订单id
            @RequestParam(value="sessionId",required=false) final String sessionId,//登录标识
            HttpServletRequest request,HttpServletResponse response
            ){

        BasisWxagent agent = null;(微信的相关参数.如appId,secret之类的等,你们都知道)

            //定义一个map集合

            Map<String, Object> result = new HashMap<String, Object>();

           //校验订单是否存在,

    RepairOrder order = repairOrderService.getRepairOrderByPrimaryKey(orderId);
        if(order == null) {
            // TODO: 错误处理
            result.put("errMsg", "订单不存在");
            result.put("returnCode", "FAIL");
            return result;
        }

        //定义这个主要作用是用户执行合并支付,用不到合并支付的直接就使用orderId即可

        ArrayList<Integer> orderIdList = new ArrayList<>();        orderIdList.add(orderId);
        result.put("orderIdList", orderIdList);
        result.put("orderId", orderId);

        //支付来源,用户区分是扫码支付还是微信支付

        result.put("paySource",WxPayUtil.PAYSOURCE_WEIXINQR);

        //微信定义的支付分类,(JSAPI:小程序,APP:安卓手机端;NATIVE:微信扫码支付;公众号:JSAPI)这里不懂的可以看微信开发文档

        String trade_type;

//我们公司是将微信需要的参数放入表里了.这都是在去需要的数据

agent = WxAgent.getWorkerAppAgent();

//将需要的参数放入map集合

        result.put("agentId", agent.getId());
        Integer payType=9;
        result.put("payType", payType);

//将map集合转为json串

String attach = JSONObject.fromObject(result).toString();

//定义支付的类型为扫码支付

trade_type = "NATIVE";

// 商户相关资料(需要提前申请,具体看文档即可,这里我就不再说明了)
        String appid = agent.getAppId();
        String partner = agent.getPartnerId();
        String partnerkey = agent.getPartnerKey();

        // 商户号
        String mch_id = partner;
        // 随机数
        String nonce_str = WxPayUtil.generateNonceStr();
        // 订单生成的机器 IP
        String spbill_create_ip = request.getRemoteAddr();

        // 这里notify_url是 支付完成后微信发给该链接信息,可以判断会员是否支付成功,改变订单状态等。
        String notify_url = Common.getRequestUrl(request, "/wxpay/notifyStatus.do");

// 非必输(都是微信需要的参数.我就不做解释了)
                SortedMap<String, String> packageParams = new TreeMap<String, String>();
                String body="微信扫码支付订单";
                packageParams.put("appid", appid);
                packageParams.put("mch_id", mch_id);
                packageParams.put("nonce_str", nonce_str);
                packageParams.put("body", body);
                packageParams.put("attach", attach);
                String out_trade_no = WxPayUtil.getOutTradeNo(orderId, order.getOrderNumber(),          WxPayUtil.PAYSOURCE_WEIXINQR); 
                //修改该订单的outtradenumber
                repairOrderService.updateOutTradeNo(orderId, out_trade_no);
                packageParams.put("out_trade_no", out_trade_no);

packageParams.put("total_fee",order.getAmount().toString());
                logger.info("支付金额" + order.getAmount().toString());
                packageParams.put("spbill_create_ip", spbill_create_ip);
                packageParams.put("notify_url", notify_url);

                packageParams.put("trade_type", trade_type);
                
                String sign = WxPayUtil.createSign(packageParams, partnerkey);
                packageParams.put("sign", sign);

String sign = WxPayUtil.createSign(packageParams, partnerkey);
                packageParams.put("sign", sign);
                String openid = "";
                if (sessionId != null && !sessionId.isEmpty()) {
                    openid = WeiXinSession.getOpenId(sessionId);
                }else {
                    openid = Common.getOpenId(request);
                }

//把刚刚填入的参数在以微信需要的格式放入xml中(不要问为什么,腾讯规定的)

String xml = "<xml>"
                        + "<appid>" + appid + "</appid>"
                        + "<mch_id>" + mch_id + "</mch_id>"
                        + "<nonce_str>" + nonce_str    + "</nonce_str>"
                        + "<sign>" + sign + "</sign>"
                        + "<body><![CDATA[" + body + "]]></body>"
                        + "<attach><![CDATA[" + attach + "]]></attach>"
                        + "<out_trade_no>" + out_trade_no + "</out_trade_no>"
                        +"<total_fee>" + order.getAmount().toString() + "</total_fee>"
                        + "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>"
                        + "<notify_url>" + notify_url + "</notify_url>"
                        + "<trade_type>" + trade_type + "</trade_type>"
                        + ("NATIVE".equals(trade_type) ? "" : "<openid>" + openid + "</openid>")
                        + "</xml>";

//通知微信的url(看文档即可)

String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";

//下面就需要将url我们自己写好的sml以post的方式提交给微信即可,我们使用的request的方式

String content = WeixinUtil.httpsRequestStringEntity(createOrderURL, "POST", xml);

//查看调用结果,如果调用成功,回返回SUCCESS

logger.info("调用结果" + content);

//接下来,就需要解析content,我们请求成功后,微信会在xml给我们返回一个url

try {    
                    
                    String content = WeixinUtil.httpsRequestStringEntity(createOrderURL, "POST", xml);
                    logger.info("调用结果" + content);
                    //解析xml(这里各位可以根据自己的方式,只要解析出来即可)
                    Map<String, String> mapfromXML = XMLUtil.MapfromXML(content);
                    if (mapfromXML.get("return_code").equals("SUCCESS")) {

                       //返回success后,获取到code_url.然后调用谷歌的二维码工具类,生成二维码即可

                        String code_url = mapfromXML.get("code_url");
                        //将qrCode二维码图片返回给app端,调用工具类
                        response.setContentType("image/png");
                        //调用工具类生成二维码
                        OutputStream out = null;
                        try {
                            out = response.getOutputStream();
                            QRCodeUtil.generateQRCodeWithLogo(request, code_url, 300, 300, "jpg", out);
                            logger.info("二维码生成成功!");
                        } catch (Exception e) {
                            // TODO: handle exception
                            logger.error("生成二维码异常!"+code_url);
                            e.printStackTrace();
                        }finally {
                            if(out!=null)  
                                out.close();
                        }
                    }
                } catch (Exception e1) {
                    e1.printStackTrace();
                    logger.error("提交支付查询订单失败!");
                    result.put("errcode", "-1");
                    result.put("errmsg", "支付失败请与管理员联系");
                    return result;
                }

//如果你能走到这里,证明已经生成二维码了,接下来,就是用户付完款之后,微信支付回调,我们获取回调参数,执行订单状态修改的一系列操作今天太累了,改天再来分享




//如果您觉得有用,并且帮到了您,请帮忙为博主支付点辛苦费吧,钱不在多少,只需要一份您的认可


                                                                                                                                                      2017/09/23


                                                                                                                         -------------------------------阿甘菜鸟原创