**原文链接:https://www.blog-china.cn/liuzaiqingshan/home/39/1510305872502
欢迎访问个人博客,分享更多技术码上中国博客(CodeChina)**
本文介绍接入微信支付的朋友们如何监控自己生成的微信二维码的支付状态。
例如生成的微信二维码如下:
通常的逻辑是,当用户使用微信扫描次二维码时,将会提示此二维码已经被扫描,当用户完成支付后,将会提示用户支付成功或者跳转到支付成功页面。
微信支付很坑的地方是,扫码支付扫码需要自己生成被扫描的二维码,这就造成,微信支付不能像支付宝支付扫码支付那样,实时监控二维码被扫描情况,并实时显示给用户二维码的状态和支付状态。
对于自己生成的微信扫码支付的二维码,如何做到像支付宝扫码支付那样实时监控被扫描状态和支付状态呢?
最好的方式是在页面上使用定时器,通过ajax不断通过后台查询该订单的支付状态,由于微信支付的订单状态查询方法中支付结果有如下几种状态:
微信支付订单支付状态查询接口 https://api.mch.weixin.qq.com/pay/orderquery
SUCCESS—支付成功
REFUND—转入退款
NOTPAY—未支付
CLOSED—已关闭
REVOKED—已撤销(刷卡支付)
USERPAYING–用户支付中
PAYERROR–支付失败
因此,我们只需要在Ajax中接收返回结果,当用户扫码后,提示通过判断USERPAYING来提示用户二维码已被扫描,通过SUCCESS来确定用户已经完成支付提示用户支付成功或跳转到成功页面;
jsp代码:
注意:此处使用的定时器为一个插件:jquery.timers-1.2.js
(function(){
//定时器AJAX查询扫码状态
var URL = “/payIndex/saomaQuery”;
var action = {“payOrderId”:’{orderId }',"merId":'{merId }’}; //订单id和商户id(‘body’).everyTime(‘2s’,function(){
var result = ajaxWithServer(URL,action);
//此处可以通过判断return_code的值来决定提示用户信息
if(result.return_code == ‘1’){
window.location.href=”/payIndex/success?orderId=”+’${orderId }’;
}
});
});
/**
* 和后台进行交互
* @param URL URL
* @param action 传送的参数
* @returns {String} 返回的结果
*/
function ajaxWithServer(URL,action){
var dataJson = “”;
$.ajax({
url:URL,
type:’post’,
datatype:”json”,
data:action,
async:false,
cache:false,
success:function(result){
dataJson = result;
},error:function(){
alert(“网络出现问题,请稍后再试!”);
return false;
}
});
return dataJson;
}
controller代码:
@Controller
@RequestMapping(value=”/payIndex”)
public class IndexContraller {
/**
* 支付成功页面
* @param model
* @param request
* @return
*/
@RequestMapping(value=Constant.PAYSUCCESS,method=RequestMethod.GET)
public String successIndex(Model model,HttpServletRequest request){
String orderId = request.getParameter("orderId");
LOGGER.info("orderId:"+orderId);
Map map = new HashMap();
//...此处根据订单号码查询订单信息,来显示到成功页面
map.put("orderId", orderId);
model.addAttribute("map", map);
return "success";//跳转到成功页面
}
/**
* 扫码支付主动查询
* @param model
* @param req
* @param session
* @return
* @throws SocketException
*/
@RequestMapping(value = Constant.SAOMAQUERY, method = RequestMethod.POST)
@ResponseBody
public Map queryWechatSaoPay(Model model,
HttpServletRequest request, HttpSession session) throws SocketException {
Map resultMap = new HashMap();
LOGGER.info("*************************调用支付查询 start*************************");
String out_trade_no = request.getParameter("payOrderId");
String merId = request.getParameter("merId");
if( out_trade_no == null || out_trade_no.trim().equals("")){
resultMap.put("return_code", "0");
resultMap.put("return_msg", "订单号为空");
return resultMap;
}
if( merId == null || merId.trim().equals("")){
resultMap.put("return_code", "0");
resultMap.put("return_msg", "商户号为空");
return resultMap;
}
//...此处根据商户号去找商户的信息 appId,appkey 等等
String appId ="";
String appKey ="";
//查询微信支付状态
try {
rspWeiXinData = QueryOrderPayUtil.queryWeiXinPay(appId,merId, appKey, out_trade_no);
LOGGER.info("js定时器查询微信订单结果为=="+rspWeiXinData);
if(rspWeiXinData==null||rspWeiXinData.isEmpty()){
resultMap.put("return_code", "0");
resultMap.put("return_msg","查询支付状态失败!"));
return resultMap;
}else{
String total_fee = rspWeiXinData.get("total_fee");//交易金额
resultMap.put("return_code", "1");
resultMap.put("total_fee", total_fee);
resultMap.put("orderId", out_trade_no);
}
} catch (Exception e) {
e.printStackTrace();
resultMap.put("return_code", "0");
resultMap.put("return_msg","查询支付状态失败!"));
return resultMap;
}
return resultMap;
}
}
QueryOrderPayUtil.java工具类
注意,请引入微信支付SDK,否则,此类中的方法会报错
/**
* 调用微信支付查询接口,返回支付信息
* @param appid
* @param mch_id
* @param orderId
* @return
* @throws Exception
*/
public static Map queryWeiXinPay(String appid,String mch_id,String appKey,String orderId)throws Exception{
Map resp = null;
MyConfig config = new MyConfig();
config.setAppID(appid);//微信公众号ID
config.setKey(appKey);//私钥
config.setMchID(mch_id);//商户号
WXPay wxpay = new WXPay(config,WXPayConstants.SignType.MD5,Constant.WEIXIN_ISSHABOX);//true为测试环境
Map data = new HashMap();
data.put("out_trade_no", orderId);//订单号
try{
resp = wxpay.orderQuery(data);
String return_code = (String)resp.get("return_code");
String return_msg = (String)resp.get("return_msg");
String result_code = (String)resp.get("result_code");
String err_code = (String)resp.get("err_code");
String err_code_des = (String)resp.get("err_code_des");
String trade_state = (String)resp.get("trade_state");
String trade_state_desc = (String)resp.get("trade_state_desc");
if("SUCCESS".equals(return_code)){//微信返回状态码为成功
if("SUCCESS".equals(result_code)){//业务结果状态码为成功
if("SUCCESS".equals(trade_state)){//交易状态为成功
return resp;
}else if("USERPAYING".equals(trade_state)){
//支付中
return resp;
}
else{
//交易状态为不是成功
LOGGER.info("***************支付平台订单ID:"+orderId+"查询微信支付接口异常:trade_state="+trade_state+",trade_state_desc="+trade_state_desc);
resp = null;
return resp;
}
}
else{
//业务结果状态码为失败
LOGGER.info("***************支付平台订单ID:"+orderId+"查询微信支付接口异常:err_code="+err_code+",err_code_des="+err_code_des);
resp = null;
return resp;
}
}
else{
//微信返回状态码为失败
LOGGER.info("***************支付平台订单ID:"+orderId+"查询微信支付接口异常:"+err_code);
resp = null;
return resp;
}
}
catch(Exception e){
LOGGER.info("***************支付平台订单ID:"+orderId+"查询微信支付接口:"+e.getMessage());
e.printStackTrace();
resp = null;
}
//仅返回交易状态trade_state是SUCCESS的值
return resp;
}
通过上述代码,即可实现实时监控微信扫码支付生成的二维码的支付状态,并即时给用户显示支付状态和结果。
广告时间:
分享来之不易,赠人玫瑰,手有余香,欢迎打赏作者,一分不嫌少,一百不嫌多,您的打赏是我前进的动力!