欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > 尚品汇-支付宝支付同步异步回调实现(四十七)

尚品汇-支付宝支付同步异步回调实现(四十七)

2024/10/24 18:25:01 来源:https://blog.csdn.net/dengfengling999/article/details/142019828  浏览:    关键词:尚品汇-支付宝支付同步异步回调实现(四十七)

目录:

(1)订单支付码有效时间

(2)支付后回调—同步回调

(3)支付宝回调—异步回调

(1)订单支付码有效时间

(2)支付后回调—同步回调

 

 

static修饰,不能通过Vuale注解获取配置文件的值,可以通过下面的方法进行获取值 

 

实现类放开同步回调地址 

 

 

成功页面:

 修改配置类:

控制器AlipayController

/*** 支付宝回调* @return*/
@RequestMapping("callback/return")
public String callBack() {// 同步回调给用户展示信息return "redirect:" + AlipayConfig.return_order_url;
}

在web-all 项目中添加对应的返回控制器

/*** 支付成功页* @return*/
@GetMapping("pay/success.html")
public String success() {return "payment/success";
}

 

最终跳转到这个页面:

 

(3)支付宝回调—异步回调

 

 

 

 

 

 

... 

 

 

 

 

异步回调有两个重要的职责:

确认并记录用户已付款通知电商模块。新版本的支付接口已经取消了同步回调的支付结果传递。所以用户付款成功与否全看异步回调。

接收到回调要做的事情:

  1. 验证回调信息的真伪
  2. 验证用户付款的成功与否
  3. 把新的支付状态写入支付信息表{paymentInfo}中。
  4. 通知电商
  5. 给支付宝返回回执。

 

 

应用公网暴露 

支付宝异步回调,需要我们的应用在公网上,怎么办呢?可以使用一个软件把我们的应用跟公网绑定,相当于我们的应用就在公网了

 

 

 

authttoken是申请的

双击启动:就实现了我们的应用进行了公网地址的绑定

 

这样就接受到了异步回调的数据了:

 

配置类: 

 

 

 

 

控制器AlipayController

@Autowired
private PaymentService paymentService;
@PostMapping("/callback/notify")
@ResponseBody
public String callbackNotify(@RequestParam Map<String, String> paramsMap){System.out.println("你回来了.....");// Map<String, String> paramsMap = ... // 将异步通知中收到的所有参数都存放到map中//返回的异步结果进行验签boolean signVerified = false; //调用SDK验证签名try {//参数阿里公钥、字符编码、签名算法signVerified = AlipaySignature.rsaCheckV1(paramsMap, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);} catch (AlipayApiException e) {e.printStackTrace();}//  获取异步通知的参数中的订单号!String outTradeNo = paramsMap.get("out_trade_no");//  获取异步通知的参数中的订单总金额!String totalAmount = paramsMap.get("total_amount");//  获取异步通知的参数中的appId!String appId = paramsMap.get("app_id");//  获取异步通知的参数中的交易状态!String tradeStatus = paramsMap.get("trade_status");//  根据outTradeNo 查询数据!PaymentInfo paymentinfo = this.paymentService.getPaymentInfo(outTradeNo, PaymentType.ALIPAY.name());//  保证异步通知的幂等性!notify_idString notifyId = paramsMap.get("notify_id");//  true:if(signVerified){// TODO 验签成功后,按照支付结果异步通知中的描述,对支付结果中的业务内容进行二次校验,校验成功后在response中返回success并继续商户自身业务处理,校验失败返回failureif (paymentinfo==null || new BigDecimal("0.01").compareTo(new BigDecimal(totalAmount))!=0|| AlipayConfig.app_id.equals(appId)){return "failure";}//  放入redis! setnx:当 key 不存在的时候生效!Boolean flag = this.redisTemplate.opsForValue().setIfAbsent(notifyId, notifyId, 1462, TimeUnit.MINUTES);//  说明已经处理过了!if (!flag){return "failure";}if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)){//  修改交易记录状态!再订单状态!this.paymentService.paySuccess(outTradeNo,PaymentType.ALIPAY.name(),paramsMap);//  this.paymentService.paySuccess(paymentinfo.getId(),paramsMap);return "success";}}else{// TODO 验签失败则记录异常日志,并在response中返回failure.return "failure";}return "failure";
}

幂等性:多次操作跟一次操作是一样的

这里更上面返回的不一样,返回sucess,支付宝就不会再发送了,如果返回faild支付宝会间隔一段的时间持续发送,返回啥都一样功能都能够实现 

 

为了保证更新支付状态时出现异常,前面存不进去了,出现异常删掉前面Redis中的key 

 

 

接口PaymentService

/*** 获取paymentInfo 对象* @param outTradeNo* @param name* @return*/
PaymentInfo getPaymentInfo(String outTradeNo, String name);/*** 支付成功更新交易记录方法* @param outTradeNo* @param name* @param paramMap*/
void paySuccess(String outTradeNo, String name, Map<String, String> paramMap);/*** 根据outTradeNo 支付方式name 更新数据* @param outTradeNo* @param name* @param paymentInfo*/
void updatePaymentInfo(String outTradeNo, String name, PaymentInfo paymentInfo);

实现类

@Override
public PaymentInfo getPaymentInfo(String outTradeNo, String name) {//  select * from payment_info where out_trade_no = ? and payment_type = ?QueryWrapper<PaymentInfo> paymentInfoQueryWrapper = new QueryWrapper<>();paymentInfoQueryWrapper.eq("out_trade_no",outTradeNo);paymentInfoQueryWrapper.eq("payment_type",name);return paymentInfoMapper.selectOne(paymentInfoQueryWrapper);
}@Override
public void paySuccess(String outTradeNo, String paymentType, Map<String, String> paramsMap) {//  根据outTradeNo,paymentType 查询PaymentInfo paymentInfoQuery = this.getPaymentInfo(outTradeNo, paymentType);if (paymentInfoQuery==null){return;}try {//  改造一下更新的方法!PaymentInfo paymentInfo = new PaymentInfo();//回调时间paymentInfo.setCallbackTime(new Date());//支付状态paymentInfo.setPaymentStatus(PaymentStatus.PAID.name());/回调内容paymentInfo.setCallbackContent(paramsMap.toString());//交易编号paymentInfo.setTradeNo(paramsMap.get("trade_no"));//  查询条件也可以作为更新条件!this.updatePaymentInfo(outTradeNo, paymentType, paymentInfo);} catch (Exception e) {//  删除keythis.redisTemplate.delete(paramsMap.get("notify_id"));e.printStackTrace();}}//  更新交易状态记录!
public void updatePaymentInfo(String outTradeNo, String name, PaymentInfo paymentInfo) {QueryWrapper<PaymentInfo> paymentInfoQueryWrapper = new QueryWrapper<>();paymentInfoQueryWrapper.eq("out_trade_no",outTradeNo);paymentInfoQueryWrapper.eq("payment_type",name);paymentInfoMapper.update(paymentInfo,paymentInfoQueryWrapper);
}

 支付成功后数据库的状态会更改

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com