# alipay
**Repository Path**: YzHutMall/alipay
## Basic Information
- **Project Name**: alipay
- **Description**: SpringBoot整合支付宝支付 扫码支付+退款 详细文档
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 3
- **Forks**: 0
- **Created**: 2022-02-20
- **Last Updated**: 2026-01-27
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# SpringBoot整合支付宝支付
## 项目工程
```
│ pom.xml
│ Readme.md
│
├─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─alipay
│ │ │ └─alipayDemo
│ │ │ │ AlipayDemoApplication.java
│ │ │ │
│ │ │ ├─bean
│ │ │ │ AlipayBean.java
│ │ │ │
│ │ │ ├─config
│ │ │ │ AlipayUtil.java
│ │ │ │
│ │ │ ├─controller
│ │ │ │ NotifyController.java
│ │ │ │ OrderController.java
│ │ │ │
│ │ │ └─service
│ │ │ │ PayService.java
│ │ │ │
│ │ │ └─impl
│ │ │ PayServiceImpl.java
│ │ │
│ │ └─resources
│ │ │ application.yml
│ │ │
│ │ ├─config
│ │ │ alipay.properties
│ │ │
│ │ ├─static
│ │ │ error.html
│ │ │ index.html
│ │ │ success.html
│ │ │
│ │ └─templates
│ └─test
│ └─java
│ └─com
│ ├─java98k
│ │ └─alipayDemo
│ │ AlipayDemoApplicationTests.java
│ │
│ └─kylin
```
### 效果展示
#### 支付页面

#### 待支付页面

#### 扫码支付

#### 支付成功

#### 支付回调

### 代码
#### 依赖
```xml
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
com.alipay.sdk
alipay-sdk-java
3.1.0
org.projectlombok
lombok
com.alibaba
fastjson
1.2.44
```
#### 支付控制层
```java
/**
* 功能描述: 订单接口
*
* @author CHENKAIFANG
* @date 2022/2/20 2:44
* @since JDK 1.8
*/
@RestController()
@RequestMapping("order")
public class OrderController {
@Resource
private PayService payService;
/**
* 功能描述: 支付宝支付
*
* @param outTradeNo 订单号
* @param subject 主题
* @param totalAmount 总价
* @param body 主题
* @return {@link String}
* @author CHENKAIFANG
* @date 2022/2/20 2:44
* @since JDK 1.8
*/
@PostMapping(value = "alipay")
public String alipay(String outTradeNo, String subject, StringBuffer totalAmount, String body) throws AlipayApiException {
return payService.aliPay(AlipayBean.builder()
.body(body)
.out_trade_no(outTradeNo)
.total_amount(totalAmount)
.subject(subject).build());
}
/**
* 功能描述: 退款
*
* @author CHENKAIFANG
* @date 2022/2/20 14:14
* @since JDK 1.8
*/
@PostMapping(value = "alipayRefound")
public String alipayRefound(@RequestParam("tradeNo") String tradeNo, @RequestParam("outRequestNo") String outRequestNo, @RequestParam("refundAmount") String refundAmount) throws AlipayApiException {
return payService.alipayRefound(AlipayBean.builder()
.tradeNo(tradeNo)
.outRequestNo(outRequestNo)
.refundAmount(refundAmount)
.build());
}
}
```
#### 支付配置
```text
沙箱配置文档:https://open.alipay.com/dev/workspace
```
```yml
# 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
app_id=2016102100734823
# 商户私钥,您的PKCS8格式RSA2私钥
merchant_private_key=商户私钥(支付宝沙箱配置)
# 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
alipay_public_key=支付宝公钥 (支付宝沙箱配置)
# 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
notify_url=http://外网IP(ngrok内外网穿透工具)/notify/alipay
# 面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
return_url=http://外网IP(ngrok内外网穿透工具)/success.html
# 签名方式
sign_type=RSA2
# 字符编码格式
charset=utf-8
# 支付宝网关
gatewayUrl=https://openapi.alipaydev.com/gateway.do
# 支付宝网关
log_path="C:\\"
```
#### 支付成功页面
```html
支付成功
支付成功!
```
#### 支付回调
```java
/**
*
* 支付回调
*
*
* @SINCE 2022/2/20 2:53
* @AUTHOR CHENKAIFANG
* @Date: 2022/2/20 02:53
*/
@RestController()
@RequestMapping("notify")
public class NotifyController {
@Autowired
private PayService payService;
/**
* 功能描述: 支付成功回调
*
* @author CHENKAIFANG
* @date 2022/2/20 14:14
* @since JDK 1.8
*/
@PostMapping(value = "alipay")
public String pay(HttpServletRequest request) {
System.out.println("支付成功回调!");
int im = 0;
im++;
//测试请求次数
System.out.println("次数:" + im);
Map params = new HashMap();
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] + ",";
}
//乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
params.put(name, valueStr);
}
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
//商户订单号
String outTradeNo = request.getParameter("out_trade_no");
System.out.println("商户订单号: " + outTradeNo);
//支付宝交易号
String tradeNo = request.getParameter("trade_no");
System.out.println("支付宝交易号: " + tradeNo);
//支付宝交易金额
String totalAmount = request.getParameter("total_amount");
System.out.println("支付宝交易金额: " + totalAmount);
//交易状态
String tradeStatus = request.getParameter("trade_status");
System.out.println("交易状态: " + tradeStatus);
System.out.println("params: " + JSONObject.toJSONString(params));
return payService.rsaCheck(params, tradeStatus);
}
}
```
#### 验签
``` java
/**
* 功能描述: 支付回调验签
*
* @param params 获取支付宝POST过来反馈信息
* @param tradeStatus 交易状态
* @return {@link Boolean}
* @author CHENKAIFANG
* @date 2022/2/20 15:20
*/
public String rsaCheck(Map params, String tradeStatus) {
try {
boolean verifyResult = AlipaySignature.rsaCheckV1(params,
alipayPublicKey,
charset,
signType);
if (verifyResult) {
//验证成功
//请在这里加上商户的业务逻辑程序代码
System.out.println("returnUrl_params: 验证成功");
//——请根据您的业务逻辑来编写程序(以下代码仅作参考)——
boolean flg = false;
if ("TRADE_FINISHED".equals(tradeStatus)) {
System.out.println("returnUrl_params: 交易结束");
//交易结束,不可退款
//注意:
//退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
} else if ("TRADE_SUCCESS".equals(tradeStatus)) {
//交易支付成功
//注意:
//付款完成后,支付宝系统发送该交易状态通知
//根据订单号将订单状态和支付宝记录表中状态都改为已支付
System.out.println("returnUrl_params: 交易支付成功");
flg = true;
}
//——请根据您的业务逻辑来编写程序(以上代码仅作参考)——
if (flg) {
return "success";
} else {
return "fail";
}
} else {
return "fail";
}
} catch (AlipayApiException e) {
e.printStackTrace();
return "fail";
}
}
```
#### 回调返回
``` text
支付成功回调!
次数:1
商户订单号: 22
支付宝交易号: 2022031922001404550501570961
支付宝交易金额: 100.00
交易状态: TRADE_SUCCESS
params: {"gmt_create":"2022-03-19 13:50:29","charset":"utf-8","gmt_payment":"2022-03-19 13:50:36","notify_time":"2022-03-19 13:50:38","subject":"E-c-mall 支付100元","sign":"XO1b5ELBiQ3SOKv9rw3A2BaHD+NnwAH3i1JHWZXGxHishhcTOqMvUx41aXdbtgYtJy2u/7wKjnfAptJlMG+aMQNIerxX8vFUORWryUSZkXHQTTIJGyx6E0BUnKtRtehBJnK7iHU3jgg3eRYfs65bYr5qlIB6N/PHjzALVrZcLD/ozepAkGKDKKHi+ZkYVF51G3AQr+AUF3hAzPw5SOorx7FmEhLShHA0hHn6Q9YQL+UgF0CWy6/be1Ilgf6/NVY9PfoQbC/KeEl9azfN1dCNVC6jFi4a9GHs4P4E1johtRuvc/p8u0Z5iUyQFHY5eX2clg4KqRaCred7wkrD0F6ciA==","buyer_id":"2088102180804554","body":"E-c-mall 支付100元","invoice_amount":"100.00","version":"1.0","notify_id":"2022031900222135037004550519937487","fund_bill_list":"[{\"amount\":\"100.00\",\"fundChannel\":\"ALIPAYACCOUNT\"}]","notify_type":"trade_status_sync","out_trade_no":"22","total_amount":"100.00","trade_status":"TRADE_SUCCESS","trade_no":"2022031922001404550501570961","auth_app_id":"2016102100734823","receipt_amount":"100.00","point_amount":"0.00","app_id":"2016102100734823","buyer_pay_amount":"100.00","sign_type":"RSA2","seller_id":"2088102180570093"}
returnUrl_params: 验证成功
returnUrl_params: 交易支付成功
```
#### 支付宝退款
``` java
/**
* 功能描述: 支付宝退款
*
* @param alipayBean 支付实体对象
* @return {@link String}
* @author CHENKAIFANG
* @date 2022/2/20 14:21
* @since JDK 1.8
*/
public String alipayRefound(AlipayBean alipayBean) throws AlipayApiException {
// 1.接口参数调用
AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl,
appId,
merchantPrivateKey,
FORMAT,
charset,
alipayPublicKey,
signType);
AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
JSONObject bizContent = new JSONObject();
bizContent.put(TRADE_NO, alipayBean.getTradeNo());
bizContent.put(OUT_REQUEST_NO, alipayBean.getOutRequestNo());
bizContent.put(REFUND_AMOUNT, alipayBean.getRefundAmount());
request.setBizContent(bizContent.toString());
// 2.接口调用<原理就是返回的form表单。然后执行而已>
return alipayClient.execute(request).getBody();
}
```
### 内外网穿透工具
```shell
Sunny-Ngrok www.ngrok.cc (Ctrl+C to quit)
Tunnel Status online
Version 2.1.1/2.1.1
Forwarding http://前置域名.vipgz1.91tunnel.com -> 127.0.0.1:8081
Web Interface 127.0.0.1:4040
# Conn 14
Avg Conn Time 48960.21ms
```