1. 账号注册
注册地址: 支付宝
文档地址: 小程序文档 - 支付宝文档中心
2.登录商家平台
登录地址: https://b.alipay.com/page/portal/home
1. 产品中心 - 当面付 - 申请开通
3. 登录开放平台
访问地址: 支付宝开放平台
1. 控制台 - 网页移动应用
2. 进入应用详情 - 开发设置
3. 设置接口加签方式
4. 下载密钥工具 , 生成密钥 (记录应用私钥, 后面要用到)
5. 记录支付宝公钥
6. 设置接口内容加密方式
4. 支付代码
项目引入Pom
<dependency> <groupId>com.alipay.sdk</groupId> <artifactId>alipay-sdk-java</artifactId> <version>4.39.2.ALL</version> </dependency>
配置文件
pay:
ali-pay:
# 应用ID
app-id:
# 支付宝服务器网关地址
url: https://openapi.alipay.com/gateway.do
# 应用私钥
private-key:
# 支付宝公钥
ali-public-key:
# 支付&二维码超时时间/单位:分钟
time-out: 5
# 接收结果通知地址.如果路径需要动态替换订单号,则以 {orderNo} 占位
notify-url: https://xxxxxx/{orderNo}
# 单笔最大金额
max-money: 2000
# 单笔最小金额
min-money: 0.1
package cn.com.baidu.operator.util.pay;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* 从配置文件读取阿里支付的配置文件
* 2024年3月21日10:20:50
* 崔宝铖
*/
@Configuration
@ConfigurationProperties(prefix = "pay.ali-pay")
public class AliPayProperties {
// 应用ID
private String appId;
// 支付宝服务器地址
private String url;
// 应用私钥
private String privateKey;
// 支付宝公钥
private String aliPublicKey;
// 超时时间
private String timeOut;
// 接收结果通知地址
private String notifyUrl;
// 单笔最大金额
private Double maxMoney;
// 单笔最小金额
private Double minMoney;
public String getAppId() {
return appId == null ? "" : appId.trim();
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getUrl() {
return url == null ? "" : url.trim();
}
public void setUrl(String url) {
this.url = url;
}
public String getPrivateKey() {
return privateKey == null ? "" : privateKey.trim();
}
public void setPrivateKey(String privateKey) {
this.privateKey = privateKey;
}
public String getAliPublicKey() {
return aliPublicKey == null ? "" : aliPublicKey.trim();
}
public void setAliPublicKey(String aliPublicKey) {
this.aliPublicKey = aliPublicKey;
}
public String getTimeOut() {
return timeOut == null ? "5" : timeOut.trim();
}
public void setTimeOut(String timeOut) {
this.timeOut = timeOut;
}
public String getNotifyUrl() {
return notifyUrl == null ? "" : notifyUrl.trim();
}
public void setNotifyUrl(String notifyUrl) {
this.notifyUrl = notifyUrl;
}
public Double getMaxMoney() {
return maxMoney == null ? 2000 : maxMoney;
}
public void setMaxMoney(Double maxMoney) {
this.maxMoney = maxMoney;
}
public Double getMinMoney() {
return minMoney == null ? 0.1 : minMoney;
}
public void setMinMoney(Double minMoney) {
this.minMoney = minMoney;
}
}
package cn.com.baidu.operator.util.pay;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.domain.AlipayTradeCloseModel;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeCloseResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import cn.com.baidu.exceptions.SaveException;
import cn.com.baidu.exceptions.SearchException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.awt.image.BufferedImage;
import java.text.SimpleDateFormat;
/**
* 支付宝支付
* 2024年3月19日15:47:30
* CBC
*/
@Component
public class ALiPay {
@Autowired
private AliPayProperties aliPayProperties;
private static AliPayProperties aliPayStaticProperties;
@PostConstruct
public void init() {
aliPayStaticProperties = this.aliPayProperties;
}
private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static void closePay(String orderNo) {
AlipayConfig alipayConfig = new AlipayConfig();
alipayConfig.setServerUrl(aliPayStaticProperties.getUrl());// 支付地址
alipayConfig.setAppId(aliPayStaticProperties.getAppId());// 应用ID
alipayConfig.setPrivateKey(aliPayStaticProperties.getPrivateKey());// 应用私钥
alipayConfig.setFormat("json");
alipayConfig.setAlipayPublicKey(aliPayStaticProperties.getAliPublicKey());// 支付宝公钥
alipayConfig.setCharset("UTF-8");
alipayConfig.setSignType("RSA2");// 编码
try{
AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
AlipayTradeCloseModel model = new AlipayTradeCloseModel();
model.setOutTradeNo(orderNo);
request.setBizModel(model);
AlipayTradeCloseResponse response = alipayClient.execute(request);
if (!response.isSuccess() && !response.getSubMsg().equals("交易不存在")) {
throw new SearchException(response.getSubMsg());
}
}catch(Exception e) {
throw new SearchException(e.getMessage());
}
}
public static PayResultDTO queryPay(String orderNo) {
AlipayConfig alipayConfig = new AlipayConfig();
alipayConfig.setServerUrl(aliPayStaticProperties.getUrl());// 支付地址
alipayConfig.setAppId(aliPayStaticProperties.getAppId());// 应用ID
alipayConfig.setPrivateKey(aliPayStaticProperties.getPrivateKey());// 应用私钥
alipayConfig.setFormat("json");
alipayConfig.setAlipayPublicKey(aliPayStaticProperties.getAliPublicKey());// 支付宝公钥
alipayConfig.setCharset("UTF-8");
alipayConfig.setSignType("RSA2");// 编码
try{
AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
AlipayTradeQueryModel model = new AlipayTradeQueryModel();
model.setOutTradeNo(orderNo);
request.setBizModel(model);
AlipayTradeQueryResponse response = alipayClient.execute(request);
PayResultDTO dto = new PayResultDTO();
dto.setOrderStatus("0");
dto.setOrderNo(response.getOutTradeNo());
if (response.isSuccess()) {
dto.setOrderId(response.getTradeNo());
dto.setOrderStatus(response.getTradeStatus().equals("TRADE_SUCCESS") || response.getTradeStatus().equals("TRADE_FINISHED") ? "1" : "0");
dto.setOrderSuccessTime(sdf.format(response.getSendPayDate()));
dto.setMoney(PayUtil.buiderMoney(Double.parseDouble(response.getTotalAmount())));
}
if (response == null || (!response.isSuccess() && !response.getSubMsg().equals("交易不存在"))) {
throw new SearchException(response.getSubMsg());
}
return dto;
}catch(Exception e) {
throw new SearchException(e.getMessage());
}
}
/**
* 创建支付的二维码
* @param orderNo 本地订单编号(唯一)
* @param money 支付金额, 1元为100
* @param orderDescription 订单详细说明
* @return
*/
public static String createPay(String orderNo, Integer money, String orderDescription) {
AlipayConfig alipayConfig = new AlipayConfig();
alipayConfig.setServerUrl(aliPayStaticProperties.getUrl());// 支付地址
alipayConfig.setAppId(aliPayStaticProperties.getAppId());// 应用ID
alipayConfig.setPrivateKey(aliPayStaticProperties.getPrivateKey());// 应用私钥
alipayConfig.setFormat("json");
alipayConfig.setAlipayPublicKey(aliPayStaticProperties.getAliPublicKey());// 支付宝公钥
alipayConfig.setCharset("UTF-8");
alipayConfig.setSignType("RSA2");// 编码
try{
if (PayUtil.buiderMoney(money) > aliPayStaticProperties.getMaxMoney() || PayUtil.buiderMoney(money) < aliPayStaticProperties.getMinMoney()) {
throw new SaveException("支付金额超出范围");
}
AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
String notifyUrl = aliPayStaticProperties.getNotifyUrl().replaceAll("\\{orderNo}", orderNo);
request.setNotifyUrl(notifyUrl);
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
model.setOutTradeNo(orderNo);// 本地订单号
model.setTotalAmount(PayUtil.buiderMoney(money) + ""); // 本次付款金额
model.setTimeoutExpress(aliPayStaticProperties.getTimeOut() + "m");//交易超时时间
model.setQrCodeTimeoutExpress(aliPayStaticProperties.getTimeOut() + "m");//二维码失效时间
model.setSubject(orderDescription); // 本次订单说明
request.setBizModel(model);
AlipayTradePrecreateResponse response = alipayClient.execute(request);
if (response.isSuccess()) {
String qrCode = response.getQrCode();
if (qrCode.startsWith("http")) {
BufferedImage bufferedImage = QRUtils.createQrCodeImage(QRUtils.createQrCode(qrCode, 330, 330), "");
return QRUtils.imageToBase64(bufferedImage);
}
}
throw new SaveException(response.getSubMsg());
}catch(Exception e) {
e.printStackTrace();
throw new SaveException("生成支付二维码失败");
}
}
}
package cn.com.baidu.operator.util.pay;
import io.swagger.annotations.ApiModelProperty;
/**
* 支付结果对象
* 2024年3月19日17:03:25
* CBC
*/
public class PayResultDTO {
@ApiModelProperty(name = "orderId", value = "第三方订单ID")
private String orderId;
@ApiModelProperty(name = "orderNo", value = "本地订单编号")
private String orderNo;
@ApiModelProperty(name = "orderStatus", value = "支付结果,1:成功")
private String orderStatus;
@ApiModelProperty(name = "orderSuccessTime", value = "支付成功时间")
private String orderSuccessTime;
@ApiModelProperty(name = "orderMessage", value = "支付结果详情")
private String orderMessage;
@ApiModelProperty(name = "money", value = "订单总金额")
private Integer money;
public String getOrderId() {
return orderId == null ? "" : orderId.trim();
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getOrderNo() {
return orderNo == null ? "" : orderNo.trim();
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public String getOrderStatus() {
return orderStatus == null ? "" : orderStatus.trim();
}
public void setOrderStatus(String orderStatus) {
this.orderStatus = orderStatus;
}
public String getOrderSuccessTime() {
return orderSuccessTime == null ? "" : orderSuccessTime.trim();
}
public void setOrderSuccessTime(String orderSuccessTime) {
this.orderSuccessTime = orderSuccessTime;
}
public String getOrderMessage() {
return orderMessage == null ? "" : orderMessage.trim();
}
public void setOrderMessage(String orderMessage) {
this.orderMessage = orderMessage;
}
public Integer getMoney() {
return money == null ? 0 : money;
}
public void setMoney(Integer money) {
this.money = money;
}
}