From 7d65add2ca6d62820b323295a17b2944bc0dfd0e Mon Sep 17 00:00:00 2001 From: bootx Date: Sat, 10 Feb 2024 22:50:24 +0800 Subject: [PATCH] =?UTF-8?q?feat=20=E8=81=9A=E5=90=88=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E5=A4=84=E7=90=86,=20=E5=A2=9E=E5=8A=A0h5=E5=B5=8C=E5=85=A5?= =?UTF-8?q?=E5=BC=8F=E9=A1=B9=E7=9B=AE=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _doc/Task.md | 114 +------- _license/LICENSE.md | 3 + _license/vue3-vant4-mobile/LICENSE | 21 ++ .../demo/config/DaxPayDemoProperties.java | 3 + .../demo/controller/AggregateController.java | 62 +++++ ...Controller.java => CashierController.java} | 4 +- .../demo/controller/RedirectH5Controller.java | 23 ++ .../daxpay/demo/domain/AggregatePayInfo.java | 27 ++ .../demo/param/AggregateSimplePayParam.java | 33 +++ .../daxpay/demo/result/WxJsapiSignResult.java | 29 ++ .../daxpay/demo/service/AggregateService.java | 258 ++++++++++++++++++ .../daxpay/sdk/code/AggregatePayEnum.java | 23 ++ .../sdk/model/assist/WxAccessTokenModel.java | 23 ++ .../sdk/model/assist/WxAuthUrlModel.java | 20 ++ .../sdk/model/assist/WxJsapiSignModel.java | 32 +++ .../daxpay/sdk/net/DaxPayRequest.java | 36 +-- .../sdk/param/assist/WxAccessTokenParam.java | 38 +++ .../sdk/param/assist/WxAuthUrlParam.java | 49 ++++ .../sdk/param/assist/WxJsapiSignParam.java | 44 +++ .../daxpay/sdk/param/pay/PayCloseParam.java | 9 + .../daxpay/sdk/param/pay/PayParam.java | 15 + .../daxpay/sdk/param/pay/SimplePayParam.java | 15 + .../param/refund/QueryRefundOrderParam.java | 15 + .../daxpay/sdk/param/refund/RefundParam.java | 9 + .../sdk/param/refund/SimpleRefundParam.java | 10 + .../daxpay/sdk/payment/RefundOrderTest.java | 1 - ...mmonParam.java => PaymentCommonParam.java} | 23 +- .../param/assist/WxAccessTokenParam.java | 22 ++ .../daxpay/param/assist/WxAuthUrlParam.java | 28 ++ .../param/assist/WxJsapiPrePayParam.java | 24 ++ .../daxpay/param/pay/PayCloseParam.java | 3 +- .../platform/daxpay/param/pay/PayParam.java | 22 +- .../daxpay/param/pay/PaySyncParam.java | 3 +- .../daxpay/param/pay/QueryPayOrderParam.java | 3 +- .../daxpay/param/pay/QueryPayParam.java | 3 +- .../param/pay/QueryRefundOrderParam.java | 3 +- .../daxpay/param/pay/QueryRefundParam.java | 3 +- .../daxpay/param/pay/RefundParam.java | 14 +- .../daxpay/param/pay/RefundSyncParam.java | 3 +- .../daxpay/param/pay/SimplePayParam.java | 20 +- .../daxpay/param/pay/SimpleRefundParam.java | 16 +- .../result/assist/WxAccessTokenResult.java | 22 ++ .../daxpay/result/assist/WxAuthUrlResult.java | 19 ++ .../result/assist/WxJsapiPrePayResult.java | 31 +++ .../gateway/controller/TestController.java | 27 -- .../controller/UniPayAssistController.java | 63 +++++ .../gateway/controller/UniPayController.java | 1 + .../controller/UniQueryController.java | 2 + daxpay-single/daxpay-single-service/pom.xml | 10 + .../service/code/PayApiCallBackTypeEnum.java | 23 ++ .../core/channel/voucher/entity/Voucher.java | 10 - .../voucher/service/VoucherService.java | 52 ---- .../wallet/dao/WalletConfigManager.java | 6 - .../channel/wallet/entity/WalletConfig.java | 14 - .../wallet/service/WalletConfigService.java | 10 - .../wechat/entity/WeChatPayConfig.java | 5 + .../wechat/service/WeChatPayService.java | 2 +- .../order/pay/entity/PayChannelOrder.java | 2 +- .../refund/entity/PayRefundChannelOrder.java | 2 +- .../assist/service/UniPayAssistService.java | 88 ++++++ .../common/aop/PaymentVerifySignAop.java | 6 +- .../common/service/PaymentAssistService.java | 18 +- .../common/service/PaymentSignService.java | 4 +- .../service/PayRefundAssistService.java | 3 +- .../system/config/entity/PayApiConfig.java | 9 + .../dto/system/config/PayApiConfigDto.java | 8 + .../src/main/resources/application-dev.yml | 6 +- pom.xml | 2 +- 68 files changed, 1246 insertions(+), 305 deletions(-) create mode 100644 _license/vue3-vant4-mobile/LICENSE create mode 100644 daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/controller/AggregateController.java rename daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/controller/{DaxPayCashierController.java => CashierController.java} (92%) create mode 100644 daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/controller/RedirectH5Controller.java create mode 100644 daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/domain/AggregatePayInfo.java create mode 100644 daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/param/AggregateSimplePayParam.java create mode 100644 daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/result/WxJsapiSignResult.java create mode 100644 daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/service/AggregateService.java create mode 100644 daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/code/AggregatePayEnum.java create mode 100644 daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/model/assist/WxAccessTokenModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/model/assist/WxAuthUrlModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/model/assist/WxJsapiSignModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/assist/WxAccessTokenParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/assist/WxAuthUrlParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/assist/WxJsapiSignParam.java rename daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/{pay/PayCommonParam.java => PaymentCommonParam.java} (60%) create mode 100644 daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/assist/WxAccessTokenParam.java create mode 100644 daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/assist/WxAuthUrlParam.java create mode 100644 daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/assist/WxJsapiPrePayParam.java create mode 100644 daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/assist/WxAccessTokenResult.java create mode 100644 daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/assist/WxAuthUrlResult.java create mode 100644 daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/assist/WxJsapiPrePayResult.java create mode 100644 daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/UniPayAssistController.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/PayApiCallBackTypeEnum.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/assist/service/UniPayAssistService.java diff --git a/_doc/Task.md b/_doc/Task.md index dae8d3b5f..1cec69d9c 100644 --- a/_doc/Task.md +++ b/_doc/Task.md @@ -1,115 +1,13 @@ +2.0.1: +- [ ] 支付回调通知和退款回调通知功能 +- [ ] 增加收银台演示功能, 金额固定, 不允许进行修改 +- [ ] 增加聚合支付(直接支付模式)演示功能, + 2.0.1 里程碑 -- 支持各类回调通知 - 现金、钱包、储值卡功能进行重构 - -2.0.0 重构进度 -- 已经完成的 - - [x] 参数签名和验签机制 - - [x] 开放接口供第三方调用 - - [x] 将零散的上下文对象进行抽取为统一的上下文对象 - - [x] 拆分原有的策略类,实现粒度更细 - - [x] 去除用户概念,作为独立的支付网关使用,不与其他系统产生耦合性 -- 2023-12-31: - - [x] 支付关闭相关逻辑 - - [x] 各支付通道补充相关未实现的逻辑 - - [x] 支付订单修复逻辑, 用于回调和同步不一致的情况处理 -- 2024-01-01: - - [x] 支付订单修复逻辑, 用于回调和支付同步后不一致的情况处理 -- 2024-01-02: - - [x] 添加管理端的各类`Controller` - - [x] 支持定时同步支付中订单状态, 借助订单超时任务 -- 2024-01-03: - - [x] 支付流程联调 - - [x] 支付同步和支付修复流程优化 - - [x] 支付平台全局性配置 -- 2024-01-04: - - [x] 支付同步时, 如果订单已经超时, 但状态还是待支付, 触发修复操作关闭订单 - - [x] 发起支付时, 如果已经超过订单超时时间, 但状态还是待支付, 触发同步和修复操作 - - [x] 支付宝关闭支付订单,如果网关已经关闭,会返回错误导致本地订单无法关闭 - - [x] 增加支付单关闭记录功能 - - [x] 支付单存在异步支付时, 支付时间需要读取支付网关的返回的时间 - - [x] 同步记录/关闭记录/修复记录 增加记录请求ID -- 2024-01-05: - - [x] 支付同步日志记录, 无论同步成功还是失败, 以及修复成功还是失败, 都需要记录日志 - - [x] 超时自动取消功能联调, 先用spring定时任务实现, 通过支付同步实现 - - [x] 支付同步和修复时, 对一些模糊状态进行处理, 例如支付宝返回的订单未查到 - - [x] 待支付支付单定时同步状态, 先用spring定时任务实现, 通过支付同步实现 - - [x] 退款功能联调 -- 2024-01-06: - - [x] 订单取消/修复/取消/同步等操作添加分布式锁, 防止出现重复操作 - - [x] 增加支付修复记录 -- 2024-01-07: - - [x] 抽取签名工具类 - - [x] 增加消息通知机制(通知客户端) -- 2024-01-08: - - [x] (前端) 更新代码为platform最新版本 - - [x] (前端) 接口配置 -- 2024-01-09: - - [x] (前端) 支付配置 -- 2024-01-10: - - [x] 支付常量数据维护 - - [x] (前端) 支付回调记录 -- 2024-01-11: - - [x] (前端) 支付关闭记录 - - [x] (前端) 支付修复记录 -- 2024-01-12: - - [x] (前端) 支付订单 - - [x] (前端) 退款订单 - - [x] (前端) 支付通道配置列表 -- 2024-01-13: - - [x] (前端) 微信/支付宝支付通道配置 - - [x] 支付通道支持停用 - - [x] ~~请求支付网关时区退款号以R开头, 用于与支付ID的区分~~ - - [x] (前端) 平台配置 -- 2024-01-15: - - [x] 优化支付相关订单和记录的查询条件 - - [x] 开放接口新增查询类接口 -- 2024-01-16: - - [x] 支付单涉及退款状态同步逻辑 -- 2024-01-17: - - [x] 支付宝和微信支付对账下载接口 -- 2024-01-21: - - [x] (对账) 微信对账文件解析 - - [x] (对账) 支付宝对账文件解析 - - [x] (对账) 对账策略类和定时任务 - - [x] (对账) 对账记录和明细保存 -- 2024-01-22: - - [x] (对账) 通用结构对账结构转换 - - [x] (对账) 对账列表页、操作按钮(手动创建、执行、重试) -- 2024-01-23: - - [x] 支付对账收尾 - - [x] 支付退款调整为订单+明细 -- 2024-01-24: - - [x] 支付策略优化通道支付单和可退款信息相关关系 - - [x] 支付退款默认为退款中状态, 根据返回数据或回调来完成退款操作 - - [x] 拆分支付回调为支付和退款回调 -- 2024-01-25: - - [x] 支付修复策略优化存储记录信息 - - [x] 去除各通道支付记录,统一为通道支付记录 -- 2024-01-26: - - [x] 优化支付修复时的触发来源的获取 - - [x] 优化支付回调处理, 处理各种错误 - - [x] 调整支付修复策略, 拆分为支付和退款修复两大类 -- 2024-01-28: - - [x] 支付宝对账单下载异常排查-支付宝每日都会生成对账单, 哪怕为空, 也会生成 - - [x] 订单修复记录前端显示调整 -- 2044-01-30: - - [x] 退款接口更改为先落库, 后更新, 同时退款余额先先进行扣减, 根据退款状态进行处理 - - [x] 增加退款同步策略, 对退款中的状态的退款订单进行处理 - - [x] 修改退款补偿处理, 更改为退款粒度为整个退款单, 要不全部成功, 要不全部失败 - - [x] 支付通道对出现疑似退款的订单进行**报错提醒**, 通过退款同步进行补偿 -- 2024-01-31: - - [x] 微信退款同步策略 - - [x] 支付和退款同步时, 填充完成时间和网关订单号 -- 2024-02-01: - - [x] 支付切换异步方式时, 订单未更换 - - [x] 支付同步时, 支付宝未支付订单无法自动关闭 - - [x] 调整订单页面查询条件 -- 2024-02-02: - - [ ] 接入SDK编写 - - [ ] 接入支付网关的演示项目 -- 2.0.1 版本内容 +- 2.0.x 版本内容 - [ ] 退款操作支持重试 - [ ] 支付流程也改为先落库后支付情况, 避免极端情况导致掉单 - [ ] 支付流程涉及异步支付时, 更换支付方式需要控制预防客户重复付款 diff --git a/_license/LICENSE.md b/_license/LICENSE.md index 19fcc34a6..aed2e4327 100644 --- a/_license/LICENSE.md +++ b/_license/LICENSE.md @@ -41,3 +41,6 @@ https://gitee.com/xiaoym/knife4j easy_trans 一个注解搞定数据翻译: https://gitee.com/dromara/easy_trans + +vue3-vant4-mobile Vant4脚手架: +https://github.com/xiangshu233/vue3-vant4-mobile diff --git a/_license/vue3-vant4-mobile/LICENSE b/_license/vue3-vant4-mobile/LICENSE new file mode 100644 index 000000000..453b9cd35 --- /dev/null +++ b/_license/vue3-vant4-mobile/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 傲慢或香橙 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/config/DaxPayDemoProperties.java b/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/config/DaxPayDemoProperties.java index 6c548420c..af71217e1 100644 --- a/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/config/DaxPayDemoProperties.java +++ b/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/config/DaxPayDemoProperties.java @@ -17,6 +17,9 @@ public class DaxPayDemoProperties { /** 服务地址 */ private String serverUrl; + /** 前端地址 */ + private String frontUrl; + /** 签名方式 */ private SignTypeEnum signType = SignTypeEnum.MD5; diff --git a/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/controller/AggregateController.java b/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/controller/AggregateController.java new file mode 100644 index 000000000..78e026dd6 --- /dev/null +++ b/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/controller/AggregateController.java @@ -0,0 +1,62 @@ +package cn.bootx.platform.daxpay.demo.controller; + +import cn.bootx.platform.common.core.annotation.IgnoreAuth; +import cn.bootx.platform.common.core.rest.Res; +import cn.bootx.platform.common.core.rest.ResResult; +import cn.bootx.platform.daxpay.demo.domain.AggregatePayInfo; +import cn.bootx.platform.daxpay.demo.param.AggregateSimplePayParam; +import cn.bootx.platform.daxpay.demo.result.PayOrderResult; +import cn.bootx.platform.daxpay.demo.service.AggregateService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; + +import static org.springframework.http.HttpHeaders.USER_AGENT; + +/** + * 聚合支付 + * @author xxm + * @since 2024/2/9 + */ +@IgnoreAuth +@Tag(name = "聚合支付") +@RestController +@RequestMapping("/demo/aggregate") +@RequiredArgsConstructor +public class AggregateController { + private final AggregateService aggregateService; + + @Operation(summary = "创建聚合支付码") + @PostMapping("/createUrl") + public ResResult createUrl(@RequestBody AggregateSimplePayParam param) { + return Res.ok(aggregateService.createUrl(param)); + } + + @Operation(summary = "获取聚合支付信息") + @GetMapping("/getInfo") + public ResResult getInfo(String code){ + return Res.ok(aggregateService.getInfo(code)); + } + + @Operation(summary = "聚合支付扫码跳转中间页") + @GetMapping("/qrPayPage/{code}") + public ModelAndView qrPayPage(@PathVariable String code,@RequestHeader(USER_AGENT) String ua){ + String url = aggregateService.qrPayPage(code, ua); + return new ModelAndView("redirect:" + url); + } + + @Operation(summary = "通过聚合支付码发起支付") + @PostMapping("/qrPay") + public ResResult qrPa(String code){ + return Res.ok(aggregateService.aliQrPay(code)); + } + + @Operation(summary = "通过付款码发起支付") + @PostMapping("/barCodePay") + public ResResult barCodePay(@RequestBody AggregateSimplePayParam param){ + return Res.ok(); + } + +} diff --git a/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/controller/DaxPayCashierController.java b/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/controller/CashierController.java similarity index 92% rename from daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/controller/DaxPayCashierController.java rename to daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/controller/CashierController.java index b9bba9332..4529dec31 100644 --- a/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/controller/DaxPayCashierController.java +++ b/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/controller/CashierController.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.demo.controller; +import cn.bootx.platform.common.core.annotation.IgnoreAuth; import cn.bootx.platform.common.core.rest.Res; import cn.bootx.platform.common.core.rest.ResResult; import cn.bootx.platform.common.core.util.ValidationUtil; @@ -16,11 +17,12 @@ import org.springframework.web.bind.annotation.*; * @author xxm * @since 2024/2/8 */ +@IgnoreAuth @Tag(name = "结算台演示") @RestController @RequestMapping("/demo/cashier") @RequiredArgsConstructor -public class DaxPayCashierController { +public class CashierController { private final DaxPayCashierService cashierService; diff --git a/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/controller/RedirectH5Controller.java b/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/controller/RedirectH5Controller.java new file mode 100644 index 000000000..b67496008 --- /dev/null +++ b/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/controller/RedirectH5Controller.java @@ -0,0 +1,23 @@ +package cn.bootx.platform.daxpay.demo.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * 嵌入式h5项目转发控制器, 不用输入 index.html也可以正常访问 + * @author xxm + * @since 2024/2/10 + */ +@Controller +@RequestMapping +public class RedirectH5Controller { + /** + * 将/h5/*的访问请求代理到/h5/index.html* + */ + @GetMapping("/h5/") + public String toH5(){ + return "forward:/h5/index.html"; + } + +} diff --git a/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/domain/AggregatePayInfo.java b/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/domain/AggregatePayInfo.java new file mode 100644 index 000000000..bd037e25c --- /dev/null +++ b/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/domain/AggregatePayInfo.java @@ -0,0 +1,27 @@ +package cn.bootx.platform.daxpay.demo.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 聚合支付发起信息 + * @author xxm + * @since 2024/2/9 + */ +@Data +@Accessors(chain = true) +@Schema(title = "聚合支付发起信息") +public class AggregatePayInfo { + /** 标题 */ + @Schema(description = "标题") + private String title; + + /** 订单业务号 */ + @Schema(description = "订单业务号") + private String businessNo; + + /** 支付金额 */ + @Schema(description = "支付金额") + private Integer amount; +} diff --git a/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/param/AggregateSimplePayParam.java b/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/param/AggregateSimplePayParam.java new file mode 100644 index 000000000..4192e75f5 --- /dev/null +++ b/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/param/AggregateSimplePayParam.java @@ -0,0 +1,33 @@ +package cn.bootx.platform.daxpay.demo.param; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; + +/** + * 聚合简单支付 + * @author xxm + * @since 2024/2/9 + */ +@Data +@Accessors(chain = true) +@Schema(title = "聚合简单支付") +public class AggregateSimplePayParam { + @Schema(description = "业务号") + @NotNull + private String businessNo; + + @Schema(description = "标题") + @NotNull + private String title; + + @Schema(description = "金额") + @NotNull + private BigDecimal amount; + + @Schema(description = "付款码") + private String authCode; +} diff --git a/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/result/WxJsapiSignResult.java b/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/result/WxJsapiSignResult.java new file mode 100644 index 000000000..a568094db --- /dev/null +++ b/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/result/WxJsapiSignResult.java @@ -0,0 +1,29 @@ +package cn.bootx.platform.daxpay.demo.result; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 微信Jsapi预支付签名返回信息 + * @author xxm + * @since 2024/2/10 + */ +@Data +@Accessors(chain = true) +@Schema(title = "微信Jsapi预支付签名返回信息") +public class WxJsapiSignResult { + + /** 公众号ID */ + private String appId; + /** 时间戳(秒) */ + private String timeStamp; + /** 随机串 */ + private String nonceStr; + /** 预支付ID, 已经是 prepay_id=xxx 格式 */ + private String prePayId; + /** 微信签名方式 */ + private String signType; + /** 微信签名 */ + private String paySign; +} diff --git a/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/service/AggregateService.java b/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/service/AggregateService.java new file mode 100644 index 000000000..6e94fb014 --- /dev/null +++ b/daxpay-single-demo/src/main/java/cn/bootx/platform/daxpay/demo/service/AggregateService.java @@ -0,0 +1,258 @@ +package cn.bootx.platform.daxpay.demo.service; + +import cn.bootx.platform.common.core.exception.BizException; +import cn.bootx.platform.common.redis.RedisClient; +import cn.bootx.platform.common.spring.util.WebServletUtil; +import cn.bootx.platform.daxpay.demo.config.DaxPayDemoProperties; +import cn.bootx.platform.daxpay.demo.domain.AggregatePayInfo; +import cn.bootx.platform.daxpay.demo.param.AggregateSimplePayParam; +import cn.bootx.platform.daxpay.demo.result.PayOrderResult; +import cn.bootx.platform.daxpay.demo.result.WxJsapiSignResult; +import cn.bootx.platform.daxpay.sdk.code.AggregatePayEnum; +import cn.bootx.platform.daxpay.sdk.code.PayChannelEnum; +import cn.bootx.platform.daxpay.sdk.code.PayWayEnum; +import cn.bootx.platform.daxpay.sdk.model.assist.WxAccessTokenModel; +import cn.bootx.platform.daxpay.sdk.model.assist.WxAuthUrlModel; +import cn.bootx.platform.daxpay.sdk.model.assist.WxJsapiSignModel; +import cn.bootx.platform.daxpay.sdk.model.pay.PayOrderModel; +import cn.bootx.platform.daxpay.sdk.net.DaxPayKit; +import cn.bootx.platform.daxpay.sdk.param.assist.WxAccessTokenParam; +import cn.bootx.platform.daxpay.sdk.param.assist.WxAuthUrlParam; +import cn.bootx.platform.daxpay.sdk.param.assist.WxJsapiSignParam; +import cn.bootx.platform.daxpay.sdk.param.channel.WeChatPayParam; +import cn.bootx.platform.daxpay.sdk.param.pay.SimplePayParam; +import cn.bootx.platform.daxpay.sdk.response.DaxPayResult; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.servlet.ServletUtil; +import cn.hutool.json.JSONUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.Optional; + +/** + * 聚合支付 + * @author xxm + * @since 2024/2/9 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class AggregateService { + private final DaxPayDemoProperties daxPayDemoProperties; + private final RedisClient redisClient; + + private final String PREFIX_KEY = "payment:aggregate:"; + + /** + * 创建聚合支付码连接 + */ + public String createUrl(AggregateSimplePayParam param) { + int amount = param.getAmount() + .multiply(BigDecimal.valueOf(100)) + .intValue(); + AggregatePayInfo aggregatePayInfo = new AggregatePayInfo() + .setTitle(param.getTitle()) + .setBusinessNo(param.getBusinessNo()) + .setAmount(amount); + String code = IdUtil.getSnowflakeNextIdStr(); + String serverUrl = daxPayDemoProperties.getServerUrl(); + // 有效期五分钟 + redisClient.setWithTimeout(PREFIX_KEY + code, JSONUtil.toJsonStr(aggregatePayInfo), 5 * 60 * 1000); + return StrUtil.format("{}/demo/aggregate/qrPayPage/{}", serverUrl,code); + } + + /** + * 获取聚合支付信息 + */ + public AggregatePayInfo getInfo(String key) { + String jsonStr = Optional.ofNullable(redisClient.get(PREFIX_KEY + key)) + .orElseThrow(() -> new BizException("支付超时")); + return JSONUtil.toBean(jsonStr, AggregatePayInfo.class); + } + + /** + * 聚合支付扫码跳转中间页 + */ + public String qrPayPage(String code, String ua){ + // 判断是否过期 + boolean exists = redisClient.exists(PREFIX_KEY + code); + if (!exists){ + // 跳转到过期页面 + return null; + } + // 根据UA判断是什么环境 + if (ua.contains(AggregatePayEnum.UA_ALI_PAY.getCode())) { + // 跳转支付宝中间页 + return StrUtil.format("{}/#/cashier/alipay", daxPayDemoProperties.getFrontUrl()); + } + else if (ua.contains(AggregatePayEnum.UA_WECHAT_PAY.getCode())) { + // 微信重定向到中间页, 因为微信需要授权后才能发起支付 + return this.wxJsapiAuth(code); + } + else { + // 跳转到异常页 + return null; + } + } + + /** + * 微信Jsapi发起支付, 返回预支付信息, 从页面调起支付, 分为下面三个步骤: + * 1. 获取微信OpenId + * 2. 调用支付接口拿到预支付ID + * 3. 对预支付ID签名, 拿到页面调起支付参数并返回 + */ + public WxJsapiSignResult wxJsapiPau(String aggregateCode, String authCode) { + + // 1. 获取微信OpenId + String openId = this.getOpenId(authCode); + + // 2. 发起预支付 + PayOrderModel payOrderModel = this.wxJsapiPrePay(aggregateCode, openId); + + // 3. 预付订单再次签名, 调用起页面的支付弹窗 + WxJsapiSignParam wxJsapiSignParam = new WxJsapiSignParam(); + wxJsapiSignParam.setPrepayId(payOrderModel.getPayBody()); + DaxPayResult execute = DaxPayKit.execute(wxJsapiSignParam); + + // 判断是否支付成功 + if (execute.getCode() != 0){ + throw new BizException(execute.getMsg()); + } + + WxJsapiSignResult wxJsapiSignResult = new WxJsapiSignResult(); + BeanUtil.copyProperties(execute.getData(), wxJsapiSignResult); + return wxJsapiSignResult; + } + + /** + * 支付宝发起支付 + */ + public PayOrderResult aliQrPay(String code) { + AggregatePayInfo aggregatePayInfo = getInfo(code); + SimplePayParam simplePayParam = new SimplePayParam(); + simplePayParam.setBusinessNo(aggregatePayInfo.getBusinessNo()); + simplePayParam.setTitle(aggregatePayInfo.getTitle()); + simplePayParam.setAmount(aggregatePayInfo.getAmount()); + simplePayParam.setChannel(PayChannelEnum.ALI.getCode()); + simplePayParam.setPayWay(PayWayEnum.QRCODE.getCode()); + + String ip = Optional.ofNullable(WebServletUtil.getRequest()) + .map(ServletUtil::getClientIP) + .orElse("127.0.0.1"); + simplePayParam.setClientIp(ip); + // 异步回调地址 + simplePayParam.setNotifyUrl("http://localhost:9000"); + // 同步回调地址 + simplePayParam.setReturnUrl("http://localhost:9000"); + + DaxPayResult execute = DaxPayKit.execute(simplePayParam); + + // 判断是否支付成功 + if (execute.getCode() != 0){ + throw new BizException(execute.getMsg()); + } + PayOrderResult payOrderResult = new PayOrderResult(); + BeanUtil.copyProperties(execute.getData(),payOrderResult); + return payOrderResult; + } + + /** + * 根据付款码判断属于那种支付通道 + */ + public PayChannelEnum getPayChannel(String authCode) { + if (StrUtil.isBlank(authCode)) { + throw new BizException("付款码不可为空"); + } + String[] wx = { "10", "11", "12", "13", "14", "15" }; + String[] ali = { "25", "26", "27", "28", "29", "30" }; + + // 微信 + if (StrUtil.startWithAny(authCode.substring(0, 2), wx)) { + return PayChannelEnum.WECHAT; + } + // 支付宝 + else if (StrUtil.startWithAny(authCode.substring(0, 2), ali)) { + return PayChannelEnum.ALI; + } + else { + throw new BizException("不支持的支付方式"); + } + } + + /** + * 微信jsapi支付 - 跳转到授权页面 + */ + private String wxJsapiAuth(String code) { + + + // 回调地址为 结算台微信jsapi支付的回调地址 + WxAuthUrlParam wxAuthUrlParam = new WxAuthUrlParam(); + wxAuthUrlParam.setState(code); + + String url = StrUtil.format("{}/#/cashier/wxJsapiPay", daxPayDemoProperties.getFrontUrl()); + wxAuthUrlParam.setUrl(url); + DaxPayResult execute = DaxPayKit.execute(wxAuthUrlParam); + if (execute.getCode() != 0){ + throw new BizException(execute.getMsg()); + } + return execute.getData().getUrl(); + } + + /** + * 获取微信OpenId + */ + private String getOpenId(String authCode) { + // 获取OpenId + WxAccessTokenParam param = new WxAccessTokenParam(); + param.setCode(authCode); + + DaxPayResult result = DaxPayKit.execute(param); + // 判断是否支付成功 + if (result.getCode() != 0){ + throw new BizException(result.getMsg()); + } + return result.getData().getOpenId(); + } + + /** + * 调用微信支付, 拿到预支付ID + */ + private PayOrderModel wxJsapiPrePay(String aggregateCode, String openId) { + AggregatePayInfo aggregatePayInfo = getInfo(aggregateCode); + // 拼装支付发起参数 + SimplePayParam simplePayParam = new SimplePayParam(); + simplePayParam.setBusinessNo(aggregatePayInfo.getBusinessNo()); + simplePayParam.setTitle(aggregatePayInfo.getTitle()); + simplePayParam.setAmount(aggregatePayInfo.getAmount()); + simplePayParam.setChannel(PayChannelEnum.ALI.getCode()); + simplePayParam.setPayWay(PayWayEnum.QRCODE.getCode()); + + // 设置微信专属请求参数 + WeChatPayParam weChatPayParam = new WeChatPayParam(); + weChatPayParam.setOpenId(openId); + simplePayParam.setChannelParam(weChatPayParam); + + String ip = Optional.ofNullable(WebServletUtil.getRequest()) + .map(ServletUtil::getClientIP) + .orElse("127.0.0.1"); + simplePayParam.setClientIp(ip); + // 异步回调地址 + simplePayParam.setNotifyUrl("http://localhost:9000"); + // 同步回调地址 + simplePayParam.setReturnUrl("http://localhost:9000"); + + DaxPayResult execute = DaxPayKit.execute(simplePayParam); + + // 判断是否支付成功 + if (execute.getCode() != 0){ + throw new BizException(execute.getMsg()); + } + return execute.getData(); + } + +} diff --git a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/code/AggregatePayEnum.java b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/code/AggregatePayEnum.java new file mode 100644 index 000000000..c2ddb8c7b --- /dev/null +++ b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/code/AggregatePayEnum.java @@ -0,0 +1,23 @@ +package cn.bootx.platform.daxpay.sdk.code; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 聚合支付相关枚举 + * @author xxm + * @since 2024/2/9 + */ +@Getter +@AllArgsConstructor +public enum AggregatePayEnum { + + UA_ALI_PAY("Alipay", "支付宝"), + UA_WECHAT_PAY("MicroMessenger", "微信支付"); + + /** 支付渠道字符编码 */ + private final String code; + + /** 名称 */ + private final String name; +} diff --git a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/model/assist/WxAccessTokenModel.java b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/model/assist/WxAccessTokenModel.java new file mode 100644 index 000000000..ccb4f8853 --- /dev/null +++ b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/model/assist/WxAccessTokenModel.java @@ -0,0 +1,23 @@ +package cn.bootx.platform.daxpay.sdk.model.assist; + +import cn.bootx.platform.daxpay.sdk.net.DaxPayResponseModel; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * 微信AccessToken + * @author xxm + * @since 2024/2/10 + */ +@Getter +@Setter +@ToString +public class WxAccessTokenModel extends DaxPayResponseModel { + + /** 微信AccessToken */ + private String accessToken; + + /** 微信用户唯一标识 */ + private String openId; +} diff --git a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/model/assist/WxAuthUrlModel.java b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/model/assist/WxAuthUrlModel.java new file mode 100644 index 000000000..51986f0eb --- /dev/null +++ b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/model/assist/WxAuthUrlModel.java @@ -0,0 +1,20 @@ +package cn.bootx.platform.daxpay.sdk.model.assist; + +import cn.bootx.platform.daxpay.sdk.net.DaxPayResponseModel; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * 微信oauth2授权的url连接 + * @author xxm + * @since 2024/2/10 + */ +@Getter +@Setter +@ToString +public class WxAuthUrlModel extends DaxPayResponseModel { + + /** 微信oauth2授权的url连接 */ + private String url; +} diff --git a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/model/assist/WxJsapiSignModel.java b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/model/assist/WxJsapiSignModel.java new file mode 100644 index 000000000..806d2300d --- /dev/null +++ b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/model/assist/WxJsapiSignModel.java @@ -0,0 +1,32 @@ +package cn.bootx.platform.daxpay.sdk.model.assist; + +import cn.bootx.platform.daxpay.sdk.net.DaxPayResponseModel; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * 微信Jsapi预支付签名返回信息 + * @author xxm + * @since 2024/2/10 + */ +@Getter +@Setter +@ToString +public class WxJsapiSignModel extends DaxPayResponseModel { + + /** 公众号ID */ + private String appId; + /** 时间戳(秒) */ + private String timeStamp; + /** 随机串 */ + private String nonceStr; + /** 预支付ID, 已经是 prepay_id=xxx 格式 */ + private String prePayId; + /** 微信签名方式 */ + private String signType; + /** 微信签名 */ + private String paySign; + + +} diff --git a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/net/DaxPayRequest.java b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/net/DaxPayRequest.java index 1a2b32209..505f910e1 100644 --- a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/net/DaxPayRequest.java +++ b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/net/DaxPayRequest.java @@ -14,33 +14,10 @@ import lombok.Setter; @Setter public abstract class DaxPayRequest { - /** 方法请求路径 */ - public abstract String path(); - - /** - * 将请求返回结果反序列化为实体类 - */ - public abstract DaxPayResult toModel(String json); - /** 客户端ip */ private String clientIp; - /** 商户扩展参数,回调时会原样返回 */ - private String attach; - - /** 是否不进行同步通知的跳转 */ - private boolean notReturn; - - /** 同步跳转URL, 部分接口不支持该配置,传输了也不会生效 */ - private String returnUrl; - - /** 是否不启用异步通知 */ - private boolean notNotify; - - /** 异步通知地址 */ - private String notifyUrl; - /** 签名 */ private String sign; @@ -50,4 +27,17 @@ public abstract class DaxPayRequest { /** 请求时间,传输时间戳 */ private Long reqTime = DateUtil.currentSeconds(); + /** + * 方法请求路径 + * @return 请求路径 + */ + public abstract String path(); + + /** + * 将请求返回结果反序列化为实体类 + * @param json json字符串 + * @return 反序列后的对象 + */ + public abstract DaxPayResult toModel(String json); + } diff --git a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/assist/WxAccessTokenParam.java b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/assist/WxAccessTokenParam.java new file mode 100644 index 000000000..bf9eba484 --- /dev/null +++ b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/assist/WxAccessTokenParam.java @@ -0,0 +1,38 @@ +package cn.bootx.platform.daxpay.sdk.param.assist; + +import cn.bootx.platform.daxpay.sdk.model.assist.WxAccessTokenModel; +import cn.bootx.platform.daxpay.sdk.net.DaxPayRequest; +import cn.bootx.platform.daxpay.sdk.response.DaxPayResult; +import cn.hutool.core.lang.TypeReference; +import cn.hutool.json.JSONUtil; +import lombok.Getter; +import lombok.Setter; + +/** + * 获取微信AccessToken参数 + * @author xxm + * @since 2024/2/10 + */ +@Setter +@Getter +public class WxAccessTokenParam extends DaxPayRequest { + + /** 微信code */ + private String code; + + /** + * 方法请求路径 + */ + @Override + public String path() { + return "/unipay/assist/getWxAccessToken"; + } + + /** + * 将请求返回结果反序列化为实体类 + */ + @Override + public DaxPayResult toModel(String json) { + return JSONUtil.toBean(json, new TypeReference>() {}, false); + } +} diff --git a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/assist/WxAuthUrlParam.java b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/assist/WxAuthUrlParam.java new file mode 100644 index 000000000..f3970154f --- /dev/null +++ b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/assist/WxAuthUrlParam.java @@ -0,0 +1,49 @@ +package cn.bootx.platform.daxpay.sdk.param.assist; + +import cn.bootx.platform.daxpay.sdk.model.assist.WxAuthUrlModel; +import cn.bootx.platform.daxpay.sdk.net.DaxPayRequest; +import cn.bootx.platform.daxpay.sdk.response.DaxPayResult; +import cn.hutool.core.lang.TypeReference; +import cn.hutool.json.JSONUtil; +import lombok.Getter; +import lombok.Setter; + +/** + * 构造oauth2授权的url连接 + * @author xxm + * @since 2024/2/10 + */ +@Setter +@Getter +public class WxAuthUrlParam extends DaxPayRequest { + + /** 回调地址 */ + private String url; + + /** + * 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节 + */ + private String state; + + /** + * 方法请求路径 + * + * @return 请求路径 + */ + @Override + public String path() { + return "/unipay/assist/getWxAuthUrl"; + } + + /** + * 将请求返回结果反序列化为实体类 + * + * @param json json字符串 + * @return 反序列后的对象 + */ + @Override + public DaxPayResult toModel(String json) { + return JSONUtil.toBean(json, new TypeReference>() {}, false); + + } +} diff --git a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/assist/WxJsapiSignParam.java b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/assist/WxJsapiSignParam.java new file mode 100644 index 000000000..5edb3dcf5 --- /dev/null +++ b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/assist/WxJsapiSignParam.java @@ -0,0 +1,44 @@ +package cn.bootx.platform.daxpay.sdk.param.assist; + +import cn.bootx.platform.daxpay.sdk.model.assist.WxJsapiSignModel; +import cn.bootx.platform.daxpay.sdk.net.DaxPayRequest; +import cn.bootx.platform.daxpay.sdk.response.DaxPayResult; +import cn.hutool.core.lang.TypeReference; +import cn.hutool.json.JSONUtil; +import lombok.Getter; +import lombok.Setter; + +/** + * 微信预付订单再次签名参数 + * @author xxm + * @since 2024/2/10 + */ +@Setter +@Getter +public class WxJsapiSignParam extends DaxPayRequest{ + + /** 预付订单ID */ + private String prepayId; + + + /** + * 方法请求路径 + * + * @return 请求路径 + */ + @Override + public String path() { + return "/unipay/assist/getWxJsapiPrePay"; + } + + /** + * 将请求返回结果反序列化为实体类 + * + * @param json json字符串 + * @return 反序列后的对象 + */ + @Override + public DaxPayResult toModel(String json) { + return JSONUtil.toBean(json, new TypeReference>() {}, false); + } +} diff --git a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/pay/PayCloseParam.java b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/pay/PayCloseParam.java index 590934689..bb034abe3 100644 --- a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/pay/PayCloseParam.java +++ b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/pay/PayCloseParam.java @@ -23,6 +23,15 @@ public class PayCloseParam extends DaxPayRequest { /** 业务号 */ private String businessNo; + /** 商户扩展参数,回调时会原样返回 */ + private String attach; + + /** 是否不启用异步通知 */ + private boolean notNotify; + + /** 异步通知地址 */ + private String notifyUrl; + /** * 方法请求路径 */ diff --git a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/pay/PayParam.java b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/pay/PayParam.java index 25fd4f115..4cfaa942d 100644 --- a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/pay/PayParam.java +++ b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/pay/PayParam.java @@ -39,6 +39,21 @@ public class PayParam extends DaxPayRequest { /** 支付通道信息参数 */ private List payChannels; + /** 商户扩展参数,回调时会原样返回 */ + private String attach; + + /** 是否不进行同步通知的跳转 */ + private boolean notReturn; + + /** 同步跳转URL, 部分接口不支持该配置,传输了也不会生效 */ + private String returnUrl; + + /** 是否不启用异步通知 */ + private boolean notNotify; + + /** 异步通知地址 */ + private String notifyUrl; + /** * 方法请求路径 */ diff --git a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/pay/SimplePayParam.java b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/pay/SimplePayParam.java index 7057bbf80..aa68a3f99 100644 --- a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/pay/SimplePayParam.java +++ b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/pay/SimplePayParam.java @@ -71,6 +71,21 @@ public class SimplePayParam extends DaxPayRequest { */ private ChannelParam channelParam; + /** 商户扩展参数,回调时会原样返回 */ + private String attach; + + /** 是否不进行同步通知的跳转 */ + private boolean notReturn; + + /** 同步跳转URL, 部分接口不支持该配置,传输了也不会生效 */ + private String returnUrl; + + /** 是否不启用异步通知 */ + private boolean notNotify; + + /** 异步通知地址 */ + private String notifyUrl; + /** * 请求路径 */ diff --git a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/refund/QueryRefundOrderParam.java b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/refund/QueryRefundOrderParam.java index f714659ce..a0bd22310 100644 --- a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/refund/QueryRefundOrderParam.java +++ b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/refund/QueryRefundOrderParam.java @@ -23,6 +23,21 @@ public class QueryRefundOrderParam extends DaxPayRequest /** 退款号 */ private String refundNo; + /** 商户扩展参数,回调时会原样返回 */ + private String attach; + + /** 是否不进行同步通知的跳转 */ + private boolean notReturn; + + /** 同步跳转URL, 部分接口不支持该配置,传输了也不会生效 */ + private String returnUrl; + + /** 是否不启用异步通知 */ + private boolean notNotify; + + /** 异步通知地址 */ + private String notifyUrl; + /** * 方法请求路径 */ diff --git a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/refund/RefundParam.java b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/refund/RefundParam.java index e5ebab464..4c747d866 100644 --- a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/refund/RefundParam.java +++ b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/refund/RefundParam.java @@ -44,6 +44,15 @@ public class RefundParam extends DaxPayRequest { /** 退款原因 */ private String reason; + /** 商户扩展参数,回调时会原样返回 */ + private String attach; + + /** 是否不启用异步通知 */ + private boolean notNotify; + + /** 异步通知地址 */ + private String notifyUrl; + /** * 方法请求路径 */ diff --git a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/refund/SimpleRefundParam.java b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/refund/SimpleRefundParam.java index e4cf96028..677694933 100644 --- a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/refund/SimpleRefundParam.java +++ b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/refund/SimpleRefundParam.java @@ -43,6 +43,16 @@ public class SimpleRefundParam extends DaxPayRequest { /** 退款原因 */ private String reason; + /** 商户扩展参数,回调时会原样返回 */ + private String attach; + + + /** 是否不启用异步通知 */ + private boolean notNotify; + + /** 异步通知地址 */ + private String notifyUrl; + /** * 方法请求路径 */ 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 19a3602a3..47fb67492 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 @@ -39,7 +39,6 @@ public class RefundOrderTest { RefundParam param = new RefundParam(); param.setClientIp("127.0.0.1"); param.setNotNotify(true); - param.setNotReturn(true); param.setBusinessNo("P0001"); param.setRefundAll(true); diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PayCommonParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/PaymentCommonParam.java similarity index 60% rename from daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PayCommonParam.java rename to daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/PaymentCommonParam.java index 54833749f..9848703f3 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PayCommonParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/PaymentCommonParam.java @@ -1,4 +1,4 @@ -package cn.bootx.platform.daxpay.param.pay; +package cn.bootx.platform.daxpay.param; import cn.bootx.platform.daxpay.serializer.TimestampToLocalDateTimeDeserializer; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @@ -15,32 +15,13 @@ import java.time.LocalDateTime; */ @Data @Schema(title = "支付公共参数") -public abstract class PayCommonParam { +public abstract class PaymentCommonParam { /** 客户端ip */ // @NotBlank(message = "客户端ip不可为空") @Schema(description = "客户端ip") private String clientIp; - /** 商户扩展参数,回调时会原样返回 */ - @Schema(description = "商户扩展参数,回调时会原样返回") - private String attach; - - @Schema(description = "是否不进行同步通知的跳转") - private boolean notReturn; - - /** 同步通知URL */ - @Schema(description = "同步通知URL") - private String returnUrl; - - /** 是否不启用异步通知 */ - @Schema(description = "是否不启用异步通知") - private boolean notNotify; - - /** 异步通知地址 */ - @Schema(description = "异步通知地址") - private String notifyUrl; - /** 签名 */ @Schema(description = "签名") private String sign; diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/assist/WxAccessTokenParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/assist/WxAccessTokenParam.java new file mode 100644 index 000000000..b11912d4d --- /dev/null +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/assist/WxAccessTokenParam.java @@ -0,0 +1,22 @@ +package cn.bootx.platform.daxpay.param.assist; + +import cn.bootx.platform.daxpay.param.PaymentCommonParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 获取微信AccessToken参数 + * @author xxm + * @since 2024/2/10 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@Schema(title = "获取微信AccessToken参数") +public class WxAccessTokenParam extends PaymentCommonParam { + + @Schema(description = "微信code") + private String code; +} diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/assist/WxAuthUrlParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/assist/WxAuthUrlParam.java new file mode 100644 index 000000000..b6da011b2 --- /dev/null +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/assist/WxAuthUrlParam.java @@ -0,0 +1,28 @@ +package cn.bootx.platform.daxpay.param.assist; + +import cn.bootx.platform.daxpay.param.PaymentCommonParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 构造oauth2授权的url连接 + * @author xxm + * @since 2024/2/10 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@Schema(title = "构造oauth2授权的url连接") +public class WxAuthUrlParam extends PaymentCommonParam { + + @Schema(description = "回调地址") + private String url; + + /** + * 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节 + */ + @Schema(description = "重定向后原样带回,可以为空") + private String state; +} diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/assist/WxJsapiPrePayParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/assist/WxJsapiPrePayParam.java new file mode 100644 index 000000000..5e182606f --- /dev/null +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/assist/WxJsapiPrePayParam.java @@ -0,0 +1,24 @@ +package cn.bootx.platform.daxpay.param.assist; + +import cn.bootx.platform.daxpay.param.PaymentCommonParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 预付订单再次签名参数 + * @author xxm + * @since 2024/2/10 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@Schema(title = "预付订单再次签名") +public class WxJsapiPrePayParam extends PaymentCommonParam { + + @Schema(description = "预付订单ID") + private String prepayId; + + +} diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PayCloseParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PayCloseParam.java index 8e781465a..a47f90af2 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PayCloseParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PayCloseParam.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.param.pay; +import cn.bootx.platform.daxpay.param.PaymentCommonParam; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -12,7 +13,7 @@ import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) @Data @Schema(title = "支付关闭参数") -public class PayCloseParam extends PayCommonParam{ +public class PayCloseParam extends PaymentCommonParam { @Schema(description = "支付单ID") private Long paymentId; diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PayParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PayParam.java index e2ee38581..6075fdaee 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PayParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PayParam.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.param.pay; +import cn.bootx.platform.daxpay.param.PaymentCommonParam; import cn.bootx.platform.daxpay.serializer.TimestampToLocalDateTimeDeserializer; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import io.swagger.v3.oas.annotations.media.Schema; @@ -21,7 +22,7 @@ import java.util.List; @EqualsAndHashCode(callSuper = true) @Data @Schema(title = "支付参数") -public class PayParam extends PayCommonParam{ +public class PayParam extends PaymentCommonParam { @Schema(description = "业务号") @NotBlank(message = "业务号不可为空") @@ -45,4 +46,23 @@ public class PayParam extends PayCommonParam{ @NotNull(message = "支付通道信息参数不可为空") @Valid private List payChannels; + + /** 商户扩展参数,回调时会原样返回 */ + @Schema(description = "商户扩展参数,回调时会原样返回") + private String attach; + + @Schema(description = "是否不进行同步通知的跳转") + private boolean notReturn; + + /** 同步通知URL */ + @Schema(description = "同步通知URL") + private String returnUrl; + + /** 是否不启用异步通知 */ + @Schema(description = "是否不启用异步通知") + private boolean notNotify; + + /** 异步通知地址 */ + @Schema(description = "异步通知地址") + private String notifyUrl; } diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PaySyncParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PaySyncParam.java index 38473daaf..16cad3b95 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PaySyncParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PaySyncParam.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.param.pay; +import cn.bootx.platform.daxpay.param.PaymentCommonParam; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -12,7 +13,7 @@ import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) @Data @Schema(title = "支付状态同步参数") -public class PaySyncParam extends PayCommonParam{ +public class PaySyncParam extends PaymentCommonParam { @Schema(description = "支付单ID") private Long paymentId; diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/QueryPayOrderParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/QueryPayOrderParam.java index 19e6224a4..422f9859e 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/QueryPayOrderParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/QueryPayOrderParam.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.param.pay; +import cn.bootx.platform.daxpay.param.PaymentCommonParam; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -12,7 +13,7 @@ import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) @Data @Schema(title = "支付订单查询参数") -public class QueryPayOrderParam extends PayCommonParam{ +public class QueryPayOrderParam extends PaymentCommonParam { @Schema(description = "支付号") private Long paymentId; diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/QueryPayParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/QueryPayParam.java index b49fd61f0..0676b174c 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/QueryPayParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/QueryPayParam.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.param.pay; +import cn.bootx.platform.daxpay.param.PaymentCommonParam; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -12,7 +13,7 @@ import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) @Data @Schema(title = "支付单查询参数") -public class QueryPayParam extends PayCommonParam{ +public class QueryPayParam extends PaymentCommonParam { @Schema(description = "支付单ID") private Long paymentId; diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/QueryRefundOrderParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/QueryRefundOrderParam.java index f95bc7c7d..9197cbaf8 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/QueryRefundOrderParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/QueryRefundOrderParam.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.param.pay; +import cn.bootx.platform.daxpay.param.PaymentCommonParam; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -12,7 +13,7 @@ import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) @Data @Schema(title = "查询退款订单参数") -public class QueryRefundOrderParam extends PayCommonParam { +public class QueryRefundOrderParam extends PaymentCommonParam { @Schema(description = "退款订单ID") private Long refundId; diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/QueryRefundParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/QueryRefundParam.java index f8b4a1065..01556dde3 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/QueryRefundParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/QueryRefundParam.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.param.pay; +import cn.bootx.platform.daxpay.param.PaymentCommonParam; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -12,7 +13,7 @@ import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) @Data @Schema(title = "查询退款订单参数类") -public class QueryRefundParam extends PayCommonParam{ +public class QueryRefundParam extends PaymentCommonParam { @Schema(description = "退款订单ID") private Long refundId; diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/RefundParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/RefundParam.java index bc8b1eb3b..c25a552d2 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/RefundParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/RefundParam.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.param.pay; +import cn.bootx.platform.daxpay.param.PaymentCommonParam; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -15,7 +16,7 @@ import java.util.List; @EqualsAndHashCode(callSuper = true) @Data @Schema(title = "退款参数") -public class RefundParam extends PayCommonParam { +public class RefundParam extends PaymentCommonParam { @Schema(description = "支付单ID") private Long paymentId; @@ -45,5 +46,16 @@ public class RefundParam extends PayCommonParam { @Schema(description = "退款原因") private String reason; + /** 商户扩展参数,回调时会原样返回 */ + @Schema(description = "商户扩展参数,回调时会原样返回") + private String attach; + + /** 是否不启用异步通知 */ + @Schema(description = "是否不启用异步通知") + private boolean notNotify; + + /** 异步通知地址 */ + @Schema(description = "异步通知地址") + private String notifyUrl; } diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/RefundSyncParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/RefundSyncParam.java index 65cfe919e..befcaee0d 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/RefundSyncParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/RefundSyncParam.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.param.pay; +import cn.bootx.platform.daxpay.param.PaymentCommonParam; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -12,7 +13,7 @@ import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) @Data @Schema(title = "退款状态同步参数") -public class RefundSyncParam extends PayCommonParam { +public class RefundSyncParam extends PaymentCommonParam { /** * 退款订单ID,refundId和refundNo 必传一个, 同时传输时,以 refundId 为准 diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/SimplePayParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/SimplePayParam.java index 92577e6c4..4797fa40a 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/SimplePayParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/SimplePayParam.java @@ -2,6 +2,7 @@ package cn.bootx.platform.daxpay.param.pay; import cn.bootx.platform.daxpay.code.PayChannelEnum; import cn.bootx.platform.daxpay.code.PayWayEnum; +import cn.bootx.platform.daxpay.param.PaymentCommonParam; import cn.bootx.platform.daxpay.param.channel.AliPayParam; import cn.bootx.platform.daxpay.param.channel.VoucherPayParam; import cn.bootx.platform.daxpay.param.channel.WalletPayParam; @@ -26,7 +27,7 @@ import java.util.Map; @EqualsAndHashCode(callSuper = true) @Data @Schema(title = "简单下单参数") -public class SimplePayParam extends PayCommonParam{ +public class SimplePayParam extends PaymentCommonParam { @Schema(description = "业务号") @NotBlank(message = "业务号不可为空") @@ -74,5 +75,22 @@ public class SimplePayParam extends PayCommonParam{ @Schema(description = "附加通道支付参数") private Map channelParam; + /** 商户扩展参数,回调时会原样返回 */ + @Schema(description = "商户扩展参数,回调时会原样返回") + private String attach; + @Schema(description = "是否不进行同步通知的跳转") + private boolean notReturn; + + /** 同步通知URL */ + @Schema(description = "同步通知URL") + private String returnUrl; + + /** 是否不启用异步通知 */ + @Schema(description = "是否不启用异步通知") + private boolean notNotify; + + /** 异步通知地址 */ + @Schema(description = "异步通知地址") + private String notifyUrl; } diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/SimpleRefundParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/SimpleRefundParam.java index 40755de7b..f950489f9 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/SimpleRefundParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/SimpleRefundParam.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.param.pay; +import cn.bootx.platform.daxpay.param.PaymentCommonParam; import cn.bootx.platform.daxpay.param.channel.AliPayParam; import cn.bootx.platform.daxpay.param.channel.VoucherPayParam; import cn.bootx.platform.daxpay.param.channel.WalletPayParam; @@ -18,7 +19,7 @@ import javax.validation.constraints.NotNull; @EqualsAndHashCode(callSuper = true) @Data @Schema(title = "简单退款参数") -public class SimpleRefundParam extends PayCommonParam { +public class SimpleRefundParam extends PaymentCommonParam { /** * 优先级高于业务号 @@ -58,4 +59,17 @@ public class SimpleRefundParam extends PayCommonParam { @Schema(description = "退款原因") private String reason; + + + /** 商户扩展参数,回调时会原样返回 */ + @Schema(description = "商户扩展参数,回调时会原样返回") + private String attach; + + /** 是否不启用异步通知 */ + @Schema(description = "是否不启用异步通知") + private boolean notNotify; + + /** 异步通知地址 */ + @Schema(description = "异步通知地址") + private String notifyUrl; } diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/assist/WxAccessTokenResult.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/assist/WxAccessTokenResult.java new file mode 100644 index 000000000..acdc85eae --- /dev/null +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/assist/WxAccessTokenResult.java @@ -0,0 +1,22 @@ +package cn.bootx.platform.daxpay.result.assist; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 微信AccessToken + * @author xxm + * @since 2024/2/10 + */ +@Data +@Accessors(chain = true) +@Schema(title = "微信AccessToken") +public class WxAccessTokenResult { + + @Schema(description = "微信AccessToken") + private String accessToken; + + @Schema(description = "微信用户唯一标识") + private String openId; +} diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/assist/WxAuthUrlResult.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/assist/WxAuthUrlResult.java new file mode 100644 index 000000000..53f6b8bfb --- /dev/null +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/assist/WxAuthUrlResult.java @@ -0,0 +1,19 @@ +package cn.bootx.platform.daxpay.result.assist; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 微信oauth2授权的url连接 + * @author xxm + * @since 2024/2/10 + */ +@Data +@Accessors(chain = true) +@Schema(title = "微信oauth2授权的url连接") +public class WxAuthUrlResult { + + @Schema(description = "微信oauth2授权的url连接") + private String url; +} diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/assist/WxJsapiPrePayResult.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/assist/WxJsapiPrePayResult.java new file mode 100644 index 000000000..49e523bea --- /dev/null +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/assist/WxJsapiPrePayResult.java @@ -0,0 +1,31 @@ +package cn.bootx.platform.daxpay.result.assist; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 微信Jsapi预支付信息 + * @author xxm + * @since 2024/2/10 + */ +@Data +@Accessors(chain = true) +@Schema(title = "微信Jsapi预支付信息") +public class WxJsapiPrePayResult { + + @Schema(description = "公众号ID") + private String appId; + @Schema(description = "时间戳(秒)") + private String timeStamp; + @Schema(description = "随机串") + private String nonceStr; + @Schema(description = "预支付ID, 已经是 prepay_id=xxx 格式") + private String prePayId; + @Schema(description = "") + private String signType; + @Schema(description = "") + private String paySign; + + +} diff --git a/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/TestController.java b/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/TestController.java index 6d7ab53b3..cedd36077 100644 --- a/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/TestController.java +++ b/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/TestController.java @@ -3,15 +3,12 @@ package cn.bootx.platform.daxpay.gateway.controller; import cn.bootx.platform.common.core.exception.BizException; import cn.bootx.platform.common.core.rest.Res; import cn.bootx.platform.common.core.rest.ResResult; -import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayConfig; import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayConfigService; import cn.bootx.platform.daxpay.service.core.timeout.task.PayExpiredTimeTask; import cn.bootx.platform.daxpay.service.core.timeout.task.PayWaitOrderSyncTask; import cn.hutool.core.thread.ThreadUtil; import com.baomidou.lock.LockInfo; import com.baomidou.lock.LockTemplate; -import com.ijpay.core.kit.WxPayKit; -import com.ijpay.wxpay.WxPayApiConfigKit; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; @@ -31,24 +28,8 @@ import java.util.Objects; @RequestMapping("/test") @RequiredArgsConstructor public class TestController { - private final PayExpiredTimeTask expiredTimeTask;; - private final PayWaitOrderSyncTask waitOrderSyncTask; - private final WeChatPayConfigService weChatPayConfigService; private final LockTemplate lockTemplate; - @Operation(summary = "同步") - @GetMapping("/sync") - public ResResult sync(){ - waitOrderSyncTask.task(); - return Res.ok(); - } - @Operation(summary = "超时") - @GetMapping("/expired") - public ResResult expired(){ - expiredTimeTask.task(); - return Res.ok(); - } - @Operation(summary = "锁测试1") @GetMapping("/lock1") // @Lock4j(keys = "#name", acquireTimeout = 50) @@ -71,13 +52,5 @@ public class TestController { return Res.ok(name); } - @Operation(summary = "解析微信退款信息") - @GetMapping("/wxjx") - public ResResult wxjx(){ - WeChatPayConfig config = weChatPayConfigService.getConfig(); - String reqInfo = "5WYGjdyCumTyTutbIRILrluT7ahm/8puDs+82ARE3BYaELjmCQ2nsjpM68nQBUHj1x1a0o/5h5k4VI7hz6iEHtBwNwuxIqxesVDX6WtAcBeIR0fACDT+NxefEj1BPFGJqueyA2XxKLuhK8fvO3qiowHcNu3N0QJxSvL5V85wQ3oMnE90VUG8XVTjGBsS6ARaRafyfeHfIyH6ZfH0CBrZlpvM8hzyN1S4T+aNojAaiAQqzgDUGC/TLYgvovgzRmfkRH/dnuxHh4gzh53SqEDSMy1wp/xXQKrbJGjolAbVCVaQ1AHGa4/KZeA6UV7uUYNhGqFDHEqQ1Nqc8lJfcBg9VRMWwJtgCfx3lEilj7LJ/FPRRQKqXUZgcQsKvd87lAU5vQMeYho6mP65nazMLN5sABbAvNNzKMtXkNbL7PxPXy5+FMdj/NDiVCWvCToPpnBfK66rwvdEF4BftEoHYUAnp+WiHnVuposTwkSxQT6vDAkfui2pFOi/PGutHcfeJndUYqLgJgTMTUAApUCUIwMy+3dSeO3kcMT/x4KAPCNIEWE0qfxQOke7aaN3qFqT1p9kkWzlPFrC4FNnCpCMaJktbNQOxAqYHNAp6YHCRGIOmwJ9Rej005G2s+RjyPY3/zBE0VueghtaejszMf4OcrNGCNnXM9/6u/tu3ZeIv8vJnFfgc70GpyrHfgTjupr/cxDqAgfgJlk6aQIRtaAM8lu19zl+s2RP3oHL50G7gNOdtw7pP5shHcLhaf2OQc7IRbmOELGtjh+7fZrrwK6U6/te9JAJcNEY3RdXQ2KgNIiuvAoKHaMXEFL4D+n3wW3AHQVWze2lBZIHcCpTCTwdjjCEWTNFOEzKuzFejJSJOQqQ6gHJ2JrqTuhcE6jetLTtk51LK1C50kMjwt+bIgXbceE7csJSgcMo8/g3w4LmakSNX1kdRI6p2EesM+W/2CKLAKga8TN78Y/v6BhbbdjubpeUtN8+JjM3Wr66I2FeXWxW2Fuh0Enb73rGfrnvhrFVM3L1NeA9Fp1I3nAmWyhULYUZdaiyu8dHjfV3g5HzmOl44iEDMZ14o44QCecjNhtRUtpJLABwP3fXYoNBI7iLQ1alfKvfukh1dzX6gAvbNxTn0jM="; - String decryptData = WxPayKit.decryptData(reqInfo, WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey()); - return Res.ok(); - } } diff --git a/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/UniPayAssistController.java b/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/UniPayAssistController.java new file mode 100644 index 000000000..6ccfbe6ab --- /dev/null +++ b/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/UniPayAssistController.java @@ -0,0 +1,63 @@ +package cn.bootx.platform.daxpay.gateway.controller; + +import cn.bootx.platform.common.core.annotation.CountTime; +import cn.bootx.platform.common.core.annotation.IgnoreAuth; +import cn.bootx.platform.common.core.rest.Res; +import cn.bootx.platform.common.core.rest.ResResult; +import cn.bootx.platform.daxpay.param.assist.WxAccessTokenParam; +import cn.bootx.platform.daxpay.param.assist.WxAuthUrlParam; +import cn.bootx.platform.daxpay.param.assist.WxJsapiPrePayParam; +import cn.bootx.platform.daxpay.result.DaxResult; +import cn.bootx.platform.daxpay.result.assist.WxAccessTokenResult; +import cn.bootx.platform.daxpay.result.assist.WxAuthUrlResult; +import cn.bootx.platform.daxpay.result.assist.WxJsapiPrePayResult; +import cn.bootx.platform.daxpay.service.annotation.PaymentApi; +import cn.bootx.platform.daxpay.service.core.payment.assist.service.UniPayAssistService; +import cn.bootx.platform.daxpay.util.DaxRes; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 支付支撑接口 + * @author xxm + * @since 2024/2/10 + */ +@IgnoreAuth +@Tag(name = "支付支撑接口") +@RestController +@RequestMapping("/unipay/assist") +@RequiredArgsConstructor +public class UniPayAssistController { + private final UniPayAssistService uniPayAssistService; + + @CountTime + @PaymentApi("getWxAuthUrl") + @Operation(summary = "获取微信oauth2授权的url") + @PostMapping("/getWxAuthUrl") + public DaxResult getWxAuthUrl(@RequestBody WxAuthUrlParam param){ + return DaxRes.ok(uniPayAssistService.getWxAuthUrl(param)); + } + + @CountTime + @PaymentApi("getWxAccessToken") + @Operation(summary = "获取微信AccessToken数据") + @PostMapping("/getWxAccessToken") + public ResResult getWxAccessToken(@RequestBody WxAccessTokenParam param){ + return Res.ok(uniPayAssistService.getWxAccessToken(param)); + } + + @CountTime + @PaymentApi("getWxJsapiPrePay") + @Operation(summary = "获取微信预支付信息") + @PostMapping("/getWxJsapiPrePay") + public ResResult getWxJsapiPrePay(@RequestBody WxJsapiPrePayParam param){ + return Res.ok(uniPayAssistService.getWxJsapiPrePay(param)); + } + + +} diff --git a/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/UniPayController.java b/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/UniPayController.java index f32ea28d3..4265557a7 100644 --- a/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/UniPayController.java +++ b/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/UniPayController.java @@ -96,4 +96,5 @@ public class UniPayController { public DaxResult syncRefund(@RequestBody RefundSyncParam param){ return DaxRes.ok(payRefundSyncService.sync(param)); } + } diff --git a/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/UniQueryController.java b/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/UniQueryController.java index 7d97e537c..d633b3413 100644 --- a/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/UniQueryController.java +++ b/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/UniQueryController.java @@ -1,6 +1,7 @@ package cn.bootx.platform.daxpay.gateway.controller; import cn.bootx.platform.common.core.annotation.CountTime; +import cn.bootx.platform.common.core.annotation.IgnoreAuth; import cn.bootx.platform.daxpay.param.pay.QueryPayParam; import cn.bootx.platform.daxpay.param.pay.QueryRefundParam; import cn.bootx.platform.daxpay.result.DaxResult; @@ -22,6 +23,7 @@ import org.springframework.web.bind.annotation.RestController; * @author xxm * @since 2024/2/7 */ +@IgnoreAuth @Tag(name = "统一查询接口") @RestController @RequestMapping("/uni/query") diff --git a/daxpay-single/daxpay-single-service/pom.xml b/daxpay-single/daxpay-single-service/pom.xml index 2941968b0..e3123b135 100644 --- a/daxpay-single/daxpay-single-service/pom.xml +++ b/daxpay-single/daxpay-single-service/pom.xml @@ -98,17 +98,27 @@ weixin-java-pay ${wxjava.version} + + + + com.github.binarywang + weixin-java-mp + ${wxjava.version} + + cn.bootx.platform common-starter-data-perm + org.junit.jupiter junit-jupiter test + com.baomidou diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/PayApiCallBackTypeEnum.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/PayApiCallBackTypeEnum.java new file mode 100644 index 000000000..56a77943c --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/PayApiCallBackTypeEnum.java @@ -0,0 +1,23 @@ +package cn.bootx.platform.daxpay.service.code; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 支付网关接口支持回调类型的枚举 + * @author xxm + * @since 2024/2/10 + */ +@Getter +@AllArgsConstructor +public enum PayApiCallBackTypeEnum { + + /** 支持所有回调类型 */ + ALL("all"), + /** 支持异步回调通知 */ + ASYNC_NOTICE("async_notice"), + /** 不支持退掉通知 */ + NONE("none"); + + private final String code; +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/voucher/entity/Voucher.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/voucher/entity/Voucher.java index e6f2f74ce..44b406260 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/voucher/entity/Voucher.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/voucher/entity/Voucher.java @@ -32,16 +32,6 @@ import java.time.LocalDateTime; @TableName("pay_voucher") public class Voucher extends MpBaseEntity implements EntityBaseFunction { - /** 商户编码 */ - @TableField(updateStrategy = FieldStrategy.NEVER) - @DbColumn(comment = "商户编码") - private String mchCode; - - /** 商户应用编码 */ - @TableField(updateStrategy = FieldStrategy.NEVER) - @DbColumn(comment = "商户应用编码") - private String mchAppCode; - /** 卡号 */ @DbColumn(comment = "卡号") @DbMySqlIndex(comment = "卡号索引") diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/voucher/service/VoucherService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/voucher/service/VoucherService.java index 350f3ea8a..84eedcc51 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/voucher/service/VoucherService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/voucher/service/VoucherService.java @@ -1,22 +1,13 @@ package cn.bootx.platform.daxpay.service.core.channel.voucher.service; -import cn.bootx.platform.common.core.exception.BizException; import cn.bootx.platform.daxpay.service.code.VoucherCode; import cn.bootx.platform.daxpay.service.core.channel.voucher.dao.VoucherLogManager; import cn.bootx.platform.daxpay.service.core.channel.voucher.dao.VoucherManager; -import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.Voucher; -import cn.bootx.platform.daxpay.service.param.channel.voucher.VoucherImportParam; -import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.IdUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; /** * 储值卡 @@ -34,48 +25,6 @@ public class VoucherService { private final VoucherLogManager voucherLogManager; - /** - * 批量导入 - * @param skip 是否跳过已经导入的储值卡,false时将会异常 - */ - @Transactional(rollbackFor = Exception.class) - public void importBatch(Boolean skip, String mchCode, String mchAppCode,List voucherImports) { - List cardNoList = voucherImports.stream() - .map(VoucherImportParam::getCardNo) - .distinct() - .collect(Collectors.toList()); - // 卡号不能重复 - if (voucherImports.size()!=cardNoList.size()){ - throw new BizException("卡号不能重复"); - } - // 查询库中是否已经有对应的储值卡号 - List vouchersByDB = voucherManager.findByCardNoList(cardNoList); - // 不跳过已经导入的储值卡且存在数据, 抛出异常 - if (Objects.equals(skip,true)&& CollUtil.isNotEmpty(vouchersByDB)){ - log.warn("数据库中已经存在的卡号:{}",vouchersByDB.stream().map(Voucher::getCardNo).collect(Collectors.toList())); - throw new BizException("要导入的卡号在数据中已经存在"); - } - // 导入对应储值卡 - List cardNoListByDb = vouchersByDB.stream() - .map(Voucher::getCardNo) - .distinct() - .collect(Collectors.toList()); - long batchNo = IdUtil.getSnowflakeNextId(); - List vouchers = voucherImports.stream() - .filter(o -> !cardNoListByDb.contains(o.getCardNo())) - .map(o -> { - Voucher voucher = new Voucher(); - BeanUtil.copyProperties(o, voucher); - return voucher.setMchCode(mchCode) - .setMchAppCode(mchAppCode) - .setBatchNo(batchNo); - }) - .collect(Collectors.toList()); - voucherManager.saveAll(vouchers); - // TODO 记录日志 - - } - /** * 启用 */ @@ -104,5 +53,4 @@ public class VoucherService { voucherManager.changeStatusBatch(ids, VoucherCode.STATUS_FORBIDDEN); } - } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/dao/WalletConfigManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/dao/WalletConfigManager.java index e254d3dc6..4f0d2aa50 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/dao/WalletConfigManager.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/dao/WalletConfigManager.java @@ -6,8 +6,6 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Repository; -import java.util.Optional; - /** * 钱包配置 * @author xxm @@ -17,8 +15,4 @@ import java.util.Optional; @Repository @RequiredArgsConstructor public class WalletConfigManager extends BaseManager { - - public Optional findByMchCode(String mchCode){ - return this.findByField(WalletConfig::getMchCode,mchCode); - } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/entity/WalletConfig.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/entity/WalletConfig.java index 08b23db15..5631afd70 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/entity/WalletConfig.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/entity/WalletConfig.java @@ -7,9 +7,6 @@ import cn.bootx.platform.daxpay.service.dto.channel.wallet.WalletConfigDto; import cn.bootx.platform.daxpay.service.param.channel.wechat.WalletConfigParam; import cn.bootx.table.modify.annotation.DbColumn; import cn.bootx.table.modify.annotation.DbTable; -import cn.bootx.table.modify.mysql.annotation.DbMySqlIndex; -import com.baomidou.mybatisplus.annotation.FieldStrategy; -import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.EqualsAndHashCode; @@ -29,17 +26,6 @@ import java.math.BigDecimal; @TableName("pay_wallet_config") public class WalletConfig extends MpBaseEntity implements EntityBaseFunction { - /** 商户编码 */ - @TableField(updateStrategy = FieldStrategy.NEVER) - @DbColumn(comment = "商户编码") - private String mchCode; - - /** 商户应用编码 */ - @TableField(updateStrategy = FieldStrategy.NEVER) - @DbMySqlIndex(comment = "商户应用编码唯一索引") - @DbColumn(comment = "商户应用编码") - private String mchAppCode; - /** 默认余额 */ @DbColumn(comment = "默认余额") private BigDecimal defaultBalance; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/service/WalletConfigService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/service/WalletConfigService.java index 7f0c08020..274615c7c 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/service/WalletConfigService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/service/WalletConfigService.java @@ -3,7 +3,6 @@ package cn.bootx.platform.daxpay.service.core.channel.wallet.service; import cn.bootx.platform.common.core.exception.DataNotExistException; import cn.bootx.platform.daxpay.service.core.channel.wallet.dao.WalletConfigManager; import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.WalletConfig; -import cn.bootx.platform.daxpay.service.dto.channel.wallet.WalletConfigDto; import cn.bootx.platform.daxpay.service.param.channel.wechat.WalletConfigParam; import cn.hutool.core.bean.BeanUtil; import lombok.RequiredArgsConstructor; @@ -21,15 +20,6 @@ import org.springframework.stereotype.Service; public class WalletConfigService { private final WalletConfigManager walletConfigManager; - /** - * 根据应用编码获取钱包配置 - */ - public WalletConfigDto findByMchCode(String mchCode){ - return walletConfigManager.findByMchCode(mchCode) - .map(WalletConfig::toDto) - .orElse(new WalletConfigDto()); - } - /** * 新增或更新 */ diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WeChatPayConfig.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WeChatPayConfig.java index abbabea26..b1f323034 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WeChatPayConfig.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WeChatPayConfig.java @@ -63,6 +63,11 @@ public class WeChatPayConfig extends MpBaseEntity implements EntityBaseFunction< @DbColumn(comment = "同步通知路径") private String returnUrl; + /** 接口版本, 使用v2还是v3接口 */ + @DbColumn(comment = "接口版本") + private String apiVersion; + + /** 商户平台「API安全」中的 APIv2 密钥 */ @TableField(updateStrategy = FieldStrategy.ALWAYS) @BigField diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayService.java index 56c2cf1bd..de34c873e 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayService.java @@ -152,7 +152,7 @@ public class WeChatPayService { Map packageParams = WxPayKit.miniAppPrepayIdCreateSign(weChatPayConfig.getWxAppId(), prepayId, weChatPayConfig.getApiKeyV2(), SignType.HMACSHA256); String jsonStr = JacksonUtil.toJson(packageParams); - log.info("小程序支付的参数:" + jsonStr); + log.info("Jsapi支付的参数:" + jsonStr); return jsonStr ; } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/entity/PayChannelOrder.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/entity/PayChannelOrder.java index 176c8cdee..3be2d17ea 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/entity/PayChannelOrder.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/entity/PayChannelOrder.java @@ -68,7 +68,7 @@ public class PayChannelOrder extends MpCreateEntity implements EntityBaseFunctio * @see WalletPayParam */ @DbColumn(comment = "附加支付参数") - @TableField(updateStrategy = FieldStrategy.NEVER) + @TableField(updateStrategy = FieldStrategy.ALWAYS) private String channelExtra; /** diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/entity/PayRefundChannelOrder.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/entity/PayRefundChannelOrder.java index 9e521b0f5..9e1e348ee 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/entity/PayRefundChannelOrder.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/entity/PayRefundChannelOrder.java @@ -47,7 +47,7 @@ public class PayRefundChannelOrder extends MpCreateEntity implements EntityBaseF private Integer amount; @DbColumn(comment = "剩余可退余额") - @TableField(updateStrategy = FieldStrategy.NEVER) + @TableField(updateStrategy = FieldStrategy.ALWAYS) private Integer refundableAmount; /** diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/assist/service/UniPayAssistService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/assist/service/UniPayAssistService.java new file mode 100644 index 000000000..1faca51a2 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/assist/service/UniPayAssistService.java @@ -0,0 +1,88 @@ +package cn.bootx.platform.daxpay.service.core.payment.assist.service; + +import cn.bootx.platform.daxpay.param.assist.WxAccessTokenParam; +import cn.bootx.platform.daxpay.param.assist.WxAuthUrlParam; +import cn.bootx.platform.daxpay.param.assist.WxJsapiPrePayParam; +import cn.bootx.platform.daxpay.result.assist.WxAccessTokenResult; +import cn.bootx.platform.daxpay.result.assist.WxAuthUrlResult; +import cn.bootx.platform.daxpay.result.assist.WxJsapiPrePayResult; +import cn.bootx.platform.daxpay.service.code.WeChatPayCode; +import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayConfig; +import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayConfigService; +import cn.hutool.core.bean.BeanUtil; +import com.ijpay.core.enums.SignType; +import com.ijpay.core.kit.WxPayKit; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; +import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; +import org.springframework.stereotype.Service; + +import java.util.Map; +import java.util.Objects; + +/** + * 支付支撑服务类 + * @author xxm + * @since 2024/2/10 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class UniPayAssistService { + private final WeChatPayConfigService weChatPayConfigService; + + /** + * 构建微信oauth2授权的url连接 + */ + public WxAuthUrlResult getWxAuthUrl(WxAuthUrlParam param) { + WxMpService wxMpService = this.getWxMpService(); + String url = wxMpService.getOAuth2Service() + .buildAuthorizationUrl(param.getUrl(), WxConsts.OAuth2Scope.SNSAPI_BASE, param.getState()); + return new WxAuthUrlResult().setUrl(url); + } + + /** + * 获取微信AccessToken数据 + */ + @SneakyThrows + public WxAccessTokenResult getWxAccessToken(WxAccessTokenParam wxAccessToken){ + WxMpService wxMpService = this.getWxMpService(); + WxOAuth2AccessToken accessToken = wxMpService.getOAuth2Service().getAccessToken(wxAccessToken.getCode()); + return new WxAccessTokenResult() + .setAccessToken(accessToken.getAccessToken()) + .setOpenId(accessToken.getOpenId()); + } + + /** + * 获取微信预支付信息 + */ + public WxJsapiPrePayResult getWxJsapiPrePay(WxJsapiPrePayParam param){ + WeChatPayConfig config = weChatPayConfigService.getConfig(); + String apiKey; + if (Objects.equals(config.getApiKeyV2(), WeChatPayCode.API_V3)){ + apiKey = config.getApiKeyV3(); + } else { + apiKey = config.getApiKeyV2(); + } + Map map = WxPayKit.prepayIdCreateSign(param.getPrepayId(), config.getWxAppId(), apiKey, SignType.HMACSHA256); + return BeanUtil.toBean(map, WxJsapiPrePayResult.class); + } + + /** + * 获取微信公众号API的Service + */ + private WxMpService getWxMpService() { + WeChatPayConfig config = weChatPayConfigService.getConfig(); + WxMpService wxMpService = new WxMpServiceImpl(); + WxMpDefaultConfigImpl wxMpConfig = new WxMpDefaultConfigImpl(); + wxMpConfig.setAppId(config.getWxAppId()); // 设置微信公众号的appid + wxMpConfig.setSecret(config.getAppSecret()); // 设置微信公众号的app corpSecret + wxMpService.setWxMpConfigStorage(wxMpConfig); + return wxMpService; + } +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/common/aop/PaymentVerifySignAop.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/common/aop/PaymentVerifySignAop.java index 18e45b826..9222815d2 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/common/aop/PaymentVerifySignAop.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/common/aop/PaymentVerifySignAop.java @@ -2,7 +2,7 @@ package cn.bootx.platform.daxpay.service.core.payment.common.aop; import cn.bootx.platform.common.core.util.ValidationUtil; import cn.bootx.platform.daxpay.exception.pay.PayFailureException; -import cn.bootx.platform.daxpay.param.pay.PayCommonParam; +import cn.bootx.platform.daxpay.param.PaymentCommonParam; import cn.bootx.platform.daxpay.service.annotation.PaymentApi; import cn.bootx.platform.daxpay.service.core.payment.common.service.PaymentSignService; import lombok.RequiredArgsConstructor; @@ -32,11 +32,11 @@ public class PaymentVerifySignAop { throw new PayFailureException("支付方法至少有一个参数,并且需要签名支付参数需要放在第一位"); } Object param = args[0]; - if (param instanceof PayCommonParam){ + if (param instanceof PaymentCommonParam){ // 参数校验 ValidationUtil.validateParam(param); // 验签 - paymentSignService.verifySign((PayCommonParam) param); + paymentSignService.verifySign((PaymentCommonParam) param); } else { throw new PayFailureException("支付参数需要继承PayCommonParam"); } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/common/service/PaymentAssistService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/common/service/PaymentAssistService.java index 52792893c..7f04584ac 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/common/service/PaymentAssistService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/common/service/PaymentAssistService.java @@ -6,7 +6,7 @@ import cn.bootx.platform.daxpay.service.common.context.RequestLocal; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; import cn.bootx.platform.daxpay.service.core.system.config.entity.PlatformConfig; import cn.bootx.platform.daxpay.service.core.system.config.service.PlatformConfigService; -import cn.bootx.platform.daxpay.param.pay.PayCommonParam; +import cn.bootx.platform.daxpay.param.PaymentCommonParam; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.slf4j.MDC; @@ -27,9 +27,9 @@ public class PaymentAssistService { /** * 初始化上下文 */ - public void initContext(PayCommonParam payCommonParam){ + public void initContext(PaymentCommonParam paymentCommonParam){ this.initPlatform(); - this.initRequest(payCommonParam); + this.initRequest(paymentCommonParam); } /** @@ -49,13 +49,13 @@ public class PaymentAssistService { /** * 初始化请求相关信息上下文 */ - private void initRequest(PayCommonParam payCommonParam){ + private void initRequest(PaymentCommonParam paymentCommonParam){ RequestLocal request = PaymentContextLocal.get().getRequestInfo(); - request.setClientIp(payCommonParam.getClientIp()) - .setAttach(payCommonParam.getAttach()) - .setSign(payCommonParam.getSign()) - .setVersion(payCommonParam.getVersion()) - .setReqTime(payCommonParam.getReqTime()) + request.setClientIp(paymentCommonParam.getClientIp()) +// .setAttach(paymentCommonParam.getAttach()) + .setSign(paymentCommonParam.getSign()) + .setVersion(paymentCommonParam.getVersion()) + .setReqTime(paymentCommonParam.getReqTime()) .setReqId(MDC.get(CommonCode.TRACE_ID)); } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/common/service/PaymentSignService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/common/service/PaymentSignService.java index aa8fe2865..b08a161f8 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/common/service/PaymentSignService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/common/service/PaymentSignService.java @@ -2,7 +2,7 @@ package cn.bootx.platform.daxpay.service.core.payment.common.service; import cn.bootx.platform.daxpay.code.PaySignTypeEnum; import cn.bootx.platform.daxpay.exception.pay.PayFailureException; -import cn.bootx.platform.daxpay.param.pay.PayCommonParam; +import cn.bootx.platform.daxpay.param.PaymentCommonParam; import cn.bootx.platform.daxpay.service.common.context.ApiInfoLocal; import cn.bootx.platform.daxpay.service.common.context.PlatformLocal; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; @@ -28,7 +28,7 @@ public class PaymentSignService { /** * 签名 */ - public void verifySign(PayCommonParam param) { + public void verifySign(PaymentCommonParam param) { // 先触发上下文的初始化 paymentAssistService.initContext(param); ApiInfoLocal apiInfo = PaymentContextLocal.get().getApiInfo(); diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/service/PayRefundAssistService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/service/PayRefundAssistService.java index 616e9aa61..5286a58d7 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/service/PayRefundAssistService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/service/PayRefundAssistService.java @@ -65,14 +65,13 @@ public class PayRefundAssistService { PlatformLocal platform = PaymentContextLocal.get().getPlatformInfo(); // 异步回调 if (!param.isNotNotify()){ - noticeInfo.setNotifyUrl(param.getReturnUrl()); + noticeInfo.setNotifyUrl(param.getNotifyUrl()); if (StrUtil.isNotBlank(param.getNotifyUrl())){ noticeInfo.setNotifyUrl(platform.getNotifyUrl()); } } } - /** * 根据退款参数获取支付订单 */ diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/system/config/entity/PayApiConfig.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/system/config/entity/PayApiConfig.java index 6f637cf73..d31b1e5b9 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/system/config/entity/PayApiConfig.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/system/config/entity/PayApiConfig.java @@ -2,6 +2,7 @@ package cn.bootx.platform.daxpay.service.core.system.config.entity; import cn.bootx.platform.common.core.function.EntityBaseFunction; import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity; +import cn.bootx.platform.daxpay.service.code.PayApiCallBackTypeEnum; import cn.bootx.platform.daxpay.service.core.system.config.convert.PayApiConfigConvert; import cn.bootx.platform.daxpay.service.dto.system.config.PayApiConfigDto; import cn.bootx.table.modify.annotation.DbColumn; @@ -37,6 +38,14 @@ public class PayApiConfig extends MpBaseEntity implements EntityBaseFunction1.5.3.Final 0.2.0 1.5.4 - 4.5.2.B + 4.6.0 2.2.3 2.2.5