
springboot集成支付宝沙箱支付
支付宝沙箱环境配置
首先进入支付宝开放平台的沙箱支付(如果没有支付宝开发平台账号的需要注册,需要相应的认证信息填写)点击进入沙箱环境用支付宝登录。
点击沙箱工具后进入沙箱管理界面
这里的应用公钥需要下载一个工具获取密钥工具下载,下载安装之后打开软件是这样的界面
点击生成密钥。会得到一对密钥分别是应用公钥和应用私钥,应用公钥是生成支付宝公钥必需的前置条件,应用私钥是我们后面springboot集成支付宝支付需要的
按照步骤把应用公钥复制到开放平台中得到支付宝公钥,这一步就不在赘述。
现在我们已经完成了沙箱环境的所有前置条件的获取,包括支付宝公钥,应用私钥,支付宝网关地址,appId,现在可以开始代码的编写了。
springboot 环境配置
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.35.79.ALL</version>
</dependency>
在你的yml文件里面配置支付宝沙箱相关参数
alipay:
appId:
appPrivateKey:
alipayPublicKey:
notifyUrl: #如果是在本地测试需要下载内网穿透工具,用来支付宝的调的回调接口
支付宝支付的相关配置代码AlipayConfig.java
@Component
@ConfigurationProperties(prefix = "alipay")
public class AliPayConfig {
private String appId;
private String appPrivateKey;
private String alipayPublicKey;
private String notifyUrl;
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getAppPrivateKey() {
return appPrivateKey;
}
public void setAppPrivateKey(String appPrivateKey) {
this.appPrivateKey = appPrivateKey;
}
public String getAlipayPublicKey() {
return alipayPublicKey;
}
public void setAlipayPublicKey(String alipayPublicKey) {
this.alipayPublicKey = alipayPublicKey;
}
public String getNotifyUrl() {
return notifyUrl;
}
public void setNotifyUrl(String notifyUrl) {
this.notifyUrl = notifyUrl;
}
}
添加相关的支付接口
@RestController
@RequestMapping("/alipay")
public class AliPayController {
// 支付宝沙箱网关地址
private static final String GATEWAY_URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
private static final String FORMAT = "JSON";
private static final String CHARSET = "UTF-8";
//签名方式
private static final String SIGN_TYPE = "RSA2";
@Resource
private AliPayConfig aliPayConfig;
@Resource
private DonationProjectService ordersService;
@Resource
private DonationRecordService recordService;
@GetMapping("/pay")
public void pay(@RequestParam("projectId") Integer projectId, @RequestParam("userId") Integer userId,
@RequestParam("amount") BigDecimal amount, @RequestParam("username") String username,
@RequestParam("userImg") String userImg,
HttpServletResponse httpResponse) throws Exception {
LambdaQueryWrapper<DonationProject> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DonationProject::getId, projectId);
// 查询捐赠信息
DonationProject orders = ordersService.getOne(queryWrapper);
if (orders == null) {
return;
}
// 生成捐赠记录
DonationRecord donationRecord = new DonationRecord();
donationRecord.setProjectId(projectId);
donationRecord.setUserId(userId);
donationRecord.setUsername(username);
donationRecord.setUserImg(userImg);
donationRecord.setAmount(amount);
donationRecord.setPaymentNo(IdUtil.fastSimpleUUID());
donationRecord.setPayStatus("待支付");
donationRecord.setCreateTime(LocalDateTime.now());
recordService.createRecord(donationRecord);
// 1. 创建Client,通用SDK提供的Client,负责调用支付宝的API
AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
// 2. 创建 Request并设置Request参数
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setNotifyUrl(aliPayConfig.getNotifyUrl());
JSONObject bizContent = new JSONObject();
bizContent.set("out_trade_no", donationRecord.getPaymentNo());
bizContent.set("total_amount", donationRecord.getAmount());
bizContent.set("subject", orders.getTitle()); // 支付的名称
bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY");
request.setBizContent(bizContent.toString());
request.setReturnUrl("http://7g6zrz.natappfree.cc/alipay/redirect");
// 执行请求,拿到响应的结果,返回给浏览器
String form = "";
try {
form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单
} catch (AlipayApiException e) {
e.printStackTrace();
}
httpResponse.setContentType("text/html;charset=" + CHARSET);
httpResponse.getWriter().write(form);
httpResponse.getWriter().flush();
httpResponse.getWriter().close();
}
@PostMapping("/notify") // 注意这里必须是POST接口
public void payNotify(HttpServletRequest request) throws Exception {
if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
System.out.println("=========支付宝异步回调========");
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
params.put(name, request.getParameter(name));
}
String sign = params.get("sign");
String content = AlipaySignature.getSignCheckContentV1(params);
boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, aliPayConfig.getAlipayPublicKey(), "UTF-8");
// 支付宝验签
if (checkSignature) {
// 验签通过
System.out.println("交易名称: " + params.get("subject"));
System.out.println("交易状态: " + params.get("trade_status"));
System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
System.out.println("商户订单号: " + params.get("out_trade_no"));
System.out.println("交易金额: " + params.get("total_amount"));
System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
System.out.println("买家付款时间: " + params.get("gmt_payment"));
System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
String tradeNo = params.get("out_trade_no");
String gmtPayment = params.get("gmt_payment");
String alipayTradeNo = params.get("trade_no");
// 更新订单状态为已支付,设置支付信息
LambdaQueryWrapper<DonationRecord> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DonationRecord::getPaymentNo, tradeNo);
DonationRecord record = recordService.getOne(queryWrapper);
record.setPayStatus("捐赠成功");
record.setPaymentTime(gmtPayment);
record.setAlipayTradeNo(alipayTradeNo);
recordService.updateById(record);
// 更新捐赠项目
DonationProject donationProject = ordersService.getById(record.getProjectId());
donationProject.setCurrentAmount(donationProject.getCurrentAmount().add(record.getAmount()));
donationProject.setDonationCount(donationProject.getDonationCount() + 1);
// 判断是否达到目标金额,如果达到则更新状态为已完成
if (donationProject.getCurrentAmount().compareTo(donationProject.getTargetAmount()) >= 0) {
donationProject.setStatus(1);
}
ordersService.updateById(donationProject);
}
}
}
/**
* 支付成功跳转前端页面接口
* @param request
* @param response
* @throws Exception
*/
@GetMapping("/redirect")
public void alipayRedirect(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 添加缓存控制头
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "0");
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
params.put(name, request.getParameter(name));
}
boolean signVerified = checkAlipaySignature(params);
if (signVerified) {
String orderNo = params.get("out_trade_no");
LambdaQueryWrapper<DonationRecord> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DonationRecord::getPaymentNo, orderNo);
DonationRecord record = recordService.getOne(queryWrapper);
if (record != null && "捐赠成功".equals(record.getPayStatus())) {
response.sendRedirect("http://localhost:8081/front/donation/detail/" + record.getProjectId());
} else {
response.sendRedirect("http://localhost:8081/404");
}
} else {
response.sendRedirect("http://localhost:8081/404");
}
}
private boolean checkAlipaySignature(Map<String, String> params) {
try {
String sign = params.get("sign");
String content = AlipaySignature.getSignCheckContentV1(params);
return AlipaySignature.rsa256CheckContent(
content,
sign,
aliPayConfig.getAlipayPublicKey(),
"UTF-8"
);
} catch (AlipayApiException e) {
e.printStackTrace();
return false;
}
}
}
在你后端代码中的拦截器上忽略支付宝接口的配置
//允许直接访问的接口
.excludePathPatterns(
"/sysUser/login",
"/sysUser/register",
"/file/**",
//swagger放行
"/swagger-ui/**",
"/swagger-ui.html",
"/swagger-resources/**",
"/images/**",
"/webjars/**",
"/v2/api-docs",
"/configuration/ui",
"/configuration/security",
"/doc.html",
"/alipay/**" //重点别忘了
);
如果是微服务项目,需要在网关处添加相应白名单,允许不鉴权。
按照上述配置之后,是可以成功进行沙箱支付。
希望本文对你进一步了解沙箱支付的相关逻辑有更大的帮助。
一入java深似海,争渡争渡!
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 程序员橙子
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果