前言:最近开发支付宝支付功能,总结一下做个分享
官方文档:https://opendocs.alipay.com/apis
支付宝沙箱地址: https://openhome.alipay.com/platform/appDaily.htm?tab=info
支付宝支付流程:
- 准备工作:获取支付宝沙箱数据(APPID,支付宝网关,RSA2秘,沙箱支付账号等)
- 集成SpringBoot,使用Java代码发起支付请求
- 支付宝收到支付请求后,返回HTML代码片段,用于前端展示二维码
- 扫码支付成功后,支付宝发送同步、异步通知请求,同步、异步通知路径可在配置文件中进行配置
- 收到异步通知结果后,进行验签,验签通过,返回成功信息通知支付宝不在进行异步通知
- 此时支付宝支付流程完成,调用支付宝查询接口,确认支付成功
一、获取支付宝沙箱数据
打开上述沙箱地址,获取沙箱配置,查看下图信息
二、集成SpringBoot,使用Java代码发起支付请求
1、在pom.xml文件添加支付宝依赖
<!-- 支付宝支付 -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.7.26.ALL</version>
</dependency>
2、在项目中新建一个支付宝工具类
public class AlipayConfig {
// ↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
public static String app_id = "";
// 商户私钥,您的PKCS8格式RSA2私钥
public static String merchant_private_key = "";
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
public static String alipay_public_key = "";
// 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
// 这里需要配置支付宝回调的后端路径,必须要外网可以访问
public static String notify_url = "http://localhost:8080/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp";
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
// TODO 这里需要配置支付宝回调的前端路径,必须要外网可以访问
public static String return_url = "http://localhost:8080/alipay.trade.page.pay-JAVA-UTF-8/return_url.jsp";
// 签名方式
public static String sign_type = "RSA2";
// 字符编码格式
public static String charset = "UTF-8";
// 支付宝网关
public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
// 日志路径
public static String log_path = "C:\\";
// ↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
/**
* 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
*
* @param sWord 要写入日志里的文本内容
*/
public static void logResult(String sWord) {
FileWriter writer = null;
try {
writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis() + ".txt");
writer.write(sWord);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3、定义Service
public interface AlipayService {
/**
* 发起支付
* @param outTradeNo 订单编号(唯一)
* @param totalAmount 订单价格
* @param subject 商品名称
*/
String goPay(String outTradeNo,BigDecimal totalAmount,String subject) throws Exception;
/**
* 交易查询
* @param outTradeNo 订单编号(唯一)
*/
String query(String outTradeNo) throws AlipayApiException;
/**
* 交易关闭
* @param outTradeNo订单编号(唯一)
*/
String close(String outTradeNo) throws AlipayApiException;
}
4、实现ServiceImpl,发起支付请求,交易查询等
public class AlipayServiceImpl implements AlipayService {
@Autowired
private RechargeDetailService rechargeDetailService;
@Override
public String goPay(String outTradeNo, BigDecimal totalAmount, String subject) throws Exception {
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id,
AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key,
AlipayConfig.sign_type);
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
/** 同步通知,支付完成后,支付成功页面 */
alipayRequest.setReturnUrl(AlipayConfig.return_url);
/** 异步通知,支付完成后,需要进行的异步处理 */
alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
alipayRequest.setBizContent("{\"out_trade_no\":\"" + outTradeNo + "\"," + "\"total_amount\":\"" + totalAmount
+ "\"," + "\"subject\":\"" + subject + "\"," + "\"body\":\"付款\"," + "\"timeout_express\":\"15m\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
/** 转换格式 */
String form = "";
form = alipayClient.pageExecute(alipayRequest).getBody();
return form;
}
@Override
public String query(String outTradeNo) throws AlipayApiException {
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id,
AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key,
AlipayConfig.sign_type);
AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();
/** 请求接口 */
alipayRequest.setBizContent("{\"out_trade_no\":\"" + outTradeNo + "\"," + "\"trade_no\":\"" + "" + "\"}");
/** 转换格式 */
String result = alipayClient.execute(alipayRequest).getBody();
return result;
}
@Override
public String close(String outTradeNo) throws AlipayApiException {
AlipayTradeCloseRequest alipayRequest = new AlipayTradeCloseRequest();
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id,
AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key,
AlipayConfig.sign_type);
alipayRequest.setBizContent("{\"out_trade_no\":\"" + outTradeNo + "\"," + "\"trade_no\":\"" + "" + "\"}");
String result = alipayClient.execute(alipayRequest).getBody();
return result;
}
}
5、创建支付宝controller
public class AlipayController {
@Autowired
private AlipayService alipayService;
/**
* 订单支付
*/
@GetMapping("goPay")
public Map<Object, Object> goPay() throws Exception{
/** 模仿数据库,从后台调数据*/
String outTradeNo = "202101010001";
BigDecimaltotalAmount = new BigDecimal(10000);
String subject = "苹果12";
String pay = alipayService.goPay(outTradeNo, totalAmount, subject);
Map<Object, Object> pays = new HashMap<>();
pays.put("pay", pay);
return pays;
}
/**
* 交易查询
*/
@PostMapping("aipayQuery")
public Result<Object> alipayQuery() throws Exception{
/**调取支付订单号*/
String outTradeNo = "13123";
String query = alipayService.query(outTradeNo);
Object json = JSONObject.toJSON(query);
/*JSONObject jObject = new JSONObject();
jObject.get(query);*/
return Result.success(json);
}
/**
* 交易关闭
* @throws AlipayApiException
*/
@PostMapping("alipayclose")
public Result<Object> alipaycolse() throws AlipayApiException{
/** 调取数据*/
String outTradeNo = "13123";
String close = alipayService.close(outTradeNo);
return Result.success(close);
}
/**
* 异步通知支付结果
*
* @param request
* @return String
* @throws AlipayApiException
* @throws ParseException
*/
@PostMapping("/callBack")
public String alipayNotify(HttpServletRequest request) throws Exception {
// 获取支付宝的请求信息
Map<String, String> map = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
if(requestParams.isEmpty()) {
return "failure";
}
// 将 Map<String,String[]> 转为 Map<String,String>
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] + ",";
}
map.put(name, valueStr);
}
// 验签
boolean signVerified = AlipaySignature.rsaCheckV1(map, AlipayConfig.alipay_public_key, AlipayConfig.charset,
AlipayConfig.sign_type);
// 验签通过
if (signVerified) {
//支付成功后进行操作
}
return "failure";
}
}
到此SpringBoot整合支付宝扫码支付,就完成了
有什么问题大家多互相交流^_^