一、打开支付宝开放平台
二、点击右上角的控制台
三、滑到最底下,找到沙箱
进去之后,可以看到沙箱应用、沙箱账号、沙箱工具,可以下载沙箱工具,后面可以进行模拟支付。沙箱账号可以用来登录沙箱工具,沙箱应用里面的密钥、网关等,后面细说。
四、回到支付宝开放平台首页,滑到底下,找到开发接入中的网页/移动应用开发
点进去,找到开发支持中的开发工具
点进去,找到服务端SDK
里面有多种语言可以选择,选择java之后,选择通用版
里面会教你如何实现各种功能(包括支付功能)
五、代码实现
工具: idea、springboot 3.0版本以上
(一)、导入相关依赖
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.34.0.ALL</version>
</dependency>
(二)、配置configure
public class AlipayConfig {
//ServiceURL 设置网关
public static String ServiceUrl="https://openapi-sandbox.dl.alipaydev.com/gateway.do";
//APP支付宝支付业务:app_id
public static String app_id = "9021000136643502";
// 商户的私钥,使用支付宝自带的openssl工具生成。
public static String private_key = "";
// 应用的公钥,无需修改该值
public static String ali_public_key = "";
// 支付宝的公钥,去open.alipay.com对应应用下查看
public static String zfb_public_key= "";
// 字符编码格式 目前支持 gbk 或 utf-8
public static String input_charset = "UTF-8";
//异步回调
public static String notify_url="http://1ca86894.r8.cpolar.cn/notify";
//同步回调
public static String return_url="http://1ca86894.r8.cpolar.cn/su";
(三)、controller类
import cn.hutool.core.lang.UUID;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.cth.springThymeleaf.config.AlipayConfig;
import com.cth.springThymeleaf.mapper.OptMapper;
import com.cth.springThymeleaf.pojo.DiDan;
import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.IOException;
import java.util.List;
@Slf4j
@Controller
public class payController {
@Autowired
private OptMapper optMapper;
@ResponseBody //将payController的方法返回的对象通过适当的转换器转换为指定的格式,写入到
//response对象的body区
@RequestMapping("/alipay")
@ApiOperation("zfbsx")
public String ailipay(Model model,HttpServletRequest r1, HttpServletResponse servletResponse) throws AlipayApiException, IOException {
// 拼装客户端
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.ServiceUrl, AlipayConfig.app_id,
AlipayConfig.private_key, "json", AlipayConfig.input_charset, AlipayConfig.zfb_public_key, "RSA2");
// 支付宝 request
// String total=r1.getParameter("total");
// String subject1=r1.getParameter("subject");
// AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
// String storeId = "1008611";
// AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
// r1.setAttribute("out_trade_no", "1999334445545");
// model.setOutTradeNo("1999334445545");
// model.setSubject(subject1);
// model.setTotalAmount(total);
// model.setStoreId(storeId);
// model.setTimeoutExpress("5m");
// //商品订单号码 out_trade_no 商户订单号,64个字符以内、只能包含字母、数字、下划线;需保证在商户端不重复
// model.setOutTradeNo(UUID.randomUUID().toString());
// request.setBizModel(model);
// request.setReturnUrl(AlipayConfig.return_url);
// request.setNotifyUrl(AlipayConfig.notify_url);
//
// String form=null;
// form = alipayClient.pageExecute(request).getBody();
// //request.set
// // 支付宝 response 这里已经对相应结果解析了。返回值
// AlipayTradePrecreateResponse response = alipayClient.execute(request);
// System.out.println(response.getOutTradeNo());
try {
servletResponse.setContentType("text/html;charset="
+ AlipayConfig.input_charset);
servletResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
servletResponse.getWriter().flush();
servletResponse.getWriter().close();
}catch (Exception e){
e.printStackTrace();
}
// System.out.println(form);
// if (response.isSuccess()) {
// String code = response.getQrCode();
// System.out.println(response.getOutTradeNo());
// //二维码数据流
// System.out.println(code);
// ZxingUtils.writeToServletFile(code, servletResponse);
// } else {
// System.out.println("调用失败");
// }
//商户订单号,商户网站订单系统中唯一订单号,必填
String out_trade_no = UUID.randomUUID().toString();
//付款金额,必填
String total_amount = "520";
//订单名称,必填
String subject = "aiq";
//商品描述,可空
String body = "aiq";
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
//同步回调
alipayRequest.setReturnUrl(AlipayConfig.return_url);
//异步回调
alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
+ "\"total_amount\":\""+ total_amount +"\","
+ "\"subject\":\""+ subject +"\","
+ "\"body\":\""+ body +"\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
if(id1.size()>0){
return alipayClient.pageExecute(alipayRequest).getBody();
}else {
return "你已付款";
}
}
其中,异步回调的作用是验证你的支付宝开放平台的密钥、账号等。同步回调的作用是在异步回调的验证正确之后,返回你设定的页面,同时,操作数据库。异步回调需要通过公网或内网穿透的方式告诉支付宝开发平台,支付宝开放平台方能成功进行同步回调你设定的页面。
(四)异步回调类
import com.alipay.api.internal.util.AlipaySignature;
import com.cth.springThymeleaf.config.AlipayConfig;
import com.cth.springThymeleaf.mapper.OptMapper;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@Slf4j
@Controller
public class Success extends HttpServlet {
/**
* @Author : flc
* @Description 支付回掉URL
* @Date 2024/6/9 14:31
* @Param [licensePlateNumber]
* @Return java.lang.String
**/
@Autowired
private OptMapper optMapper;
@RequestMapping("/notify")
public void aliPayCallBack(HttpServletResponse r1, HttpServletRequest request){
try {
Map<String,String> params = new HashMap<String,String>();
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] + ",";
}
//乱码解决,这段代码在出现乱码时使用。
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}
request.setCharacterEncoding("utf-8");
r1.setCharacterEncoding("utf-8");
r1.setHeader("Content-Type", "text/html;charset=utf-8");
boolean flag = AlipaySignature.rsaCheckV1(params, AlipayConfig.zfb_public_key, AlipayConfig.input_charset,"RSA2");
String trade_status = request.getParameter("trade_status");// 交易状态
String total_amount = request.getParameter("total_amount");//交易金额
String body=request.getParameter("body"); //订单内容
System.out.println(body);
log.info("交易状态:{}",trade_status);
String order_no = request.getParameter("out_trade_no"); // 获取订单号
log.info("回调过程获取的订单编号:{}" ,order_no);
// 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
if (flag&&body!=null) {// 验证成功
System.out.println("支付宝订单支付成功!");
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("支付异常^-^");
}
}
(五)同步回调的网页可以自己设定。
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class SuccessController {
@RequestMapping("/su")
public String success() {
return "su";
}
}
返回成功页面:
<!doctype html>
<html lang="ch">
<meta content="text/html" charset="UTF-8">
<head>
<title>Success</title>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
</head>
<body>
<h1>支付成功!</h1>
<div>请刷新!</div>
</body>
</html>
最后,可以通过在支付宝开放平台的开发工具哪里使用支付宝密钥工具自己生成密钥
使用支付宝开发平台密钥工具生成的密钥需上传到到开放平台才能生效。
Cpolar下载网址:https://www.cpolar.com/
Cpolar使用:
(一)、来到cpolar的已安装文件位置,键盘按住shift,鼠标右键,选择 打开终端
在终端输入:cpolar.exe http 8080 (8080为端口号,可以自己设置)
其中,http://1ca86894.r8.cpolar.cn 为内网穿透网址