首先需要说明的是,接入支付宝可以实现第三方授权,支付等功能。但是有些功能是需要进行签约的。而且创建一个应用之后需要进行审核,过程比较长,不利于开发进行测试。幸运的是,支付宝为我们提供了一个沙箱环境可以用来测试,而且里面把所有的权限都开启了,不需要进行签约操作。同时这个环境的逻辑与真实情况下一样,所以可以先用沙箱环境下的APPID把代码写好,然后等审核通过了之后,切换到真实的APPID。
这里主要讲如何在沙箱环境下实现微信支付的接入,真实环境和这个是差不多的。首先登陆支付宝开放平台:https://openhome.alipay.com/platform/home.htm
然后进入管理中心,找到开发服务下的研发服务
配置信息
这里的沙箱环境可以理解为,支付宝给我们提供了一个上线了的应用,具有真实的APPID等信息。
这里需要配置的就是公钥和私钥。
点设置后就会让你填RSA2密钥信息或者证书,这里选密钥就可以了。
我这里已经配置过了,没办法截图,就不截图了。
RSA2密钥可以用支付宝提供的工具来生成:https://opendocs.alipay.com/open/291/105971
注意额:安装路径不能有中文、空格.
工具安装好后,打开就是这样子的。
点击生成密钥就可以生成下面的一对公钥和私钥。
然后把公钥信息填到刚才的页面上就可以了。
然后其他的就可以不用设置了,可以开始写代码了。
代码实现
1、引入POM依赖
<!-- 使用thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- 自定义properties文件配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- alipay 支付宝SDk-->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.1.0</version>
</dependency>
<!-- fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
2、配置支付宝支付的相关Properties
创建一个Properties文件:
这个文件是自己创建的,不是alipay-jdk需要使用的,只是我们为了方便才创建的。主要就是放应用的一些隐私信息,比如:客户端私钥、支付宝公钥、APPID等。当然也可以不写这个文件,直接写死在代码上也是可以的。
# 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
alipay.app_id=2021000117612299
# 商户私钥,您的PKCS8格式RSA2私钥
alipay.privateKey=MIIEvgIBADANBgkqhkiG.........
# 支付宝公钥,查看地址:https://openhome.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
alipay.publicKey=MIIBIjANB.............
# 服务器异步通知页面路径需http://格式的完整路径,不能加?id=123这类自定义参数 必须是外网才能访问的页面
alipay.notify_url=http://ruv6tc.natappfree.cc
# 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数
alipay.return_url=http://localhost:8098/alipay/success
# 签名方式
alipay.sign_type=RSA2
# 字符编码格式
alipay.charset=utf-8
# 支付宝网关(这里是沙箱环境的网关,正式环境需要切换)
alipay.gatewayUrl=https://openapi.alipaydev.com/gateway.do
# 支付宝网关
alipay.logPath="C:\\"
创建一个Properties主动配置类:
让Spring自动帮我们注入值,就可以不用@Value注解一个一个的注入了。
@Component
@PropertySource(value = "classpath:alipay.properties")
@ConfigurationProperties(prefix = "alipay")
@Data
public class AlipayProperties {
private String app_id;
private String privateKey;
private String publicKey;
private String notify_url;
private String return_url;
private String sign_type;
private String charset;
private String gatewayUrl;
private String logPath;
}
3、创建一个订单类
根据支付宝接口协议,这里面的字段,必须使用下划线,不能进行自定义。因为后面需要把这个对象序列化后传给支付宝接口进行支付。
@Data
public class AlipayOrder {
/**
* 商户订单号,必填
*
*/
private String out_trade_no;
/**
* 订单名称,必填
*/
private String subject;
/**
* 付款金额,必填
* 根据支付宝接口协议,必须使用下划线
*/
private String total_amount;
/**
* 商品描述,可空
*/
private String body;
/**
* 超时时间参数
*/
private String timeout_express= "5m";
/**
* 产品编号
*/
private String product_code= "FAST_INSTANT_TRADE_PAY";
}
4、编写支付方法
这里我就只粘贴核心的部分了。自己写一个Service就可以了。
@Autowired
AlipayProperties alipayProperties;
@Override
public String pay(AlipayOrder alipayOrder) throws AlipayApiException {
// 1、获得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(
alipayProperties.getGatewayUrl(),
alipayProperties.getApp_id(),
alipayProperties.getPrivateKey(),
"json",
alipayProperties.getCharset(),
alipayProperties.getPublicKey(),
alipayProperties.getSign_type());
// 2、设置请求参数
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
// 页面跳转同步通知页面路径(就是支付成功之后跳转的页面)
alipayRequest.setReturnUrl(alipayProperties.getReturn_url());
// 服务器异步通知页面路径
alipayRequest.setNotifyUrl(alipayProperties.getNotify_url());
//账户订单号
String out_trade_no = System.currentTimeMillis()+ UUID.randomUUID().toString();
alipayOrder.setOut_trade_no(out_trade_no);
// 封装参数
alipayRequest.setBizContent(JSON.toJSONString(alipayOrder));
// 3、请求支付宝进行付款,并获取支付结果
String result = alipayClient.pageExecute(alipayRequest).getBody();
// 返回付款信息
return result;
}
5、Controller
@Controller
@RequestMapping("/alipay")
public class AlipayController {
@Autowired
AlipayService alipayService;
/**
* 支付
* @param alipayOrder
* @return {@link String}
* @author lianhong
* @date 2021/2/20 19:01
*/
@PostMapping("/pay")
@ResponseBody
public String pay(AlipayOrder alipayOrder) throws AlipayApiException {
return alipayService.pay(alipayOrder);
}
/**
* 支付成功后的回调
* @param
* @return {@link String}
* @author lianhong
* @date 2021/2/20 19:02
*/
@GetMapping("/success")
public String paySuccess(){
return "success";
}
}
6、页面
这里需要提供两个页面,一个是用来提交登订单信息的,一个是登录成功之后的回调页面,这里是不能用PostMAN来测试的,因为需要进行重定向。
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<hr>
<div class="form-container">
<form id="form" action="/alipay/pay" method="post">
*订单名称 :<input type="text" name="subject" value="Easy Mock订单"><br>
*付款金额 :<input type="text" name="total_amount" value="1000" ><br>
*描述 :<input type="text" name="body" value="巴拉巴拉巴拉"><br>
<input type="submit" value="支付宝支付" >
</form>
</div>
</body>
<style>
.form-container {
padding-top:10px;
}
input {
margin:10px;
}
</style>
</html>
success.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>支付成功</title>
</head>
<body>
<h1>支付成功</h1>
</body>
</html>
7、测试
注意:这里的测试不能用真实的支付宝来测试。支付宝提供了沙箱版本的支付宝可以下载。
下载沙箱支付宝(扫这二维码):
账户查看地址:https://openhome.alipay.com/platform/appDaily.htm?tab=account
访问:localhost:8098
然后就会出现订单提交页面
然后就可以提交支付了。BUT,这个时候很可能会碰到这个尴尬的问题,支付存在钓鱼风险。这个时候可以尝试清除历史浏览记录或者换一个浏览器尝试。
正常的话是会出现以下界面的,然后正常支付就行了。
然后就没然后了,可以愉快的等待自己申请的应用上线之后,切换到正式环境上。