java 實時監控微信掃碼支付,支付成功跳轉到成功頁面
例如生成的微信二維碼如下:
通常的邏輯是,當用戶使用微信掃描次二維碼時,將會提示此二維碼已經被掃描,當用戶完成支付後,將會提示使用者支付成功或者跳轉到支付成功頁面。
微信支付很坑的地方是,掃碼支付掃碼需要自己生成被掃描的二維碼,這就造成,微信支付不能像支付寶支付掃碼支付那樣,實時監控二維碼被掃描情況,並實時顯示給使用者二維碼的狀態和支付狀態。
對於自己生成的微信掃碼支付的二維碼,如何做到像支付寶掃碼支付那樣實時監控被掃描狀態和支付狀態呢?
最好的方式是在頁面上使用定時器,通過ajax不斷通過後臺查詢該訂單的支付狀態,由於微信支付的訂單狀態查詢方法中支付結果有如下幾種狀態:
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”:’
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<String, Object> map = new HashMap<String, Object>();
//...此處根據訂單號碼查詢訂單資訊,來顯示到成功頁面
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<String, String> queryWechatSaoPay(Model model,
HttpServletRequest request, HttpSession session) throws SocketException {
Map<String, String> resultMap = new HashMap<String, String>();
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<String, String> queryWeiXinPay(String appid,String mch_id,String appKey,String orderId)throws Exception{
Map<String, String> 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<String, String> data = new HashMap<String, String>();
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;
}
通過上述程式碼,即可實現實時監控微信掃碼支付生成的二維碼的支付狀態,並即時給使用者顯示支付狀態和結果。
廣告時間:
分享來之不易,贈人玫瑰,手有餘香,歡迎打賞作者,一分不嫌少,一百不嫌多,您的打賞是我前進的動力!