1、支付宝支付前期的准备工作(沙箱模式,因为没有商家认证,但是和真实环境之差极小,后期很容易修改)
1、进入https://open.alipay.com/,登陆,认证身份为自研开发者
2、下载密钥生成器生成密钥,同时里面附带了sdk,操作很简单,东西已经卸载掉了,就不截图了。sdk做代码时需要用到。
链接:https://pan.baidu.com/s/1XHbsZ4kWFEf69dyLXkwlIA
提取码:8qop
3、修改支付接口的接口加签方式,将生成的支付宝公钥保存下来
2、编码阶段
4、先引入第二步中下载的sdk,虽然是maven项目,但是我选择引入本地sdk。具体方法可以在我的另外一篇博客中找到。https://blog.csdn.net/weixin_45501830/article/details/105015005
5、创建支付宝接口的配置参数类(1,2在图上位置,3是之前自己生成的私钥)
package com.xjj.util;
/**
* 用来设置支付宝的相关参数
* @author 徐敬杰
* @Date 2020/3/22 15:34
*/
public class AlipayConfig {
/**
* 应用的AppId
*/
public static String app_id = "1";
/**
* 支付宝公钥
*/
public static String alipay_public_key = "2";
/**
* 商户私钥,您的PKCS8格式RSA2私钥
*/
public static String merchant_private_key = "3";
/**
* 这个我暂时不知道能有什么用处,可以随便填写
*/
public static String notify_url = "http://工程公网访问地址/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp";
/**
* 订单提交成功以后,我们跳转到哪个页面
*/
public static String return_url = "http://工程公网访问地址/alipay.trade.page.pay-JAVA-UTF-8/notify_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 = "D:\\";
}
6、编写支付请求
1、前端页面
<%--
Created by IntelliJ IDEA.
User: 徐敬杰
Date: 2020/3/22
Time: 16:12
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/interface/alipay/pay" method="post">
商品订单号<input type="text" name="no"><br>
商品名称<input type="text" name="name"><br>
金额<input type="text" name="price"><br>
商品描述<input type="text" name="describe"><br>
<input type="submit" value="支付订单">
</form>
</body>
</html>
2、controller层
/**
* description: 二阶段,输入完商品信息以后,提交表单过来,然后自动提交该表单,跳转到支付宝的平台。同时这个订单号一定不能被用户用过了
* time: 2020/3/23日16:21
* params: [request, response]
* returns: void
*/
@RequestMapping(value = "/alipay/pay",method = {RequestMethod.POST})
public void pay(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException {
//1、获取商户的属性,这样才可以找到商户
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
//2、设置回调地址
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setReturnUrl(AlipayConfig.return_url);
alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
//3、这四项就是表单提交的信息,也是订单的基本信息
String no = new String(request.getParameter("no").getBytes("ISO-8859-1"),"UTF-8");
String name = new String(request.getParameter("name").getBytes("ISO-8859-1"),"UTF-8");
String price = new String(request.getParameter("price").getBytes("ISO-8859-1"),"UTF-8");
String describe = new String(request.getParameter("describe").getBytes("ISO-8859-1"),"UTF-8");
//4、存入订单信息。即out_trade_no、total_amount、subject、body。
//5、设置可选项,product_code。其中的属性可以在官方文档中查询到
alipayRequest.setBizContent("{\"out_trade_no\":\""+ no +"\","
+ "\"total_amount\":\""+ price +"\","
+ "\"subject\":\""+ name +"\","
+ "\"body\":\""+ describe +"\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
//6、生成相对应的表单信息
String result = alipayClient.pageExecute(alipayRequest).getBody();
//7、返回这个表单,可以被自动提交并且提交到支付页面
response.setContentType("text/html;charset=utf-8");
response.getWriter().println(result);
response.getWriter().close();
}
7、编写查询请求
1、前端页面
<%--
Created by IntelliJ IDEA.
User: 徐敬杰
Date: 2020/3/22
Time: 16:12
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/interface/alipay/query" method="post">
商户订单号<input type="text" name="person_no"><br>
淘宝订单号<input type="text" name="alipay_no"><br>
<input type="submit" value="查询订单">
</form>
</body>
</html>
2、controller层
/**
* description: 二阶段,输入完订单号以后,提交表单过来,然后自动提交该表单,跳转到页面上查看json
* time: 2020/3/23日18:41
* params: [request, response]
* returns: java.lang.String
*/
@RequestMapping(value = "/alipay/query",produces = "application/json;charset=utf-8",method = {RequestMethod.POST})
@ResponseBody
public String query(HttpServletRequest request) throws AlipayApiException, IOException {
//1、获取商户的属性,这样才可以找到商户
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
//2、设置请求的request
AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();
//3、填写商户订单号,这是相对于商户来说的,因为商户的信息刚刚已经设置好了,所以存在唯一性。
String person_no = new String(request.getParameter("person_no").getBytes("ISO-8859-1"),"UTF-8");
//3、也可以填写支付宝交易号,这是对于普通用户而言的,他们只能拿到支付宝交易号
String alipay_no = new String(request.getParameter("alipay_no").getBytes("ISO-8859-1"),"UTF-8");
//4、将商户订单号或者支付宝交易号保存下来
alipayRequest.setBizContent("{\"out_trade_no\":\""+ person_no +"\","+"\"trade_no\":\""+ alipay_no +"\"}");
//5、获得相对应的查询结果,是一个json串
String result = alipayClient.execute(alipayRequest).getBody();
//6、返回这个json串
return result;
}
8、退款请求
1、前端页面
<%--
Created by IntelliJ IDEA.
User: 徐敬杰
Date: 2020/3/23
Time: 18:56
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form method="post" action="${pageContext.request.contextPath}/interface/alipay/refund">
商户订单号:<input type="text" name="person_no"><br>
支付宝交易号:<input type="text" name="alipay_no"><br>
退款金额:<input type="text" name="price"><br>
退款原因:<input type="text" name="reason"><br>
退款请求号:<input type="text" name="refund_no"><br>
<input type="submit" value="订单退款">
</form>
</body>
</html>
2、controller层
/**
* description: 二阶段,输入完退款单详细信息以后,提交表单过来,然后自动提交该表单,跳转到页面上查看json
* time: 2020/3/23日19:29
* params: [request]
* returns: java.lang.String
*/
@RequestMapping(value = "/alipay/refund",produces = "application/json;charset=utf-8",method = {RequestMethod.POST})
@ResponseBody
public String refund(HttpServletRequest request) throws UnsupportedEncodingException, AlipayApiException {
//1、获取商户的信息
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
//2、设置请求的request
AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();
//3、获取退款单的详细信息
//商户订单号,商户网站订单系统中唯一订单号,可以通过加上商户信息来找到这笔订单。
String person_no = new String(request.getParameter("person_no").getBytes("ISO-8859-1"),"UTF-8");
//支付宝订单号,可以通过这个来找到这笔订单。与商品订单号2选1
String alipay_no = new String(request.getParameter("alipay_no").getBytes("ISO-8859-1"),"UTF-8");
//退款金额,到底退多少钱。可以通过与退款单号一起查询出退款的详细信息
String price = new String(request.getParameter("price").getBytes("ISO-8859-1"),"UTF-8");
//退款单号。
String refund_no = new String(request.getParameter("refund_no").getBytes("ISO-8859-1"),"UTF-8");
//退款的理由。
String reason = new String(request.getParameter("reason").getBytes("ISO-8859-1"),"UTF-8");
//4、将这些信息写到request中
alipayRequest.setBizContent("{\"out_trade_no\":\""+ person_no +"\","
+ "\"trade_no\":\""+ alipay_no +"\","
+ "\"refund_amount\":\""+ price +"\","
+ "\"refund_reason\":\""+ reason +"\","
+ "\"out_request_no\":\""+ refund_no +"\"}");
//5、发起退款请求,result是一个json串,即退款信息。
String result = alipayClient.execute(alipayRequest).getBody();
//6、返回json信息到界面上,容易观看
return result;
}
9、退款查询请求
1、前端页面
<%--
Created by IntelliJ IDEA.
User: 徐敬杰
Date: 2020/3/23
Time: 19:07
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form method="post" action="${pageContext.request.contextPath}/interface/alipay/refundQuery">
商户订单号:<input type="text" name="person_no"><br>
支付宝订单号:<input type="text" name="alipay_no"><br>
退款单号:<input type="text" name="refund_no"><br>
<input type="submit" value="退款查询">
</form>
</body>
</html>
2、controller层
/**
* description: 二阶段,输入完退款查询详细信息以后,提交表单过来,然后自动提交该表单,跳转到页面上查看json
* time: 2020/3/23日19:30
* params: [request]
* returns: java.lang.String
*/
@RequestMapping(value = "/alipay/refundQuery",produces = "application/json;charset=utf-8",method = {RequestMethod.POST})
@ResponseBody
public String refundQuery(HttpServletRequest request) throws UnsupportedEncodingException, AlipayApiException {
//1、获取商户的基本信息
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
//2、获取请求的request
AlipayTradeFastpayRefundQueryRequest alipayRequest = new AlipayTradeFastpayRefundQueryRequest();
//3、获取详细信息
//商户订单号,商户网站订单系统中唯一订单号,可以和商户信息搭配形成唯一性。
String person_no = new String(request.getParameter("person_no").getBytes("ISO-8859-1"),"UTF-8");
//支付宝交易号。和商户订单号之间只需要填写一个就行了
String alipay_no = new String(request.getParameter("alipay_no").getBytes("ISO-8859-1"),"UTF-8");
//请求退款接口时,传入的退款请求号,如果在退款请求时未传入,则该值为创建交易时的外部交易号,必填
String refund_no = new String(request.getParameter("refund_no").getBytes("ISO-8859-1"),"UTF-8");
//4、将详细信息纳入到request中
alipayRequest.setBizContent("{\"out_trade_no\":\""+ person_no +"\","
+"\"trade_no\":\""+ alipay_no +"\","
+"\"out_request_no\":\""+ refund_no +"\"}");
//5、发起退款查询请求,查询得到的结果是一串json串
String result = alipayClient.execute(alipayRequest).getBody();
//6、返回这串json串到页面给用户
return result;
}
10、关闭请求
1、前端请求
<%--
Created by IntelliJ IDEA.
User: 徐敬杰
Date: 2020/3/22
Time: 16:12
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/interface/alipay/close" method="post">
商户订单号<input type="text" name="person_no"><br>
淘宝订单号<input type="text" name="alipay_no"><br>
<input type="submit" value="关闭订单">
</form>
</body>
</html>
2、controller层
/**
* description: 二阶段,一定要在订单已经生成,并且已经在用户准备付钱的界面的时候才能使用,否则无效的
* time: 2020/3/23日19:31
* params: [request]
* returns: java.lang.String
*/
@RequestMapping(value = "/alipay/close",produces = "application/json;charset=utf-8",method = {RequestMethod.POST})
@ResponseBody
public String close(HttpServletRequest request) throws AlipayApiException, UnsupportedEncodingException {
//1、获取商户信息
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
//2、获取request
AlipayTradeCloseRequest alipayRequest = new AlipayTradeCloseRequest();
//3、获取关闭请求的详细信息
//商户订单号,商户网站订单系统中唯一订单号。可以和商户信息搭配使用。
String person_no = new String(request.getParameter("person_no").getBytes("ISO-8859-1"),"UTF-8");
//支付宝交易号。和商户订单号取一个就行了。
String alipay_no = new String(request.getParameter("alipay_no").getBytes("ISO-8859-1"),"UTF-8");
//4、将详细信息纳入request中去
alipayRequest.setBizContent("{\"out_trade_no\":\""+ person_no +"\"," +"\"trade_no\":\""+ alipay_no +"\"}");
//5、发起关闭请求,返回一个json字符串
String result = alipayClient.execute(alipayRequest).getBody();
//6、显示在界面上,方便用户查看
return result;
}