前些天帮朋友实现了一个微信扫码的接口,在之前也是不会搞这个东西,抱着试试的心态就开始看各种文档和blogs,大多数人都在吐槽微信给的java调用微信接口文档太含糊,而且网上的查到的资料也不详细,只有大概的开发流程没有太多细节上的讲解,最后还是花了一些钱买了一套视频和demo(理清了我的思路),最后完成了开发,如果有同学需要的话可以给我留言,我将免费提供帮助(可能不能及时回复)。
(在这之间我们需要申请商家号)首先我们要理清思路要怎么进行扫码接口调用开发:
图自己画的不太好,见谅。
从图中可以看出微信扫码支付的大概流程,首先是下单,我们需要拼接一个xml(包含商户平台ID,价格,随机数等信息)发送给微信接口,首先我们要知道,我们和微信接口之间的信息传递都需要使用xml,所以在开发中xml信息的拼接和解析是至关重要的。
①
发送统一下单的xml,首先我们应该知道需要将哪些信息拼接成xml信息:
这个是我们的一些必须清单:
APP_ID
这个APP_ID我就填错了(当时没找到APP_ID),一直报空指针错误。
MCH_ID这个是商家号:
就是我涂鸦的那个部分,申请过商户平台账号后会给你分配一个账号。
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
我们需要知道首先我们应该将需要发送的信息放入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 m = new HashMap();
try {
m = XMLUtil4jdom.doXMLParse(sb.toString());
} catch (JDOMException e) {
e.printStackTrace();
}
SortedMap packageParams = new TreeMap();
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 = "" + " "
+ " " + " ";
} else {
resXml = "" + " "
+ " " + " ";
}
//------------------------------
//处理业务完毕
//------------------------------
BufferedOutputStream out = new BufferedOutputStream(
response.getOutputStream());
out.write(resXml.getBytes());
System.out.println("success");
out.flush();
out.close();
}
这些是用到的工具类:
关于工具类有点多,这里就不一一给出了,如果有需要的小伙伴可以留言你的邮箱,我会一一发给你们(可能不及时)。
这个例子是自己第一次做的,所以有很多不好的地方,所以还请包含。
限于篇幅,就讲到这里,如有错误欢迎指正。