Java调用微信扫码支付接口(模式二)

前些天帮朋友实现了一个微信扫码的接口,在之前也是不会搞这个东西,抱着试试的心态就开始看各种文档和blogs,大多数人都在吐槽微信给的java调用微信接口文档太含糊,而且网上的查到的资料也不详细,只有大概的开发流程没有太多细节上的讲解,最后还是花了一些钱买了一套视频和demo(理清了我的思路),最后完成了开发,如果有同学需要的话可以给我留言,我将免费提供帮助(可能不能及时回复)。

(在这之间我们需要申请商家号)首先我们要理清思路要怎么进行扫码接口调用开发:
这里写图片描述
图自己画的不太好,见谅。

从图中可以看出微信扫码支付的大概流程,首先是下单,我们需要拼接一个xml(包含商户平台ID,价格,随机数等信息)发送给微信接口,首先我们要知道,我们和微信接口之间的信息传递都需要使用xml,所以在开发中xml信息的拼接和解析是至关重要的。


发送统一下单的xml,首先我们应该知道需要将哪些信息拼接成xml信息:
这里写图片描述

这个是我们的一些必须清单:
APP_ID
这里写图片描述
这个APP_ID我就填错了(当时没找到APP_ID),一直报空指针错误。

MCH_ID这个是商家号:
这里写图片描述
就是我涂鸦的那个部分,申请过商户平台账号后会给你分配一个账号。

API_KEY:
这里写图片描述

这里写图片描述
在这个页面可以查看API_KEY,如果忘了就重置一下。

UFDODER_URL:这个是固定值,是我们统一下单的目的url:
https://api.mch.weixin.qq.com/pay/unifiedorder

NOTIFY_URL:这个是回调地址(支付成功后,微信接口返回给我们的url,一定要是公网可以访问的,不能是我们的本地localhost)。

CREATE_IP:这个东西可有可无,随便填写一个ip就行了。

//返回可生成二维码的urlCode,这里面用到了一些工具(拼接解析xml和发送http请求)
String out_trade_no = "" + System.currentTimeMillis(); //订单号 
        // 账号信息 
        String appid = PayConfigUtil.APP_ID;  // appid  
        //String appsecret = PayConfigUtil.APP_SECRET; // appsecret  
        String mch_id = PayConfigUtil.MCH_ID; // 商业号  
        String key = PayConfigUtil.API_KEY; // key  
        
        String currTime = PayToolUtil.getCurrTime();  
        String strTime = currTime.substring(8, currTime.length());  
        String strRandom = PayToolUtil.buildRandom(4) + "";  
        String nonce_str = strTime + strRandom;  
        // 获取发起电脑 ip
        String spbill_create_ip = PayConfigUtil.CREATE_IP;
        // 回调接口   
        String notify_url = PayConfigUtil.NOTIFY_URL;
        String trade_type = "NATIVE";
          
        SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();  
        packageParams.put("appid", appid);
        //packageParams.put("appsecret", appsecret);
        packageParams.put("mch_id", mch_id);  
        //随机字符串
        packageParams.put("nonce_str", nonce_str);  
        packageParams.put("body", "报名费用");  //(调整为自己的名称)
        packageParams.put("out_trade_no", out_trade_no);
        if(productId.equals("1")) {
        	packageParams.put("total_fee", "1");//一级费用240元,价格的单位为分  
        }else if(productId.equals("2")) {
        	packageParams.put("total_fee", "28000");
        }else if(productId.equals("3")) {
        	packageParams.put("total_fee", "32000");
        }else if(productId.equals("4")) {
        	packageParams.put("total_fee", "36000");
        }else if(productId.equals("5")) {
        	packageParams.put("total_fee", "42000");
        }else{
        	packageParams.put("total_fee", "48000");
        } 
        packageParams.put("spbill_create_ip", spbill_create_ip);  
        packageParams.put("notify_url", notify_url);  
        packageParams.put("trade_type", trade_type);  
  
        String sign = PayToolUtil.createSign("UTF-8", packageParams,key);  
        packageParams.put("sign", sign);
          
        String requestXML = PayToolUtil.getRequestXml(packageParams); 
        requestXML= requestXML.replaceAll("__", "_");
        System.out.println("请求xml:"+requestXML);
        //记录请求商户订单号
        Map<String,String> out_map = XMLUtil4jdom.doXMLParse(requestXML);
        String out_no = (String) out_map.get("out_trade_no");
        System.out.println("第一次商户号:"+out_no);
        //接下来存储商户订单号和用户(身份证号)对应关系
        //这里执行数据库逻辑
        
        String resXml = HttpUtil.postData(PayConfigUtil.UFDODER_URL, requestXML); 
        System.out.println("响应xml:"+resXml); 
		Map<String,String>map = XMLUtil4jdom.doXMLParse(resXml);
        String urlCode = (String) map.get("code_url"); //code_url
        //System.out.println(urlCode);
        return urlCode;

我们需要知道首先我们应该将需要发送的信息放入map中,然后将它们拼接成xml,然后发送给微信,然后接收来自微信的xml,我们解析这个xml,获得url_code,就是生成二维码的content,然后使用谷歌的生成代码zxing进行生成二维码,最后将生成的二维码通过你想要的方式发送给前台。

——————————————————————————————

接下来就是扫码过后进行信息的回调了(例如对用户下单进行数据库操作),可以使用外部订单号来唯一标识订单和用户。
需要对微信接口回调的数据(xml)进行解析,比对result_code结果,如果是SUCCESS就是支付成功,如果是FALSE就是支付失败。

		 //读取参数
		//System.out.println("haha");
        InputStream inputStream ;  
        StringBuffer sb = new StringBuffer();  
        inputStream = request.getInputStream();  
        String s ;  
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));  
        while ((s = in.readLine()) != null){  
            sb.append(s);  
        }  
        in.close();  
        inputStream.close();  
        System.out.println("回调xml:"+sb.toString());//测试
        //解析xml成map  
        Map<String, String> m = new HashMap<String, String>();  
        try {
			m = XMLUtil4jdom.doXMLParse(sb.toString());
		} catch (JDOMException e) {
			e.printStackTrace();
		}  
          
        SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();        
        Iterator it = m.keySet().iterator();  
        while (it.hasNext()) {  
            String parameter = (String) it.next();  
            String parameterValue = m.get(parameter);  
              
            String v = "";  
            if(null != parameterValue) {  
                v = parameterValue.trim();  
            }  
            packageParams.put(parameter, v);  
        }  
          
        // 账号信息  
        String key = PayConfigUtil.API_KEY; // key  
  
       
        //判断签名是否正确  
        if(PayToolUtil.isTenpaySign("UTF-8", packageParams,key)) {
        	
            //------------------------------  
            //处理业务开始  
            //------------------------------  
            String resXml = "";  
            if("SUCCESS".equals((String)packageParams.get("result_code"))){
               String fee = (String)packageParams.get("total_fee");
               int level;
            	if(fee.equals("24000")) {
            		level = 1;
            	}else if(fee.equals("28000")) {
            		level = 2;
            	}else if(fee.equals("32000")) {
            		level = 3;
            	}else if(fee.equals("36000")) {
            		level = 4;
            	}else if(fee.equals("42000")) {
            		level = 5;
            	}else{
            		level = 6;
            	}
            	
            	
                // 这里是支付成功  
                //接下来对数据库进行操作 ,先查询订单号对应的身份证号
            	String out_no = (String)packageParams.get("out_trade_no");
            	System.out.println("商家订单号:"+out_no);
            
//            	Connection conn = DBUtils.getConnection();
//            	String sql="insert into uers values(?,?)";
//            	
//                try {
//                	PreparedStatement pstmt=(PreparedStatement) conn.prepareStatement(sql);
//					pstmt.setInt(0, 321333);
//					pstmt.setInt(1,level);
//				} catch (SQLException e) {
//					e.printStackTrace();
//				}
                
                
                 
                //通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.  
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"  
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";  
                  
            } else {   
                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"  
                        + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";  
            }  
            //------------------------------  
            //处理业务完毕  
            //------------------------------  
            BufferedOutputStream out = new BufferedOutputStream(  
                    response.getOutputStream());  
            out.write(resXml.getBytes());
            System.out.println("success");
            out.flush();  
            out.close();  
        }  

这些是用到的工具类:
这里写图片描述
关于工具类有点多,这里就不一一给出了,如果有需要的小伙伴可以留言你的邮箱,我会一一发给你们(可能不及时)。

这个例子是自己第一次做的,所以有很多不好的地方,所以还请包含。

限于篇幅,就讲到这里,如有错误欢迎指正。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 35
    评论
评论 35
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值