From 3c2deabfdf905f9c17e8eb3074b4a8875225e10b Mon Sep 17 00:00:00 2001 From: xxm1995 Date: Mon, 11 Mar 2024 18:47:01 +0800 Subject: [PATCH] =?UTF-8?q?feat=20=E4=BA=91=E9=97=AA=E4=BB=98=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E5=AF=B9=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + _doc/Task.md | 6 +- .../daxpay/sdk/payment/PayCloseOrderTest.java | 2 + .../daxpay/sdk/payment/PayOrderSyncTest.java | 2 + .../daxpay/sdk/payment/PayOrderTest.java | 2 + .../sdk/payment/RefundOrderSyncTest.java | 2 + .../daxpay/sdk/payment/RefundOrderTest.java | 2 + .../sdk/payment/SimplePayOrderTest.java | 2 + .../sdk/payment/SimpleRefundOrderTest.java | 2 + .../daxpay/sdk/query/QueryPayOrderTest.java | 2 + .../sdk/query/QueryRefundOrderTest.java | 2 + .../daxpay/code/RefundSyncStatusEnum.java | 4 +- .../daxpay/service/code/UnionPayCode.java | 48 +++----- .../service/UnionPayCallbackService.java | 59 ++++++--- .../union/service/UnionPayConfigService.java | 10 +- .../union/service/UnionPayRefundService.java | 45 ++----- .../union/service/UnionPayService.java | 24 ---- .../union/service/UnionPaySyncService.java | 112 ++++++++---------- .../service/WeChatPayCallbackService.java | 7 +- .../refund/service/RefundAssistService.java | 1 + .../refund/strategy/UnionRefundStrategy.java | 2 +- .../strategy/pay/UnionPayRepairStrategy.java | 31 ++++- .../factory/RefundSyncStrategyFactory.java | 4 + .../payment/sync/service/PaySyncService.java | 6 +- .../sync/service/RefundSyncService.java | 5 +- .../Refund/UnionRefundSyncStrategy.java | 49 ++++++++ .../service/sdk/union/api/UnionPayKit.java | 7 +- 用户授权使用协议.txt | 7 +- 28 files changed, 252 insertions(+), 194 deletions(-) create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/strategy/Refund/UnionRefundSyncStrategy.java diff --git a/README.md b/README.md index 7085bcca2..9822fdd8b 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,7 @@ public class SimplePayOrderTest { .serviceUrl("http://127.0.0.1:9000") // 需要跟网关中配置一致 .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) .build(); DaxPayKit.initConfig(config); } diff --git a/_doc/Task.md b/_doc/Task.md index 0f7c51f82..affe8267b 100644 --- a/_doc/Task.md +++ b/_doc/Task.md @@ -1,9 +1,9 @@ 2.0.3: - [ ] 云闪付接入 - - [ ] 支付 - - [ ] 退款 - - [ ] 同步 + - [x] 支付 + - [x] 退款 + - [x] 同步 - [ ] 对账 - [ ] 回调 - [ ] 统一关闭接口增加使用撤销关闭订单 diff --git a/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/PayCloseOrderTest.java b/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/PayCloseOrderTest.java index c65ce5862..d223ea942 100644 --- a/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/PayCloseOrderTest.java +++ b/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/PayCloseOrderTest.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.sdk.payment; +import cn.bootx.platform.daxpay.sdk.code.SignTypeEnum; import cn.bootx.platform.daxpay.sdk.model.pay.PayCloseModel; import cn.bootx.platform.daxpay.sdk.net.DaxPayConfig; import cn.bootx.platform.daxpay.sdk.net.DaxPayKit; @@ -22,6 +23,7 @@ public class PayCloseOrderTest { DaxPayConfig config = DaxPayConfig.builder() .serviceUrl("http://127.0.0.1:9000") .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) .build(); DaxPayKit.initConfig(config); } diff --git a/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/PayOrderSyncTest.java b/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/PayOrderSyncTest.java index 89ec9cf68..e3eaf9d15 100644 --- a/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/PayOrderSyncTest.java +++ b/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/PayOrderSyncTest.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.sdk.payment; +import cn.bootx.platform.daxpay.sdk.code.SignTypeEnum; import cn.bootx.platform.daxpay.sdk.model.sync.PaySyncModel; import cn.bootx.platform.daxpay.sdk.net.DaxPayConfig; import cn.bootx.platform.daxpay.sdk.net.DaxPayKit; @@ -22,6 +23,7 @@ public class PayOrderSyncTest { DaxPayConfig config = DaxPayConfig.builder() .serviceUrl("http://127.0.0.1:9000") .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) .build(); DaxPayKit.initConfig(config); } diff --git a/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/PayOrderTest.java b/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/PayOrderTest.java index 80e0bec67..77de4fe86 100644 --- a/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/PayOrderTest.java +++ b/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/PayOrderTest.java @@ -2,6 +2,7 @@ package cn.bootx.platform.daxpay.sdk.payment; import cn.bootx.platform.daxpay.sdk.code.PayChannelEnum; import cn.bootx.platform.daxpay.sdk.code.PayWayEnum; +import cn.bootx.platform.daxpay.sdk.code.SignTypeEnum; import cn.bootx.platform.daxpay.sdk.model.pay.PayOrderModel; import cn.bootx.platform.daxpay.sdk.net.DaxPayConfig; import cn.bootx.platform.daxpay.sdk.net.DaxPayKit; @@ -30,6 +31,7 @@ public class PayOrderTest { DaxPayConfig config = DaxPayConfig.builder() .serviceUrl("http://127.0.0.1:9000") .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) .build(); DaxPayKit.initConfig(config); } diff --git a/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/RefundOrderSyncTest.java b/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/RefundOrderSyncTest.java index be665b119..e71aaa4ee 100644 --- a/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/RefundOrderSyncTest.java +++ b/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/RefundOrderSyncTest.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.sdk.payment; +import cn.bootx.platform.daxpay.sdk.code.SignTypeEnum; import cn.bootx.platform.daxpay.sdk.model.sync.RefundSyncModel; import cn.bootx.platform.daxpay.sdk.net.DaxPayConfig; import cn.bootx.platform.daxpay.sdk.net.DaxPayKit; @@ -22,6 +23,7 @@ public class RefundOrderSyncTest { DaxPayConfig config = DaxPayConfig.builder() .serviceUrl("http://127.0.0.1:9000") .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) .build(); DaxPayKit.initConfig(config); } diff --git a/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/RefundOrderTest.java b/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/RefundOrderTest.java index 680a7a76f..7e88af42e 100644 --- a/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/RefundOrderTest.java +++ b/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/RefundOrderTest.java @@ -1,6 +1,7 @@ package cn.bootx.platform.daxpay.sdk.payment; import cn.bootx.platform.daxpay.sdk.code.PayChannelEnum; +import cn.bootx.platform.daxpay.sdk.code.SignTypeEnum; import cn.bootx.platform.daxpay.sdk.model.refund.RefundModel; import cn.bootx.platform.daxpay.sdk.net.DaxPayConfig; import cn.bootx.platform.daxpay.sdk.net.DaxPayKit; @@ -29,6 +30,7 @@ public class RefundOrderTest { DaxPayConfig config = DaxPayConfig.builder() .serviceUrl("http://127.0.0.1:9000") .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) .build(); DaxPayKit.initConfig(config); } diff --git a/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/SimplePayOrderTest.java b/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/SimplePayOrderTest.java index 865cc241f..f2e59004e 100644 --- a/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/SimplePayOrderTest.java +++ b/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/SimplePayOrderTest.java @@ -2,6 +2,7 @@ package cn.bootx.platform.daxpay.sdk.payment; import cn.bootx.platform.daxpay.sdk.code.PayChannelEnum; import cn.bootx.platform.daxpay.sdk.code.PayWayEnum; +import cn.bootx.platform.daxpay.sdk.code.SignTypeEnum; import cn.bootx.platform.daxpay.sdk.model.pay.PayOrderModel; import cn.bootx.platform.daxpay.sdk.net.DaxPayConfig; import cn.bootx.platform.daxpay.sdk.net.DaxPayKit; @@ -24,6 +25,7 @@ public class SimplePayOrderTest { DaxPayConfig config = DaxPayConfig.builder() .serviceUrl("http://127.0.0.1:9000") .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) .build(); DaxPayKit.initConfig(config); } diff --git a/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/SimpleRefundOrderTest.java b/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/SimpleRefundOrderTest.java index e5b5f03be..597c21615 100644 --- a/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/SimpleRefundOrderTest.java +++ b/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/payment/SimpleRefundOrderTest.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.sdk.payment; +import cn.bootx.platform.daxpay.sdk.code.SignTypeEnum; import cn.bootx.platform.daxpay.sdk.model.refund.RefundModel; import cn.bootx.platform.daxpay.sdk.net.DaxPayConfig; import cn.bootx.platform.daxpay.sdk.net.DaxPayKit; @@ -26,6 +27,7 @@ public class SimpleRefundOrderTest { DaxPayConfig config = DaxPayConfig.builder() .serviceUrl("http://127.0.0.1:9000") .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) .build(); DaxPayKit.initConfig(config); } diff --git a/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/query/QueryPayOrderTest.java b/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/query/QueryPayOrderTest.java index 9758efd9b..a7ad6a84e 100644 --- a/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/query/QueryPayOrderTest.java +++ b/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/query/QueryPayOrderTest.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.sdk.query; +import cn.bootx.platform.daxpay.sdk.code.SignTypeEnum; import cn.bootx.platform.daxpay.sdk.model.pay.QueryPayOrderModel; import cn.bootx.platform.daxpay.sdk.net.DaxPayConfig; import cn.bootx.platform.daxpay.sdk.net.DaxPayKit; @@ -21,6 +22,7 @@ public class QueryPayOrderTest { DaxPayConfig config = DaxPayConfig.builder() .serviceUrl("http://127.0.0.1:9000") .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) .build(); DaxPayKit.initConfig(config); } diff --git a/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/query/QueryRefundOrderTest.java b/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/query/QueryRefundOrderTest.java index 86fbff96d..751c19c5d 100644 --- a/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/query/QueryRefundOrderTest.java +++ b/daxpay-single-sdk/src/test/java/cn/bootx/platform/daxpay/sdk/query/QueryRefundOrderTest.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.sdk.query; +import cn.bootx.platform.daxpay.sdk.code.SignTypeEnum; import cn.bootx.platform.daxpay.sdk.model.refund.QueryRefundOrderModel; import cn.bootx.platform.daxpay.sdk.net.DaxPayConfig; import cn.bootx.platform.daxpay.sdk.net.DaxPayKit; @@ -21,6 +22,7 @@ public class QueryRefundOrderTest { DaxPayConfig config = DaxPayConfig.builder() .serviceUrl("http://127.0.0.1:9000") .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) .build(); DaxPayKit.initConfig(config); } diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/RefundSyncStatusEnum.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/RefundSyncStatusEnum.java index 09a165922..bf37fc891 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/RefundSyncStatusEnum.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/RefundSyncStatusEnum.java @@ -11,9 +11,11 @@ import lombok.Getter; @Getter @AllArgsConstructor public enum RefundSyncStatusEnum { + SUCCESS("refund_success","退款成功"), FAIL("refund_fail","退款失败"), - PROGRESS("refund_progress","退款中"); + PROGRESS("refund_progress","退款中"), + NOT_FOUND("pay_not_found", "交易不存在"); /** 编码 */ private final String code; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/UnionPayCode.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/UnionPayCode.java index 1eb44a0d9..8566b01da 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/UnionPayCode.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/UnionPayCode.java @@ -1,5 +1,7 @@ package cn.bootx.platform.daxpay.service.code; +import com.egzosn.pay.union.bean.SDKConstants; + /** * 云闪付常量 * @author xxm @@ -11,21 +13,29 @@ public interface UnionPayCode { /** 成功状态 */ String SUCCESS = "0"; - /** 状态 0表示成功 */ - String STATUS = "status"; + /** 状态 00表示成功 */ + String RESP_CODE = SDKConstants.param_respCode; - /** 业务结果 0表示成功,非0表示失败 */ - String RESULT_CODE = "result_code"; + /** 业务结果 00表示成功 */ + String RESP_SUCCESS = SDKConstants.OK_RESP_CODE; + + /** 交易类型 */ + String TXN_TYPE = "txnType"; /** 网关订单号 */ String QUERY_ID = "queryId"; - /** 第三方订单号 */ + /** 第三方订单号(本地订单号) */ String ORDER_ID = "orderId"; /** 退款ID */ String REFUND_ID = "refund_id"; + /** 交易类型 支付 */ + String TXN_TYPE_PAY = "01"; + + /** 交易类型 退款 */ + String TXN_TYPE_REFUND = "04"; /** * 订单发送时间 @@ -33,35 +43,13 @@ public interface UnionPayCode { */ String TXN_TIME = "txnTime"; - /** 支付结果 */ - String PAY_RESULT = "pay_result"; + + /** 退款金额 */ + String TXN_AMT = "txnAmt"; /** 总金额 */ String TOTAL_FEE = "settleAmt"; - /** 交易状态 */ - String TRADE_STATE = "trade_state"; - - /** 支付成功 */ - String TRADE_SUCCESS = "SUCCESS"; - - /** 转入退款 */ - String TRADE_REFUND = "REFUND"; - - /** 未支付 */ - String TRADE_NOT_PAY = "NOTPAY"; - - /** 已关闭 */ - String TRADE_CLOSED = "CLOSED"; - - /** 支付失败(其他原因,如银行返回失败) */ - String TRADE_PAY_ERROR = "PAYERROR"; - - /** 返回信息 */ - String MESSAGE = "message"; - - /** 错误代码描述 */ - String ERR_MSG = "err_msg"; /** 对账单下载类型编码 */ diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayCallbackService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayCallbackService.java index 3e5b06175..5fd7706a5 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayCallbackService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayCallbackService.java @@ -3,17 +3,19 @@ package cn.bootx.platform.daxpay.service.core.channel.union.service; import cn.bootx.platform.common.core.util.LocalDateTimeUtil; import cn.bootx.platform.daxpay.code.PayChannelEnum; import cn.bootx.platform.daxpay.code.PayStatusEnum; +import cn.bootx.platform.daxpay.code.RefundStatusEnum; import cn.bootx.platform.daxpay.service.code.PaymentTypeEnum; +import cn.bootx.platform.daxpay.service.code.UnionPayCode; import cn.bootx.platform.daxpay.service.common.context.CallbackLocal; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; import cn.bootx.platform.daxpay.service.core.channel.union.entity.UnionPayConfig; import cn.bootx.platform.daxpay.service.func.AbsCallbackStrategy; import cn.bootx.platform.daxpay.service.sdk.union.api.UnionPayKit; import cn.hutool.core.date.DatePattern; +import cn.hutool.core.thread.ThreadUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.egzosn.pay.common.bean.NoticeParams; -import com.ijpay.core.kit.WxPayKit; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -22,7 +24,6 @@ import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.Collections; import java.util.Map; -import java.util.Objects; import static cn.bootx.platform.daxpay.service.code.UnionPayCode.*; @@ -49,21 +50,9 @@ public class UnionPayCallbackService extends AbsCallbackStrategy { String callReq = JSONUtil.toJsonStr(params); log.info("云闪付发起回调 报文: {}", callReq); - String status = params.get(STATUS); - String returnCode = params.get(RESULT_CODE); - - // 处理失败 - if (!Objects.equals(SUCCESS, status)||!Objects.equals(SUCCESS, returnCode)){ - return false; - } - // 支付回调信息校验 UnionPayConfig config = unionPayConfigService.getConfig(); UnionPayKit unionPayKit = unionPayConfigService.initPayService(config); - if (Objects.isNull(config)) { - log.warn("云闪付支付配置不存在"); - return false; - } NoticeParams noticeParams = new NoticeParams(); noticeParams.setBody(Collections.unmodifiableMap(params)); @@ -71,13 +60,20 @@ public class UnionPayCallbackService extends AbsCallbackStrategy { } /** - * 判断类型 支付回调/退款回调, 云闪付只有支付回调 + * 判断类型 支付回调/退款回调 * * @see PaymentTypeEnum */ @Override public PaymentTypeEnum getCallbackType() { - return PaymentTypeEnum.PAY; + CallbackLocal callbackInfo = PaymentContextLocal.get().getCallbackInfo(); + Map params = callbackInfo.getCallbackParam(); + String txnType = params.get(TXN_TYPE); + if (UnionPayCode.TXN_TYPE_PAY.equals(txnType)){ + return PaymentTypeEnum.PAY; + } else { + return PaymentTypeEnum.REFUND; + } } /** @@ -93,10 +89,12 @@ public class UnionPayCallbackService extends AbsCallbackStrategy { // 支付订单ID callbackInfo.setOrderId(Long.valueOf(callbackParam.get(ORDER_ID))); // 支付结果 - PayStatusEnum payStatus = WxPayKit.codeIsOk(callbackParam.get(PAY_RESULT)) ? PayStatusEnum.SUCCESS : PayStatusEnum.FAIL; + String resultCode = callbackParam.get(UnionPayCode.RESP_CODE); + PayStatusEnum payStatus = UnionPayCode.RESP_SUCCESS.equals(resultCode) ? PayStatusEnum.SUCCESS : PayStatusEnum.FAIL; + callbackInfo.setGatewayStatus(payStatus.getCode()); // 支付金额 - callbackInfo.setAmount(callbackParam.get(TOTAL_FEE)); + callbackInfo.setAmount(callbackParam.get(UnionPayCode.TXN_AMT)); String timeEnd = callbackParam.get(TXN_TIME); if (StrUtil.isNotBlank(timeEnd)) { LocalDateTime time = LocalDateTimeUtil.parse(timeEnd, DatePattern.PURE_DATETIME_PATTERN); @@ -111,6 +109,31 @@ public class UnionPayCallbackService extends AbsCallbackStrategy { */ @Override public void resolveRefundData() { + // 云闪付需要延迟半秒再进行处理, 不然会出现业务未处理完, 但回调已经到达的情况 + ThreadUtil.sleep(300); + + CallbackLocal callbackInfo = PaymentContextLocal.get().getCallbackInfo(); + Map callbackParam = callbackInfo.getCallbackParam(); + // 网关订单号 + callbackInfo.setGatewayOrderNo(callbackParam.get(QUERY_ID)); + // 退款订单Id + callbackInfo.setOrderId(Long.valueOf(callbackParam.get(ORDER_ID))); + // 退款金额 + callbackInfo.setAmount(callbackParam.get(TXN_AMT)); + + // 交易状态 + String resultCode = callbackParam.get(UnionPayCode.RESP_CODE); + RefundStatusEnum refundStatus = UnionPayCode.RESP_SUCCESS.equals(resultCode) ? RefundStatusEnum.SUCCESS : RefundStatusEnum.FAIL; + callbackInfo.setGatewayStatus(refundStatus.getCode()); + + // 退款时间 + String timeEnd = callbackParam.get(TXN_TIME); + if (StrUtil.isNotBlank(timeEnd)) { + LocalDateTime time = LocalDateTimeUtil.parse(timeEnd, DatePattern.PURE_DATETIME_PATTERN); + callbackInfo.setFinishTime(time); + } else { + callbackInfo.setFinishTime(LocalDateTime.now()); + } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayConfigService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayConfigService.java index b96a48c14..9e72aed5e 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayConfigService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayConfigService.java @@ -93,19 +93,19 @@ public class UnionPayConfigService { unionPayConfigStorage.setInputCharset(CharsetUtil.UTF_8); // 商户号 unionPayConfigStorage.setMerId(config.getMachId()); - //是否为证书签名 - unionPayConfigStorage.setCertSign(config.isCertSign()); + // 云闪付必须使用证书才可以进行调用 + unionPayConfigStorage.setCertSign(true); - //中级证书 流 + // 中级证书 流 unionPayConfigStorage.setAcpMiddleCert(new ByteArrayInputStream(Base64.decode(config.getAcpMiddleCert()))); - //根证书 流 + // 根证书 流 unionPayConfigStorage.setAcpRootCert(new ByteArrayInputStream(Base64.decode(config.getAcpRootCert()))); // 私钥证书 流 unionPayConfigStorage.setKeyPrivateCert(new ByteArrayInputStream(Base64.decode(config.getKeyPrivateCert()))); //私钥证书对应的密码 私钥证书对应的密码 unionPayConfigStorage.setKeyPrivateCertPwd(config.getKeyPrivateCertPwd()); - //设置证书对应的存储方式,证书字符串信息 + //设置证书对应的存储方式,证书流 unionPayConfigStorage.setCertStoreType(CertStoreType.INPUT_STREAM); // 回调地址 diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayRefundService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayRefundService.java index 912c976b3..c0956ef7a 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayRefundService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayRefundService.java @@ -1,25 +1,20 @@ package cn.bootx.platform.daxpay.service.core.channel.union.service; -import cn.bootx.platform.daxpay.exception.pay.PayFailureException; +import cn.bootx.platform.daxpay.code.RefundStatusEnum; import cn.bootx.platform.daxpay.service.code.UnionPayCode; import cn.bootx.platform.daxpay.service.common.context.RefundLocal; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; +import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundOrder; import cn.bootx.platform.daxpay.service.sdk.union.api.UnionPayKit; import cn.bootx.platform.daxpay.service.sdk.union.bean.UnionRefundOrder; -import cn.hutool.core.util.StrUtil; import com.egzosn.pay.union.bean.UnionRefundResult; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.math.BigDecimal; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -import static cn.bootx.platform.daxpay.service.code.UnionPayCode.*; /** * 云闪付退款操作 @@ -34,46 +29,22 @@ public class UnionPayRefundService { /** * 退款方法 */ - public void refund(RefundOrder refundOrder, int amount, PayChannelOrder channelOrder, UnionPayKit unionPayKit) { + public void refund(RefundOrder refundOrder, PayOrder payOrder, int amount, PayChannelOrder channelOrder, UnionPayKit unionPayKit) { // 金额转换 BigDecimal refundAmount = BigDecimal.valueOf(amount * 0.01); BigDecimal orderAmount = BigDecimal.valueOf(channelOrder.getAmount() * 0.01); UnionRefundOrder unionRefundOrder = new UnionRefundOrder(); - unionRefundOrder.setOutTradeNo(String.valueOf(refundOrder.getPaymentId())); unionRefundOrder.setRefundNo(String.valueOf(refundOrder.getId())); + unionRefundOrder.setTradeNo(String.valueOf(payOrder.getGatewayOrderNo())); unionRefundOrder.setRefundAmount(refundAmount); unionRefundOrder.setTotalAmount(orderAmount); UnionRefundResult refund = unionPayKit.refund(unionRefundOrder); -// String xmlResult = UnionPayApi.execution(unionPayConfig.getServerUrl(), params); -// Map result = WxPayKit.xmlToMap(xmlResult); -// this.verifyErrorMsg(result); -// // 云闪付退款是否成功需要查询状态, 所以设置为退款中状态 -// RefundLocal refundInfo = PaymentContextLocal.get().getRefundInfo(); -// refundInfo.setStatus(RefundStatusEnum.PROGRESS) -// .setGatewayOrderNo(result.get(REFUND_ID)); - } - - /** - * 验证错误信息 - */ - private void verifyErrorMsg(Map result) { - String status = result.get(UnionPayCode.STATUS); - String returnCode = result.get(UnionPayCode.RESULT_CODE); - - // 判断查询是否成功 - if (!(Objects.equals(SUCCESS, status) && Objects.equals(SUCCESS, returnCode))){ - String errorMsg = result.get(ERR_MSG); - if (StrUtil.isBlank(errorMsg)) { - errorMsg = result.get(MESSAGE); - } - log.error("订单退款失败 {}", errorMsg); - RefundLocal refundInfo = PaymentContextLocal.get().getRefundInfo(); - refundInfo.setErrorMsg(errorMsg); - refundInfo.setErrorCode(Optional.ofNullable(returnCode).orElse(returnCode)); - throw new PayFailureException(errorMsg); - } + String gatewayNo = (String) refund.getAttr(UnionPayCode.QUERY_ID); + // 云闪付退款是否成功需要查询状态, 所以设置为退款中状态 + RefundLocal refundInfo = PaymentContextLocal.get().getRefundInfo(); + refundInfo.setStatus(RefundStatusEnum.PROGRESS).setGatewayOrderNo(gatewayNo); } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayService.java index 43f0dbf21..f114e5a93 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayService.java @@ -5,7 +5,6 @@ import cn.bootx.platform.daxpay.exception.pay.PayFailureException; import cn.bootx.platform.daxpay.param.channel.UnionPayParam; import cn.bootx.platform.daxpay.param.pay.PayChannelParam; import cn.bootx.platform.daxpay.service.code.AliPayWay; -import cn.bootx.platform.daxpay.service.code.UnionPayCode; import cn.bootx.platform.daxpay.service.common.context.PayLocal; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; import cn.bootx.platform.daxpay.service.core.channel.union.entity.UnionPayConfig; @@ -14,7 +13,6 @@ import cn.bootx.platform.daxpay.service.sdk.union.api.UnionPayKit; import cn.bootx.platform.daxpay.service.sdk.union.bean.UnionPayOrder; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.StrUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -22,11 +20,8 @@ import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.util.Date; import java.util.Map; -import java.util.Objects; import java.util.Optional; -import static cn.bootx.platform.daxpay.service.code.UnionPayCode.*; - /** * 云闪付支付 * @author xxm @@ -163,23 +158,4 @@ public class UnionPayService { // String xmlResult = UnionPayApi.execution(unionPayKit.getServerUrl(), params); } - - /** - * 验证错误信息 - */ - private void verifyErrorMsg(Map result) { - String status = result.get(UnionPayCode.STATUS); - String returnCode = result.get(UnionPayCode.RESULT_CODE); - - // 判断查询是否成功 - if (!(Objects.equals(SUCCESS, status) && Objects.equals(SUCCESS, returnCode))){ - String errorMsg = result.get(ERR_MSG); - if (StrUtil.isBlank(errorMsg)) { - errorMsg = result.get(MESSAGE); - } - log.error("订单关闭失败 {}", errorMsg); - throw new PayFailureException(errorMsg); - } - } - } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPaySyncService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPaySyncService.java index 605cdbddb..b4b1bb1a6 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPaySyncService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPaySyncService.java @@ -9,10 +9,8 @@ import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundOrder; import cn.bootx.platform.daxpay.service.core.payment.sync.result.PayGatewaySyncResult; import cn.bootx.platform.daxpay.service.core.payment.sync.result.RefundGatewaySyncResult; import cn.bootx.platform.daxpay.service.sdk.union.api.UnionPayKit; -import cn.bootx.platform.daxpay.service.sdk.union.bean.UnionRefundOrder; import cn.hutool.core.date.DatePattern; import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.egzosn.pay.common.bean.AssistOrder; import com.egzosn.pay.common.bean.NoticeParams; @@ -25,7 +23,8 @@ import java.time.LocalDateTime; import java.util.Map; import java.util.Objects; -import static cn.bootx.platform.daxpay.service.code.UnionPayCode.*; +import static cn.bootx.platform.daxpay.service.code.UnionPayCode.QUERY_ID; +import static cn.bootx.platform.daxpay.service.code.UnionPayCode.TXN_TIME; /** * 云闪付支付同步 @@ -44,6 +43,7 @@ public class UnionPaySyncService { PayGatewaySyncResult syncResult = new PayGatewaySyncResult().setSyncStatus(PaySyncStatusEnum.FAIL); AssistOrder query = new AssistOrder(); +// query.setOutTradeNo("1766811070348001280"); query.setOutTradeNo(String.valueOf(order.getId())); Map result = unionPayKit.query(query); @@ -53,24 +53,29 @@ public class UnionPaySyncService { return syncResult.setErrorMsg("查询订单验签失败"); } + String resultCode = MapUtil.getStr(result, UnionPayCode.RESP_CODE); + + // 订单不存在 + if (Objects.equals(resultCode, "34")) { + return syncResult.setSyncStatus(PaySyncStatusEnum.NOT_FOUND); + } // 查询失败 - String resultCode = MapUtil.getStr(result, SDKConstants.param_respCode); - if (!SDKConstants.OK_RESP_CODE.equals(resultCode)) { + if (!UnionPayCode.RESP_SUCCESS.equals(resultCode)) { log.warn("查询云闪付订单失败:{}", result); return syncResult.setErrorMsg(MapUtil.getStr(result, SDKConstants.param_respMsg)); } + // 状态响应码 String origRespCode = MapUtil.getStr(result, SDKConstants.param_origRespCode); - // 查询流水号, 相当于网关订单号 - - // 成功 - if (Objects.equals(origRespCode, SDKConstants.OK_RESP_CODE)) { + if (Objects.equals(origRespCode, UnionPayCode.RESP_SUCCESS)) { + // 查询流水号, 相当于网关订单号 String queryId = MapUtil.getStr(result, QUERY_ID); String timeEnd = MapUtil.getStr(result, TXN_TIME); LocalDateTime time = LocalDateTimeUtil.parse(timeEnd, DatePattern.PURE_DATETIME_PATTERN); return syncResult.setGatewayOrderNo(queryId).setPayTime(time).setSyncStatus(PaySyncStatusEnum.SUCCESS); } + // 支付超时 交易不在受理时间范围内 if (Objects.equals(origRespCode, "39")) { return syncResult.setSyncStatus(PaySyncStatusEnum.TIMEOUT) @@ -81,74 +86,55 @@ public class UnionPaySyncService { if (Objects.equals(origRespCode, "05")) { return syncResult.setSyncStatus(PaySyncStatusEnum.PROGRESS); } -// -// // 已退款/退款中 -// if (Objects.equals(tradeStatus, TRADE_REFUND)) { -// return syncResult.setSyncStatus(PaySyncStatusEnum.REFUND); -// } -// // 已关闭 -// if (Objects.equals(tradeStatus, TRADE_CLOSED)) { -// return syncResult.setSyncStatus(PaySyncStatusEnum.CLOSED); -// } return syncResult; } /** * 退款信息查询 + * 云闪付退款和支付查询接口是一个 */ public RefundGatewaySyncResult syncRefundStatus(RefundOrder refundOrder, UnionPayKit unionPayKit){ RefundGatewaySyncResult syncResult = new RefundGatewaySyncResult(); - UnionRefundOrder query = new UnionRefundOrder(); - query.setRefundNo(String.valueOf(refundOrder.getId())); - Map results = unionPayKit.refundquery(query); + AssistOrder query = new AssistOrder(); + query.setOutTradeNo(String.valueOf(refundOrder.getId())); + Map result = unionPayKit.query(query); - try { -// String xmlResult = WxPayApi.orderRefundQuery(false, params); -// Map result = WxPayKit.xmlToMap(xmlResult); -// syncResult.setSyncInfo(JSONUtil.toJsonStr(result)); + if (!unionPayKit.verify(new NoticeParams(result))) { + log.warn("查询云闪付订单验签失败:{}", result); + return syncResult.setErrorMsg("查询订单验签失败"); + } + String resultCode = MapUtil.getStr(result, UnionPayCode.RESP_CODE); - // 设置微信支付网关订单号 -// syncResult.setGatewayOrderNo(result.get(UnionPayCode.REFUND_ID)); - // 状态 -// String tradeStatus = result.get(UnionPayCode.REFUND_STATUS); -// // 退款成功 -// if (Objects.equals(tradeStatus, UnionPayCode.REFUND_SUCCESS)) { -// String timeEnd = result.get(UnionPayCode.REFUND_SUCCESS_TIME); -// LocalDateTime time = LocalDateTimeUtil.parse(timeEnd, DatePattern.NORM_DATETIME_PATTERN); -// return syncResult.setRefundTime(time).setSyncStatus(RefundSyncStatusEnum.SUCCESS); -// } -// // 退款中 -// if (Objects.equals(tradeStatus, UnionPayCode.REFUND_PROCESSING)) { -// return syncResult.setSyncStatus(RefundSyncStatusEnum.PROGRESS); -// } -// String errorMsg = this.getErrorMsg(result); -// return syncResult.setSyncStatus(RefundSyncStatusEnum.FAIL).setErrorMsg(errorMsg); - } catch (Exception e) { - log.error("查询退款订单失败:", e); - syncResult.setSyncStatus(RefundSyncStatusEnum.PROGRESS).setErrorMsg(e.getMessage()); + // 订单不存在 + if (Objects.equals(resultCode, "34")) { + return syncResult.setSyncStatus(RefundSyncStatusEnum.NOT_FOUND); + } + + // 查询失败 + if (!UnionPayCode.RESP_SUCCESS.equals(resultCode)) { + log.warn("查询云闪付订单失败:{}", result); + return syncResult.setErrorMsg(MapUtil.getStr(result, SDKConstants.param_respMsg)); + } + + // 状态响应码 + String origRespCode = MapUtil.getStr(result, SDKConstants.param_origRespCode); + + // 成功 + if (Objects.equals(origRespCode, UnionPayCode.RESP_SUCCESS)) { + // 查询流水号, 相当于网关订单号 + String queryId = MapUtil.getStr(result, QUERY_ID); + String timeEnd = MapUtil.getStr(result, TXN_TIME); + LocalDateTime time = LocalDateTimeUtil.parse(timeEnd, DatePattern.PURE_DATETIME_PATTERN); + return syncResult.setGatewayOrderNo(queryId).setRefundTime(time).setSyncStatus(RefundSyncStatusEnum.SUCCESS); + } + + // 退款中 + if (Objects.equals(origRespCode, "05")) { + return syncResult.setSyncStatus(RefundSyncStatusEnum.PROGRESS); } return syncResult; } - - /** - * 验证错误信息 - */ - private String getErrorMsg(Map result) { - String status = result.get(UnionPayCode.STATUS); - String returnCode = result.get(UnionPayCode.RESULT_CODE); - - // 判断查询是否成功 - if (!(Objects.equals(SUCCESS, status) && Objects.equals(SUCCESS, returnCode))){ - String errorMsg = result.get(ERR_MSG); - if (StrUtil.isBlank(errorMsg)) { - errorMsg = result.get(MESSAGE); - } - log.error("订单查询失败 {}", errorMsg); - return errorMsg; - } - return null; - } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayCallbackService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayCallbackService.java index ab03eff6a..345342249 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayCallbackService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayCallbackService.java @@ -3,6 +3,7 @@ package cn.bootx.platform.daxpay.service.core.channel.wechat.service; import cn.bootx.platform.common.core.util.LocalDateTimeUtil; import cn.bootx.platform.daxpay.code.PayChannelEnum; import cn.bootx.platform.daxpay.code.PayStatusEnum; +import cn.bootx.platform.daxpay.code.RefundStatusEnum; import cn.bootx.platform.daxpay.service.code.PaymentTypeEnum; import cn.bootx.platform.daxpay.service.common.context.CallbackLocal; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; @@ -126,9 +127,9 @@ public class WeChatPayCallbackService extends AbsCallbackStrategy { callbackInfo.setAmount(callbackParam.get(CALLBACK_REFUND_FEE)); // 交易状态 - PayStatusEnum payStatus = Objects.equals(callbackParam.get(CALLBACK_REFUND_STATUS), REFUND_SUCCESS) - ? PayStatusEnum.SUCCESS : PayStatusEnum.FAIL; - callbackInfo.setGatewayStatus(payStatus.getCode()); + RefundStatusEnum refundStatus = Objects.equals(callbackParam.get(CALLBACK_REFUND_STATUS), REFUND_SUCCESS) + ? RefundStatusEnum.SUCCESS : RefundStatusEnum.FAIL; + callbackInfo.setGatewayStatus(refundStatus.getCode()); // 退款时间 String timeEnd = callbackParam.get(CALLBACK_SUCCESS_TIME); diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/service/RefundAssistService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/service/RefundAssistService.java index fe6280f3b..d4cc69c9c 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/service/RefundAssistService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/service/RefundAssistService.java @@ -244,6 +244,7 @@ public class RefundAssistService { refundOrder.setErrorMsg(refundInfo.getErrorMsg()); // 退款失败不保存剩余可退余额, 否则数据看起开会产生困惑 refundOrder.setRefundableBalance(null); + refundOrderManager.updateById(refundOrder); } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/UnionRefundStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/UnionRefundStrategy.java index 20678ffd0..f2b042c5f 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/UnionRefundStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/UnionRefundStrategy.java @@ -63,7 +63,7 @@ public class UnionRefundStrategy extends AbsRefundStrategy { @Override public void doRefundHandler() { UnionPayKit unionPayKit = unionPayConfigService.initPayService(unionPayConfig); - unionPayRefundService.refund(this.getRefundOrder(), this.getRefundChannelParam().getAmount(), this.getPayChannelOrder(), unionPayKit); + unionPayRefundService.refund(this.getRefundOrder(), this.getPayOrder(), this.getRefundChannelParam().getAmount(), this.getPayChannelOrder(), unionPayKit); } /** diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/UnionPayRepairStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/UnionPayRepairStrategy.java index 7ae4a84c6..c1cdf87f3 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/UnionPayRepairStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/UnionPayRepairStrategy.java @@ -1,12 +1,17 @@ package cn.bootx.platform.daxpay.service.core.payment.repair.strategy.pay; import cn.bootx.platform.daxpay.code.PayChannelEnum; +import cn.bootx.platform.daxpay.code.PayStatusEnum; +import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; +import cn.bootx.platform.daxpay.service.core.channel.union.service.UnionPayRecordService; import cn.bootx.platform.daxpay.service.func.AbsPayRepairStrategy; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; +import java.time.LocalDateTime; + import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE; /** @@ -20,6 +25,7 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT @RequiredArgsConstructor public class UnionPayRepairStrategy extends AbsPayRepairStrategy { + private final UnionPayRecordService unionPayRecordService; /** * 策略标识 @@ -30,10 +36,31 @@ public class UnionPayRepairStrategy extends AbsPayRepairStrategy { } /** - * 取消支付 + * 支付成功处理 + */ + @Override + public void doPaySuccessHandler() { + LocalDateTime payTime = PaymentContextLocal.get() + .getRepairInfo() + .getFinishTime(); + this.getChannelOrder().setStatus(PayStatusEnum.SUCCESS.getCode()) + .setPayTime(payTime); + unionPayRecordService.pay(this.getOrder(), this.getChannelOrder()); + } + + /** + * 等待支付处理 + */ + @Override + public void doWaitPayHandler(){ + this.getChannelOrder().setPayTime(null).setStatus(PayStatusEnum.PROGRESS.getCode()); + } + + /** + * 关闭本地支付 */ @Override public void doCloseLocalHandler() { - + this.getChannelOrder().setStatus(PayStatusEnum.CLOSE.getCode()); } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/factory/RefundSyncStrategyFactory.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/factory/RefundSyncStrategyFactory.java index 07484d6f0..6d15ce754 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/factory/RefundSyncStrategyFactory.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/factory/RefundSyncStrategyFactory.java @@ -3,6 +3,7 @@ package cn.bootx.platform.daxpay.service.core.payment.sync.factory; import cn.bootx.platform.daxpay.code.PayChannelEnum; import cn.bootx.platform.daxpay.exception.pay.PayUnsupportedMethodException; import cn.bootx.platform.daxpay.service.core.payment.sync.strategy.Refund.AliRefundSyncStrategy; +import cn.bootx.platform.daxpay.service.core.payment.sync.strategy.Refund.UnionRefundSyncStrategy; import cn.bootx.platform.daxpay.service.core.payment.sync.strategy.Refund.WeChatRefundSyncStrategy; import cn.bootx.platform.daxpay.service.func.AbsRefundSyncStrategy; import cn.hutool.extra.spring.SpringUtil; @@ -27,6 +28,9 @@ public class RefundSyncStrategyFactory { case ALI: strategy = SpringUtil.getBean(AliRefundSyncStrategy.class); break; + case UNION_PAY: + strategy = SpringUtil.getBean(UnionRefundSyncStrategy.class); + break; case WECHAT: strategy = SpringUtil.getBean(WeChatRefundSyncStrategy.class); break; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/service/PaySyncService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/service/PaySyncService.java index b2abc2d07..da3281664 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/service/PaySyncService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/service/PaySyncService.java @@ -181,7 +181,11 @@ public class PaySyncService { } // 退款比对状态不做额外处理, 需要通过退款接口进行处理 - if (orderStatus.equals(PayStatusEnum.REFUNDED.getCode()) && syncStatus.equals(PaySyncStatusEnum.REFUND)){ + List orderClose = Arrays.asList( + PayStatusEnum.REFUNDED.getCode(), + PayStatusEnum.REFUNDING.getCode(), + PayStatusEnum.PARTIAL_REFUND.getCode()); + if (orderClose.contains(orderStatus) || syncStatus.equals(PaySyncStatusEnum.REFUND)){ return true; } return false; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/service/RefundSyncService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/service/RefundSyncService.java index 08fbe6c8a..4fd389989 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/service/RefundSyncService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/service/RefundSyncService.java @@ -170,18 +170,19 @@ public class RefundSyncService { RefundRepairResult repair = new RefundRepairResult(); // 对支付网关同步的结果进行处理 switch (syncStatusEnum) { - // 调用出错 case SUCCESS: repair = repairService.repair(order, RefundRepairWayEnum.REFUND_SUCCESS); break; case PROGRESS: // 不进行处理 - log.warn("退款状态同步接口调用出错"); break; case FAIL: { repair = repairService.repair(order, RefundRepairWayEnum.REFUND_FAIL); break; } + case NOT_FOUND: + repair = repairService.repair(order, RefundRepairWayEnum.REFUND_FAIL); + break; default: { throw new BizException("代码有问题"); } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/strategy/Refund/UnionRefundSyncStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/strategy/Refund/UnionRefundSyncStrategy.java new file mode 100644 index 000000000..b064a1c92 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/strategy/Refund/UnionRefundSyncStrategy.java @@ -0,0 +1,49 @@ +package cn.bootx.platform.daxpay.service.core.payment.sync.strategy.Refund; + +import cn.bootx.platform.daxpay.code.PayChannelEnum; +import cn.bootx.platform.daxpay.code.PaySyncStatusEnum; +import cn.bootx.platform.daxpay.service.core.channel.union.entity.UnionPayConfig; +import cn.bootx.platform.daxpay.service.core.channel.union.service.UnionPayConfigService; +import cn.bootx.platform.daxpay.service.core.channel.union.service.UnionPaySyncService; +import cn.bootx.platform.daxpay.service.core.payment.sync.result.RefundGatewaySyncResult; +import cn.bootx.platform.daxpay.service.func.AbsRefundSyncStrategy; +import cn.bootx.platform.daxpay.service.sdk.union.api.UnionPayKit; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE; + +/** + * 云闪付退款同步 + * @author xxm + * @since 2024/3/11 + */ +@Scope(SCOPE_PROTOTYPE) +@Component +@RequiredArgsConstructor +public class UnionRefundSyncStrategy extends AbsRefundSyncStrategy { + + private final UnionPaySyncService unionPaySyncService; + + private final UnionPayConfigService unionPayConfigService; + /** + * 异步支付单与支付网关进行状态比对后的结果 + * + * @see PaySyncStatusEnum + */ + @Override + public RefundGatewaySyncResult doSyncStatus() { + UnionPayConfig config = unionPayConfigService.getConfig(); + UnionPayKit unionPayKit = unionPayConfigService.initPayService(config); + return unionPaySyncService.syncRefundStatus(this.getRefundOrder(),unionPayKit); + } + + /** + * 策略标识 + */ + @Override + public PayChannelEnum getChannel() { + return PayChannelEnum.UNION_PAY; + } +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/sdk/union/api/UnionPayKit.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/sdk/union/api/UnionPayKit.java index 63245a5af..9b4e19b77 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/sdk/union/api/UnionPayKit.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/sdk/union/api/UnionPayKit.java @@ -81,6 +81,11 @@ public class UnionPayKit extends UnionPayService { if (null != certDescriptor) { return this; } + // + if (!payConfigStorage.isCertSign()){ + return this; + } + try { certDescriptor = new CertDescriptor(); certDescriptor.initPrivateSignCert(payConfigStorage.getKeyPrivateCertInputStream(), payConfigStorage.getKeyPrivateCertPwd(), "PKCS12"); @@ -683,7 +688,7 @@ public class UnionPayKit extends UnionPayService { */ @Override public Map refundquery(RefundOrder refundOrder) { - return Collections.emptyMap(); + return this.query(refundOrder); } /** diff --git a/用户授权使用协议.txt b/用户授权使用协议.txt index 5906b43fb..b8183046e 100644 --- a/用户授权使用协议.txt +++ b/用户授权使用协议.txt @@ -21,8 +21,6 @@ 3. 您拥有使用本软件构建的网站全部内容所有权,并独立承担与这些内容的相关法律义务 -4. 本软件由济南易杯光年软件技术有限公司进行分发,没有授权分销商,也没有任何分公司、代理商、办事处、经销商等销售和分发本产品 - 四、有限担保和免责声明 1. 本软件及所附带的文件是作为不提供任何明确的或隐含的赔偿或担保的形式提供的。 @@ -38,6 +36,9 @@ 7. 如发现客户在使用产品时有任何的非法行为,有权解除授权停止技术支持,并配合有关机关进行调查或向政府部门举报。 +8. 本软件由济南易杯光年软件技术有限公司进行分发,没有授权分销商,也没有任何分公司、代理商、办事处、经销商等销售和分发本产品 + + 五、禁止接入的内容包括但不限于以下内容 1. 诈骗、BC严禁接入、赛车、V盘、X资金盘、贷款、P2P、汇兑、ICO、二清支付严禁接入 @@ -52,5 +53,5 @@ 6. 微信/支付宝/银联官方要求禁止接入的、其他支付通道禁止接入的、以及所有国家法规规定禁止的一切情景 -协议时间:2023年01月01日 +协议日期:2023年01月01日 济南易杯光年软件技术有限公司