mirror of
https://gitee.com/dromara/dax-pay.git
synced 2025-09-03 11:06:46 +00:00
feat 云闪付回调处理和一些接口联调, 优化精简统一SDK
This commit is contained in:
@@ -1,9 +1,15 @@
|
||||
package org.dromara.daxpay.channel.union.controller;
|
||||
|
||||
import cn.bootx.platform.core.annotation.IgnoreAuth;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.daxpay.channel.union.service.callback.UnionPayCallbackService;
|
||||
import org.dromara.daxpay.channel.union.service.callback.UnionRefundCallbackService;
|
||||
import org.dromara.daxpay.service.service.assist.PaymentAssistService;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@@ -15,24 +21,27 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@IgnoreAuth
|
||||
@Tag(name = "银联回调通知")
|
||||
@RestController
|
||||
@RequestMapping("/unipay/callback/{AppId}")
|
||||
@RequestMapping("/unipay/callback/{AppId}/union")
|
||||
@RequiredArgsConstructor
|
||||
public class UnionPayCallbackController {
|
||||
|
||||
private final PaymentAssistService paymentAssistService;
|
||||
private final UnionPayCallbackService unionPayCallbackService;
|
||||
|
||||
// @Operation(summary = "云闪付支付回调")
|
||||
// @PostMapping("/pay")
|
||||
// public String wechatPayNotify(@PathVariable("AppId") String appId, HttpServletRequest request) {
|
||||
// paymentAssistService.initMchApp(appId);
|
||||
// return payCallbackService.payHandle(request);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @Operation(summary = "云闪付退款回调")
|
||||
// @PostMapping("/refund")
|
||||
// public String wechatRefundNotify(@PathVariable("AppId") String appId,HttpServletRequest request) {
|
||||
// paymentAssistService.initMchApp(appId);
|
||||
// return refundCallbackService.refundHandle(request);
|
||||
// }
|
||||
private final PaymentAssistService paymentAssistService;
|
||||
private final UnionRefundCallbackService refundCallbackService;
|
||||
|
||||
@Operation(summary = "云闪付支付回调")
|
||||
@PostMapping("/pay")
|
||||
public String wechatPayNotify(@PathVariable("AppId") String appId, HttpServletRequest request) {
|
||||
paymentAssistService.initMchApp(appId);
|
||||
return unionPayCallbackService.payHandle(request);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "云闪付退款回调")
|
||||
@PostMapping("/refund")
|
||||
public String wechatRefundNotify(@PathVariable("AppId") String appId, HttpServletRequest request) {
|
||||
paymentAssistService.initMchApp(appId);
|
||||
return refundCallbackService.refundHandle(request);
|
||||
}
|
||||
}
|
||||
|
@@ -23,7 +23,6 @@ import org.dromara.daxpay.unisdk.common.util.sign.encrypt.RSA2;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.cert.*;
|
||||
@@ -146,18 +145,15 @@ public class UnionPayKit extends BasePayService<UnionPayConfigStorage> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台通知地址
|
||||
* 初始化异步通知地址
|
||||
*
|
||||
* @param parameters 预订单信息
|
||||
* @param order 订单
|
||||
* @return 预订单信息
|
||||
*/
|
||||
private Map<String, Object> initNotifyUrl(Map<String, Object> parameters, AssistOrder order) {
|
||||
//后台通知地址
|
||||
private void initNotifyUrl(Map<String, Object> parameters, AssistOrder order) {
|
||||
OrderParaStructure.loadParameters(parameters, SDKConstants.param_backUrl, payConfigStorage.getNotifyUrl());
|
||||
OrderParaStructure.loadParameters(parameters, SDKConstants.param_backUrl, order.getNotifyUrl());
|
||||
OrderParaStructure.loadParameters(parameters, SDKConstants.param_backUrl, order);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
|
||||
@@ -178,8 +174,6 @@ public class UnionPayKit extends BasePayService<UnionPayConfigStorage> {
|
||||
|
||||
//订单发送时间
|
||||
params.put(SDKConstants.param_txnTime, DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN));
|
||||
//后台通知地址
|
||||
params.put(SDKConstants.param_backUrl, payConfigStorage.getNotifyUrl());
|
||||
|
||||
//交易币种
|
||||
params.put(SDKConstants.param_currencyCode, "156");
|
||||
@@ -197,7 +191,7 @@ public class UnionPayKit extends BasePayService<UnionPayConfigStorage> {
|
||||
*/
|
||||
@Override
|
||||
public boolean verify(NoticeParams noticeParams) {
|
||||
final Map<String, Object> result = noticeParams.getBody();
|
||||
final Map<String, ?> result = noticeParams.getBody();
|
||||
if (null == result || result.get(SDKConstants.param_signature) == null) {
|
||||
log.debug("银联支付验签异常:params:{}", result);
|
||||
return false;
|
||||
@@ -212,7 +206,7 @@ public class UnionPayKit extends BasePayService<UnionPayConfigStorage> {
|
||||
* @param sign 签名原文
|
||||
* @return 签名校验 true通过
|
||||
*/
|
||||
public boolean signVerify(Map<String, Object> params, String sign) {
|
||||
public boolean signVerify(Map<String, ?> params, String sign) {
|
||||
SignUtils signUtils = SignUtils.valueOf(payConfigStorage.getSignType());
|
||||
|
||||
String data = SignTextUtils.parameterText(params, "&", "signature");
|
||||
@@ -244,7 +238,6 @@ public class UnionPayKit extends BasePayService<UnionPayConfigStorage> {
|
||||
* @return 具体的时间字符串
|
||||
*/
|
||||
private String getPayTimeout(Date expirationTime) {
|
||||
//
|
||||
if (null != expirationTime) {
|
||||
return DateUtil.format(expirationTime, DatePattern.PURE_DATETIME_PATTERN);
|
||||
}
|
||||
@@ -445,8 +438,7 @@ public class UnionPayKit extends BasePayService<UnionPayConfigStorage> {
|
||||
@Override
|
||||
public Map<String, Object> microPay(UniOrder order) {
|
||||
order.setTransactionType(UnionTransactionType.CONSUME);
|
||||
JSONObject response = postOrder(order, getBackTransUrl());
|
||||
return response;
|
||||
return postOrder(order, getBackTransUrl());
|
||||
}
|
||||
|
||||
|
||||
@@ -570,50 +562,6 @@ public class UnionPayKit extends BasePayService<UnionPayConfigStorage> {
|
||||
return UriVariables.getParametersToMap(responseStr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 消费撤销/退货接口
|
||||
*
|
||||
* @param origQryId 原交易查询流水号.
|
||||
* @param orderId 退款单号
|
||||
* @param refundAmount 退款金额
|
||||
* @param type UnionTransactionType.REFUND 或者UnionTransactionType.CONSUME_UNDO
|
||||
* @return 返回支付方申请退款后的结果
|
||||
*/
|
||||
public UnionRefundResult unionRefundOrConsumeUndo(String origQryId, String orderId, BigDecimal refundAmount, UnionTransactionType type) {
|
||||
return unionRefundOrConsumeUndo(new UniRefundOrder(orderId, origQryId, refundAmount), type);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 消费撤销/退货接口
|
||||
*
|
||||
* @param refundOrder 退款订单信息
|
||||
* @param type UnionTransactionType.REFUND 或者UnionTransactionType.CONSUME_UNDO
|
||||
* @return 返回支付方申请退款后的结果
|
||||
*/
|
||||
public UnionRefundResult unionRefundOrConsumeUndo(UniRefundOrder refundOrder, UnionTransactionType type) {
|
||||
Map<String, Object> params = this.getCommonParam();
|
||||
type.convertMap(params);
|
||||
params.put(SDKConstants.param_orderId, refundOrder.getRefundNo());
|
||||
params.put(SDKConstants.param_txnAmt, Util.conversionCentAmount(refundOrder.getRefundAmount()));
|
||||
params.put(SDKConstants.param_origQryId, refundOrder.getTradeNo());
|
||||
params.putAll(refundOrder.getAttrs());
|
||||
this.setSign(params);
|
||||
String responseStr = getHttpRequestTemplate().postForObject(this.getBackTransUrl(), params, String.class);
|
||||
JSONObject response = UriVariables.getParametersToMap(responseStr);
|
||||
|
||||
if (this.verify(new NoticeParams(response))) {
|
||||
final UnionRefundResult refundResult = UnionRefundResult.create(response);
|
||||
if (SDKConstants.OK_RESP_CODE.equals(refundResult.getRespCode())) {
|
||||
return refundResult;
|
||||
|
||||
}
|
||||
throw new PayErrorException(new PayException(response.getString(SDKConstants.param_respCode), response.getString(SDKConstants.param_respMsg), response.toJSONString()));
|
||||
}
|
||||
throw new PayErrorException(new PayException("failure", "验证签名失败", response.toJSONString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 交易关闭接口
|
||||
* TODO 这个是冲正接口, 后续进行迁移
|
||||
@@ -639,9 +587,34 @@ public class UnionPayKit extends BasePayService<UnionPayConfigStorage> {
|
||||
return UriVariables.getParametersToMap(responseStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 消费撤销/退货接口
|
||||
*
|
||||
* @param refundOrder 退款订单信息
|
||||
* @return 返回支付方申请退款后的结果
|
||||
*/
|
||||
@Override
|
||||
public UnionRefundResult refund(UniRefundOrder refundOrder) {
|
||||
return unionRefundOrConsumeUndo(refundOrder, UnionTransactionType.REFUND);
|
||||
Map<String, Object> params = this.getCommonParam();
|
||||
initNotifyUrl(params, refundOrder);
|
||||
UnionTransactionType.REFUND.convertMap(params);
|
||||
params.put(SDKConstants.param_orderId, refundOrder.getRefundNo());
|
||||
params.put(SDKConstants.param_txnAmt, Util.conversionCentAmount(refundOrder.getRefundAmount()));
|
||||
params.put(SDKConstants.param_origQryId, refundOrder.getTradeNo());
|
||||
params.putAll(refundOrder.getAttrs());
|
||||
this.setSign(params);
|
||||
String responseStr = getHttpRequestTemplate().postForObject(this.getBackTransUrl(), params, String.class);
|
||||
JSONObject response = UriVariables.getParametersToMap(responseStr);
|
||||
|
||||
if (this.verify(new NoticeParams(response))) {
|
||||
final UnionRefundResult refundResult = UnionRefundResult.create(response);
|
||||
if (SDKConstants.OK_RESP_CODE.equals(refundResult.getRespCode())) {
|
||||
return refundResult;
|
||||
|
||||
}
|
||||
throw new PayErrorException(new PayException(response.getString(SDKConstants.param_respCode), response.getString(SDKConstants.param_respMsg), response.toJSONString()));
|
||||
}
|
||||
throw new PayErrorException(new PayException("failure", "验证签名失败", response.toJSONString()));
|
||||
}
|
||||
|
||||
|
||||
@@ -690,7 +663,7 @@ public class UnionPayKit extends BasePayService<UnionPayConfigStorage> {
|
||||
JSONObject response = UriVariables.getParametersToMap(responseStr);
|
||||
// if (this.verify(response)) {
|
||||
// if (SDKConstants.OK_RESP_CODE.equals(response.get(SDKConstants.param_respCode))) {
|
||||
return response;
|
||||
return response;
|
||||
// }
|
||||
// throw new PayErrorException(new PayException(response.get(SDKConstants.param_respCode).toString(), response.get(SDKConstants.param_respMsg).toString(), response.toString()));
|
||||
// }
|
||||
|
@@ -1,6 +1,8 @@
|
||||
package org.dromara.daxpay.channel.union.sdk.bean;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.dromara.daxpay.unisdk.common.bean.BaseRefundResult;
|
||||
import org.dromara.daxpay.unisdk.common.bean.CurType;
|
||||
|
||||
@@ -14,6 +16,8 @@ import java.util.Map;
|
||||
* email egzosn@gmail.com
|
||||
* date 2020/8/16 22:15
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class UnionRefundResult extends BaseRefundResult {
|
||||
|
||||
/**
|
||||
@@ -182,142 +186,6 @@ public class UnionRefundResult extends BaseRefundResult {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getQrCode() {
|
||||
return qrCode;
|
||||
}
|
||||
|
||||
public void setQrCode(String qrCode) {
|
||||
this.qrCode = qrCode;
|
||||
}
|
||||
|
||||
public String getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
public void setSignature(String signature) {
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
public String getSignMethod() {
|
||||
return signMethod;
|
||||
}
|
||||
|
||||
public void setSignMethod(String signMethod) {
|
||||
this.signMethod = signMethod;
|
||||
}
|
||||
|
||||
public String getRespCode() {
|
||||
return respCode;
|
||||
}
|
||||
|
||||
public void setRespCode(String respCode) {
|
||||
this.respCode = respCode;
|
||||
}
|
||||
|
||||
public String getRespMsg() {
|
||||
return respMsg;
|
||||
}
|
||||
|
||||
public void setRespMsg(String respMsg) {
|
||||
this.respMsg = respMsg;
|
||||
}
|
||||
|
||||
public String getSignPubKeyCert() {
|
||||
return signPubKeyCert;
|
||||
}
|
||||
|
||||
public void setSignPubKeyCert(String signPubKeyCert) {
|
||||
this.signPubKeyCert = signPubKeyCert;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
public void setEncoding(String encoding) {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
public String getBizType() {
|
||||
return bizType;
|
||||
}
|
||||
|
||||
public void setBizType(String bizType) {
|
||||
this.bizType = bizType;
|
||||
}
|
||||
|
||||
public String getTxnTime() {
|
||||
return txnTime;
|
||||
}
|
||||
|
||||
public void setTxnTime(String txnTime) {
|
||||
this.txnTime = txnTime;
|
||||
}
|
||||
|
||||
public String getTxnType() {
|
||||
return txnType;
|
||||
}
|
||||
|
||||
public void setTxnType(String txnType) {
|
||||
this.txnType = txnType;
|
||||
}
|
||||
|
||||
public String getTxnSubType() {
|
||||
return txnSubType;
|
||||
}
|
||||
|
||||
public void setTxnSubType(String txnSubType) {
|
||||
this.txnSubType = txnSubType;
|
||||
}
|
||||
|
||||
public String getAccessType() {
|
||||
return accessType;
|
||||
}
|
||||
|
||||
public void setAccessType(String accessType) {
|
||||
this.accessType = accessType;
|
||||
}
|
||||
|
||||
public String getReqReserved() {
|
||||
return reqReserved;
|
||||
}
|
||||
|
||||
public void setReqReserved(String reqReserved) {
|
||||
this.reqReserved = reqReserved;
|
||||
}
|
||||
|
||||
public String getMerId() {
|
||||
return merId;
|
||||
}
|
||||
|
||||
public void setMerId(String merId) {
|
||||
this.merId = merId;
|
||||
}
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public void setOrderId(String orderId) {
|
||||
this.orderId = orderId;
|
||||
}
|
||||
|
||||
public String getReserved() {
|
||||
return reserved;
|
||||
}
|
||||
|
||||
public void setReserved(String reserved) {
|
||||
this.reserved = reserved;
|
||||
}
|
||||
|
||||
public static UnionRefundResult create(Map<String, Object> result){
|
||||
UnionRefundResult refundResult = new JSONObject(result).toJavaObject(UnionRefundResult.class);
|
||||
refundResult.setAttrs(result);
|
||||
|
@@ -0,0 +1,99 @@
|
||||
package org.dromara.daxpay.channel.union.service.callback;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.daxpay.channel.union.code.UnionPayCode;
|
||||
import org.dromara.daxpay.channel.union.sdk.api.UnionPayKit;
|
||||
import org.dromara.daxpay.channel.union.sdk.bean.SDKConstants;
|
||||
import org.dromara.daxpay.channel.union.service.config.UnionPayConfigService;
|
||||
import org.dromara.daxpay.core.enums.CallbackStatusEnum;
|
||||
import org.dromara.daxpay.core.enums.ChannelEnum;
|
||||
import org.dromara.daxpay.core.enums.PayStatusEnum;
|
||||
import org.dromara.daxpay.core.enums.TradeTypeEnum;
|
||||
import org.dromara.daxpay.core.util.PayUtil;
|
||||
import org.dromara.daxpay.service.common.context.CallbackLocal;
|
||||
import org.dromara.daxpay.service.common.local.PaymentContextLocal;
|
||||
import org.dromara.daxpay.service.service.record.callback.TradeCallbackRecordService;
|
||||
import org.dromara.daxpay.service.service.trade.pay.PayCallbackService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 云闪付支付回调
|
||||
* @author xxm
|
||||
* @since 2024/10/9
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UnionPayCallbackService {
|
||||
|
||||
private final PayCallbackService payCallbackService;
|
||||
private final TradeCallbackRecordService tradeCallbackRecordService;
|
||||
private final UnionPayConfigService unionPayConfigService;
|
||||
|
||||
/**
|
||||
* 支付回调处理
|
||||
*/
|
||||
public String payHandle(HttpServletRequest request){
|
||||
// 解析数据
|
||||
if (this.resolve(request)){
|
||||
// 执行回调业务处理
|
||||
payCallbackService.payCallback();
|
||||
// 保存记录
|
||||
tradeCallbackRecordService.saveCallbackRecord();
|
||||
return "success";
|
||||
} else {
|
||||
// 保存记录
|
||||
tradeCallbackRecordService.saveCallbackRecord();
|
||||
return "fail";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析支付回调数据并放到上下文中
|
||||
*/
|
||||
@SneakyThrows
|
||||
public boolean resolve(HttpServletRequest request) {
|
||||
Map<String, String> callbackParam = PayUtil.toMap(request);
|
||||
CallbackLocal callbackInfo = PaymentContextLocal.get().getCallbackInfo();
|
||||
// 设置类型和通道
|
||||
callbackInfo.setCallbackType(TradeTypeEnum.PAY)
|
||||
.setChannel(ChannelEnum.UNION_PAY.getCode())
|
||||
.setCallbackData(callbackParam);
|
||||
// 签名校验
|
||||
UnionPayKit unionPayKit = unionPayConfigService.initPayKit();
|
||||
boolean verify = unionPayKit.signVerify(callbackParam, callbackParam.get(SDKConstants.param_signature));
|
||||
if (!verify){
|
||||
callbackInfo.setCallbackStatus(CallbackStatusEnum.FAIL);
|
||||
return false;
|
||||
}
|
||||
// 网关支付号
|
||||
callbackInfo.setOutTradeNo(callbackParam.get(UnionPayCode.QUERY_ID));
|
||||
// 支付号
|
||||
callbackInfo.setTradeNo(callbackParam.get(UnionPayCode.ORDER_ID));
|
||||
// 支付结果
|
||||
String resultCode = callbackParam.get(UnionPayCode.RESP_CODE);
|
||||
PayStatusEnum payStatus = UnionPayCode.RESP_SUCCESS.equals(resultCode) ? PayStatusEnum.SUCCESS : PayStatusEnum.FAIL;
|
||||
// 支付状态
|
||||
callbackInfo.setTradeStatus(payStatus.getCode());
|
||||
// 支付金额
|
||||
String amount = callbackParam.get(UnionPayCode.TXN_AMT);
|
||||
callbackInfo.setAmount(PayUtil.conversionAmount(Integer.parseInt(amount)));
|
||||
String timeEnd = callbackParam.get(UnionPayCode.TXN_TIME);
|
||||
if (StrUtil.isNotBlank(timeEnd)) {
|
||||
LocalDateTime time = LocalDateTimeUtil.parse(timeEnd, DatePattern.PURE_DATETIME_PATTERN);
|
||||
callbackInfo.setFinishTime(time);
|
||||
} else {
|
||||
callbackInfo.setFinishTime(LocalDateTime.now());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -0,0 +1,98 @@
|
||||
package org.dromara.daxpay.channel.union.service.callback;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.daxpay.channel.union.code.UnionPayCode;
|
||||
import org.dromara.daxpay.channel.union.sdk.api.UnionPayKit;
|
||||
import org.dromara.daxpay.channel.union.sdk.bean.SDKConstants;
|
||||
import org.dromara.daxpay.channel.union.service.config.UnionPayConfigService;
|
||||
import org.dromara.daxpay.core.enums.CallbackStatusEnum;
|
||||
import org.dromara.daxpay.core.enums.ChannelEnum;
|
||||
import org.dromara.daxpay.core.enums.RefundStatusEnum;
|
||||
import org.dromara.daxpay.core.enums.TradeTypeEnum;
|
||||
import org.dromara.daxpay.core.util.PayUtil;
|
||||
import org.dromara.daxpay.service.common.context.CallbackLocal;
|
||||
import org.dromara.daxpay.service.common.local.PaymentContextLocal;
|
||||
import org.dromara.daxpay.service.service.record.callback.TradeCallbackRecordService;
|
||||
import org.dromara.daxpay.service.service.trade.refund.RefundCallbackService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 云闪付退款回调
|
||||
* @author xxm
|
||||
* @since 2024/10/9
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UnionRefundCallbackService {
|
||||
|
||||
private final RefundCallbackService refundCallbackService;
|
||||
private final TradeCallbackRecordService tradeCallbackRecordService;
|
||||
private final UnionPayConfigService unionPayConfigService;
|
||||
|
||||
/**
|
||||
* 退款回调处理
|
||||
*/
|
||||
public String refundHandle(HttpServletRequest request){
|
||||
// 解析数据
|
||||
if (this.resolve(request)){
|
||||
// 执行回调业务处理
|
||||
refundCallbackService.refundCallback();
|
||||
// 保存记录
|
||||
tradeCallbackRecordService.saveCallbackRecord();
|
||||
return "success";
|
||||
} else {
|
||||
// 保存记录
|
||||
tradeCallbackRecordService.saveCallbackRecord();
|
||||
return "fail";
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public boolean resolve(HttpServletRequest request) {
|
||||
Map<String, String> callbackParam = PayUtil.toMap(request);
|
||||
CallbackLocal callbackInfo = PaymentContextLocal.get().getCallbackInfo();
|
||||
// 设置类型和通道
|
||||
callbackInfo.setCallbackType(TradeTypeEnum.REFUND)
|
||||
.setChannel(ChannelEnum.UNION_PAY.getCode())
|
||||
.setCallbackData(callbackParam);
|
||||
|
||||
// 签名校验
|
||||
UnionPayKit unionPayKit = unionPayConfigService.initPayKit();
|
||||
boolean verify = unionPayKit.signVerify(callbackParam, callbackParam.get(SDKConstants.param_signature));
|
||||
if (!verify){
|
||||
callbackInfo.setCallbackStatus(CallbackStatusEnum.FAIL);
|
||||
return false;
|
||||
}
|
||||
// 网关退款号
|
||||
callbackInfo.setOutTradeNo(callbackParam.get(UnionPayCode.QUERY_ID));
|
||||
// 退款订单号
|
||||
callbackInfo.setTradeNo(callbackParam.get(UnionPayCode.ORDER_ID));
|
||||
// 退款金额
|
||||
String amount = callbackParam.get(UnionPayCode.TXN_AMT);
|
||||
callbackInfo.setAmount(PayUtil.conversionAmount(Integer.parseInt(amount)));
|
||||
// 交易状态
|
||||
String resultCode = callbackParam.get(UnionPayCode.RESP_CODE);
|
||||
RefundStatusEnum refundStatus = UnionPayCode.RESP_SUCCESS.equals(resultCode) ? RefundStatusEnum.SUCCESS : RefundStatusEnum.FAIL;
|
||||
callbackInfo.setTradeStatus(refundStatus.getCode());
|
||||
|
||||
// 退款时间
|
||||
String timeEnd = callbackParam.get(UnionPayCode.TXN_TIME);
|
||||
if (StrUtil.isNotBlank(timeEnd)) {
|
||||
LocalDateTime time = LocalDateTimeUtil.parse(timeEnd, DatePattern.PURE_DATETIME_PATTERN);
|
||||
callbackInfo.setFinishTime(time);
|
||||
} else {
|
||||
callbackInfo.setFinishTime(LocalDateTime.now());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -115,14 +115,6 @@ public class UnionPayConfigService {
|
||||
return UnionPayConfig.convertConfig(channelConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取异步通知地址
|
||||
*/
|
||||
public String getNotifyUrl() {
|
||||
var mchAppInfo = PaymentContextLocal.get().getMchAppInfo();
|
||||
var platformInfo = platformConfigService.getConfig();
|
||||
return StrUtil.format("{}/unipay/callback/{}/{}/union",platformInfo.getGatewayServiceUrl(),mchAppInfo.getAppId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支付异步通知地址
|
||||
@@ -130,7 +122,7 @@ public class UnionPayConfigService {
|
||||
public String getPayNotifyUrl() {
|
||||
MchAppLocal mchAppInfo = PaymentContextLocal.get().getMchAppInfo();
|
||||
var platformInfo = platformConfigService.getConfig();
|
||||
return StrUtil.format("{}/unipay/callback/{}/{}/wechat/pay",platformInfo.getGatewayServiceUrl(),mchAppInfo.getAppId());
|
||||
return StrUtil.format("{}/unipay/callback/{}/union/pay",platformInfo.getGatewayServiceUrl(),mchAppInfo.getAppId());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,7 +131,7 @@ public class UnionPayConfigService {
|
||||
public String getRefundNotifyUrl() {
|
||||
MchAppLocal mchAppInfo = PaymentContextLocal.get().getMchAppInfo();
|
||||
var platformInfo = platformConfigService.getConfig();
|
||||
return StrUtil.format("{}/unipay/callback/{}/{}/wechat/refund",platformInfo.getGatewayServiceUrl(), mchAppInfo.getAppId());
|
||||
return StrUtil.format("{}/unipay/callback/{}/union/refund",platformInfo.getGatewayServiceUrl(), mchAppInfo.getAppId());
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user