Files
template-10559/java/payment/dto/PaymentRequest.java
赵忠林 5749fab9e8 feat(payment): 初始化支付模块核心代码
- 添加支付常量类PaymentConstants,定义支付状态、微信、支付宝、银联等相关常量
- 创建微信支付类型常量类WechatPayType,支持JSAPI、NATIVE、H5、APP支付方式
- 新增支付控制器PaymentController,提供创建支付、查询状态、退款等统一接口
- 实现支付回调控制器PaymentNotifyController,处理微信、支付宝、银联异步通知
- 添加支付请求数据传输对象PaymentRequest,支持多种支付方式参数校验
- 定义支付响应、状态更新请求等相关DTO类- 集成Swagger注解,完善接口文档说明- 添加参数校验和异常处理机制,确保支付流程安全可靠
2025-11-03 12:31:47 +08:00

208 lines
6.5 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.gxwebsoft.payment.dto;
import com.gxwebsoft.payment.enums.PaymentChannel;
import com.gxwebsoft.payment.enums.PaymentType;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.util.Map;
/**
* 统一支付请求DTO
* 支持所有支付方式的统一请求格式
*
* @author 科技小王子
* @since 2025-01-26
*/
@Data
@Schema(name = "统一支付请求", description = "支持所有支付方式的统一支付请求参数")
public class PaymentRequest {
@Schema(description = "租户ID", required = true)
@NotNull(message = "租户ID不能为空")
@Positive(message = "租户ID必须为正数")
private Integer tenantId;
@Schema(description = "用户ID", required = true)
@NotNull(message = "用户ID不能为空")
@Positive(message = "用户ID必须为正数")
private Integer userId;
@Schema(description = "支付类型", required = true, example = "WECHAT")
@NotNull(message = "支付类型不能为空")
private PaymentType paymentType;
@Schema(description = "支付渠道", example = "wechat_native")
private PaymentChannel paymentChannel;
@Schema(description = "支付金额", required = true, example = "0.01")
@NotNull(message = "支付金额不能为空")
@DecimalMin(value = "0.01", message = "支付金额必须大于0.01元")
@DecimalMax(value = "999999.99", message = "支付金额不能超过999999.99元")
@Digits(integer = 6, fraction = 2, message = "支付金额格式不正确最多6位整数2位小数")
private BigDecimal amount;
@Schema(description = "订单号(可选,不提供则自动生成)")
@Size(max = 32, message = "订单号不能超过32个字符")
@Pattern(regexp = "^[a-zA-Z0-9_-]*$", message = "订单号只能包含字母、数字、下划线和横线")
private String orderNo;
@Schema(description = "订单标题", required = true)
@NotBlank(message = "订单标题不能为空")
@Size(max = 127, message = "订单标题不能超过127个字符")
private String subject;
@Schema(description = "订单描述")
@Size(max = 500, message = "订单描述不能超过500个字符")
private String description;
@Schema(description = "商品ID")
@Positive(message = "商品ID必须为正数")
private Integer goodsId;
@Schema(description = "购买数量", example = "1")
@Min(value = 1, message = "购买数量必须大于0")
@Max(value = 9999, message = "购买数量不能超过9999")
private Integer quantity = 1;
@Schema(description = "订单类型", example = "0")
@Min(value = 0, message = "订单类型不能为负数")
private Integer orderType = 0;
@Schema(description = "客户端IP地址")
private String clientIp;
@Schema(description = "用户代理")
private String userAgent;
@Schema(description = "回调通知URL")
private String notifyUrl;
@Schema(description = "支付成功跳转URL")
private String returnUrl;
@Schema(description = "支付取消跳转URL")
private String cancelUrl;
@Schema(description = "订单超时时间(分钟)", example = "30")
@Min(value = 1, message = "订单超时时间必须大于0分钟")
@Max(value = 1440, message = "订单超时时间不能超过1440分钟24小时")
private Integer timeoutMinutes = 30;
@Schema(description = "买家备注")
@Size(max = 500, message = "买家备注不能超过500个字符")
private String buyerRemarks;
@Schema(description = "商户备注")
@Size(max = 500, message = "商户备注不能超过500个字符")
private String merchantRemarks;
@Schema(description = "收货地址ID")
@Positive(message = "收货地址ID必须为正数")
private Integer addressId;
@Schema(description = "扩展参数")
private Map<String, Object> extraParams;
// 微信支付特有参数
@Schema(description = "微信OpenIDJSAPI支付必填")
private String openId;
@Schema(description = "微信UnionID")
private String unionId;
// 支付宝特有参数
@Schema(description = "支付宝用户ID")
private String alipayUserId;
@Schema(description = "花呗分期数")
private Integer hbFqNum;
// 银联支付特有参数
@Schema(description = "银行卡号")
private String cardNo;
@Schema(description = "银行代码")
private String bankCode;
/**
* 获取有效的支付渠道
*/
public PaymentChannel getEffectivePaymentChannel() {
if (paymentChannel != null) {
return paymentChannel;
}
return PaymentChannel.getDefaultByPaymentType(paymentType);
}
/**
* 获取有效的订单描述
*/
public String getEffectiveDescription() {
if (description != null && !description.trim().isEmpty()) {
return description.trim();
}
return subject;
}
/**
* 获取格式化的金额字符串
*/
public String getFormattedAmount() {
if (amount == null) {
return "0.00";
}
return String.format("%.2f", amount);
}
/**
* 转换为分微信支付API需要
*/
public Integer getAmountInCents() {
if (amount == null) {
return 0;
}
return amount.multiply(new BigDecimal(100)).intValue();
}
/**
* 验证必要参数是否完整
*/
public boolean isValid() {
return tenantId != null && tenantId > 0
&& userId != null && userId > 0
&& paymentType != null
&& amount != null && amount.compareTo(BigDecimal.ZERO) > 0
&& subject != null && !subject.trim().isEmpty();
}
/**
* 验证微信JSAPI支付参数
*/
public boolean isValidForWechatJsapi() {
return isValid() && paymentType.isWechatPay() && openId != null && !openId.trim().isEmpty();
}
/**
* 验证支付宝支付参数
*/
public boolean isValidForAlipay() {
return isValid() && paymentType == PaymentType.ALIPAY;
}
/**
* 获取订单超时时间(秒)
*/
public long getTimeoutSeconds() {
return timeoutMinutes * 60L;
}
@Override
public String toString() {
return String.format("PaymentRequest{tenantId=%d, userId=%d, paymentType=%s, amount=%s, orderNo='%s', subject='%s'}",
tenantId, userId, paymentType, getFormattedAmount(), orderNo, subject);
}
}