<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.2.2version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.4.3.1version>
dependency>
<dependency>
<groupId>cn.hutoolgroupId>
<artifactId>hutool-allartifactId>
<version>5.8.3version>
dependency>
<dependency>
<groupId>com.auth0groupId>
<artifactId>java-jwtartifactId>
<version>3.4.0version>
dependency>
<dependency>
<groupId>com.alipay.sdkgroupId>
<artifactId>alipay-easysdkartifactId>
<version>2.2.0version>
dependency>
dependencies>
package com.pzj.springboot.config;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AliPayConfig {
private String appId;
private String appPrivateKey;
private String alipayPublicKey;
private String notifyUrl;
@PostConstruct
public void init() {
// 设置参数(全局只需设置一次)
Config options = getOptions();
options.appId = this.appId;
options.merchantPrivateKey = this.appPrivateKey;
options.alipayPublicKey = this.alipayPublicKey;
options.notifyUrl = this.notifyUrl;
Factory.setOptions(options);
System.out.println("=======支付宝SDK初始化成功=======");
}
private Config getOptions() {
Config config = new Config();
config.protocol = "https";
config.gatewayHost = "openapi.alipaydev.com";
config.signType = "RSA2";
return config;
}
}
package com.pzj.springboot.controller.dto;
import lombok.Data;
@Data
public class AliPay {
private String subject;
private String traceNo;
private String totalAmount;
}
package com.pzj.springboot.controller;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.pzj.springboot.controller.dto.AliPay;
import com.pzj.springboot.mapper.OrderMapper;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/alipay")
public class AliPayController {
@Resource
private OrderMapper orderMapper;
@GetMapping("/pay")
public String pay(AliPay aliPay) {
AlipayTradePagePayResponse response;
try {
// 发起API调用(以创建当面付收款二维码为例)
response = Factory.Payment.Page()
.pay(aliPay.getSubject(), aliPay.getTraceNo(), aliPay.getTotalAmount(), "");
} catch (Exception e) {
System.err.println("调用遭遇异常,原因:" + e.getMessage());
throw new RuntimeException(e.getMessage(), e);
}
return response.getBody();
}
@PostMapping("/notify") // 注意这里必须是POST接口
public String payNotify(HttpServletRequest request) throws Exception {
if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
System.out.println("=========支付宝异步回调========");
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
params.put(name, request.getParameter(name));
// System.out.println(name + " = " + request.getParameter(name));
}
String tradeNo = params.get("out_trade_no");
String gmtPayment = params.get("gmt_payment");
// 支付宝验签
if (Factory.Payment.Common().verifyNotify(params)) {
// 验签通过
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"));
// 更新订单未已支付
orderMapper.updateState(tradeNo, 1, gmtPayment);
}
}
return "success";
}
}
server.port=9090
######################## 配置MySQL连接 ##########################
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/vue?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 接入支付宝 (换成你自己的配置才能使用)
alipay.appId=2016101100661875
alipay.appPrivateKey=MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDCRZRqOUzIBwk7X5zEVtYIWSGOodU2Rj6VMJWSgvOGLQrGGsUq9spRQqxwhGgjETGedPX/qzcqM80afrlHbJfnz4KYE9KMPcsBVMBIwONOW53I6t7tOXTtd+2yYvhicosFor5fZhKsQoJfTwsSC+zIuSoNCGNWaHgyjrw3T09kjEDEXLBoVJeHtDRPsiXUk71RyLmNFpTjwh9o3juf46VmIKWJTSQYZ5USMF4vy58coq16rbbJFaC1gQkQ+hUgwXuxoy5VRkExMtD1nAfWF3TYnRfSXUal3RiQSNC2IJh7VL99GiyYb2K8o2GoM8Xcw2fovVx1W1K/pwAQL1f8H3WJAgMBAAECggEBAJj/73kRE5VdZTnrfS1sLjh46eLJNX//Jn6cus+ebmg3xQpsPugtYP1Kg0BCJzmm6usetjbbAyErltbNAuJrdd9NIE7hHarxZ5Xux1kFAH/Py55Wy6cM3ze+gedB5tix2SdhGolLfF1KLB8fw1o9JgiXO7Tz7Dg7Ip6+pyDwR1ipcmf22Gc4RFPZ+4GyhxhSMKoY6dHNippDJ3L0G9/Azw2cnAEWx/Vd02PU9b+Zj6f9wNR8uWqrTUQmKA5TmM5YFcmLjV/g6xIyRb2CT7mmPzrQdfIXGf9pHqAc3UpVKWi0zeagr7C9Hhxt0XuPI3fyGc9Kb2OpizbRXzTc3jmLmnkCgYEA/omyvggYXPo7mgGXVwZ5cEF0rz75I0+Qricwe15OmJiyqay+4R6RHLqlVafBQWMos5npdYHWLkAtto0uCJntwnY2V8AxEiHHN/PP4kR4M39CeD+YBdwL6QL+OmKc4EkWMKt5+dNKe7cp2BbCHaXAzsv74Qu3G8A+qqW6haOJu5MCgYEAw2NCZGxkw2K3HEusmFTRKFRSE5iva9ihhwy/uLfDYZ/epRCcYdh3+veqplex4qHPj1kis6gPuStWLZ7o2bKtkkdpWg/jZtBX93vzEN3OY8Z+OMCBZrqf2DO6ZWfjNWyhlYmQxX8dySUtwrME9fsMEpzoiG1MF87d+3O9qs2/k/MCgYEArSqs6c/EE21CIzI17cS/1XkSky76e+Vjfre2qheszqFfwJ8rYhOApO1kRfVTSTPtLKCGQ38FcWi0ljqVM7+KmwRQitBfXtzP65M5sPrlTseUH/0Li4URhIMgaYdyR0h4r+szHfeGlp931ApQP+83AhAfUCgYBvf7pIgo6x7ShfblPNDkHZiNzZr/0TRylOXxkdeUh28ntkqOkE8TnurtzkVhD+Kqa+v/gMm/B1E+T23cM1UEC6xCO7sGttpaE9aq9Xxavcxk4LZtexXviOsV5CNhmzyA0hv8Is4hCGU8AcZnqDQMMv7/jGudB9maCVuQPYb9dOvwKBgQC35caCVliQ0xPfhgB9mzxq+janKctq9q/8PPfQIJ0iQX1GqIe8PvXqvaXB5bZs5pBcPFfAawMwykFmAdUjmsZkfpTTz4ZErUFIhalvaqio0rpR78c2eRJnBw7ijRQF888Pyg84KriGJIj4MTMj5Js6sDh8ZKc+vesX4Drx40eYWA==
alipay.alipayPublicKey=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqs/u9nr3IEgpZ3ZLwsJBybq7QkQ3B/lt9bHtX5VZKGoPWM3Prc0RNYPbo44+ZKikqJBImqB1KwtrLmb+b+RSzY30ZRakaWoaqXVKG+DnAxr/VcIy+L4nwKnP2KE8WlVTq+0WvIP9v+D17OJlIp/yB3ffZNJtClOkvS6criGVKDk+Vp8Yoi6Hf/hRXmds4yHRriLmlvn+KcuW4XAchL3wLrwzP+STYl4JfvHFCqldgPjsQGxDJ0AlwZKp2zuYYSvNr66ojm8CtDt61CG4QwzyaJDkyUGE0bknFVVw8JJQ9b8LEJ4WPovDA94Ly
# 飞鸽内网穿透免费域名,否则,支付宝无法回调你的异步通知接口,告知支付状态
alipay.notifyUrl=http://pzj123.free.svipss.top/alipay/notify
(比较麻烦,但是最重要的一步,需要细心点,而且支付宝页面可能有变动)
看到第5步中,有几个参数:
alipay.appId
alipay.appPrivateKey
alipay.alipayPublicKey
alipay.notifyUrl
如何获取了?
alipay.notifyUrl,这个参数,其实就是我们自己定义的接口地址,供支付宝回调,告知处理结果的。
所以,是自定义的,和普通controller没什么区别,主要是,你要知道,支付宝回调后,会给你回传
什么参数,然后,拿来更新自己订单状态。
alipay.appId
alipay.appPrivateKey
alipay.alipayPublicKey
这三个参数,如何获取了?
步骤如下:
https://opendocs.alipay.com/common/02kipl
我是Windows系统,所以,下载Windows版本的,正常安装
再打开客户端,如下所示操作即可:
这样,就得到 alipay.appPrivateKey 参数,对应图中的应用私钥,贴到application.properties中。
再通过,图中的应用公钥,去获取支付宝公钥。
获取步骤如下:
访问:https://open.alipay.com/
登录后,点击右侧控制台
页面最底下,点击沙箱
页面中,我们选择自定义秘钥,点击设置并查看
这里,我们就得到了 alipay.appId 参数,就是截图中,基本信息-APPID。
同时,获取到 alipay.alipayPublicKey 这个参数,及图中的支付宝公钥。
复制粘贴到application.properties中即可。
最后,我们还要获取,支付宝沙箱账号,这样,才能测试购买
到此为止,所有的配置就都做好了,下面进入测试环节。
请求地址:
http://mypay.free.svipss.top/alipay/pay?subject=买书&traceNo=20220723130000001&totalAmount=100.0
会跳转到支付宝沙箱环境的登录页,输入上面的沙箱账号
付款成功后,你再次看自己的商家账号下的账户余额时,就多了刚才支付的100元。
其中飞鸽内网穿透教程
https://blog.csdn.net/Brave_heart4pzj/article/details/120042579
源码位置:
springboot-vue-demo