增加支付宝支付功能

This commit is contained in:
2025-09-02 00:11:37 +08:00
parent 081a9491fd
commit 91c52a1281
15 changed files with 1000 additions and 0 deletions

View File

@ -0,0 +1,47 @@
package com.sczx.pay.service;
import com.sczx.pay.dto.*;
import java.util.Map;
public interface AlipayService {
/**
* 支付宝统一下单
*/
AlipayCreateResponse unifiedOrder(AlipayCreateRequest request);
/**
* 查询订单
*/
AlipayQueryResponse orderQuery(Long companyId, String outTradeNo);
/**
* 关闭订单
*/
AlipayResponse closeOrder(AlipayCloseRequest alipayCloseRequest);
/**
* 申请退款
*/
AlipayResponse refund(AlipayRefundRequest request);
/**
* 查询退款
*/
AlipayResponse refundQuery(AlipayRefundRequest refundQueryRequest);
/**
* 验证通知签名
*/
boolean verifyNotifySign(Long companyId, Map<String, String> params);
/**
* 处理支付成功通知
*/
boolean processPaySuccessNotify(Long companyId, Map<String, String> notifyMap);
/**
* 处理退款通知
*/
boolean processRefundNotify(Map<String, String> notifyMap);
}

View File

@ -0,0 +1,479 @@
package com.sczx.pay.service.impl;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.sczx.pay.config.AlipayConf;
import com.sczx.pay.dto.*;
import com.sczx.pay.entity.OrderMain;
import com.sczx.pay.entity.PayStatus;
import com.sczx.pay.entity.PaymentRecord;
import com.sczx.pay.entity.RefundRecord;
import com.sczx.pay.mapper.OrderPayMapper;
import com.sczx.pay.mapper.PaymentRecordMapper;
import com.sczx.pay.mapper.RefundRecordMapper;
import com.sczx.pay.service.AlipayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
@Slf4j
@Service
public class AlipayServiceImpl implements AlipayService {
@Autowired
private AlipayConf alipayConf;
@Value("${ali.pay.app-id}")
private String appId;
@Value("${ali.pay.notify-url}")
private String notifyUrl;
@Value("${ali.pay.refund-notify-url}")
private String refundNotifyUrl;
@Value("${ali.pay.privateKey}")
private String privateKey;
// @Value("${alipay.miniapp.publicKey}")
// private String publicKey;
@Value("${ali.pay.appCertPath}")
private String appCertPath;
@Value("${ali.pay.alipayCertPath}")
private String alipayCertPath;
@Value("${ali.pay.alipayRootCertPath}")
private String alipayRootCertPath;
@Autowired
private PaymentRecordMapper paymentRecordMapper;
@Autowired
private RefundRecordMapper refundRecordMapper;
@Autowired
private OrderPayMapper orderPayMapper;
@Override
public AlipayCreateResponse unifiedOrder(AlipayCreateRequest alipayCreateRequest) {
AlipayCreateResponse response = new AlipayCreateResponse();
try {
AlipayClient alipayClient = alipayConf.alipayClient();
// 构造请求参数以调用接口
AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
AlipayTradeCreateModel model = new AlipayTradeCreateModel();
// 设置商户订单号
model.setOutTradeNo(alipayCreateRequest.getOutTradeNo());
// 设置订单总金额
model.setTotalAmount(alipayCreateRequest.getTotalAmount());
// 设置订单标题
model.setSubject(alipayCreateRequest.getSubject());
// 设置订单相对超时时间
// model.setTimeoutExpress("90m");
// uid参数未来计划废弃存量商户可继续使用新商户请使用openid。请根据应用-开发配置-openid配置选择支持的字段。
// model.setBuyerId("2088102146225135");
// 设置买家支付宝用户唯一标识
model.setBuyerOpenId(alipayCreateRequest.getOpenId());
model.setOpAppId(alipayConf.getCompanyAppid(alipayCreateRequest.getCompanyId()));
// 设置产品码
model.setProductCode("JSAPI_PAY");
request.setBizModel(model);
//设置回调地址
request.setNotifyUrl(notifyUrl);
// 第三方代调用模式下请设置app_auth_token
// request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");
AlipayTradeCreateResponse alipayResponse = alipayClient.certificateExecute(request);
if (alipayResponse.isSuccess()) {
response.setSuccess(true);
response.setOrderStr(alipayResponse.getBody());
response.setOutTradeNo(alipayCreateRequest.getOutTradeNo());
response.setTradeNo(alipayResponse.getTradeNo());
response.setCode("SUCCESS");
response.setMessage("下单成功");
//保存支付单
recordPaymentInfo(alipayCreateRequest);
} else {
response.setSuccess(false);
response.setCode("FAIL");
response.setMessage("下单失败: " + alipayResponse.getMsg() + ":" + alipayResponse.getSubMsg());
}
} catch (Exception e) {
log.error("支付宝下单异常公司ID: {}, 订单号: {}", alipayCreateRequest.getCompanyId(), alipayCreateRequest.getOutTradeNo(), e);
response.setSuccess(false);
response.setCode("FAIL");
response.setMessage("下单异常: " + e.getMessage());
}
return response;
}
@Override
public AlipayQueryResponse orderQuery(Long companyId, String outTradeNo) {
AlipayQueryResponse response = new AlipayQueryResponse();
try {
AlipayClient alipayClient = alipayConf.alipayClient();
// 构造请求参数以调用接口
// 构造请求参数以调用接口
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
AlipayTradeQueryModel model = new AlipayTradeQueryModel();
// 设置订单支付时传入的商户订单号
model.setOutTradeNo(outTradeNo);
request.setBizModel(model);
// 第三方代调用模式下请设置app_auth_token
// request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");
AlipayTradeQueryResponse alipayResponse = alipayClient.certificateExecute(request);
if (alipayResponse.isSuccess()) {
response.setSuccess(true);
response.setOutTradeNo(alipayResponse.getOutTradeNo());
response.setTradeNo(alipayResponse.getTradeNo());
response.setTradeStatus(alipayResponse.getTradeStatus());
response.setCode("SUCCESS");
response.setMessage("查询支付单成功");
} else {
response.setSuccess(false);
response.setCode("FAIL");
response.setMessage("查询支付单失败: " + alipayResponse.getMsg() + ":" + alipayResponse.getSubMsg());
}
} catch (Exception e) {
log.error("支付宝订单查询异常公司ID: {}, 订单号: {}", companyId, outTradeNo, e);
response.setSuccess(false);
response.setCode("FAIL");
response.setMessage("支付宝订单查询败异常: " + e.getMessage());
}
return response;
}
@Override
public AlipayResponse closeOrder(AlipayCloseRequest alipayCloseRequest) {
AlipayResponse response = new AlipayResponse();
try {
AlipayClient alipayClient = alipayConf.alipayClient();
// 构造请求参数以调用接口
AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
AlipayTradeCloseModel model = new AlipayTradeCloseModel();
// 设置订单支付时传入的商户订单号
model.setOutTradeNo(alipayCloseRequest.getOutTradeNo());
request.setBizModel(model);
// 第三方代调用模式下请设置app_auth_token
// request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");
AlipayTradeCloseResponse closeResponse = alipayClient.certificateExecute(request);
log.info("关闭订单响应 : {}",closeResponse.getBody());
if (closeResponse.isSuccess()) {
response.setSuccess(true);
response.setCode("SUCCESS");
response.setMessage("关闭支付单成功");
} else {
response.setSuccess(false);
response.setCode("FAIL");
response.setMessage("关闭支付单失败: " + closeResponse.getMsg() + ":" + closeResponse.getSubMsg());
}
} catch (Exception e) {
log.error("支付宝关闭异常公司ID: {}, 订单号: {}", alipayCloseRequest.getCompanyId(), alipayCloseRequest.getOutTradeNo(), e);
response.setSuccess(false);
response.setCode("FAIL");
response.setMessage("关闭支付单失败异常: " + e.getMessage());
}
return response;
}
@Override
public AlipayResponse refund(AlipayRefundRequest request) {
AlipayResponse response = new AlipayResponse();
try {
AlipayClient alipayClient = alipayConf.alipayClient();
// 构造请求参数以调用接口
AlipayTradeRefundRequest refundRequest = new AlipayTradeRefundRequest();
AlipayTradeRefundModel model = new AlipayTradeRefundModel();
// 设置商户订单号
model.setOutTradeNo(request.getOutTradeNo());
//
// // 设置支付宝交易号
// model.setTradeNo("2014112611001004680073956707");
// 设置退款金额
model.setRefundAmount(request.getRefundAmount());
// 设置退款原因说明
model.setRefundReason(request.getRefundReason());
// 设置退款请求号
model.setOutRequestNo(request.getOutRequestNo());
refundRequest.setBizModel(model);
AlipayTradeRefundResponse refundResponse = alipayClient.certificateExecute(refundRequest);
log.info("退款响应 : {}",refundResponse.getBody());
if (refundResponse.isSuccess()) {
response.setSuccess(true);
response.setCode("SUCCESS");
response.setMessage("发起退款成功");
//保存退款信息
recordRefundInfo(request);
} else {
response.setSuccess(false);
response.setCode("FAIL");
response.setMessage("退款失败: " + refundResponse.getMsg() + ":" + refundResponse.getSubMsg());
}
} catch (Exception e) {
log.error("支付宝退款异常公司ID: {}, 订单号: {}", request.getCompanyId(), request.getOutTradeNo(), e);
response.setSuccess(false);
response.setCode("FAIL");
response.setMessage("退款失败异常: " + e.getMessage());
}
return response;
}
@Override
public AlipayResponse refundQuery(AlipayRefundRequest refundQueryRequest) {
AlipayResponse response = new AlipayResponse();
try {
AlipayClient alipayClient = alipayConf.alipayClient();
// 构造请求参数以调用接口
AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
AlipayTradeFastpayRefundQueryModel model = new AlipayTradeFastpayRefundQueryModel();
// 设置商户订单号
model.setOutTradeNo(refundQueryRequest.getOutTradeNo());
// 设置退款请求号
model.setOutRequestNo(refundQueryRequest.getOutRequestNo());
request.setBizModel(model);
// 第三方代调用模式下请设置app_auth_token
// request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");
AlipayTradeFastpayRefundQueryResponse refundQueryResponse = alipayClient.certificateExecute(request);
log.info("退款查询响应 : {}",refundQueryResponse.getBody());
if (refundQueryResponse.isSuccess() && "REFUND_SUCCESS".equals(refundQueryResponse.getRefundStatus())) {
response.setSuccess(true);
response.setCode("SUCCESS");
response.setMessage("退款成功");
} else {
response.setSuccess(false);
response.setCode("FAIL");
response.setMessage("退款查询失败: " + refundQueryResponse.getMsg() + ":" + refundQueryResponse.getSubMsg());
}
} catch (Exception e) {
log.error("支付宝退款异常公司ID: {}, 订单号: {}", refundQueryRequest.getCompanyId(), refundQueryRequest.getOutTradeNo(), e);
response.setSuccess(false);
response.setCode("FAIL");
response.setMessage("支付宝退款失败异常: " + e.getMessage());
}
return response;
}
@Override
public boolean verifyNotifySign(Long companyId, Map<String, String> params) {
try {
return AlipaySignature.rsaCertCheckV1(params, alipayCertPath, "UTF-8", "RSA2");
} catch (AlipayApiException e) {
log.error("支付宝通知签名验证异常公司ID: {}", companyId, e);
return false;
}
}
@Override
public boolean processPaySuccessNotify(Long companyId, Map<String, String> notifyMap) {
try {
// 这里实现您的业务逻辑
// 例如:更新订单状态、发送通知等
String outTradeNo = notifyMap.get("out_trade_no");
String tradeNo = notifyMap.get("trade_no");
String totalAmount = notifyMap.get("total_amount");
log.info("处理支付宝支付成功通知公司ID: {}, 订单号: {}, 交易号: {}, 金额: {}",
companyId, outTradeNo, tradeNo, totalAmount);
// 更新支付记录状态
int updated = paymentRecordMapper.updateToSuccess(
outTradeNo,
tradeNo,
new Date(), // 支付时间
new Date() // 更新时间
);
if (updated > 0) {
log.info("支付宝支付记录状态已更新,订单号: {}, 支付宝交易号: {}", outTradeNo, tradeNo);
//更新主订单状态
OrderMain orderMain = orderPayMapper.getOrderStatusByOrderNo(outTradeNo);
String OrderStatus = orderMain.getOrderStatus();
if(OrderStatus.equals("WAIT_PAY")){
orderPayMapper.updateOrderStatus(orderMain.getOrderNo(),"WAIT_PICK");
}else if (OrderStatus.equals("RERENT_WAIT_PAY")){
orderPayMapper.updateOrderStatus(orderMain.getOrderNo(),"RENT_ING");
}
orderPayMapper.updateSubOrderPaymentStatus(outTradeNo,"ZFB_PAY", PayStatus.SUCCESS.getCode(),tradeNo);
return true;
} else {
log.warn("未找到对应的支付宝支付记录,订单号: {}", outTradeNo);
return false;
}
} catch (Exception e) {
log.error("处理支付宝支付成功通知异常公司ID: {}", companyId, e);
return false;
}
}
@Override
public boolean processRefundNotify(Map<String, String> notifyMap) {
try {
String outTradeNo = notifyMap.get("out_trade_no");
String outRequestNo = notifyMap.get("out_request_no");
String refundAmount = notifyMap.get("refund_amount");
String refundStatus = notifyMap.get("refund_status");
log.info("处理支付宝退款通知,订单号: {}, 退款请求号: {}, 退款金额: {}",
outTradeNo, outRequestNo, refundAmount);
//
//
// String outRefundNo = notifyData.get("out_refund_no");
// String refundId = notifyData.get("refund_id");
// String refundStatus = notifyData.get("refund_status");
// String outTradeNo = notifyData.get("out_trade_no");
// BigDecimal refundFee = new BigDecimal(notifyData.get("refund_fee"));
// 根据退款状态更新退款记录
String statusDesc = "";
String payStatus = "";
statusDesc = "退款成功";
payStatus = "REFUND_SUCCESS";
// switch (refundStatus) {
// case "SUCCESS":
// statusDesc = "退款成功";
// payStatus = "REFUND_SUCCESS";
// break;
// case "REFUNDCLOSE":
// statusDesc = "退款关闭";
// payStatus = "REFUND_SUCCESS";
// break;
// case "PROCESSING":
// statusDesc = "退款处理中";
// payStatus = "REFUNDING";
// break;
// case "CHANGE":
// statusDesc = "退款异常";
// payStatus = "REFUND_ERROR";
// break;
// default:
// statusDesc = "未知状态";
// payStatus = "REFUND_ERROR";
// }
orderPayMapper.updateSubOrderRefundStatus(outTradeNo,payStatus,new BigDecimal(refundAmount),new Date(),outRequestNo);
int updated = refundRecordMapper.updateRefundStatus(
outRequestNo,
refundStatus,
statusDesc,
outRequestNo,
"SUCCESS".equals(refundStatus) ? new Date() : null, // 退款成功时间
new Date() // 更新时间
);
if (updated > 0) {
log.info("支付宝退款记录状态已更新,退款单号: {}, 支付宝退款单号: {}, 状态: {}", outRequestNo, outRequestNo, refundStatus);
return true;
} else {
log.warn("未找到对应的微信退款记录,退款单号: {}", outRequestNo);
return false;
}
} catch (Exception e) {
log.error("处理微信退款通知异常,退款单号: {}", notifyMap.get("out_request_no"), e);
return false;
}
}
/**
* 记录支付信息到数据库
*/
private void recordPaymentInfo(AlipayCreateRequest request) {
try {
PaymentRecord paymentRecord = new PaymentRecord();
paymentRecord.setCompanyId(request.getCompanyId());
paymentRecord.setOutTradeNo(request.getOutTradeNo());
paymentRecord.setTotalFee(new BigDecimal(request.getTotalAmount())); // 转换为元
paymentRecord.setBody(request.getBody());
paymentRecord.setOpenid(request.getOpenId());
paymentRecord.setTradeState("NOTPAY"); // 未支付
paymentRecord.setTradeStateDesc("未支付");
paymentRecord.setCreateTime(new Date());
paymentRecord.setUpdateTime(new Date());
// paymentRecord.setAttach(request.getAttach());
paymentRecord.setPayChannel(PaymentRecord.PayChannel.ALIPAY.name()); // 设置支付渠道为支付宝支付
paymentRecordMapper.insertPaymentRecord(paymentRecord);
log.info("支付记录已保存,订单号: {}", request.getOutTradeNo());
} catch (Exception e) {
log.error("保存支付记录异常,订单号: {}", request.getOutTradeNo(), e);
}
}
/**
* 记录退款信息到数据库
*/
private void recordRefundInfo(AlipayRefundRequest request) {
try {
RefundRecord refundRecord = new RefundRecord();
refundRecord.setCompanyId(request.getCompanyId());
refundRecord.setOutTradeNo(request.getOutTradeNo());
refundRecord.setOutRefundNo(request.getOutRequestNo());
// refundRecord.setTotalFee(totalFee);
refundRecord.setRefundFee(new BigDecimal(request.getRefundAmount())); // 转换为元
refundRecord.setRefundDesc(request.getRefundReason());
refundRecord.setCreateTime(new Date());
refundRecord.setUpdateTime(new Date());
refundRecord.setRefundStatus("PROCESSING"); // 退款处理中
refundRecord.setRefundStatusDesc("退款处理中");
refundRecord.setRefundId(request.getOutRequestNo());
refundRecord.setPayChannel(PaymentRecord.PayChannel.ALIPAY.name());
refundRecordMapper.insertRefundRecord(refundRecord);
log.info("退款记录已保存,退款单号: {}", request.getOutRequestNo());
} catch (Exception e) {
log.error("保存退款记录异常,退款单号: {}", request.getOutRequestNo(), e);
}
}
}