SpringBoot实现支付宝沙箱
接入文档:https://opendocs.alipay.com/common/02khjm
1 申请沙箱账号并配置
https://open.alipay.com/develop/manage ①申请沙箱账号  ②配置公钥 
选择启用,启用之后选择查看,可以看到有应用公钥、应用私钥、支付宝公钥,这三个是需要记住的
如果要测试APP支付的,可以下载沙箱版支付宝APP(暂支持Android)
沙箱版的支付宝APP,系统会默认给我们配置好账号,不用我们自己注册  沙箱版APP下载,在页面左侧的沙箱工具中,直接使用正式版支付宝扫码下载即可
2 创建SpringBoot项目配置环境
此处为了演示,我就没有创建数据库、以及实体类等操作了
如果有人想看稍微完整的过程,可以在gitee或者GitHub上搜索Alipay-demo 例如:https://gitee.com/xqnode/alipay-demo?_from=gitee_search
注意:我们如果想要支付宝调用我们,需要暴露在公网,此处我使用内网穿透工具natapp实现
natapp官网 大家参考网上的教程实现即可,该工具是免费的。
2.1 application.properties
spring.application.name=demo
server.port=8080
alipay.appId=2021000121681756
alipay.appPrivateKey=MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCXUQi/JIYwYTfMAZTzirtUOjcUFh2yZ0MrueG3fUnun+LO1tnUvSZk+nKjpYpE5k0RRs+M3t2YgfZLGHed/34iVACgIP2hKzb3DLLO0qUgCOj6kUdbpReWA1k97Ga2l7DvknePYkg+XCtvE8s4jflAxYaKEpmIwrKgl9TlAO9+6yObEVbyLkQOwDamsTA2vqwVYXu9NIB5cnNV0qWPy4/NXaQ9+1IgJcvT71fnVku6vGr4rxUoWGg9FjDFzADLN4KzUbF5+qp+3CHrtF5I8GJ4fCLIw9H8N/uZW+3T5+6ovg+4IDl9eVzMAp8dpy1LKy4+dlX7kggmDAwyaJgYvFSLAgMBAAECggEALTnnJ1o/UU59YthGMNSSUQZlV/eUQLJkfTk9oZ4s7smS/MdyrAcs5pmEkiz0Osuq1TMY7b3e9apCdweFGRA4HwKEfVfe9sD32LdO6kpDWGPRXrL1ZQrfFdNCZSO3P3PvSmu4mH6DoT/jK3v7DZhBm35uS+5rPVkUErPOyfORoZknx6+LS2Ih1EbykxJLj5Pmnc1MU0W4gGpckCVP43y5bKWLMXDMzQT72CqKJxgrnEzlhZH1IlFObMFvYhv0WCKu58Aq/filcWVeY3T6i44ZNU1/8iACex5ohteCoI+oC/E/FufE0k6MO7Iai1pD368zkAzHsKBuFWqtettAmzgzIQKBgQDc3cXvCjn9J5WqmzGgtFih+61UzG3F7ICaqy6xFLiSaqTlARS3w8eNrNgZEysXUXQz2ucBkzILHeKtTdVcj4W+cBngIa14cvINTn6R4/Yi9HZFmvdOpAfJXBajNvIEPbVAL4fbTSYfNEXR5hQ9S6RJ2uKvDhm4Ihy/36tTmXr9LQKBgQCvYwVrobpJOVXY6vh+tDm7dCTVVC4iqIJudZtu9IFi/nfSOkl7SNh0dBBDJXs0j9sW7w2EZIAdDkPtOxHLIEMBIiOM/bXcjA+De41WCFWeP9GEuzVfY6100uL93qSQnJN2MLuNyTDp65yEexrrehN5fhOhG0NSFRJWjKcOkTpblwKBgGKV51Tkpq+2LJsjfMpz1aAwG9VfDpyrDVh8knHeguhwC7xgeCPykq9NeIPwx2o4JHtE+Zn9XvgRVe3vcQ5IzfUMSrB9t9Ws0RhZciuiqmo93lEBc+Q5WXRq03v0+aAk/zNwQ98Cl8KT7ZpcbapSijmhJ0/mJlrHdze6GdpOBtTdAoGBAKkQ1B3P9eo2GdoTj11cUDayG/uEvUBtneXq+t13Vu5djJWb2E++heGkLDT+AYlGjxTJdgdEdfcMVFBv25QqUkzaYti7jT6/yQie5jyjphz5OfgwGqAMTx3JWEUPBSXduYx6J6Hi6oLju6o9nVKXCATakwN/a2LJqzbBORyixFWbAoGBAMI6KuvLND1C00rWWzxF2PzES9jUB1GA+vZ9qyOtQT33cYL43LNZylGaynpyg3W9onRLjan8HKeK7XpfuET+6SK2RoZQF9cJ1OheZixBQm7B2+ONPNhY0LbiWsIHQjFSeCS7Kw03J8eJd9M73X8eE8ha4OlQPpbYSMhBWb4jGzZ+
alipay.alipayPublicKey=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn8X7CR4VKB7r7bcdfyc+23RJcmQdLPybnDBVlHMnZPM2aeQwQLgNymKUqxjMdQoPUtGWMV7x63xjTstaPLCnTJffQL4S9bLB8RskAniz+24uzGdqXOzWhpRk09LdjMOtbC8ceNrBtBLyQJoB2NtsB0pGh8fgHQHfX0b8lhyvpgmtg2BEXkXWpi9KBb5bSC79Evve30O7Vg4nWC5Rz/vv8Op/GGtLy03PvxovvEGMZgX3m8t+vYQIB5PpQaS0f3M4HguXL0cwol48iKDknDSzAhISwZHKzvu9AosXBi2kV9vQPBglJkHdYxxMlpiUy1BvrDyAhz9xFQiz+qCdv4L3GwIDAQAB
alipay.notifyUrl="natapp映射的网址"/alipay/notify
pom文件所需依赖:
<!-- alipay-sdk-java -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.16.2.ALL</version>
</dependency>
2.2 配置类【封装公私钥】
AlipayConfig
@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AlipayConfig {
private String appId;
private String appPrivateKey;
private String alipayPublicKey;
private String notifyUrl;
}
2.3 创建实体类【与阿里交互的对象】
@Data
public class AliPay {
private String traceNo;
private Double totalAmount;
private String subject;
private String alipayTraceNo;
}
2.4 controller
①请求支付宝
@GetMapping("/pay")
public void pay(AliPay aliPay, HttpServletResponse response) throws IOException {
AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL,
alipayConfig.getAppId(),
alipayConfig.getAppPrivateKey(),
FORMAT,
CHARSET,
alipayConfig.getAlipayPublicKey(),
SIGN_TYPE);
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setNotifyUrl(alipayConfig.getNotifyUrl());
JSONObject bizContent = new JSONObject();
bizContent.put("out_trade_no", aliPay.getTraceNo());
bizContent.put("total_amount", aliPay.getTotalPrice());
bizContent.put("subject", aliPay.getSubject());
bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
request.setBizContent(bizContent.toString());
String form = "";
try{
form = alipayClient.pageExecute(request).getBody();
} catch (AlipayApiException e) {
e.printStackTrace();
}
response.setContentType("text/html;charset=" + CHARSET);
response.getWriter().write(form);
response.getWriter().flush();
response.getWriter().close();
}
②支付宝回调【post】
@PostMapping("/notify")
public String payNotify(HttpServletRequest request) throws AlipayApiException {
if(request.getParameter("trade_status").equals("TRADE_SUCCESS")){
System.out.println("-------------支付宝异步回调----");
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
System.out.println("-----params-----------");
for(String name : requestParams.keySet()){
params.put(name, request.getParameter(name));
System.out.println(name +" " + request.getParameter(name));
}
String outTradeNo = params.get("out_trade_no");
String gmtPayment = params.get("gmt_payment");
String alipayTradeNo = params.get("trade_no");
String sign = params.get("sign");
String content = AlipaySignature.getSignCheckContentV1(params);
boolean checkSignature = AlipaySignature.rsa256CheckContent(content,
sign,
alipayConfig.getAlipayPublicKey(),
"UTF-8");
if(checkSignature){
System.out.println("交易名称: " + params.get("subject"));
System.out.println("交易状态: " + params.get("trade_status"));
System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
System.out.println("商户订单号: " + params.get("out_trade_no"));
System.out.println("交易金额: " + params.get("total_amount"));
System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
System.out.println("买家付款时间: " + params.get("gmt_payment"));
System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
}
}
return "success";
}
完整controller代码
@RestController
@RequestMapping("/alipay")
public class AliPayController {
private static final String GATEWAY_URL = "https://openapi.alipaydev.com/gateway.do";
private static final String FORMAT = "JSON";
private static final String CHARSET = "UTF-8";
private static final String SIGN_TYPE = "RSA2";
@Resource
private AlipayConfig alipayConfig;
@GetMapping("/pay")
public void pay(AliPay aliPay, HttpServletResponse response) throws IOException {
AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL,
alipayConfig.getAppId(),
alipayConfig.getAppPrivateKey(),
FORMAT,
CHARSET,
alipayConfig.getAlipayPublicKey(),
SIGN_TYPE);
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setNotifyUrl(alipayConfig.getNotifyUrl());
JSONObject bizContent = new JSONObject();
bizContent.put("out_trade_no", aliPay.getTraceNo());
bizContent.put("total_amount", aliPay.getTotalPrice());
bizContent.put("subject", aliPay.getSubject());
bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
request.setBizContent(bizContent.toString());
String form = "";
try{
form = alipayClient.pageExecute(request).getBody();
} catch (AlipayApiException e) {
e.printStackTrace();
}
response.setContentType("text/html;charset=" + CHARSET);
response.getWriter().write(form);
response.getWriter().flush();
response.getWriter().close();
}
@PostMapping("/notify")
public String payNotify(HttpServletRequest request) throws AlipayApiException {
if(request.getParameter("trade_status").equals("TRADE_SUCCESS")){
System.out.println("-------------支付宝异步回调----");
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
System.out.println("-----params-----------");
for(String name : requestParams.keySet()){
params.put(name, request.getParameter(name));
System.out.println(name +" " + request.getParameter(name));
}
String outTradeNo = params.get("out_trade_no");
String gmtPayment = params.get("gmt_payment");
String alipayTradeNo = params.get("trade_no");
String sign = params.get("sign");
String content = AlipaySignature.getSignCheckContentV1(params);
boolean checkSignature = AlipaySignature.rsa256CheckContent(content,
sign,
alipayConfig.getAlipayPublicKey(),
"UTF-8");
if(checkSignature){
System.out.println("交易名称: " + params.get("subject"));
System.out.println("交易状态: " + params.get("trade_status"));
System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
System.out.println("商户订单号: " + params.get("out_trade_no"));
System.out.println("交易金额: " + params.get("total_amount"));
System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
System.out.println("买家付款时间: " + params.get("gmt_payment"));
System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
}
}
return "success";
}
}
3 测试
在浏览器中输入:
localhost:8080/alipay/pay?subject=收购阿里&traceNo=412341243&totalAmount=999999

此处我们可以直接选用网上支付或者通过沙箱版APP扫码支付,输入开始沙箱账号的支付密码即可
此处我选择网上支付,直接输入支付密码点击下一步  选择确认付款【余额不足的实现在沙箱账号那个位置,点击充值即可】: 
至此,实现支付宝沙箱支付成功
控制台结果:
-------------支付宝异步回调----
-----params-----------
gmt_create 2022-10-19 11:37:11
charset UTF-8
gmt_payment 2022-10-19 11:37:30
notify_time 2022-10-19 11:37:32
subject 收购阿里
sign YOeaSKhFkL8y4NPXIOizH18t2kDZRfVYFDVaqUDQMUO+1GfYg2ALxQblt6/AlZLqFD1I5ewFHG+8SdlOatO/ggWh04zuy+CDh/hdW0LIKzsCOAdAF+tgCxLnzB2EBdwkSVHlphplxjW3YxQfs92MYKs/NFTd2UlzILh+GwiJxSsjLxTTN5S7vpfqjBBcFiZ1um5OWA20x2ZuChYfgyJASnqSdWI0aL6dQDH72t8eprZ0yxHGlO9DVXZ9p65j00e62+KcDGlptcQOhdlPsfq1nhswJBQ+gcMgyah2K6FLbQYrO2D9uXTIywlhatvpyCtSkbPRWseHCn+od81dCpVrRw==
buyer_id 2088622999628670
invoice_amount 999999.00
version 1.0
notify_id 2022101900222113731028670522160981
fund_bill_list [{"amount":"999999.00","fundChannel":"ALIPAYACCOUNT"}]
notify_type trade_status_sync
out_trade_no 49141241413
total_amount 999999.00
trade_status TRADE_SUCCESS
trade_no 2022101922001428670502495150
auth_app_id 2021000121681756
receipt_amount 999999.00
point_amount 0.00
app_id 2021000121681756
buyer_pay_amount 999999.00
sign_type RSA2
seller_id 2088621993737227
交易名称: 收购阿里
交易状态: TRADE_SUCCESS
支付宝交易凭证号: 2022101922001428670502495150
商户订单号: 49141241413
交易金额: 999999.00
买家在支付宝唯一id: 2088622999628670
买家付款时间: 2022-10-19 11:37:30
买家付款金额: 999999.00
4 更加完整详细代码
https://gitee.com/Zifasdfa/alipay-demo 参考:https://gitee.com/xqnode
|