SpringBoot对接支付宝实现支付功能
准备工作:
① 去支付宝开放平台创建一个沙箱应用
官网:https://open.alipay.com/develop/sandbox/app申请完毕之后获得如下内容:
开启公钥模式
总之要拿到如下内容:
1.APPID(自动生成)
2.应用私钥(自动生成)
3.支付宝公钥(自动生成)
4.支付宝网关地址(自动生成)
5.授权回调地址(自己准备地址)
6.应用网关地址(自己准备地址)做好如上准备之后我们就可以着手开发了
开发环境
我这里开发的是JavaWeb项目,使用Maven管理,依赖SpringBoot
对接步骤
第一、在Maven的pom.xml加入支付宝依赖的SDK
<!-- 阿里支付SDK -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.38.23.ALL</version>
</dependency>
第二、新建一个config类配置如下信息(变量自行替换)
/**
* @Author gityyge
* @Description 支付功能配置类(支付宝)
* @Date 2023/7/25 11:55
* @Version 1.0
*/
public class AlipayConfig {
public static final String APPID = "商户Appid";
/**
* (RSA加密方法) 私钥-加密用 pkcs8格式的
*/
public static final String RSA_PRIVATE_KEY = "应用私钥";
/**
* (RSA加密方法) 支付宝公钥-解密用
*/
public static final String ALIPAY_PUBLIC_KEY = "支付宝公钥";
/**
* 服务器异步通知页面路径POST请求 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
* 这个地址就是支付成功后回调的地址POST请求
*/
public static final String notify_url = "请求地址";
/**
* 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址
* 这个地址是支付成功后跳转的地址GET请求
*/
public static String return_url = "页面跳转同步通知页面路径";
public static String URL = "请求网关地址";
/**
* 编码
*/
public static String CHARSET = "UTF-8";
/**
* 返回格式
*/
public static String FORMAT = "json";
/**
* 日志记录目录
*/
public static String log_path = "/log";
/**
* RSA2 签名 加密算法
*/
public static String SIGNTYPE = "RSA2";
}
第三、在controller包下面新建一个controller类用于请求支付的功能
import cn.hutool.core.util.StrUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yyge.common.enums.AckCode;
import com.yyge.common.exception.ServiceException;
import com.yyge.config.AlipayConfig;
import com.yyge.entity.Orders;
import com.yyge.service.OrdersService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* @Author gityyge
* @Description 支付的业务逻辑控制器
* @Date 2023/7/25 11:42
* @Version 1.0
*/
@RestController
@RequestMapping(value = "/front/alipay")
public class AlipayController{
//注入业务逻辑的Bean对象
@Autowired
private OrdersService ordersService;
//向支付宝提交支付申请
@GetMapping(value = "/{orderNumber}")
public void submitAlipay(@PathVariable(value = "orderNumber") String orderNumber, HttpServletResponse response) throws UnsupportedEncodingException{
//1.判断当前的orderNumber 订单号是否为空 如果为空则抛出异常
if(StrUtil.isBlank(orderNumber)){
throw new ServiceException(AckCode.SYSTEM_PARAM_FAIL);
}
//2、向支付宝发起支付申请 ( 必须是一个网页,不能是json字符串)
// 商户订单号,商户网站订单系统中唯一订单号,必填
String out_trade_no = orderNumber + "";
// 订单名称,必填
String merchandiserName = this.ordersService.searchByMerchandiserName(orderNumber);
String subject = "向" + merchandiserName + "付款";
// 付款金额(保留2位小数),必填
String total_amount = dbOrder.getAmount().setScale(2, RoundingMode.HALF_UP).doubleValue() + "";
// 商品描述,可空
String body = merchandiserName;
// 超时时间 可空
String timeout_express = "2m";
/**********************/
// SDK 公共请求类,包含公共请求参数,以及封装了签名与验签,开发者无需关注签名与验签
//调用RSA签名方式
AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);
AlipayTradeWapPayRequest alipay_request = new AlipayTradeWapPayRequest();
// 封装请求支付信息
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
model.setOutTradeNo(out_trade_no);
model.setSubject(subject);
model.setTotalAmount(total_amount);
model.setBody(body);
model.setTimeoutExpress(timeout_express);
alipay_request.setBizModel(model);
// 设置异步通知地址
alipay_request.setNotifyUrl(AlipayConfig.notify_url);
// 设置同步地址
alipay_request.setReturnUrl(AlipayConfig.return_url);
// form表单生产
String form = "";
try{
// 调用SDK生成表单
form = client.pageExecute(alipay_request).getBody();
log.info(form);
response.setContentType("text/html;charset=" + AlipayConfig.CHARSET);
//直接将完整的表单html输出到页面
response.getWriter().write(form);
response.getWriter().flush();
response.getWriter().close();
}catch (AlipayApiException | IOException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//支付宝通知支付情况
@PostMapping(value = "/notify")
public void alipay_notify(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException, ParseException, IOException
{
PrintWriter out = response.getWriter();
Map < String, String > params = new HashMap < > ();
Map < String, String[] > requestParams = request.getParameterMap();
for(String name: requestParams.keySet()){
params.put(name, request.getParameter(name));
}
//商户订单号
String out_trade_no = params.get("out_trade_no");
//支付宝交易号
String trade_no = params.get("trade_no");
//实际支付金额
String total_amount = params.get("total_amount");
//交易时间 yyyy-MM-dd HH:mm:ss
String gmt_payment = params.get("gmt_payment");
//交易状态
String trade_status = params.get("trade_status");
SimpleDateFormat smf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//计算得出通知验证结果
boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");
if(verify_result){
//支付成功
if(trade_status.equals("TRADE_SUCCESS")){
//更新订单状态
//支付成功的业务逻辑
//....
out.println("success");
}
}else{
out.println("fail");
}
}
}
展示效果:
发表评论