java 实时监控微信扫码支付,支付成功跳转到成功页面

技术标签: java  支付  java编程  前端页面设计  微信  二维码  

**原文链接: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<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;
 }

通过上述代码,即可实现实时监控微信扫码支付生成的二维码的支付状态,并即时给用户显示支付状态和结果。


广告时间:

分享来之不易,赠人玫瑰,手有余香,欢迎打赏作者,一分不嫌少,一百不嫌多,您的打赏是我前进的动力!

这里写图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013611978/article/details/78502062

智能推荐

mysql 事件 建表_Mysql事件的创建和使用_田仲政的博客-程序员宅基地

1、查看事件是否开启SHOW VARIABLES LIKE 'event_scheduler';2、开启事件SET GLOBAL event_scheduler = ON;3、创建事件DELIMITER $$-- SET GLOBAL event_scheduler = ON$$ -- required for event to execute but not createCREATE/*...

java 泛型 多参数_具有多个参数的Java泛型_weixin_39877581的博客-程序员宅基地

我在网站上看到过处理具有多个参数的泛型的示例,但没有一个适用于我的情况.所以这是交易:我正在尝试学习Java泛型,并决定创建一个简单的二进制数组搜索实用程序函数.我正在使用自定义对象和整数进行测试.要获得有关错误和警告的反馈,我正在使用Eclipse.这是我有的:public static int binarySearch(Comparable[] array, Comparable item, ...

mysql能用case嵌套sql吗,关于sqlserver中查询语句中嵌套case语句使用方法_Jumbo yii的博客-程序员宅基地

ryxxlong的博客 Sql server 中的 CASE 语句文章, 链接 http://ryxxlong.iteye.com/blog/531221 写的比较详细,具体内容如下,主要用于自己以后方便查询 CASE 具有两种式: Simple CASE function: CASE input_expression WHEN when_expression THEN result_exryxx...

git初级使用者避坑指南_除了学习无所事事的博客-程序员宅基地

问题一:出现如下报错是因为github上有些文件,本地文件夹没有解决:强制推送git push 仓库名 master -f先把仓库内容下载到本地,重新推送git pull 仓库名 master之后再推送文件...

【项目分享】使用 PointNet 进行点云分割_穗虔居士的博客-程序员宅基地_pointnet点云分割

“点云(point cloud)”是一种用于存储几何形状数据的重要数据结构类型。由于其不规则的格式,在用于深度学习应用程序之前,它通常会转换为规则的 3D 体素网格或图像集合,这会使数据变得不必要地大。PointNet 系列模型通过直接使用点云解决了这个问题,同时尊重点数据的排列不变性。PointNet 系列模型为从对象分类、部分分割到场景语义解析等应用提供了一个简单、统一的架构。

angular2+ 的复制_「已注销」的博客-程序员宅基地_angular 复制

今天在做项目的时候遇到点击复制的一个功能,虽然原生js的点击复制只需要三行就搞定了,但是在angular里面并不生效,于是在网上找了半天,也没有找到答案,最后无意间看见了大漠老师的视频,才有所启发。下面是原生的点击复制方法: function copyUrl2(){ var copyInnerHTML = document.getElementById('invite_code'); ...

随便推点

php移动端适配,移动端适配谈起_吕宸昊的博客-程序员宅基地

移动端适配谈起常用单位px绝对单位,一个 px 是一个点,一个像素,比如常常听到的电脑像素是1024x768的,表示的是水平方向是1024个像素点,不会随屏幕变大变小而变化。em相对单位,相对于父级的字体大小。如果自身定义了font-size按自身来计算(浏览器默认字体是16px)。不设置的话默认 1em = 16px。em的值并不是固定的,会继承父级元素的字体大小// 浏览器默认的大小.p {f...

SpringBoot——外部配置_不知道改什么昵称的博客-程序员宅基地

文章目录外部配置1、配置随机值2、命令行配置属性3、Application Property 文件4、profile5、加密属性值6、YAML的使用6.1 YAML语法6.2 多文档块方式6.3 YAML的缺点7、配置属性的类型安全7.1 配置文件注入JavaBean7.2 构造函数绑定7.3 @ConfigurationProperties7.4 松散绑定不同属性的松散绑定规则7.5 @Conf...

CAN总线(一)_weixin_33868027的博客-程序员宅基地

原文出处:http://www.cnblogs.com/jacklu/p/4729638.html嵌入式的工程师一般都知道CAN总线广泛应用到汽车中,其实船舰电子设备通信也广泛使用CAN,随着国家对海防的越来越重视,对CAN的需求也会越来越大。这个暑假,通过参加苏州社会实践,去某船舶电气公司实习几周,也借此机会,学习了一下CAN总线。概述CAN(Controller Area Netw...

什么叫侧链_什么是侧链技术?_weixin_39726379的博客-程序员宅基地

早期,比特币开发团队在升级比特币协议时,想要增加新的功能,但是直接在原来的基础上进行改动,就会有较大的风险,一旦某一个改动的功能发生故障,就会影响整个网络的运行。于是在侧链技术概念应用而生。侧链技术先把新功能加在其他链上,然后将这条链和比特币区块链联系起来,这样既补充了比特币链的功能,又不会损害比特币网络的安全。到后来侧链技术的应用就不仅仅只局限于比特币这一条链作为主链,各种链都可以彼此链接,甚至...

牛鞭效应matlab代码,基于控制工程的牛鞭效应建模与仿真研究_weixin_39710660的博客-程序员宅基地

第14卷专辑2006年10月中国管理科学ChineseJournalofManagementScienceV01.14,SpecialIssueOctober,2006文章编号:1003—207(2006)zk一0469—05基于控制工程的牛鞭效应建模与仿真研究王旭坪,郭瑞东,胡祥培(大连理工大学系统工程研究所,大连116023)摘要:“牛鞭效应”对供应链性能和绩效产生了严重的影响。本文基于控制理...

socket java_Java Socket应用——通信是这样炼成的_春光古大侠的博客-程序员宅基地

一、网络基础知识1.1、两台计算机通过网络进行通信(1)两台主机要有一个唯一的标识(IP地址)。(2)需要有共同的语言(协议)。(3)每台主机需要有相应的端口号(为了辨别不同应用程序的通信)。1.2、TCP/IP协议(1)TCP/IP是目前世界上应用最为广泛的协议,是以TCP和IP为基础的不同层次上多个协议的集合,也称:TCP/IP协议族或TCP/IP协议栈。(2)TCP:Transmission...

推荐文章

热门文章

相关标签