Spring Boot是一个非常流行的Java框架,它提供了一种快速、简便的方式来开发基于Java的Web应用程序。支付宝是中国最大的第三方支付平台,它提供了丰富的API,支持多种支付方式。在本篇博客中,我将介绍如何使用Spring Boot集成支付宝支付,包括以下几个场景:
- 手机网站支付
- 电脑网站支付
- 移动支付
- 扫码支付
- APP支付
在开始之前,您需要先在 支付宝开放平台 注册一个支付宝账号,并且完成开发者认证,获取到支付宝开放平台的APPID、商户私钥、支付宝公钥等信息。
一. 手机网站支付
手机网站支付是指在手机浏览器中完成支付的一种方式。下面是集成步骤:
1.引入支付宝SDK依赖
在pom.xml文件中添加以下依赖:
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.22.22.ALL</version>
</dependency>
2.配置支付宝信息
在SpringBoot的配置文件(application.yml或application.properties)中,添加支付宝的配置参数,例如:
alipay:
alipayPublicKey: ALIPAY_PUBLIC_KEY
appId: YOUR_APP_ID
gateway: https://openapi.alipay.com/gateway.do
appPrivateKey: YOUR_PRIVATE_KEY
或
alipay.alipayPublicKey=ALIPAY_PUBLIC_KEY
alipay.appId=YOUR_APP_ID
alipay.gateway=https://openapi.alipay.com/gateway.do
alipay.appPrivateKey=YOUR_PRIVATE_KEY
3.编写支付请求接口
@RestController
public class PayController {
@Value("${alipay.appId}")
private String appId;
@Value("${alipay.gateway}")
private String gateway;
@Value("${alipay.appPrivateKey}")
private String appPrivateKey;
@Value("${alipay.alipayPublicKey}")
private String alipayPublicKey;
@RequestMapping("/pay")
public String pay(HttpServletRequest request) throws AlipayApiException {
// 实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient(gateway, appId, appPrivateKey, "json", "utf-8", alipayPublicKey, "RSA2");
// 实例化请求对象
AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
// 设置回调地址
alipayRequest.setReturnUrl(request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/return_url");
alipayRequest.setNotifyUrl(request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/notify_url");
// 设置订单信息
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
model.setOutTradeNo("20150320010101001");
model.setSubject("Iphone6 16G");
model.setTotalAmount("0.01");
model.setBody("Iphone6 16G");
model.setTimeoutExpress("30m");
model.setProductCode("QUICK_WAP_WAY");
alipayRequest.setBizModel(model);
// 调用SDK生成表单
String form = alipayClient.pageExecute(alipayRequest).getBody();
return form;
}
@RequestMapping("/return_url")
public String returnUrl(HttpServletRequest request) throws AlipayApiException {
// 获取支付宝GET过来反馈信息
Map<String, String> params = new HashMap<String, String>();
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] + ",";
}
// 解码
params.put(name, URLDecoder.decode(valueStr, "UTF-8"));
}
// 验证签名
boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayPublicKey, "UTF-8", "RSA2");
if (signVerified) {
return "success";
} else {
return "fail";
}
}
@RequestMapping("/notify_url")
public String notifyUrl(HttpServletRequest request) throws AlipayApiException {
// 获取支付宝POST过来反馈信息
Map<String, String> params = new HashMap<String, String>();
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] + ",";
}
// 解码
params.put(name, URLDecoder.decode(valueStr, "UTF-8"));
}
// 验证签名
boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayPublicKey, "UTF-8", "RSA2");
if (signVerified) {
// 商户订单号
String outTradeNo = params.get("out_trade_no");
// 支付宝交易号
String tradeNo = params.get("trade_no");
// 交易状态
String tradeStatus = params.get("trade_status");
if (tradeStatus.equals("TRADE_SUCCESS")) {
// TODO: 处理业务逻辑
return "success";
}
}
return "fail";
}
}
二. 电脑网站支付
电脑网站支付是指在电脑浏览器中完成支付的一种方式。下面是集成步骤:
1.引入支付宝SDK依赖
在pom.xml文件中添加以下依赖:
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.22.22.ALL</version>
</dependency>
2.配置支付宝信息
在SpringBoot的配置文件(application.yml或application.properties)中,添加支付宝的配置参数,例如:
alipay:
alipayPublicKey: ALIPAY_PUBLIC_KEY
appId: YOUR_APP_ID
gateway: https://openapi.alipay.com/gateway.do
appPrivateKey: YOUR_PRIVATE_KEY
或
alipay.alipayPublicKey=ALIPAY_PUBLIC_KEY
alipay.appId=YOUR_APP_ID
alipay.gateway=https://openapi.alipay.com/gateway.do
alipay.appPrivateKey=YOUR_PRIVATE_KEY
3.编写支付请求接口
@RestController
public class PayController {
@Value("${alipay.appId}")
private String appId;
@Value("${alipay.gateway}")
private String gateway;
@Value("${alipay.appPrivateKey}")
private String appPrivateKey;
@Value("${alipay.alipayPublicKey}")
private String alipayPublicKey;
@RequestMapping("/pay")
public String pay(HttpServletRequest request) throws AlipayApiException {
// 实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient(gateway, appId, appPrivateKey, "json", "utf-8", alipayPublicKey, "RSA2");
// 实例化请求
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
// 设置异步通知地址
alipayRequest.setNotifyUrl("http://localhost:8080/notify_url");
// 设置同步通知地址
alipayRequest.setReturnUrl("http://localhost:8080/return_url");
// 设置订单号
String outTradeNo = "20220326112000001";
// 设置订单总金额
String totalAmount = "100.00";
// 设置订单标题
String subject = "测试电脑网站支付";
// 组装请求参数
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
model.setOutTradeNo(outTradeNo);
model.setTotalAmount(totalAmount);
model.setSubject(subject);
model.setBody("测试电脑网站支付");
model.setProductCode("FAST_INSTANT_TRADE_PAY");
alipayRequest.setBizModel(model);
// 请求支付宝进行支付
String form = alipayClient.pageExecute(alipayRequest).getBody();
return form;
}
@RequestMapping("/return_url")
public String returnUrl(HttpServletRequest request) throws AlipayApiException, UnsupportedEncodingException {
// 获取支付宝GET过来反馈信息
Map<String, String> params = new HashMap<String, String>();
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] + ",";
}
// 解码
params.put(name, URLDecoder.decode(valueStr, "UTF-8"));
}
// 验证签名
boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayPublicKey, "UTF-8", "RSA2");
if (signVerified) {
// 获取订单号
String outTradeNo = params.get("out_trade_no");
// 获取支付宝交易号
String tradeNo = params.get("trade_no");
// 获取交易状态
String tradeStatus = params.get("trade_status");
if (tradeStatus.equals("TRADE_SUCCESS")) {
// TODO: 处理业务逻辑
return "success";
}
}
return "fail";
}
@RequestMapping("/notify_url")
public String notifyUrl(HttpServletRequest request) throws AlipayApiException {
// 获取支付宝POST过来反馈信息
Map<String, String> params = new HashMap<String, String>();
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] + ",";
}
// 解码
params.put(name, URLDecoder.decode(valueStr, "UTF-8"));
}
// 验证签名
boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayPublicKey, "UTF-8", "RSA2");
if (signVerified) {
// 获取订单号
String outTradeNo = params.get("out_trade_no");
// 获取支付宝交易号
String tradeNo = params.get("trade_no");
// 获取交易状态
String tradeStatus = params.get("trade_status");
if (tradeStatus.equals("TRADE_SUCCESS")) {
// TODO: 处理业务逻辑
return "success";
}
}
return "fail";
}
}
在上面的代码中,我们首先定义了一个AlipayClient
对象,用来创建支付宝请求对象和发送请求。然后,我们定义了一个方法,用于生成电脑网站支付的表单,该方法接收订单号、订单总金额和订单标题等参数,并返回生成的表单字符串。在该方法中,我们首先创建了一个AlipayTradePagePayRequest
对象,设置了异步通知地址和同步通知地址等参数,然后使用AlipayTradePagePayModel
对象组装了请求参数,最后使用alipayClient.pageExecute()方法发起支付宝支付请求,并将返回的表单字符串返回给调用方。
在returnUrl
方法中,我们首先获取支付宝返回的参数,并验证签名是否正确。如果签名验证通过,我们再从返回参数中获取订单号、支付宝交易号和交易状态等信息,根据交易状态进行业务逻辑处理。如果交易状态为TRADE_SUCCESS,表示交易成功,我们可以在这里处理相关业务逻辑,例如更新订单状态等操作。
在notifyUrl
方法中,与returnUrl方法类似,我们也是首先获取支付宝返回的参数,并验证签名是否正确。如果签名验证通过,我们再从返回参数中获取订单号、支付宝交易号和交易状态等信息,根据交易状态进行业务逻辑处理。与returnUrl方法不同的是,该方法是异步通知
接口,支付宝服务器会向该接口发送POST请求,通知支付结果,我们需要在该方法中及时处理通知,并返回success字符串表示已成功接收到通知。
三. 移动支付
除了电脑网站支付,支付宝还提供了移动支付的功能,让用户可以在手机端完成支付。
1.注册支付宝开发者账号并创建应用
在使用支付宝移动支付之前,我们需要注册一个支付宝开发者账号,并在开发者中心创建一个应用。具体步骤如下:
1.1. 打开支付宝开发者中心网址: https://openhome.alipay.com/platform/appManage.htm
1.2. 登录支付宝开发者账号,如果还没有账号,可以先注册一个。
1.3. 点击“创建应用”按钮,进入创建应用页面。
1.4. 填写应用名称和应用类型,选择移动应用,并提交创建。
1.5. 创建成功后,会自动生成AppID、私钥等信息。我们需要将这些信息保存下来,后面会用到。
2.引入支付宝SDK依赖
在项目的pom.xml文件中添加支付宝SDK依赖,具体代码如下:
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.22.22.ALL</version>
</dependency>
3.配置支付宝参数
在SpringBoot的配置文件(application.yml或application.properties)中,添加支付宝的配置参数,例如:
ali:
pay:
app-id: YOUR_APP_ID
notify-url: http://www.example.com/notify
private-key: YOUR_PRIVATE_KEY
public-key: ALIPAY_PUBLIC_KEY
或
ali.pay.app-id=YOUR_APP_ID
ali.pay.private-key=YOUR_PRIVATE_KEY
ali.pay.public-key=ALIPAY_PUBLIC_KEY
ali.pay.notify-url=http://www.example.com/notify
其中,ali.pay.app-id是在支付宝开发者中心创建应用时生成的AppID;ali.pay.private-key是我们自己生成的私钥,需要在支付宝开发者中心上传,同时也需要保存在本地;ali.pay.public-key是支付宝公钥,也需要在支付宝开发者中心获取;ali.pay.notify-url是支付成功后,支付宝服务器将支付结果通知给商户服务器的回调接口地址。
4.编写支付接口
在SpringBoot中,我们可以使用@Controller和@ResponseBody注解来定义一个接口,用于处理支付请求。具体代码如下:
@Controller
public class PayController {
@Autowired
private AliPayConfig aliPayConfig;
@PostMapping("/pay")
@ResponseBody
public String pay(@RequestParam("outTradeNo") String outTradeNo,
@RequestParam("totalAmount") String totalAmount,
@RequestParam("subject") String subject) throws AlipayApiException {
// 创建 AlipayClient 对象,用于调用支付宝接口
AlipayClient alipayClient = new DefaultAlipayClient(
aliPayConfig.getServerUrl(),
aliPayConfig.getAppId(),
aliPayConfig.getPrivateKey(),
"json",
"utf-8",
aliPayConfig.getPublicKey(),
"RSA2");
// 创建 AlipayTradeAppPayRequest 对象,用于设置支付参数
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
// 设置异步回调地址
request.setNotifyUrl(aliPayConfig.getNotifyUrl());
// 设置订单信息
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setOutTradeNo(outTradeNo);
model.setTotalAmount(totalAmount);
model.setSubject(subject);
model.setProductCode("QUICK_MSECURITY_PAY");
request.setBizModel(model);
// 调用支付接口,获取支付参数
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
// 返回客户端支付参数
return response.getBody();
}
}
在代码中,我们通过AlipayClient
和AlipayTradeAppPayRequest
对象来设置支付参数,然后调用支付宝的接口获取支付参数。最后将支付参数返回给客户端,客户端就可以使用支付宝SDK调起支付宝APP进行支付了。
5. 处理支付结果回调
当客户端支付成功后,支付宝服务器会将支付结果通知给商户服务器的回调接口地址,我们需要编写一个接口来处理支付结果回调。具体代码如下:
@Controller
public class NotifyController {
@PostMapping("/notify")
@ResponseBody
public String notify(HttpServletRequest request) throws AlipayApiException {
// 获取支付宝POST过来反馈信息
Map<String, String> params = new HashMap<>();
Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()) {
String paramName = parameterNames.nextElement();
String paramValue = request.getParameter(paramName);
params.put(paramName, paramValue);
}
// 验证签名
boolean signVerified = AlipaySignature.rsaCheckV1(params,
aliPayConfig.getPublicKey(),
"utf-8",
"RSA2");
if (signVerified) {
// 处理支付结果
String tradeStatus = params.get("trade_status");
String outTradeNo = params.get("out_trade_no");
String tradeNo = params.get("trade_no");
String totalAmount = params.get("total_amount");
// TODO: 处理支付结果
return "success";
} else {
return "failure";
}
}
}
在代码中,我们首先获取支付宝POST过来的反馈信息,然后通过AlipaySignature.rsaCheckV1()方法验证签名,确保支付结果是合法的。最后,我们可以根据支付结果进行相应的业务处理,例如更新订单状态、发送邮件通知等。
6.发起支付请求
客户端在发起支付请求时,需要调用我们编写的支付接口,并将支付参数传递给支付宝SDK。具体代码如下:
public class PayActivity extends AppCompatActivity {
private static final String TAG = "PayActivity";
private static final String SERVER_URL = "http://www.example.com/pay";
private static final int SDK_PAY_FLAG = 1;
private Button mBtnPay;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pay);
mBtnPay = findViewById(R.id.btn_pay);
mBtnPay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pay();
}
});
}
private void pay() {
String outTradeNo = UUID.randomUUID().toString();
String totalAmount = "0.01";
String subject = "测试商品";
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new FormBody.Builder()
.add("out_trade_no", outTradeNo)
.add("total_amount", totalAmount)
.add("subject", subject)
.build();
Request request = new Request.Builder()
.url(SERVER_URL)
.post(requestBody)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e(TAG, "请求支付接口失败", e);
showToast("请求支付接口失败");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
// 获取支付参数成功,打印日志,并将支付参数传递给支付宝SDK
String body = response.body().string();
Log.d(TAG, "获取支付参数成功: " + body);
PayTask task = new PayTask(PayActivity.this);
Map<String, String> result = task.payV2(body, true);
// 将支付结果通过 Handler 对象传递回主线程
Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
} else {
// 获取支付参数失败,打印日志,并提示用户
Log.e(TAG, "获取支付参数失败: " + response.code());
showToast("获取支付参数失败");
}
}
});
}
private Handler mHandler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what) {
case SDK_PAY_FLAG:
Map<String, String> result = (Map<String, String>) msg.obj;
String resultStatus = result.get("resultStatus");
if (TextUtils.equals(resultStatus, "9000")) {
showToast("支付成功");
} else if (TextUtils.equals(resultStatus, "6001")) {
showToast("支付取消");
} else {
showToast("支付失败");
}
break;
}
}
};
private void showToast(String message) {
runOnUiThread(() -> Toast.makeText(PayActivity.this, message, Toast.LENGTH_SHORT).show());
}
}
在代码中,我们首先调用我们编写的支付接口获取支付参数,然后将支付参数传递给支付宝SDK,让SDK调起支付宝APP进行支付。支付结果会通过SDK_PAY_FLAG
标志和Handler
对象返回到主线程,我们可以在Handler
对象中根据支付结果进行相应的提示。
至此,我们已经成功集成了支付宝移动支付。在实际开发中,还需要考虑异常处理、订单状态同步、订单查询等问题。
四. 扫码支付
除了电脑网站支付和移动支付,支付宝还提供了扫码支付的功能,让用户可以在商户店铺扫描二维码完成支付。
1.注册支付宝开发者账号
首先,我们需要注册一个支付宝开发者账号。在注册完成后,我们需要进入开发者中心,在“应用管理”中创建一个新的应用,选择“PC网站支付”作为接口类型。
在创建完应用后,我们需要获取一些必要的配置信息,包括应用ID、商户私钥、支付宝公钥、异步通知地址、同步跳转地址等。这些配置信息将在后面的代码中使用。
2.引入支付宝SDK依赖
在我们的Spring Boot项目中,我们需要引入支付宝SDK。支付宝SDK提供了一系列用于调用支付宝接口的Java类和方法。我们可以使用Maven或Gradle来管理我们的项目依赖。下面是一个Maven的依赖配置示例:
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.22.22.ALL</version>
</dependency>
3.配置支付宝信息
在我们的Spring Boot项目中,我们需要在配置文件中添加支付宝信息。下面是一个示例配置文件:
# 支付宝网关
alipay.gatewayUrl=https://openapi.alipay.com/gateway.do
# 应用ID
alipay.appId=xxxxxxxxxxxx
# 商户私钥
alipay.privateKey=xxxxxxxxxxxx
# 支付宝公钥
alipay.alipayPublicKey=xxxxxxxxxxxx
# 异步通知地址
alipay.notifyUrl=http://localhost:8080/notify
# 同步跳转地址
alipay.returnUrl=http://localhost:8080/return
或
alipay:
alipayPublicKey: xxxxxxxxxxxx
appId: xxxxxxxxxxxx
gatewayUrl: https://openapi.alipay.com/gateway.do
notifyUrl: http://localhost:8080/notify
privateKey: xxxxxxxxxxxx
returnUrl: http://localhost:8080/return
4.实现支付接口
在我们的Spring Boot项目中,我们需要实现一个支付接口,用于生成支付二维码并返回给前端。下面是一个示例代码:
@RestController
public class AlipayController {
@Resource
private AlipayConfig alipayConfig;
/**
* 支付宝扫码支付
*/
@GetMapping("/scan/pay")
public String scanPay(String orderNo, String amount, String subject) throws AlipayApiException {
// 创建AlipayClient对象
AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.getServerUrl(), alipayConfig.getAppId(), alipayConfig.getPrivateKey(), "json", "UTF-8", alipayConfig.getAlipayPublicKey(), "RSA2");
// 创建AlipayTradePrecreateRequest对象
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
// 设置异步通知地址
request.setNotifyUrl("异步通知地址");
// 设置订单信息
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
model.setOutTradeNo(orderNo);
model.setTotalAmount(amount);
model.setSubject(subject);
request.setBizModel(model);
// 发起支付请求
AlipayTradePrecreateResponse response = alipayClient.execute(request);
if (response.isSuccess()) {
// 返回二维码链接给前端
return response.getQrCode();
} else {
// 处理支付失败的情况
throw new AlipayApiException(response.getMsg());
}
}
/**
* 处理支付结果
*/
@PostMapping("/notify")
public String notify(HttpServletRequest request) throws AlipayApiException {
// 获取支付宝POST过来反馈信息
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
String[] values = requestParams.get(name);
StringBuilder valueStr = new StringBuilder();
for (int i = 0; i < values.length; i++) {
valueStr.append((i == values.length - 1) ? values[i] : values[i] + ",");
}
params.put(name, valueStr.toString());
}
// 验证签名
boolean verifyResult = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipayPublicKey(), "UTF-8", "RSA2");
if (verifyResult) {
// 处理支付成功的情况
String orderNo = params.get("out_trade_no");
String tradeNo = params.get("trade_no");
String amount = params.get("total_amount");
// TODO: 处理订单状态
return "success";
} else {
// 处理验签失败的情况
return "failure";
}
}
}
在上面的代码中,我们定义了一个AlipayController,其中包含了两个接口:scanPay
和notify
。
在scanPay
接口中,我们首先创建了一个AlipayClient对象,然后创建了一个AlipayTradePrecreateRequest对象,并设置了异步通知地址和订单信息。最后,我们通过AlipayClient对象的execute方法发送支付请求,获取二维码链接,并将其返回给前端。
在notify
接口中,我们首先从request中获取支付结果参数,并使用AlipaySignature.rsaCheckV1方法验证签名。如果验签成功,则处理支付成功的情况,否则处理验签失败的情况。在处理支付成功的情况时,我们可以根据订单号、交易号和金额等参数来更新订单状态。
5. 测试支付接口
最后,我们可以使用Postman等工具来测试我们的支付接口。在测试时,我们需要传入订单号、订单金额和订单标题等参数,然后可以获取到支付宝生成的二维码,并使用支付宝App或支付宝扫码枪扫描二维码来完成支付。
至此,我们已经完成了在Spring Boot中集成支付宝扫码支付的过程。如果您在实际使用中遇到了问题,可以查看支付宝SDK文档或咨询支付宝开发者支持。
五. APP支付
除了移动支付和扫码支付,支付宝还提供了APP支付的功能,让开发者可以在APP中集成支付宝支付。
1.引入支付宝SDK依赖
在pom.xml文件中添加以下依赖:
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.22.22.ALL</version>
</dependency>
2.配置支付宝信息
在application.properties文件中添加支付宝相关配置信息,包括应用ID、私钥、公钥等:
# 支付宝配置信息
alipay.app-id=应用ID
alipay.private-key=应用私钥
alipay.public-key=支付宝公钥
alipay.server-url=https://openapi.alipay.com/gateway.do
或
alipay:
app-id: 应用ID
private-key: 应用私钥
public-key: 支付宝公钥
server-url: https://openapi.alipay.com/gateway.do
其中,应用ID可以在支付宝开放平台中创建应用后获得,私钥和公钥需要在创建应用时生成。
3.创建支付接口
在Spring Boot应用程序中创建一个控制器类,命名为AlipayController,用于处理支付相关的请求:
@RestController
@RequestMapping("/alipay")
public class AlipayController {
@Autowired
private AlipayConfig alipayConfig;
/**
* 处理支付请求
*/
@PostMapping("/app-pay")
public String appPay(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException, IOException {
// 实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.getServerUrl(),
alipayConfig.getAppId(),
alipayConfig.getPrivateKey(),
"json",
"UTF-8",
alipayConfig.getAlipayPublicKey(),
"RSA2");
// 实例化请求对象
AlipayTradeAppPayRequest alipayRequest = new AlipayTradeAppPayRequest();
// 设置异步通知地址
alipayRequest.setNotifyUrl("http://localhost:8080/alipay/notify");
// 设置订单信息
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setOutTradeNo("订单号");
model.setSubject("订单标题");
model.setBody("订单描述");
model.setTotalAmount("订单金额");
alipayRequest.setBizModel(model);
// 请求支付宝生成支付结果
String form = alipayClient.sdkExecute(alipayRequest).getBody();
// 将支付结果返回给客户端
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write(form);
response.getWriter().flush();
response.getWriter().close();
return null;
}
/**
* 处理支付结果
*/
@PostMapping("/notify")
public String notify(HttpServletRequest request) throws AlipayApiException {
// 获取支付宝POST过来反馈信息
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
String[] values = requestParams.get(name);
StringBuilder valueStr = new StringBuilder();
for (int i = 0; i < values.length; i++) {
valueStr.append((i == values.length - 1) ? values[i] : values[i] + ",");
}
params.put(name, valueStr.toString());
}
// 验证签名
boolean verifyResult = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipayPublicKey(), "UTF-8", "RSA2");
if (verifyResult) {
// 处理支付结果
String tradeStatus = params.get("trade_status");
if ("TRADE_SUCCESS".equals(tradeStatus)) {
String outTradeNo = params.get("out_trade_no");
String tradeNo = params.get("trade_no");
// TODO: 处理支付结果
}
return "success";
} else {
return "failure";
}
}
}
在支付请求处理方法appPay()
中,我们创建了一个AlipayTradeAppPayRequest对象,设置了异步通知地址、订单信息等参数,然后通过AlipayClient对象调用sdkExecute()方法向支付宝发起支付请求,并将支付结果以HTML形式返回给客户端。
在支付结果处理方法notify()
中,我们获取支付宝POST过来的反馈信息,使用AlipaySignature类的rsaCheckV1()方法验证签名,然后根据支付结果处理业务逻辑,最后返回一个success字符串表示处理成功,或者返回failure字符串表示处理失败。
4.调用支付接口
在客户端调用支付接口时,需要向服务端发送支付请求,并获取服务端返回的支付结果。具体代码如下:
public class AlipayClient {
private static final String APP_PAY_URL = "http://localhost:8080/alipay/app-pay";
/**
* 调用支付接口
*/
public String pay() {
OkHttpClient client = new OkHttpClient();
RequestBody formBody = new FormBody.Builder()
.build();
Request request = new Request.Builder()
.url(APP_PAY_URL)
.post(formBody)
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
return response.body().string();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
在客户端的AlipayClient类中,我们通过OkHttpClient对象向服务端发送一个POST请求,获取服务端返回的支付结果,最后将支付结果返回给调用方。
以上就是集成支付宝APP支付的基本步骤。需要注意的是,在使用支付宝SDK进行支付开发时,需要遵守支付宝的相关规定和安全要求,确保支付过程的安全和正确性。在实际开发中,还需要根据业务需求进行相关的调整和优化。例如,可以根据不同的支付场景选择不同的支付方式,或者对支付结果进行定时查询和处理等等。总之,只有不断地实践和优化,才能在实际项目中使用支付宝SDK进行高效、安全、稳定的支付开发。
总结
在本篇博客中,我们介绍了在SpringBoot项目中集成支付宝支付的五种场景;需要注意保护支付宝API密钥和支付宝公钥等敏感信息,确保支付过程的安全性。
在实际的开发过程中,我们可以根据具体的业务场景和需求,进行支付宝支付功能的扩展和定制化开发。同时,我们也需要考虑支付宝支付过程中的异常情况和处理方法,例如订单重复支付、支付超时、支付金额不正确等问题。
希望这篇博客能够帮助您掌握SpringBoot集成支付宝支付的方法,并能够在实际项目中得到应用。如果您有任何问题或建议,欢迎在评论区留言,谢谢!
标签:集成,支付宝,SpringBoot,alipay,request,params,支付,String From: https://blog.51cto.com/loveddz/6150371