版权声明:本文为博主原创文章,未经博主允许不得转载。如需转载请标明原博地址:https://blog.csdn.net/m0_37898659/article/details/81908219
话不多说,先上代码地址:https://download.csdn.net/download/m0_37898659/10617890
微信支付开发官方地址:https://pay.weixin.qq.com/wiki/doc/api/index.html
1. appid, 微信公众账号或开放平台APP的唯一标识
2. mch_id, 微信支付系统中的商户收款账号
3. partner, 财付通平台的商户账号
4. partnerkey, 财付通平台的商户密钥
5. sign, 数字签名, 根据微信官方提供的密钥和一套算法生成的一个加密信息, 就是为了保证交易的安全性
如何获得:
企业在微信公众平台(申请扫码支付、公众号支付)或开放平台(申请APP支付)按照相应提示,申请相应微信支付模式。微信支付工作人员审核资料无误后开通相应的微信支付权限。微信支付申请审核通过后,商户在申请资料填写的邮箱中会收取到由微信支付小助手发送的邮件,此邮件包含开发时需要使用的支付账户信息。
第一个:日志包
第二、三个:网络通讯使用的jar
第四个:xml解析使用的jar
4、src下创建servlet、utils包
1、 拷贝四个工具类到utils包里
第三个PayConfig 是:支付参数的java类
三、生成订单xml格式数据
1、准备订单支付确认页面
例如demo中的 order.jsp
2、修改扫码支付按钮跳转到二维码页面
3、创建NativeServlet
1、 在dopost方法中定义微信官方要求xml格式数据字符串
String xml = "<xml>" + "<appid>" + PayConfig.appid + "appid>"
+ "<mch_id>" + PayConfig.partner + "mch_id>" + "<nonce_str>"
+ nonce_str + "nonce_str>" + "<sign>" + sign + "sign>"
+ "<body>body>" + "<out_trade_no>"
+ out_trade_no + "out_trade_no>" + "<attach>" + attach
+ "attach>" + "<total_fee>" + totalFee + "total_fee>"
+ "<spbill_create_ip>" + spbill_create_ip+ "spbill_create_ip>" +
"<notify_url>" + PayConfig.notifyurl + "notify_url>" +
"<trade_type>" + trade_type + "trade_type>" + "xml>";
2、创建一个空的map集合用来装载 xml用的数据
微信支付后台必须传过去的:
appid:公众号的appid
paryner:财付通收款账号
nonce_str:随机字符串
body:商品名
attach:额外的附加数据(不是必须的,看业务逻辑)
out_trade_no:订单号
totalFee:支付总金额(我们平时用的单位是:元,需要转换为微信支付官方的单位:分)
spbill_create_ip:当前电脑的ip地址
notifyurl: 回调的url
trade_type:支付方式(官方规定扫码支付为:NARTIVE)
sign:数字签名
3、生成订单并获取订单数据
//微信支付官方统一下单接口链接:
URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder
把xml格式的数据发送到这就好了
使用httpCilent工具类的方法即可
开启https协议
在服务器生成订单并返回数据给你
这个是微信支付后台返回的xml格式的字符串(需进行异常处理)
5 、解析xmlStr (因为二维码页面需要的1是json数据)
里面内容非常多,但是对于我们来说只要其中用于支付的url地址就好
6、人工拼接成json数据
需要订单号、和上面得用于支付得url地址
String resJson=”{\”code_url\”:\”“+code_url+”\”,\”out_trade_no\”:\”“+out_trade_no+”\”}”;
然后返回到页面上
四、生成用于支付得二维码
1、创建二维码页面(native.jsp)
1、导入js文件
2、给定一个div用于装二维码
3、编写js代码
①发送异步请求
打开页面,自动发送请求
$.post("${pageContext.request.contextPath}/NativeServlet",{},function(data){
//第一个参数是访问servlet得url地址,访问后返回得json数据会放到data中
//第二个参数是发送得参数,这次不用,所以为空
//第三个是回调函数
var url=data.code_url;
var out_trade_no=data.out_trade_no;
//生成二维码(注意:二维码生成可能根据api不用而不同)
var qr=qrcode(10,"H");
qr.addData(url);
qr.make();
$('#qrcode').html(qr.createImgTag());
$('#qrtext').html("请打开手机微信进行扫描");
});
五、准备查询支付状态的数据
1、准备检测客户支付状态的servlet(PayStatusCheckServlet)
1、servlet中另外创建查询某订单支付状态的方法
xml格式要求的字符串:
String xml = "" + "" + PayConfig.appid + ""
+ "" + PayConfig.partner + ""
+ "" + out_trade_no + ""
+ "" + nonce_str + "" + "" + sign
+ "" + "";
2、 准备treeMap集合
3、发送查询
微信官方查询订单的API:
接口链接:https://api.mch.weixin.qq.com/pay/orderquery
4、获取返回的数据
5、解析返回的xml
返回的是一个map集合,把方法体的void修改为 Map
添加return map;
6、在dopost中调用检测的方法
(1)、 但是在实际的应用中,客户可能扫描了二维码之后,也许会不支付,所以要不停的调用检测的方法 每三秒 进行检测支付状态。
(2)、判断 超时支付的情况
检测时间 — 方法初始时间 > 30秒就break;
(3)、判断支付状态
支付成功就退出循环并且返回trade_state
7、查询的最终结果要返回二维码页面
(1)二维码一生成就马上检测支付状态
(2)通过异步请求 发送请求获取数据
需要传送一个订单号到servlet中:
所以要把 第一个生成二维码的异步请求中获取到的订单号定义在外围,方便两个异步请求都可以用。如图:
放到第二个异步请求中:
支付成功,则支付状态返回到回调函数的data中
接着判断是否支付成功
失败则重新刷新,重新支付
8、支付结果页面
先在异步请求中修改代码,如果支付成功,则跳转到notify.jsp页面
创建notify.jsp
在页面中展示微信支付后台返回的数据
想要拿到返回的数据,在servlet中检测的时候要要把返回的Map集合放到Session中,再从页面中把Session取出来用El表达式展示。
notify页面中用EL表达式展示代码:
测试:
1、部署到tomcat
访问localhost:8080/WeChatPay/order.jsp
点击扫码支付,进入二维码页面
二维码正常生成
手机扫码支付,完成之后,跳到支付结果页面;
纪念我第一篇文章,加油