SpringBoot整合支付宝APP支付
作者:Snow、杨 发布时间:2021-10-12 02:57:24
标签:SpringBoot,支付宝
前言
现在是移动端产品疯狂的年代,随之,移动端支付也是热门小技能,最近本公司在做一个移动端,要接入微信支付和支付宝支付, * 惯,功能做完之后做个复盘记录,这边主要讲解支付宝APP支付
所需条件
1、创建蚂蚁金服开放平台公司账号
2、选择开发中心---->移动应用
3、选择支付接入
4、创建应用
5、查看应用appId
6、添加功能
两个功能:支付宝授权功能和APP支付功能
7、功能签约
开发流程
引入支付宝支付SDK
<!-- 支付宝支付 SDK -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.7.4.ALL</version>
</dependency>
1、支付宝参数配置类
/**
* AlipayConfig.java
* com.prereadweb.order.config
* Copyright (c) 2019, 北京聚智未来科技有限公司版权所有.
*/
package com.prereadweb.order.config;
/**
* @Description: 支付宝支付配置文件
* @author: Administrator
* @date: 2019/6/11 17:01
*/
public class AlipayConfig {
// APPID
public static String app_id = "你应用的APPID";
// 生成公钥时对应的私钥(填自己的)
public static String private_key = "你的秘钥";
//异步回调接口:得放到服务器上,且使用域名解析 IP
public static String notify_url = "回调函数接口";
//支付宝网关(注意沙箱alipaydev,正式则为 alipay)不需要修改
public static String url = "https://openapi.alipay.com/gateway.do";
//编码类型
public static String charset = "UTF-8";
//数据类型
public static String format = "json";
// 公钥
public static String public_key = "你的公钥";
//签名类型
public static String signtype = "RSA2";
}
2、下单接口
controller层
/**
* @Function: 去支付
* @author: YangXueFeng
* @Date: 2019/6/11 16:10
*/
@RequestMapping("/gotopay")
public Object goToPay(@Param("orderId") Long orderId){
return alipayViewService.setGotoPayInfos(orderId);
}
service层
/**
* @Function: 去支付
* @author: YangXueFeng
* @Date: 2019/6/11 16:11
*/
@Override
public Map<String, Object> setGotoPayInfos(Long orderId) {
Map<String, Object> map = new HashMap<>();
if(Util.isEmpty(orderId)){
map.put("code", UserStatusEnum.EMPTY.intKey());
map.put("msg", UserStatusEnum.EMPTY.value());
return map;
}
/* 查询订单信息 */
PayParameterForm payParameter = orderMapper.getPayParameter(orderId);
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.url, AlipayConfig.app_id, AlipayConfig.private_key, AlipayConfig.format, AlipayConfig.charset, AlipayConfig.public_key, AlipayConfig.signtype);//支付宝需要的参数serverUrl、appId、private_key、format、charset、public_key、signType
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setBody(payParameter.getTitle());//商品信息
model.setSubject(payParameter.getTitle());//商品名称
model.setOutTradeNo(String.valueOf(payParameter.getOrderId()));//订单号
model.setTimeoutExpress("30m");//支付超时时间
/*
model.setTotalAmount(String.valueOf(payParameter.getActualPrice()));// 支付金额
*/
model.setTotalAmount(String.valueOf(0.01));// 支付金额
request.setBizModel(model);
// 回调地址(充值订单)
request.setNotifyUrl(AlipayConfig.notify_url);// 回调地址
//这里和普通的接口调用不同,使用的是sdkExecute
AlipayTradeAppPayResponse response = null;
try {
response = alipayClient.sdkExecute(request);
map.put("code", UserStatusEnum.SUCCESS.intKey());
map.put("msg", UserStatusEnum.SUCCESS.value());
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("payPath", response.getBody());
map.put("data", dataMap);
return map;
} catch (AlipayApiException e) {
e.printStackTrace();
}
map.put("code", UserStatusEnum.ERROR.intKey());
map.put("msg", UserStatusEnum.ERROR.value());
return map;
}
3、回调接口
controller层
/**
* @Function: 支付宝异步通知回调
* @author: YangXueFeng
* @Date: 2019/6/11 20:02
*/
@ResponseBody
@RequestMapping("/notify")
public String notify(HttpServletRequest request, HttpServletResponse response) {
return alipayViewService.notify(request, response);
}
service层
/**
* @Function: 支付宝异步回调接口
* @author: YangXueFeng
* @Date: 2019/6/11 20:03
*/
@Override
public String notify(HttpServletRequest request, HttpServletResponse response) {
Map<String, String> params = new HashMap<String, String>();
//从支付宝回调的request域中取值
Map<String, String[]> requestParams = request.getParameterMap();
for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = iter.next();
String[] values = requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
}
// 乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
// valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
params.put(name, valueStr);
}
//商品订单号
String out_trade_no = request.getParameter("out_trade_no"); // 商户订单号
// 当前交易状态
String tradeStatus = request.getParameter("trade_status"); //交易状态
// 支付金额
String totalAmount = request.getParameter("total_amount"); //交易状态
// 支付时间
String payDate = request.getParameter("gmt_payment"); //交易状态
//3.签名验证(对支付宝返回的数据验证,确定是支付宝返回的)
boolean signVerified = false;
try {
//3.1调用SDK验证签名
signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.public_key, AlipayConfig.charset, AlipayConfig.signtype);
} catch (AlipayApiException e) {
e.printStackTrace();
}
//返回状态存入redis中
//对验签进行处理
if (signVerified) {
//验签通过
if(tradeStatus.equals("TRADE_SUCCESS")) {
//支付成功后的业务处理
OrderEntity order = orderMapper.getOrderInfo(Long.valueOf(out_trade_no));
if(!Util.isEmpty(order)){
order.setStatus(CalculatStaticConstant.CHECK_ONE);
order.setCompleteTime(DateUtil.currentDate());
orderMapper.updateOrder(order);
}
/* 添加支付信息 */
OrderPayEntity orderPay = new OrderPayEntity();
orderPay.setId(Long.valueOf(IdUtils.getPrimaryKey()));
orderPay.setOrderId(order.getId());
orderPay.setUserId(order.getUserId());
orderPay.setPayPrice(Double.valueOf(totalAmount));
orderPay.setPayType(PayTypeEnum.ALI_PAY.intKey());
orderPay.setStatus(CalculatStaticConstant.CHECK_ONE);
orderPay.setPayTime(payDate);
orderMapper.saveOrderPay(orderPay);
RedisUtil.set("ali"+out_trade_no, tradeStatus,300);
return "success";
}
} else { //验签不通过
System.err.println("验签失败");
return "failure";
}
return "failure";
}
此处回调函数接口要有返回值,成功后返回success(success是小写,别大写),此处如果没有返回值的话,支付宝会一直进行回调通知
至此,支付宝APP支付OK
来源:https://blog.csdn.net/qq_37345604/article/details/93855402


猜你喜欢
- MD5的全称是Message-Digest Algorithm 5,Message-Digest泛指字节串(Message)的Hash变换,
- 微信公众平台对信息做了比较清晰的分类,最基本的包括请求(Request)和响应(Response)两大类信息,这两类信息有分为文字、语音、图
- 前言『 * 』其实源于设计模式中的代理模式,而代理模式就是使用代理对象完成用户请求,屏蔽用户对真实对象的访问。举个最简单的例子,比如我们想
- 本文实例讲述了基于.net实现裁剪网站上传图片的方法。由于客户端Javascript不能操作文件,所以只能先上传图片再在服务器端剪切。1、上
- 本文实例讲述了Android编程实现系统重启与关机的方法。分享给大家供大家参考,具体如下:最近在做个东西,巧合碰到了sharedUserId
- 简介本文主要介绍如何使用java代码利用Selenium操作浏览器,某些网页元素加载慢,如何操作元素就会把找不到元素的异常,此时需要设置元素
- 泛型 一般 出现在集合中,迭代器中 也会出现!泛型 是为了 提高代码的 安全性。 泛型 确保数据类型的唯一性。在我们常用的容器中
- 背景Java是一种流行的编程语言,验证码是一种常用的网络安全技术。Java发展至今,网上也出现了各种各样的验证码,本人初学Java,下面是我
- 首先说的是LinearLayout布局下的居中一般是这样的:(注意:android:layout_width="fill_pare
- 前言可能对于很多新人来讲,看到这个题目,想到的能接收输入法输入的内容大概只有EditText和TextView这两个控件了,其实不然,只要是
- 我已经很精简了,两篇(Spring Boot启动过程(一)、spring Boot启动过程(二))依然没写完,接着来。refreshCont
- 简介Microsoft官网关于 WindowChome 的介绍截取Microsoft文章的一段话:若要在保留其标准功能时自定义窗口,可以使用
- 问题引出:最近开了新项目,项目中用到了数据字典,列表查询数据返回的时候需要手动将code转换为name,到前台展示。项目经理表示可以封装一个
- 一、需求一般项目中都需要作异常处理,基于系统架构的设计考虑,使用统一的异常处理方法。系统中异常类型有哪些?包括预期可能发生的异常、运行时异常
- 一、项目简述本系统主要实现的功能有: 学生以及老师的注册登录,在线考试,错题查询,学生管理,问题管理,错题管理,错题查询,分数查询,试卷管
- 属性CascadeType.REFRESH:级联刷新,当多个用户同时作操作一个实体,为了用户取到的数据是实时的,在用实体中的数据之前就可以调
- 题目要求阅读理解读完题的我be like:去看了遍英文版就懂了,题目中的种类【type】不是种类数…&hell
- 这篇文档主要关注下配置修改后对应的 Java 对象是如何更新,并不关注整体的配置改动流程所有代码都来自 apollo-client 项目更新
- JDK12的五大重要新特性Java12在March 19, 2019发布了。在2017年发布Java 9之后,Java平台发布节奏已从每3年
- 比较简单的一个控件,就是加些逻辑处理而已,以前貌似是直接监听的,封装起来方便点public class AccountTxtView ext