• 微信支付实现过程


    微信支付实现过程:

    1:首先是企业注册微信公众平台;

    2:需要认证,然后开通微信支付;如图

    3:进入这里来注册商户;  每一个小程序对应一个商户

     4: 商户和小程序或者公众号做邦定,

     5:根据开发需要 ,进行开发配置:

     

     ------------------------------------------------

    以上准备工作做完后可进行开发,邦定成功后如图显示

     小程序配置

     

     接下来开始配置代码:

    这里我只介绍小程序的支付配置:

    小程序相对较为简单,关键是接下来的参数需要配置正确其余就ok了;

    整体思路:

    小程序发送一个支付请求,后端进行支付处理,返回5个参数,然后小程序发起支付输入密码,支付成功;

    1: 小程发送请求 ,后端下单 ,返回5个参数

    5个参数搞清楚了一切好办:

    appid=wx5c022XXXXXXXX 小程序的appid
    secret=3165b49d0772fdf28bd20 小程序的secret
    key= 这个key就是上面商户配置中,帐户中心->API安全-> 设置密钥,,这个在你写程序的时候往往会出现解密不成功,或其他签名错误时,重新设置一下这个密钥,
    mch_id=15236 绑定的商户号
    body=支付收款名称
    notify_url =https://wx.ing.com,这里配置小程序的配置里;



    开始后端处理支付代码:

    //CommonSdo我自己定义的返回类
     public CommonSdo<Map<String,Object>> wxpay(String openid, //这是openid ,根据自己业务来传参
                                        Long oid, //这是我们的 订单id 根据自己业务来传参
                                        HttpServletRequest request){
            if (null==openid){
                return CommonSdo.error("登陆过期,请重新登陆");
            }
            //客户下订单
            Order order = findOrderById(oid).getItem();  //获取小程序端客户下的订单
        
            //微信支付开始///////////////////////////////////////////////////////////////////////////////try {
                           //生成的随机字符串
                String nonce_str =getRandomStringByLength(32);
                //商品名称
                String body = "工作室";
                //获取客户端的ip地址
                String spbill_create_ip = getIpAddr(request);
                //组装参数,用户生成统一下单接口的签名
                Map<String, String> packageParams = new HashMap<String, String>();
                packageParams.put("appid", apppid);    //小程序的appid
                packageParams.put("mch_id", mch_id);   //绑定的商户号
                packageParams.put("nonce_str", nonce_str);  //生成的随机字符串
                packageParams.put("body", body);  //商品名称
                packageParams.put("out_trade_no",order.getCode());      //商户订单号,这个订单号注意不要重复,否则会提示已支付等问题
                packageParams.put("total_fee",orderPrice);              //支付金额,这边需要转成字符串类型,否则后面的签名会失败,以分为单位
                packageParams.put("spbill_create_ip", spbill_create_ip);//
                packageParams.put("notify_url",notify_url);//支付成功后的回调地址
                packageParams.put("trade_type", "JSAPI");//支付方式
                packageParams.put("openid", openid);
    
                // 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
                String prestr = PayUtil.createLinkString(packageParams);
    
                //MD5运算生成签名,这里是第一次签名,用于调用统一下单接口
                String mysign = PayUtil.sign(prestr,key,"utf-8").toUpperCase();
    
                //拼接统一下单接口使用的xml数据,要将上一步生成的签名一起拼接进去
                String xml = "<xml>" + "<appid>"+apppid+"</appid>"
                        + "<body><![CDATA[" + body + "]]></body>"
                        + "<mch_id>"+mch_id+"</mch_id>"
                        + "<nonce_str>"+nonce_str + "</nonce_str>"
                        + "<notify_url>"+notify_url+"</notify_url>"
                        + "<openid>"+openid+"</openid>"
                        + "<out_trade_no>"+order.getCode()+"</out_trade_no>"
                        + "<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"
                        + "<total_fee>"+orderPrice+"</total_fee>"
                        + "<trade_type>"+"JSAPI"+"</trade_type>"
                        + "<sign>"+mysign+"</sign>"
                        + "</xml>";
    
                System.out.println("调试模式_统一下单接口 请求XML数据:" + xml);
    
                //调用统一下单接口,并接受返回的结果
                String result = PayUtil.httpRequest(
                        "https://api.mch.weixin.qq.com/pay/unifiedorder",
                        "POST", xml);
    
                System.out.println("调试模式_统一下单接口 返回XML数据:" + result);
                ////////////////////////////////////////////////////////////////////////////////
    
                // 将解析结果存储在HashMap中
                Map map = PayUtil.doXMLParse(result);
    
                String return_code = (String) map.get("return_code");//返回状态码
    
                Map<String, Object> response = new HashMap<String, Object>();//返回给小程序端需要的参数
                if (return_code.equals("SUCCESS")) {
                    String prepay_id = (String) map.get("prepay_id");//返回的预付单信息
                    response.put("nonceStr", nonce_str);
                    response.put("package", "prepay_id=" + prepay_id);
                    Long timeStamp = System.currentTimeMillis() / 1000;
                    response.put("timeStamp", timeStamp + "");//这边要将返回的时间戳转化成字符串,不然小程序端调用wx.requestPayment方法会报签名错误
                    //拼接签名需要的参数
                    String stringSignTemp = "appId=" + apppid + "&nonceStr=" + nonce_str + "&package=prepay_id=" + prepay_id + "&signType=MD5&timeStamp=" + timeStamp;
                    //再次签名,这个签名用于小程序端调用wx.requesetPayment方法
                    String paySign = PayUtil.sign(stringSignTemp, key, "utf-8").toUpperCase();
    
                    response.put("paySign", paySign);
                }
    
                response.put("appid", apppid);
                //////////////////////////////////////微信支付结束/////////////////////////////////
                //更改订单状态
                order.setState(Order.STATE_PAY);
                orderRepository.save(order);
                ///////////////////////////////////////////////
    
                return CommonSdo.success(response);   //CommonSdo我自己定义的返回类
            } catch (Exception e) {
                e.printStackTrace();
            }
            return CommonSdo.error("支付异常,未能支付成功");
        }
    
        /**
         * StringUtils工具类方法
         * 获取一定长度的随机字符串,范围0-9,a-z
         *
         * @param length:指定字符串长度
         * @return 一定长度的随机字符串
         */
        public static String getRandomStringByLength(int length) {
            String base = "abcdefghijklmnopqrstuvwxyz0123456789";
            Random random = new Random();
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < length; i++) {
                int number = random.nextInt(base.length());
                sb.append(base.charAt(number));
            }
            return sb.toString();
        }
    
        /**
         * IpUtils工具类方法
         * 获取真实的ip地址
         *
         * @param request
         * @return
         */
        public static String getIpAddr(HttpServletRequest request) {
            String ip = request.getHeader("X-Forwarded-For");
            if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
                //多次反向代理后会有多个ip值,第一个ip才是真实ip
                int index = ip.indexOf(",");
                if (index != -1) {
                    return ip.substring(0, index);
                } else {
                    return ip;
                }
            }
            ip = request.getHeader("X-Real-IP");
            if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
                return ip;
            }
            return request.getRemoteAddr();
        }

    2:

    官方小程序支付方法,然后小程序拿到返回的以下参数,即可发起支付

      wx.requestPayment({
        timeStamp: " ",
        nonceStr: " ",
        package: " ",
        signType: 'MD5',
        paySign: " ",
        success: function (res) {
        
           
      })
    
  • 相关阅读:
    mySQL练习题
    JAVA实现C/S结构小程序
    JavaLinkedHashSet练习
    关于Extjs删除分页后删除最后一条数据页面无效的问题。
    hibernate 插入,更新数据库错误
    错误!错误!错误!
    坑爹的oracle
    关于hibernate实体类
    第一个项目的需求分析
    Ueditor 单独使用上传图片及上传附件方法
  • 原文地址:https://www.cnblogs.com/Amos-Turing/p/10276647.html
Copyright © 2020-2023  润新知