feat: PayParam 新增订单商品明细列表(goodsDetail)

This commit is contained in:
DaxPay Dev
2026-06-16 23:02:09 +08:00
parent 21327f9feb
commit a7e42d421c
7 changed files with 141 additions and 1 deletions

View File

@@ -0,0 +1,2 @@
-- 订单商品明细列表
ALTER TABLE pay_normal_order ADD COLUMN IF NOT EXISTS goods_detail jsonb;

View File

@@ -5,15 +5,18 @@ import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.dromara.daxpay.payment.common.enums.NormalOrderStatusEnum;
import org.dromara.daxpay.payment.unipay.param.trade.pay.GoodsDetail;
import org.dromara.daxpay.platform.core.enums.pay.channel.CurrencyEnum;
import org.dromara.daxpay.platform.core.enums.pay.channel.PayMethodEnum;
import org.dromara.daxpay.platform.core.enums.pay.channel.ProductEnum;
import java.time.OffsetDateTime;
import java.util.List;
/// # 普通支付业务单容器
///
@@ -23,7 +26,7 @@ import java.time.OffsetDateTime;
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("pay_normal_order")
@TableName(value = "pay_normal_order", autoResultMap = true)
public class PayNormalOrder extends MchBaseEntity {
/// 应用号
@@ -90,6 +93,10 @@ public class PayNormalOrder extends MchBaseEntity {
/// 通道附加参数
private String extraParam;
/// 订单商品明细列表jsonb 存储)
@TableField(typeHandler = JacksonTypeHandler.class)
private List<GoodsDetail> goodsDetail;
/// 客户端 IP
private String clientIp;

View File

@@ -81,6 +81,7 @@ public class PayAssistService {
normalOrder.setMethod(payParam.getMethod());
normalOrder.setProduct(payParam.getProduct());
normalOrder.setExtraParam(payParam.getExtraParam());
normalOrder.setGoodsDetail(payParam.getGoodsDetail());
normalOrder.setTerminalNo(terminalNo);
normalOrder.setAppId(appId);
payNormalOrderManager.save(normalOrder);

View File

@@ -0,0 +1,63 @@
package org.dromara.daxpay.payment.unipay.param.trade.pay;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.Digits;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import java.math.BigDecimal;
/// # 订单商品明细
///
/// 对应支付宝 goods_detail 和微信支付 detail.goods_detail
/// 用于单品营销、电子发票等场景。金额单位为分(Long),与系统内部全局一致。
@Data
@Schema(title = "订单商品明细")
public class GoodsDetail {
/// 商户侧商品编码
/// Alipay → goods_id, WeChat → merchant_goods_id
@NotBlank(message = "{validation.field.goodsId.notBlank}")
@Size(max = 64, message = "{validation.field.goodsId.size}")
@Schema(description = "商户侧商品编码")
private String goodsId;
/// 商品名称
@NotBlank(message = "{validation.field.goodsName.notBlank}")
@Size(max = 256, message = "{validation.field.goodsName.size}")
@Schema(description = "商品名称")
private String goodsName;
/// 商品数量
@NotNull(message = "{validation.field.quantity.notNull}")
@Min(value = 1, message = "{validation.field.quantity.min}")
@Schema(description = "商品数量")
private Integer quantity;
/// 商品单价(分)
/// Alipay 需转为元WeChat 直接使用分
@NotNull(message = "{validation.field.unitPrice.notNull}")
@DecimalMin(value = "0.01", message = "{validation.field.unitPrice.decimalMin}")
@Digits(integer = 10, fraction = 2, message = "{validation.field.unitPrice.digits}")
@Schema(description = "商品单价(分)")
private BigDecimal unitPrice;
/// 商品分类Alipay 独有,选填)
@Size(max = 32, message = "{validation.field.goodsCategory.size}")
@Schema(description = "商品分类")
private String category;
/// 商品描述(选填)
@Size(max = 1000, message = "{validation.field.goodsDescription.size}")
@Schema(description = "商品描述")
private String description;
/// 商品展示链接(选填)
@Size(max = 400, message = "{validation.field.showUrl.size}")
@Schema(description = "商品展示链接")
private String showUrl;
}

View File

@@ -3,6 +3,7 @@ package org.dromara.daxpay.payment.unipay.param.trade.pay;
import org.dromara.daxpay.platform.core.enums.pay.channel.ProductEnum;
import org.dromara.daxpay.platform.core.enums.pay.channel.PayMethodEnum;
import org.dromara.daxpay.payment.unipay.param.MerchantPaymentCommonParam;
import jakarta.validation.Valid;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
@@ -85,6 +86,14 @@ public class PayParam extends MerchantPaymentCommonParam {
@Size(max = 2048, message = "{validation.field.extraParam.size}")
private String extraParam;
/// 订单商品明细列表
/// 传给支付渠道(支付宝 goods_detail / 微信 detail.goods_detail
/// 用于单品营销、电子发票等场景
@Valid
@Size(max = 50, message = "{validation.field.goodsDetail.size}")
@Schema(description = "订单商品明细列表")
private List<GoodsDetail> goodsDetail;
// ===== 通知回调 =====
/// 异步通知地址

View File

@@ -188,6 +188,35 @@
"extraParam": {
"size": "Extra param cannot exceed 2048 characters"
},
"goodsDetail": {
"size": "Goods detail list cannot exceed 50 items"
},
"goodsId": {
"notBlank": "Goods ID cannot be empty",
"size": "Goods ID cannot exceed 64 characters"
},
"goodsName": {
"notBlank": "Goods name cannot be empty",
"size": "Goods name cannot exceed 256 characters"
},
"quantity": {
"notNull": "Quantity cannot be null",
"min": "Quantity cannot be less than 1"
},
"unitPrice": {
"notNull": "Unit price cannot be null",
"decimalMin": "Unit price cannot be less than 0.01",
"digits": "Unit price precision up to cents"
},
"goodsCategory": {
"size": "Goods category cannot exceed 32 characters"
},
"goodsDescription": {
"size": "Goods description cannot exceed 1000 characters"
},
"showUrl": {
"size": "Show URL cannot exceed 400 characters"
},
"attach": {
"size": "Attach cannot exceed 500 characters"
},

View File

@@ -188,6 +188,35 @@
"extraParam": {
"size": "支付扩展参数不可超过2048位"
},
"goodsDetail": {
"size": "商品明细列表不可超过50条"
},
"goodsId": {
"notBlank": "商品编码不可为空",
"size": "商品编码不可超过64位"
},
"goodsName": {
"notBlank": "商品名称不可为空",
"size": "商品名称不可超过256位"
},
"quantity": {
"notNull": "商品数量不可为空",
"min": "商品数量不能小于1"
},
"unitPrice": {
"notNull": "商品单价不可为空",
"decimalMin": "商品单价不可小于0.01元",
"digits": "商品单价精度到分"
},
"goodsCategory": {
"size": "商品分类不可超过32位"
},
"goodsDescription": {
"size": "商品描述不可超过1000位"
},
"showUrl": {
"size": "商品展示链接不可超过400位"
},
"attach": {
"size": "商户扩展参数不可超过500位"
},