feat(checkout): 支持聚合支付条码支付

This commit is contained in:
DaxPay
2024-12-05 15:31:16 +08:00
parent 1270288c2f
commit 334af5b5f1
9 changed files with 148 additions and 12 deletions

View File

@@ -0,0 +1,31 @@
package org.dromara.daxpay.core.param.checkout;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 收银台聚合条码支付参数
* @author xxm
* @since 2024/11/26
*/
@Data
@Accessors(chain = true)
@Schema(title = "收银台聚合支付参数")
public class CheckoutAggregateBarPayParam {
/** 支付订单号 */
@NotBlank(message = "支付订单号不可为空")
@Size(max = 32, message = "支付订单号不可超过32位")
@Schema(description = "支付订单号")
private String orderNo;
/** 付款码 */
@NotBlank(message = "付款码不可为空")
@Size(max = 256, message = "付款码不可超过256位")
@Schema(description = "付款码")
private String barCode;
}

View File

@@ -6,6 +6,7 @@ import cn.bootx.platform.core.rest.result.Result;
import cn.bootx.platform.core.util.ValidationUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import org.dromara.daxpay.core.param.checkout.*;
import org.dromara.daxpay.core.result.DaxResult;
@@ -18,6 +19,7 @@ import org.dromara.daxpay.core.util.DaxRes;
import org.dromara.daxpay.service.common.anno.PaymentVerify;
import org.dromara.daxpay.service.service.checkout.CheckoutQueryService;
import org.dromara.daxpay.service.service.checkout.CheckoutService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
@@ -25,6 +27,7 @@ import org.springframework.web.bind.annotation.*;
* @author xxm
* @since 2024/11/26
*/
@Validated
@IgnoreAuth
@Tag(name = "收银台服务")
@RestController
@@ -48,7 +51,6 @@ public class CheckoutController {
}
@Operation(summary = "获取收银台订单和配置信息")
@GetMapping("/getOrderAndConfig")
public Result<CheckoutOrderAndConfigResult> getOrderAndConfig(String orderNo, String checkoutType){
@@ -84,7 +86,7 @@ public class CheckoutController {
}
@Operation(summary = "发起支付(聚合)")
@Operation(summary = "发起支付(聚合扫码)")
@PostMapping("/aggregatePay")
public Result<PayResult> aggregatePay(@RequestBody CheckoutAggregatePayParam param){
ValidationUtil.validateParam(param);
@@ -92,5 +94,19 @@ public class CheckoutController {
}
@Operation(summary = "发起支付(聚合条码)")
@PostMapping("/aggregateBarPay")
public Result<PayResult> aggregateBarPay(@RequestBody CheckoutAggregateBarPayParam param){
ValidationUtil.validateParam(param);
return Res.ok(checkoutService.aggregateBarPay(param));
}
@Operation(summary = "查询订单状态")
@GetMapping("/findStatusByOrderNo")
public Result<Boolean> findStatusByOrderNo(@NotBlank(message = "订单号不能为空") String orderNo){
return Res.ok(checkoutQueryService.findStatusByOrderNo(orderNo));
}
}

View File

@@ -4,6 +4,7 @@ import cn.bootx.platform.common.mybatisplus.base.MpIdEntity;
import cn.bootx.platform.core.exception.DataNotExistException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.daxpay.core.enums.PayStatusEnum;
import org.dromara.daxpay.core.result.checkout.*;
import org.dromara.daxpay.service.convert.config.CheckoutAggregateConfigConvert;
import org.dromara.daxpay.service.convert.config.CheckoutConfigConvert;
@@ -13,6 +14,7 @@ import org.dromara.daxpay.service.dao.config.checkout.CheckoutAggregateConfigMan
import org.dromara.daxpay.service.dao.config.checkout.CheckoutConfigManager;
import org.dromara.daxpay.service.dao.config.checkout.CheckoutGroupConfigManager;
import org.dromara.daxpay.service.dao.config.checkout.CheckoutItemConfigManager;
import org.dromara.daxpay.service.dao.order.pay.PayOrderManager;
import org.dromara.daxpay.service.entity.config.checkout.CheckoutAggregateConfig;
import org.dromara.daxpay.service.entity.config.checkout.CheckoutItemConfig;
import org.dromara.daxpay.service.entity.order.pay.PayOrder;
@@ -21,6 +23,7 @@ import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
@@ -37,6 +40,7 @@ public class CheckoutQueryService {
private final CheckoutItemConfigManager checkoutItemConfigManager;
private final CheckoutAggregateConfigManager checkoutAggregateConfigManager;
private final CheckoutAssistService checkoutAssistService;
private final PayOrderManager payOrderManager;
/**
* 获取收银台配置
@@ -124,4 +128,14 @@ public class CheckoutQueryService {
checkoutInfoResult.setAggregateConfig(CheckoutAggregateConfigConvert.CONVERT.toResult(aggregateConfig));
return checkoutInfoResult;
}
/**
* 查询订单状态
*/
public Boolean findStatusByOrderNo(String orderNo) {
String status = payOrderManager.findByOrderNo(orderNo)
.map(PayOrder::getStatus)
.orElse(null);
return Objects.equals(status, PayStatusEnum.SUCCESS.getCode());
}
}

View File

@@ -9,6 +9,8 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.daxpay.core.enums.CheckoutCallTypeEnum;
import org.dromara.daxpay.core.enums.CheckoutTypeEnum;
import org.dromara.daxpay.core.enums.PayMethodEnum;
import org.dromara.daxpay.core.exception.ChannelNotExistException;
import org.dromara.daxpay.core.exception.ConfigNotExistException;
import org.dromara.daxpay.core.exception.TradeProcessingException;
import org.dromara.daxpay.core.exception.UnsupportedAbilityException;
@@ -149,7 +151,7 @@ public class CheckoutService {
}
/**
* 聚合支付
* 聚合支付(扫码)
*/
public PayResult aggregatePay(CheckoutAggregatePayParam param){
// 订单信息
@@ -177,6 +179,38 @@ public class CheckoutService {
return payService.pay(payParam, payOrder);
}
/**
* 聚合支付(条码支付)
*/
public PayResult aggregateBarPay(CheckoutAggregateBarPayParam param){
// 订单信息
PayOrder payOrder = checkoutAssistService.getOrderAndCheck(param.getOrderNo());
var cashierStrategies = PaymentStrategyFactory.createGroup(AbsCheckoutStrategy.class);
// 获取策略
var cashierStrategy = cashierStrategies.stream()
.filter(strategy -> strategy.checkBarCode(param.getBarCode()))
.findFirst()
.orElseThrow(() -> new ChannelNotExistException("未找到支持该付款码的支付通道"));
// 获取聚合类型
paymentAssistService.initMchApp(payOrder.getAppId());
// 构建支付参数
String clientIP = JakartaServletUtil.getClientIP(WebServletUtil.getRequest());
PayParam payParam = new PayParam();
payParam.setChannel(cashierStrategy.getChannel());
payParam.setMethod(PayMethodEnum.BARCODE.getCode());
payParam.setAppId(payOrder.getAppId());
payParam.setClientIp(clientIP);
payParam.setReqTime(LocalDateTime.now());
// 进行参数预处理
CheckoutPayParam cashierPayParam = new CheckoutPayParam()
.setBarCode(param.getBarCode());
cashierStrategy.handlePayParam(cashierPayParam, payParam);
// 发起支付
return payService.pay(payParam, payOrder);
}
/**
* 生成授权链接跳转链接, 主要是微信类通道使用, 用于获取OpenId
*/

View File

@@ -19,6 +19,13 @@ public abstract class AbsCheckoutStrategy implements PaymentStrategy{
return "";
}
/**
* 检测付款码
*/
public boolean checkBarCode(String barCode){
return false;
}
/**
* 获取认证结果
*/

View File

@@ -5,6 +5,9 @@ import org.dromara.daxpay.service.strategy.PaymentStrategy;
import cn.hutool.extra.spring.SpringUtil;
import lombok.experimental.UtilityClass;
import java.util.ArrayList;
import java.util.List;
/**
* 策略工厂工具类
* @author xxm
@@ -18,7 +21,7 @@ public class PaymentStrategyFactory {
* @param channel 通道编码
* @param clazz 策略类型
* @return 策略类
* @param <T> 需要为 PayStrategy 的子类
* @param <T> 需要为 PaymentStrategy 的子类
*/
public <T extends PaymentStrategy> T create(String channel, Class<T> clazz) {
var beansOfType = SpringUtil.getBeansOfType(clazz);
@@ -28,5 +31,16 @@ public class PaymentStrategyFactory {
.orElseThrow(() -> new UnsupportedAbilityException("不支持的能力"));
}
/**
* 根据指定类型获取策略组
* @param clazz 策略类型
* @return 策略类列表
* @param <T> 需要为 PaymentStrategy 的子类
*/
public <T extends PaymentStrategy> List<T> createGroup(Class<T> clazz) {
var beansOfType = SpringUtil.getBeansOfType(clazz);
return new ArrayList<>(beansOfType.values());
}
}