支付宝沙箱使用之路

可以参考的网站

https://open.alipay.com/develop/sandbox/app

https://opendocs.alipay.com/common/02kkv7

https://opendocs.alipay.com/common/02kipl

https://opendocs.alipay.com/open/204/106450

https://open.alipay.com/api/detail?code=I1080300001000041313#api-detail-content

https://zhuanlan.zhihu.com/p/425893989

 

预处理

自定义密钥

https://opendocs.alipay.com/common/02kipl

公钥模式默认不启用,点击上面的链接获取密钥生成的exe生成密钥

应用公钥复制给网页对应窗口,会获取到支付宝公钥,启用完成。

下载沙箱版app

开发

阿里demo:https://gw.alipayobjects.com/os/bmw-prod/a526522f-37a6-4a8e-9abc-d22cf240cbbd.zip

集成

1
2
3
4
5
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-easysdk</artifactId>
<version>2.2.0</version>
</dependency>

PS.看到有人用下面这个依赖,但是更多的是下面那个(以及我)

下面这个来自这里:https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java

1
2
3
4
5
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.16.2.ALL</version>
</dependency>

好像都可以,但是下面这个要全一些

application.yml配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 配置alipay数据
alipay:
# 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
APPID: 沙箱中的APPID
# 商户私钥,您的PKCS8格式RSA2私钥
RSA_PRIVATE_KEY: 应用私钥
# 支付宝支付公钥
ALIPAY_PUBLIC_KEY: 支付宝公钥(通过应用公钥换取的值)
# 异步回调地址 必须外网能够访问(这里需要配置内网穿透),当支付成功后会调用该API
notify_url: http://hpzekg.natappfree.cc/alipay/pay/callback
# 同步回调地址 必须外网能够访问
return_url:
# 网关(注意沙箱网关和正式网关的区别,这里填写沙箱环境下的网关)
URL: https://openapi.alipaydev.com/gateway.do
# 编码
CHARSET: UTF-8
# 返回数据格式
FORMAT: json
# 日志地址
log_path: /log
# RSA2
SIGNTYPE: RSA2

config:我的配置用的是.properties格式的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package com.zwn.trainserverspringboot.config;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Component
public class AlipayConfig {

/**
* 商户appid
*/
@Value("${alipay.APPID}")
public String APPID;

/**
* 私钥 pkcs8格式的
*/
@Value("${alipay.RSA_PRIVATE_KEY}")
public String RSA_PRIVATE_KEY;
/**
* 服务器异步通知页面路径
* 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
*/
@Value("${alipay.notify_url}")
public String notify_url;

/**
* 页面跳转同步通知页面路径
* 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,
* 必须外网可以正常访问 商户可以自定义同步跳转地址
*/
@Value("${alipay.return_url}")
public String return_url;

/**
* 请求网关地址
*/
@Value("${alipay.URL}")
public String URL;

/**
* 编码
*/
@Value("${alipay.CHARSET}")
public String CHARSET;

/**
* 返回格式
*/
@Value("${alipay.FORMAT}")
public String FORMAT;

/**
* 支付宝公钥
*/
@Value("${alipay.ALIPAY_PUBLIC_KEY}")
public String ALIPAY_PUBLIC_KEY;

/**
* 日志记录目录定义在 logFile 中
*/
@Value("${alipay.log_path}")
public String log_path;

/**
* RSA2
*/
@Value("${alipay.SIGNTYPE}")
public String SIGNTYPE;

}

其余代码可以参考官方项目样例。

tips与踩的一些坑

1
model.setOutTradeNo( ..... );

这个设置的值必须是唯一的,如果扫码提升订单可能被篡改更新二维码,那么可能是这个值出现了重复。

1
model.setSubject(...);

这个值也必须设置,否则直接不会生成二维码。

个人的一些建议:不建议后端把二维码图片发到前端,官方代码样例中是通过将图片转化为byte[]发送给前端处理,但有些前端框架处理起来比较麻烦,比如我的Flutter(也可能是单纯的我菜),而且这样传输会增加传输量,我的建议是直接拿到结果后不在后端编码为图片,而是将其发送给前端,生成二维码的任务由前端解决。

个人设备(无公网ip)的开发tip

在自己电脑上开发时需要使用natapp将本机后端穿透到公网以便支付宝请求订单回调,注意在配置时将配置文件内的alipay.notify_url改成natapp给你的url,不出意外每次启动natapp这个url都会变一次。

其余的应该都还好,记得保存好你的秘钥。