Springboot整合支付宝支付功能
作者:亚利桑那的天空 发布时间:2023-07-02 17:38:09
标签:Springboot,支付宝,支付
1.需要的Maven依赖
// 支付宝
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.8.73.ALL</version>
</dependency>
2.controller层
/**
* 统一下单接口
* @param orderNo 订单号
* @param request
* @return
*/
@PostMapping("/unifiedOrder")
@CrossOrigin(origins = "*",maxAge = 3600)//跨域
public ResultMap unifiedOrder(@RequestParam("orderNo") String orderNo,@RequestParam("payType") Integer payType,
HttpServletRequest request){
try {
// 1、验证订单是否存在
// 2、开始微信支付统一下单
Orders orders = ordersService.FindOrder(orderNo);
ResultMap resultMap =null;
if(orders!=null){
if(payType==1){
String spbill_create_ip = getIpAddr(request);
resultMap = wxPayService.unifiedOrder(orders.getOrderNo(),orders.getTotalPrice(),"云App",spbill_create_ip);
Hotel hotel= hotelMapper.selHotelById(orders.getHId());
Note note=new Note();
String s=note.Notefs(hotel.getPhone(),1);
ordersService.updataorderpaytype(orders.getOrderNo(),payType);
return resultMap;
}else if(payType==2){
// 2、创建支付宝订单
String orderStr = alipayService.createOrder(orders.getOrderNo(), orders.getTotalPrice(),"App");
ordersService.updataorderpaytype(orders.getOrderNo(),payType);
return ResultMap.ok().put("data",orderStr);
}
}
return resultMap;//系统通用的返回结果集
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
return ResultMap.error("服务器异常,付款失败");
}
}
//这是支付宝异步回调函数
/**
* 支付异步通知
* 接收到异步通知并验签通过后,一定要检查通知内容,
* 包括通知中的app_id、out_trade_no、total_amount是否与请求中的一致,并根据trade_status进行后续业务处理。
* https://docs.open.alipay.com/194/103296
*/
@PostMapping("/notify")
@CrossOrigin(origins = "*",maxAge = 3600)//跨域
public String notify(HttpServletRequest request, HttpSession session) {
// 调用service层rsaCheckV1验证签名
boolean flag = alipayService.rsaCheckV1(request);
if (flag) {
String tradeStatus = request.getParameter("trade_status"); // 交易状态
String outTradeNo = request.getParameter("out_trade_no"); // 商户订单号
String tradeNo = request.getParameter("trade_no"); // 支付宝订单号
/**
* 还可以从request中获取更多有用的参数,自己尝试
*/
//调用service层notify函数
boolean notify = alipayService.notify(tradeStatus, outTradeNo, tradeNo);
if(notify){
return "success";
}
}
return "fail";
}
3.service层
private String publicKey="公钥";
@Override
public String createOrder(String orderNo, double amount, String body) throws AlipayApiException {
//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
//构造client
//构造client
CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
//设置网关地址https://openapi.alipay.com/gateway.do
certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do");
//设置应用Id
certAlipayRequest.setAppId("appid");
//设置应用私钥
certAlipayRequest.setPrivateKey("应用私钥");
certAlipayRequest.setFormat("json");
//设置字符集
certAlipayRequest.setCharset("UTF-8");
//设置签名类型
certAlipayRequest.setSignType("RSA2");
//设置应用公钥证书路径
certAlipayRequest.setCertPath("证书验证的应用公钥证书路径");
//设置支付宝公钥证书路径
certAlipayRequest.setAlipayPublicCertPath("证书验证的支付宝公钥证书路径");
//设置支付宝根证书路径
certAlipayRequest.setRootCertPath("证书验证的支付宝根证书路径");
//构造client
AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setSubject(body);
model.setOutTradeNo(orderNo);
model.setTotalAmount(String.valueOf(amount));
model.setTimeoutExpress("30m");
/*model.setTotalAmount("0.01");*/
model.setProductCode("QUICK_MSECURITY_PAY");
/* model.setPassbackParams("公用回传参数,如果请求时传递了该参数,则返回给商户时会回传该参数");*/
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
AlipayTradeAppPayRequest ali_request = new AlipayTradeAppPayRequest();
ali_request.setBizModel(model);
ali_request.setNotifyUrl("回调地址");// 回调地址
AlipayTradeAppPayResponse ali_response = alipayClient.sdkExecute(ali_request);
//就是orderString 可以直接给客户端请求,无需再做处理。
return ali_response.getBody();
}
//支付宝签名验证
@Override
public boolean rsaCheckV1(HttpServletRequest request){
try {
//获取支付宝POST过来反馈信息
Map<String,String> params = new HashMap<String,String>();
Map requestParams = request.getParameterMap();
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i]
: valueStr + values[i] + ",";
}
//乱码解决,这段代码在出现乱码时使用。
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}
//切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。
//boolean AlipaySignature.rsaCertCheckV1(Map<String, String> params, String publicKeyCertPath, String charset,String signType)
boolean flag = AlipaySignature.rsaCertCheckV1(params, publicKey, alipayConfig.getCharset(),"RSA2");
/* 千万不要调用错了!!!上面的才是证书验证调用的函数这个是普通验证调用函数 boolean verifyResult = AlipaySignature.rsaCheckV1(params, publicKey, alipayConfig.getCharset(), alipayConfig.getSignType());*/
System.out.println("flag-----------"+flag);
return flag;
}catch (AlipayApiException e) {
logger.debug("verify sigin error, exception is:{}",e);
return false;
}
}
//notify()支付成功或者失败后一系列操作
@Override
public boolean notify(String tradeStatus, String orderNo, String tradeNo) {
if ("TRADE_FINISHED".equals(tradeStatus)
|| "TRADE_SUCCESS".equals(tradeStatus)) {
Orders orders =ordersMapper.FindOrder(orderNo);
// 支付成功,根据业务逻辑修改相应数据的状态
int state =ordersMapper.updateOrder(DateUtil.now(),orderNo);
Hotel hotel= hotelMapper.selHotelById(orders.getHId());
Note note=new Note();
String s=note.Notefs(hotel.getPhone(),1);
// boolean state = orderPaymentService.updatePaymentState(orderNo, tradeNo);
if (state!=0) {
return true;
}else {
UMember m= memberMapper.selMemByOrderNo(orderNo);
Boolean b= userMapper.updateVip(m.getOpenId(),2);
}
}
//支付失败查询订单详情得到用户id
Orders orders=ordersMapper.FindOrder(orderNo);
//将扣除的积分返还
if(orderNo!=null){
//添加用户积分
ordersMapper.RefundIntegral(orders.getOpenId(),orders.getIntegral());
/*//添加退回积分记录
ordersMapper.insIntegralRecord(orders.getOpenId(),orders.getIntegral(),1,2);*/
}
return false;
}
哈哈,以上仅为基础版证书验证支付宝支付的源码,有很大的优化空间,需要小伙伴自己去优化了!
来源:https://blog.csdn.net/Mrz_woDeMeng/article/details/105122184


猜你喜欢
- springboot定时任务在springboot环境下有多种方法,这里记录下使用过的其中两种;1、使用注解,2、通过实现接口的方式。使用注
- 嵌入式Servlet容器在Spring Boot中,默认支持的web容器有 Tomcat, Jetty, 和 Undertow1、原理分析那
- 本文实例为大家分享了Java实现二分查找的变种,供大家参考,具体内容如下普通二分查找:先回顾一下普通的二分查找注意:二分查找有这样一个问题:
- 简述mysq5.7之后新增了json类型,但是在使用的过程中,Json数组中的值小于Integer.MAX_VALUE,则反序列化时会转成L
- 问题在Service层注入Mybatis的Mapper我们通常会使用@Autowired 自动注入@Autowiredprivate Pro
- 需要设置允许不安全代码.....项目->属性->生成->允许不安全代码/// <summary> &
- 一、Splash界面的作用用来展现产品的Logo应用程序初始化的操作检查应用程序的版本检查当前应用程序是否合法注册二、界面的xml定义写一个
- 前言前一阵项目中的上传图片改为上传到阿里上,记录一下实现的过程,方便以后查看。参考资料:官方文档配置Android studio添加依赖de
- RecyclerView 是 android-support-v7-21 版本中新增的一个 Widgets, 还有一个 CardView 会
- 使用C#进行WinForm开发时,经常需要从WinForm窗体中获取用户输入数据。如果是字符串,那很好办,直接使用“控件名.Text”即可。
- 一个线程如何知道另一线程已经结束?Thread类提供了回答此问题的方法。有两种方法可以判定一个线程是否结束。第一,可以在线程中调用isAli
- 一、目标效果聊天会话页的列表效果1、聊天数据不满一屏时,顶部显示所有聊天数据2、插入消息时如果最新消息紧靠列表底部时,则插入消息会使列表向上
- NO.1–注释在程序中,尤其是复杂的程序中,适当地加入注释可以增加程序的可读性,有利于程序的修改、调试和交流。注释的内容
- 前言本文主要给大家介绍了关于C/C++混合编程extern “C”使用的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介
- 目录目标为什么操作步骤工程截图运行效果完整源代码目标在SpringBoot中集成内存数据库H2.为什么像H2、hsqldb、derby、sq
- 1、Java序列化与反序列化是什么?Java序列化是指把Java对象转换为字节序列的过程,而Java反序列化是指把字节序列恢复为Java对象
- 一、观察者模式基本概况1.概念观察者模式(Observer Design Pattern)也被称为发布订阅模式(Publish-Subcri
- 废话不多说了,直接给大家贴代码了,具体代码如下所示:package com.example.yanlei.yl4;import androi
- this.tclMain.Controls["tpgSize"].Parent = null; this.tclMain
- CardView介绍CardView是Android 5.0系统引入的控件,相当于FragmentLayout布局控件然后添加圆角及阴影的效