java 实时监控微信扫码支付,支付成功跳转到成功页面_guopengfeiheze的博客-程序员宅基地_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

智能推荐

slope one 推荐算法python 代码_推荐系统SlopeOne算法的Python实现,数据基于MovieLens..._neo-zone的博客-程序员宅基地

数据从数据训练集下载地址下载,我选的是1MB版本的数据,大约10W+评分,9K+电影,600+用户。使用ratings.csv,格式为userId,movieId,评分,时间戳。步骤:1、解析CSV文件,构建训练集。2、计算两两物品分差平均值。3、预测指定用户未评分物品的评分,推荐TopN。SlopeOne算法理解起来简单,实现起来也简单,按照论文的描述,推荐结果也很不错。当然有个不是问题的问题,...

微信小程序支付---后台封装方法_OneLeafLucky的博客-程序员宅基地

1、公共类-Parampublic class Param { //小程序的appid和secret public final static String mini_appid=""; public final static String mini_secret=""; public final static String grant_type="authorization_c...

【2020最新】人工智能实战就业(面试)学习路线图_迪哥有点愁了的博客-程序员宅基地

人工智能实战就业(面试)学习路线图 这个项目是干什么的?整理这个项目的初衷是方便同学们快速开启人工智能自学计划,在学习过程中少走弯路用最快的效率入门Ai并开始实战项目,提供了近200个Ai实战案例和项目,这些并不是网上搜集来的,而是我这五年线上线下教学所开发和积累的案例。可以说都是反复迭代更新出来的,适合同学们来进行循序渐进的学习与练手。来的同学记得点个star收藏下! 配套教材如...

Cocos2d-x项目移植到WP8系列之九:使用自定义shader_weixin_34375054的博客-程序员宅基地

本文原链接:http://www.cnblogs.com/zouzf/p/3995132.html  有时候想得到一些例如灰度图等特殊的渲染效果,就得用到自定义shader,关于shader的一些背景知识,自行谷歌,列出两篇cocos2dx里介绍shader的相关文章 http://blog.csdn.net/while0/article/details/9666829     http:...

计算机术语word文档,计算机专业术语大全_weixin_39652810的博客-程序员宅基地

. IPC(Instructions Per Clock Cycle,指令/时钟周期)ISA(instruction set architecture,指令集架构)KNI(Katmai New Instructions,Katmai新指令集,即SSE)Latency(潜伏期)LDT(Lightning Data Transport,闪电数据传输总线)Local Interconnect(局域互连)...

java.sql.SQLSyntaxErrorException: Unknown database ‘firstdb‘_不惭_的博客-程序员宅基地

我首先再次创建了firstdb这个表格当然没啥用找到这个properties文件,打开后发现了这个firstdb这个地方应该填写的是firstdb所在的数据库,而不是这个表所以更改一下

随便推点

Oracle 11g RAC 负载均衡测试_Leo-2016的博客-程序员宅基地_11g rac 负载均衡

Connection BalancingConnection Balancing 这种负载均衡是在用户连接这个层次进行的,也就是在用户请求建立连接时,根据每个节点的负载决定把连接分配给哪个实例,而一旦连接建立之后,会话的所有操作就都在这个实例上完成,而不会再分派给其他节点了。Connection Balancing 有客户端和服务端两种实现方法。客户端均衡(Client-Side ...

javascript基础之CSS基础_车晋强的博客-程序员宅基地

CSS除了可以轻松设置网页元素的格式外,还可以产生滤镜,图像淡入淡出,网页淡入淡出。CSS的目标就是对网页实现与Woid一样的排版控制。不一定要记到繁多的样式。实际上只要通过辅助工具就可以了。样式规则选择器:HTML元素选择器Class选择器Id选择器关联选择器组合选择器伪元素选择器样式规则的注释。样式属性:CSS的样式属性分类,大概可以分为以下几类:字

操作系统——银行家算法_I_am_overflow的博客-程序员宅基地

操作系统——银行家算法概念银行家算法(Banker’s Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。算法思路背景将操作系统视为银行家,操作系统管理的资源视为银行家管理的资金,进程向操作系统申请资源视为客户向银行家贷款,客户...

[SVA]验证环境中全局控制Assertion的几种方法_元直数字电路验证的博客-程序员宅基地

前言:在數字電路驗證中,SVA是必不可少的檢查手段,但是在打Error Case的時候,Assertion會發生FAIL,此時我們需要通過一個開關來關閉Assertion Check,下文就提供2種關閉Assertion的方法。 1、使用define隔開,如下圖所示的Assertion,如果沒有__NO_CHECK_CRC__這個define,就會對CRC做ch............

jquery_ajax 入门实例_aodiyi6351的博客-程序员宅基地

序:本文通过几个小样例,简单介绍怎样使用jqueryAjax异步载入。1. $(selector).load(url,[data],[callback]) :加载远程HTML文件代码并插入DOM中。url (String) : 请求的HTML页的URL地址。 data (Map) : (可选參数) 发送至server的 key/value 数据。 call...

android.support.v4.app.Fragment_yixueshi9268的博客-程序员宅基地_android.support.v4.app.fragment

package com.example.duoduo.festival_sms;import android.os.Bundle;import android.support.design.widget.TabLayout;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentPager

推荐文章

热门文章

相关标签