89分布式电商项目 -检测支付状态

简介: 89分布式电商项目 -检测支付状态

当用户支付成功后跳转到成功页面

当返回异常时跳转到错误页面

实现思路:

我们通过 HttpClient 工具类实现对远程支付接口的调用。

接口链接:https://api.mch.weixin.qq.com/pay/orderquery

具体参数参见“查询订单”API, 我们在 controller 方法中轮询调用查询订单(间隔 3 秒),

当返回状态为 success 时,我们会在 controller 方法返回结果。前端代码收到结果后跳转到成

功页面。

后端代码

在 pinyougou-pay-interface 的 WeixinPayService.java 中新增方法定义

/*** 查询支付状态
* @param out_trade_no
* */
public Map queryPayStatus(String out_trade_no);

在 pinyougou-pay-service 的 WeixinPayServiceImpl.java 中实现方法

@Override
public Map queryPayStatus(String out_trade_no) {
  Map param=new HashMap();param.put("appid", appid);//公众账号 
  IDparam.put("mch_id", partner);//商户号
  param.put("out_trade_no", out_trade_no);//订单号
  param.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串
  String url="https://api.mch.weixin.qq.com/pay/orderquery";
  try {
    String xmlParam = WXPayUtil.generateSignedXml(param, partnerkey);
    HttpClient client=new HttpClient(url);
    client.setHttps(true);
    client.setXmlParam(xmlParam);client.post();String result = 
    client.getContent();Map<String, String> map = 
    WXPayUtil.xmlToMap(result);System.out.println(map);
    return map;
  } catch (Exception e) {
    e.printStackTrace();return null;
   }
  }

在 pinyougou-cart-web 的 PayController.java 新增方法

/*** 查询支付状态
* @param out_trade_no
*  @return
* */
@RequestMapping("/queryPayStatus")
public Result queryPayStatus(String out_trade_no){
    Result result=null;
    while(true){
      //调用查询接口
      Map<String,String> map = weixinPayService.queryPayStatus(out_trade_no);
      if(map==null){
      //出错
      result=new Result(false, "支付出错");
      break;
     }
     if(map.get("trade_state").equals("SUCCESS")){
       //如果成功
       result=new Result(true, "支付成功");
       break;
      }
      try {
        Thread.sleep(3000);//间隔三秒
      } catch (InterruptedException e) {
        e.printStackTrace();
      } 
      }
    return result;

前端代码

在 payService.js 新增方法

//查询支付状态
this.queryPayStatus=function(out_trade_no){
  return $http.get('pay/queryPayStatus.do?out_trade_no='+out_trade_no);
}

在 payController.js 中新增方法

//查询支付状态
queryPayStatus=function(out_trade_no){
  payService.queryPayStatus(out_trade_no).success(
  function(response){
    if(response.success){
      location.href="paysuccess.html";
     }else{
      location.href="payfail.html"; 
    }
   });
 }

在 createNative 方法的回调方法中调用此查询方法

//本地生成二维码
$scope.createNative=function({
payService.createNative().success(
    function(response){
      ..........
      queryPayStatus(response.out_trade_no);
      //查询支付状态
    });
}

查询时间限制

如果用户到了二维码页面一直未支付,或是关掉了支付页面,我们的代码会一直循环调用微信接口,这样会对程序造成很大的压力。所以我们要加一个时间限制或是循环次数限制,当超过时间或次数时,跳出循环。可以这样完善代码:

修改 pinyougou-cart-web 工程 PayController.java 的 queryPayStatus 方法

@RequestMapping("/queryPayStatus")
public Result queryPayStatus(String out_trade_no){
  Result result=null;
  int x=0;
  while(true){
    //调用查询接口.......
  try {
    Thread.sleep(3000);//间隔三秒
  } catch (
    InterruptedException e) {
    e.printStackTrace();
  }
  //为了不让循环无休止地运行,我们定义一个循环变量,如果这个变量超过了这个值则退出循环,设置时间为 5 分钟
  x++;
  if(x>=100){
    result=new Result(false, "二维码超时");
    break;
   }
  }
   return result;
  }

(2)修改 payController.js

//查询支付状态
queryPayStatus=function(out_trade_no){
payService.queryPayStatus(out_trade_no).success(
  function(response){
    if(response.success){
      location.href="paysuccess.html";
    }else{
      if(response.message=='二维码超时'){
      $scope.createNative();//重新生成二维码         
    }else{
        location.href="payfail.html";
       }
      }
   });
  }

支付成功页面显示余额

现在我们支付成功页面显示的是固定的值,怎么显示真正的支付金额呢?我们这里可以使用 angularJS 的页面传参来解决。

(1)修改 payController.js 跳转页面传参

//查询支付状态
queryPayStatus = function(out_trade_no) {
  payService.queryPayStatus(out_trade_no).success(function(response) {
    if(response.success) {
      location.href = "paysuccess.html#?money=" + $scope.money;
    } else {
      if(response.message == '二维码超时') {
        $scope.createNative(); //重新生成二维码}else{
        location.href = "payfail.html";
      }
    }
  });
}

(2)在 payController.js 中引入$location 服务 ,新增方法

//获取金额
$scope.getMoney=function(){
  return $location.search()['money'];
}

(3)修改页面 paysuccess.html ,引入 JS (与 pay.html 相同) ,body 添加指令

ng-app="pinyougou" ng-controller="payController"

用表达式显示金额

<p>支付金额:¥{{getMoney()}}元</p>



目录
相关文章
|
6月前
|
NoSQL 调度 Redis
19- 你的项目中哪里用到了分布式锁
在一个项目中,为解决集群环境下SpringTask定时任务的重复执行问题,采用了Redis实现分布式锁来管理任务调度,防止资源浪费。后来因任务量和执行规则增加,以及单节点效率限制,系统改用XXL-JOB,分布式锁不再使用。
70 2
|
6月前
|
Java 调度 Maven
【分布式任务调度平台 XXL-JOB 急速入门】从零开始将 XXL-JOB 接入到自己的项目(下)
【分布式任务调度平台 XXL-JOB 急速入门】从零开始将 XXL-JOB 接入到自己的项目(下)
350 0
|
2月前
|
NoSQL Java Redis
面试官:项目中如何实现分布式锁?
面试官:项目中如何实现分布式锁?
93 6
面试官:项目中如何实现分布式锁?
|
3月前
|
资源调度 Java 调度
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
|
6月前
|
缓存 NoSQL Java
分布式项目中锁的应用(本地锁-_redis【setnx】-_redisson-_springcache)-fen-bu-shi-xiang-mu-zhong-suo-de-ying-yong--ben-de-suo--redissetnx-springcache-redisson(一)
分布式项目中锁的应用(本地锁-_redis【setnx】-_redisson-_springcache)-fen-bu-shi-xiang-mu-zhong-suo-de-ying-yong--ben-de-suo--redissetnx-springcache-redisson
91 0
|
6月前
|
SpringCloudAlibaba Java 持续交付
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
412 0
|
3月前
|
存储 缓存 开发框架
看看 Asp.net core Webapi 项目如何优雅地使用分布式缓存
看看 Asp.net core Webapi 项目如何优雅地使用分布式缓存
|
4月前
|
SQL NoSQL Java
如何在Java项目中实现分布式锁
如何在Java项目中实现分布式锁
|
4月前
|
消息中间件 Java 中间件
如何在Java项目中实现分布式事务管理
如何在Java项目中实现分布式事务管理
|
6月前
|
SQL 负载均衡 监控
【分布式任务调度平台 XXL-JOB 急速入门】从零开始将 XXL-JOB 接入到自己的项目(上)
【分布式任务调度平台 XXL-JOB 急速入门】从零开始将 XXL-JOB 接入到自己的项目
705 0

热门文章

最新文章

下一篇
无影云桌面