在本篇文章中你将学会,将引入支付宝沙箱环境,在此之前你需要拥有
- 支付宝开发平台创建沙箱应用
- 公网可以访问的 url: 内网穿透 或 购买服务器
1. 配置沙箱环境
首先进入 支付宝开放平台-沙箱 进入沙箱应用页面, 这里面有几个重点关注的参数,如下图
首先需要配置 “接口加签方式”,选择自定义密钥,然后下载“支付宝密钥生成器 / 支付宝开放平台密钥生成器”
选择 RSA2 加密算法并生成密钥,我们会得到如下的 “应用公钥” 和 “应用私钥”
记得保存这些密钥。把“应用公钥”复制到沙箱平台,并生成“支付宝公钥”,如下图
这样我们就得到了三个密钥:“应用公钥”,“应用私钥”,“支付宝公钥”。后续配置中我们将使用“应用私钥”和“支付宝公钥”。
接下来配置支付完成后的 “授权回调地址” (跳转页面,returnUrl) 和 “应用网关地址” (回调接口,notifyUrl)
p.s. 这里的 url 需要公网地址,即支付宝回调时能正确访问到的地址。可以安装内网穿透软件或购买服务器获取公网ip。
完成上述操作后,我们得到一下几个关键参数
- appId
- 支付宝公钥
- 应用私钥
- 支付宝网关地址
- 应用网关地址
- 授权回调地址
这几个参数将在后端配置中用到。
2. 公网 ip / 内网穿透
这里我购买了一个服务器实例,因此可以获取到公网ip。然后用 nginx 在 docker 上部署了几个简单的页面在服务器实例上。
nginx 部署教程参考: # Nginx docker 部署简单教程
内网穿透教程参考: #【保姆级教程】免费内网穿透,手把手搭建,三步搞定
3. Java 后端配置
接下来进行 java 后端配置,首先引入 alipay 的 SDK。最新的 sdk 请 跳转 maven 仓库
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.40.237.ALL</version>
</dependency>
引入 sdk 后,我们将主要用到以下参数
- appId
- 支付宝公钥 (alipayPublicKey)
- 应用私钥 (privateKey)
- 支付宝网关地址 (gatewayUrl)
- 应用网关地址 (notifyUrl)
- 授权回调地址 (returnUrl)
在 yaml 中配置如下参数
alipay:
appId: 应用Id
privateKey: 应用私钥
alipayPublicKey: 支付宝公钥
notifyUrl: 应用网关地址,如,http://<公网URL>/api/alipay/notify
returnUrl: 授权回调地址,如,http://<公网URL>/test.html
signType: RSA2
charset: utf-8
gatewayUrl: 支付宝网关地址
为了读取这些配置,我们创建 AlipayProperties.java
@ConfigurationProperties(prefix = "alipay")
@Configuration
@Data
public class AlipayProperties {
private String appId;
private String privateKey;
private String alipayPublicKey;
private String notifyUrl;
private String returnUrl;
private String gatewayUrl;
private String charset;
private String signType;
}
为了演示支付操作,我们创建一个简单的订单类,如,Order.java
public class Order implements Serializable {
private static final long serialVersionUID = 1L;
// 订单号
private Long id;
// 用户Id
private Long userId;
// 商品Id
private Long itemId;
// 订单价格
private BigDecimal price;
}
接下来我们通过 alipay sdk 创建支付客户端并创建支付页面。我们将得到一个关于支付的表单html文本代码, 我们可以将改代码嵌入到前端页面上。
public class AlipayPayment{
private final AlipayProperties properties;
public AlipayPayment(AlipayProperties alipayProperties) {
this.properties = alipayProperties;
}
public String pay(Order order) throws AlipayApiException {
// 1. 根据配置创建一个支付客户端
AlipayClient client = new DefaultAlipayClient(
properties.getGatewayUrl(),
properties.getAppId(),
properties.getPrivateKey(),
"json",
properties.getCharset(),
properties.getAlipayPublicKey(),
properties.getSignType()
);
// 2.创建支付请求页面
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setReturnUrl(properties.getReturnUrl());
alipayRequest.setNotifyUrl(properties.getNotifyUrl());
AlipayTradePayModel model = new AlipayTradePayModel();
model.setOutTradeNo(order.getId().toString());
model.setTotalAmount(order.getPrice().toString());
model.setSubject("订单标题");
model.setBody("主体信息");
model.setProductCode("FAST_INSTANT_TRADE_PAY");
model.setTimeoutExpress("15m");
alipayRequest.setBizModel(model);
AlipayTradePagePayResponse alipayTradePagePayResponse = client.pageExecute(alipayRequest);
return alipayTradePagePayResponse.getBody(); // 返回的是一个表单,可以配合前端,将该表单嵌入到某个显示块内
}
}
我们创建 Order 对象并调用 pay 方法,可以得到一个表单文本代码。我们将该文本放到一个 payment.html 上,并上传到
nginx 的 html 相关目录里面,然后就可以通过访问 xxx/payment.html 可以得到如下结果
我们把“沙箱账号”里面的买家账号密码填写上去
最后返回我们设定好的跳转界面 returnUrl
总结
参考: 支付宝 SDK