mirror of
https://gitee.com/dromara/dax-pay.git
synced 2025-08-29 09:04:14 +00:00
feat 聚合支付处理, 增加h5嵌入式项目支持
This commit is contained in:
114
_doc/Task.md
114
_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 版本内容
|
||||
- [ ] 退款操作支持重试
|
||||
- [ ] 支付流程也改为先落库后支付情况, 避免极端情况导致掉单
|
||||
- [ ] 支付流程涉及异步支付时, 更换支付方式需要控制预防客户重复付款
|
||||
|
@@ -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
|
||||
|
21
_license/vue3-vant4-mobile/LICENSE
Normal file
21
_license/vue3-vant4-mobile/LICENSE
Normal file
@@ -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.
|
@@ -17,6 +17,9 @@ public class DaxPayDemoProperties {
|
||||
/** 服务地址 */
|
||||
private String serverUrl;
|
||||
|
||||
/** 前端地址 */
|
||||
private String frontUrl;
|
||||
|
||||
/** 签名方式 */
|
||||
private SignTypeEnum signType = SignTypeEnum.MD5;
|
||||
|
||||
|
@@ -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<String> createUrl(@RequestBody AggregateSimplePayParam param) {
|
||||
return Res.ok(aggregateService.createUrl(param));
|
||||
}
|
||||
|
||||
@Operation(summary = "获取聚合支付信息")
|
||||
@GetMapping("/getInfo")
|
||||
public ResResult<AggregatePayInfo> 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<PayOrderResult> qrPa(String code){
|
||||
return Res.ok(aggregateService.aliQrPay(code));
|
||||
}
|
||||
|
||||
@Operation(summary = "通过付款码发起支付")
|
||||
@PostMapping("/barCodePay")
|
||||
public ResResult<Void> barCodePay(@RequestBody AggregateSimplePayParam param){
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
}
|
@@ -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;
|
||||
|
@@ -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";
|
||||
}
|
||||
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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<WxJsapiSignModel> 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<PayOrderModel> 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<WxAuthUrlModel> 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<WxAccessTokenModel> 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<PayOrderModel> execute = DaxPayKit.execute(simplePayParam);
|
||||
|
||||
// 判断是否支付成功
|
||||
if (execute.getCode() != 0){
|
||||
throw new BizException(execute.getMsg());
|
||||
}
|
||||
return execute.getData();
|
||||
}
|
||||
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
|
||||
|
||||
}
|
@@ -14,33 +14,10 @@ import lombok.Setter;
|
||||
@Setter
|
||||
public abstract class DaxPayRequest<T extends DaxPayResponseModel> {
|
||||
|
||||
/** 方法请求路径 */
|
||||
public abstract String path();
|
||||
|
||||
/**
|
||||
* 将请求返回结果反序列化为实体类
|
||||
*/
|
||||
public abstract DaxPayResult<T> 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<T extends DaxPayResponseModel> {
|
||||
/** 请求时间,传输时间戳 */
|
||||
private Long reqTime = DateUtil.currentSeconds();
|
||||
|
||||
/**
|
||||
* 方法请求路径
|
||||
* @return 请求路径
|
||||
*/
|
||||
public abstract String path();
|
||||
|
||||
/**
|
||||
* 将请求返回结果反序列化为实体类
|
||||
* @param json json字符串
|
||||
* @return 反序列后的对象
|
||||
*/
|
||||
public abstract DaxPayResult<T> toModel(String json);
|
||||
|
||||
}
|
||||
|
@@ -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<WxAccessTokenModel> {
|
||||
|
||||
/** 微信code */
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 方法请求路径
|
||||
*/
|
||||
@Override
|
||||
public String path() {
|
||||
return "/unipay/assist/getWxAccessToken";
|
||||
}
|
||||
|
||||
/**
|
||||
* 将请求返回结果反序列化为实体类
|
||||
*/
|
||||
@Override
|
||||
public DaxPayResult<WxAccessTokenModel> toModel(String json) {
|
||||
return JSONUtil.toBean(json, new TypeReference<DaxPayResult<WxAccessTokenModel>>() {}, false);
|
||||
}
|
||||
}
|
@@ -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<WxAuthUrlModel> {
|
||||
|
||||
/** 回调地址 */
|
||||
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<WxAuthUrlModel> toModel(String json) {
|
||||
return JSONUtil.toBean(json, new TypeReference<DaxPayResult<WxAuthUrlModel>>() {}, false);
|
||||
|
||||
}
|
||||
}
|
@@ -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<WxJsapiSignModel>{
|
||||
|
||||
/** 预付订单ID */
|
||||
private String prepayId;
|
||||
|
||||
|
||||
/**
|
||||
* 方法请求路径
|
||||
*
|
||||
* @return 请求路径
|
||||
*/
|
||||
@Override
|
||||
public String path() {
|
||||
return "/unipay/assist/getWxJsapiPrePay";
|
||||
}
|
||||
|
||||
/**
|
||||
* 将请求返回结果反序列化为实体类
|
||||
*
|
||||
* @param json json字符串
|
||||
* @return 反序列后的对象
|
||||
*/
|
||||
@Override
|
||||
public DaxPayResult<WxJsapiSignModel> toModel(String json) {
|
||||
return JSONUtil.toBean(json, new TypeReference<DaxPayResult<WxJsapiSignModel>>() {}, false);
|
||||
}
|
||||
}
|
@@ -23,6 +23,15 @@ public class PayCloseParam extends DaxPayRequest<PayCloseModel> {
|
||||
/** 业务号 */
|
||||
private String businessNo;
|
||||
|
||||
/** 商户扩展参数,回调时会原样返回 */
|
||||
private String attach;
|
||||
|
||||
/** 是否不启用异步通知 */
|
||||
private boolean notNotify;
|
||||
|
||||
/** 异步通知地址 */
|
||||
private String notifyUrl;
|
||||
|
||||
/**
|
||||
* 方法请求路径
|
||||
*/
|
||||
|
@@ -39,6 +39,21 @@ public class PayParam extends DaxPayRequest<PayOrderModel> {
|
||||
/** 支付通道信息参数 */
|
||||
private List<PayChannelParam> payChannels;
|
||||
|
||||
/** 商户扩展参数,回调时会原样返回 */
|
||||
private String attach;
|
||||
|
||||
/** 是否不进行同步通知的跳转 */
|
||||
private boolean notReturn;
|
||||
|
||||
/** 同步跳转URL, 部分接口不支持该配置,传输了也不会生效 */
|
||||
private String returnUrl;
|
||||
|
||||
/** 是否不启用异步通知 */
|
||||
private boolean notNotify;
|
||||
|
||||
/** 异步通知地址 */
|
||||
private String notifyUrl;
|
||||
|
||||
/**
|
||||
* 方法请求路径
|
||||
*/
|
||||
|
@@ -71,6 +71,21 @@ public class SimplePayParam extends DaxPayRequest<PayOrderModel> {
|
||||
*/
|
||||
private ChannelParam channelParam;
|
||||
|
||||
/** 商户扩展参数,回调时会原样返回 */
|
||||
private String attach;
|
||||
|
||||
/** 是否不进行同步通知的跳转 */
|
||||
private boolean notReturn;
|
||||
|
||||
/** 同步跳转URL, 部分接口不支持该配置,传输了也不会生效 */
|
||||
private String returnUrl;
|
||||
|
||||
/** 是否不启用异步通知 */
|
||||
private boolean notNotify;
|
||||
|
||||
/** 异步通知地址 */
|
||||
private String notifyUrl;
|
||||
|
||||
/**
|
||||
* 请求路径
|
||||
*/
|
||||
|
@@ -23,6 +23,21 @@ public class QueryRefundOrderParam extends DaxPayRequest<QueryRefundOrderModel>
|
||||
/** 退款号 */
|
||||
private String refundNo;
|
||||
|
||||
/** 商户扩展参数,回调时会原样返回 */
|
||||
private String attach;
|
||||
|
||||
/** 是否不进行同步通知的跳转 */
|
||||
private boolean notReturn;
|
||||
|
||||
/** 同步跳转URL, 部分接口不支持该配置,传输了也不会生效 */
|
||||
private String returnUrl;
|
||||
|
||||
/** 是否不启用异步通知 */
|
||||
private boolean notNotify;
|
||||
|
||||
/** 异步通知地址 */
|
||||
private String notifyUrl;
|
||||
|
||||
/**
|
||||
* 方法请求路径
|
||||
*/
|
||||
|
@@ -44,6 +44,15 @@ public class RefundParam extends DaxPayRequest<RefundModel> {
|
||||
/** 退款原因 */
|
||||
private String reason;
|
||||
|
||||
/** 商户扩展参数,回调时会原样返回 */
|
||||
private String attach;
|
||||
|
||||
/** 是否不启用异步通知 */
|
||||
private boolean notNotify;
|
||||
|
||||
/** 异步通知地址 */
|
||||
private String notifyUrl;
|
||||
|
||||
/**
|
||||
* 方法请求路径
|
||||
*/
|
||||
|
@@ -43,6 +43,16 @@ public class SimpleRefundParam extends DaxPayRequest<RefundModel> {
|
||||
/** 退款原因 */
|
||||
private String reason;
|
||||
|
||||
/** 商户扩展参数,回调时会原样返回 */
|
||||
private String attach;
|
||||
|
||||
|
||||
/** 是否不启用异步通知 */
|
||||
private boolean notNotify;
|
||||
|
||||
/** 异步通知地址 */
|
||||
private String notifyUrl;
|
||||
|
||||
/**
|
||||
* 方法请求路径
|
||||
*/
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
|
||||
|
||||
}
|
@@ -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;
|
||||
|
@@ -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<PayChannelParam> 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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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 为准
|
||||
|
@@ -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<String, Object> 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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
|
||||
|
||||
}
|
@@ -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<Void> sync(){
|
||||
waitOrderSyncTask.task();
|
||||
return Res.ok();
|
||||
}
|
||||
@Operation(summary = "超时")
|
||||
@GetMapping("/expired")
|
||||
public ResResult<Void> 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<Void> 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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<WxAuthUrlResult> getWxAuthUrl(@RequestBody WxAuthUrlParam param){
|
||||
return DaxRes.ok(uniPayAssistService.getWxAuthUrl(param));
|
||||
}
|
||||
|
||||
@CountTime
|
||||
@PaymentApi("getWxAccessToken")
|
||||
@Operation(summary = "获取微信AccessToken数据")
|
||||
@PostMapping("/getWxAccessToken")
|
||||
public ResResult<WxAccessTokenResult> getWxAccessToken(@RequestBody WxAccessTokenParam param){
|
||||
return Res.ok(uniPayAssistService.getWxAccessToken(param));
|
||||
}
|
||||
|
||||
@CountTime
|
||||
@PaymentApi("getWxJsapiPrePay")
|
||||
@Operation(summary = "获取微信预支付信息")
|
||||
@PostMapping("/getWxJsapiPrePay")
|
||||
public ResResult<WxJsapiPrePayResult> getWxJsapiPrePay(@RequestBody WxJsapiPrePayParam param){
|
||||
return Res.ok(uniPayAssistService.getWxJsapiPrePay(param));
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -96,4 +96,5 @@ public class UniPayController {
|
||||
public DaxResult<SyncResult> syncRefund(@RequestBody RefundSyncParam param){
|
||||
return DaxRes.ok(payRefundSyncService.sync(param));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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")
|
||||
|
@@ -98,17 +98,27 @@
|
||||
<artifactId>weixin-java-pay</artifactId>
|
||||
<version>${wxjava.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 微信工具包 -->
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>weixin-java-mp</artifactId>
|
||||
<version>${wxjava.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 数据权限 -->
|
||||
<dependency>
|
||||
<groupId>cn.bootx.platform</groupId>
|
||||
<artifactId>common-starter-data-perm</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 测试库 -->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- 分布式锁 -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
|
@@ -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;
|
||||
}
|
@@ -32,16 +32,6 @@ import java.time.LocalDateTime;
|
||||
@TableName("pay_voucher")
|
||||
public class Voucher extends MpBaseEntity implements EntityBaseFunction<VoucherDto> {
|
||||
|
||||
/** 商户编码 */
|
||||
@TableField(updateStrategy = FieldStrategy.NEVER)
|
||||
@DbColumn(comment = "商户编码")
|
||||
private String mchCode;
|
||||
|
||||
/** 商户应用编码 */
|
||||
@TableField(updateStrategy = FieldStrategy.NEVER)
|
||||
@DbColumn(comment = "商户应用编码")
|
||||
private String mchAppCode;
|
||||
|
||||
/** 卡号 */
|
||||
@DbColumn(comment = "卡号")
|
||||
@DbMySqlIndex(comment = "卡号索引")
|
||||
|
@@ -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<VoucherImportParam> voucherImports) {
|
||||
List<String> cardNoList = voucherImports.stream()
|
||||
.map(VoucherImportParam::getCardNo)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
// 卡号不能重复
|
||||
if (voucherImports.size()!=cardNoList.size()){
|
||||
throw new BizException("卡号不能重复");
|
||||
}
|
||||
// 查询库中是否已经有对应的储值卡号
|
||||
List<Voucher> 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<String> cardNoListByDb = vouchersByDB.stream()
|
||||
.map(Voucher::getCardNo)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
long batchNo = IdUtil.getSnowflakeNextId();
|
||||
List<Voucher> 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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -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<WalletConfigMapper, WalletConfig> {
|
||||
|
||||
public Optional<WalletConfig> findByMchCode(String mchCode){
|
||||
return this.findByField(WalletConfig::getMchCode,mchCode);
|
||||
}
|
||||
}
|
||||
|
@@ -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<WalletConfigDto> {
|
||||
|
||||
/** 商户编码 */
|
||||
@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;
|
||||
|
@@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增或更新
|
||||
*/
|
||||
|
@@ -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
|
||||
|
@@ -152,7 +152,7 @@ public class WeChatPayService {
|
||||
Map<String, String> packageParams = WxPayKit.miniAppPrepayIdCreateSign(weChatPayConfig.getWxAppId(), prepayId,
|
||||
weChatPayConfig.getApiKeyV2(), SignType.HMACSHA256);
|
||||
String jsonStr = JacksonUtil.toJson(packageParams);
|
||||
log.info("小程序支付的参数:" + jsonStr);
|
||||
log.info("Jsapi支付的参数:" + jsonStr);
|
||||
return jsonStr ;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
/**
|
||||
|
@@ -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;
|
||||
|
||||
/**
|
||||
|
@@ -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<String, String> 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;
|
||||
}
|
||||
}
|
@@ -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");
|
||||
}
|
||||
|
@@ -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));
|
||||
}
|
||||
}
|
||||
|
@@ -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();
|
||||
|
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据退款参数获取支付订单
|
||||
*/
|
||||
|
@@ -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 EntityBaseFunction<Pay
|
||||
@TableField(updateStrategy = FieldStrategy.NEVER)
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 支持回调通知
|
||||
* @see PayApiCallBackTypeEnum
|
||||
*/
|
||||
@DbColumn(comment = "支持回调通知")
|
||||
@TableField(updateStrategy = FieldStrategy.NEVER)
|
||||
private boolean noticeSupport;
|
||||
|
||||
@DbColumn(comment = "是否启用")
|
||||
private boolean enable;
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package cn.bootx.platform.daxpay.service.dto.system.config;
|
||||
|
||||
import cn.bootx.platform.common.core.rest.dto.BaseDto;
|
||||
import cn.bootx.platform.daxpay.service.code.PayApiCallBackTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -26,6 +27,13 @@ public class PayApiConfigDto extends BaseDto {
|
||||
@Schema(description = "名称")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 是否支持回调通知
|
||||
* @see PayApiCallBackTypeEnum
|
||||
*/
|
||||
@Schema(description = "是否支持回调通知")
|
||||
private boolean noticeSupport;
|
||||
|
||||
@Schema(description = "是否启用")
|
||||
private boolean enable;
|
||||
|
||||
|
@@ -111,6 +111,8 @@ bootx:
|
||||
- '/demo/**'
|
||||
- '/test/**'
|
||||
- '/webjars/**'
|
||||
- '/front/**'
|
||||
- '/h5/**'
|
||||
- '/css/**'
|
||||
- '/error'
|
||||
- '/favicon.ico'
|
||||
@@ -156,6 +158,8 @@ dax-pay:
|
||||
# 演示模块
|
||||
demo:
|
||||
# 网关地址
|
||||
server-url: http://localhost:9000
|
||||
server-url: http://pay1.bootx.cn
|
||||
# 前端地址
|
||||
front-url: http://pay1.bootx.cn/h5
|
||||
# 签名秘钥
|
||||
sign-secret: 123456
|
||||
|
2
pom.xml
2
pom.xml
@@ -42,7 +42,7 @@
|
||||
<mapstruct.version>1.5.3.Final</mapstruct.version>
|
||||
<lombok-mapstruct.version>0.2.0</lombok-mapstruct.version>
|
||||
<table-modify.version>1.5.4</table-modify.version>
|
||||
<wxjava.version>4.5.2.B</wxjava.version>
|
||||
<wxjava.version>4.6.0</wxjava.version>
|
||||
<rocketmq.version>2.2.3</rocketmq.version>
|
||||
<lock4j.version>2.2.5</lock4j.version>
|
||||
</properties>
|
||||
|
Reference in New Issue
Block a user