支付调整

This commit is contained in:
2026-01-14 17:04:48 +08:00
parent e8be5dee9d
commit 4eaedcce41
70 changed files with 1065 additions and 829 deletions

View File

@@ -32,7 +32,6 @@ public class ShopInfo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 使用系统用户 sys_user id
*/
@@ -142,18 +141,6 @@ public class ShopInfo implements Serializable {
* -1 平台禁用 0-过期1正式营业
*/
private Integer status;
/**
* 微信商户id
*/
private String wechatMerchantId;
/**
* 支付宝商户id
*/
private String alipayMerchantId;
/**
* 支付宝授权信息
*/
private String alipayAuthInfo;
/**
* 到期时间

View File

@@ -38,11 +38,6 @@ public interface ShopInfoService extends IService<ShopInfo> {
Boolean edit(ShopInfoEditDTO shopInfoEditDTO);
/**
* 进件结果保存
*/
Boolean editEntry(Long shopId, String wechatMerchantId, String alipayMerchantId, String alipayAuthInfo);
ShopDetailDTO detail(Long id) throws CzgException;
ShopInfoByCodeDTO getByCode(String tableCode, String lat, String lng, boolean checkState);

View File

@@ -1,22 +0,0 @@
package com.czg.account.service;
import com.czg.account.dto.merchant.ShopMerchantEditDTO;
import com.czg.account.entity.ShopMerchant;
import com.mybatisflex.core.service.IService;
import java.io.Serializable;
/**
* 第三方商户进件 服务层。
*
* @author Administrator
* @since 2025-02-11
*/
public interface ShopMerchantService extends IService<ShopMerchant> {
ShopMerchant detail(Integer shopId);
Boolean edit(ShopMerchantEditDTO shopMerchantEditDTO);
@Override
ShopMerchant getById(Serializable id);
}

View File

@@ -79,7 +79,9 @@ public interface ParamCodeCst {
* 超掌柜支付回调地址
* <p>支付宝/微信支付完成后,支付平台回调我方系统的地址</p>
*/
public static String PAY_CZG_NOTIFY_URL = "pay_czg_notify_url";
// public static String PAY_CZG_NOTIFY_URL = "pay_czg_notify_url";
public static String NATIVE_PAY_NOTIFY_URL = "native_pay_notify_url";
public static String POLY_PAY_NOTIFY_URL = "poly_pay_notify_url";
/**
* 排队到号通知
*/

View File

@@ -28,6 +28,7 @@ public class OrderInfoAddDTO implements Serializable {
* 已出菜 SENT_OUT
* 已上菜 DELIVERED
* 已超时 EXPIRED
* 加急 URGENT
*/
private String subStatus;
//限时折扣部分

View File

@@ -0,0 +1,40 @@
package com.czg.order.dto;
import com.czg.order.entity.ShopDirectMerchant;
import com.czg.pay.NativeMerchantDTO;
import com.czg.pay.PolyMerchantDTO;
import lombok.Data;
/**
* 支付信息
*
* @author ww
*/
@Data
public class ShopMerchantDTO {
private Long shopId;
/**
* poly 聚合(支付平台) native 原生(wx/ali 原生)
* {@link com.czg.constant.PayChannelCst}
*/
private String channel;
/**
* 聚合支付商户
* native 必填 对应 tb_shop_direct_merchant 的 licence_no 营业执照
*/
private String relatedLicenceNo;
/**
* 原生支付参数
*/
private NativeMerchantDTO nativeMerchantDTO;
/**
* 聚合支付参数
*/
private PolyMerchantDTO polyMerchantDTO;
/**
* 店铺绑定的商户信息
*/
private ShopDirectMerchant shopDirectMerchant;
}

View File

@@ -5,6 +5,7 @@ import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@@ -40,6 +41,12 @@ public class OrderPayment implements Serializable {
*/
private Long shopId;
/**
* 支付渠道
* {@link com.czg.constant.PayChannelCst}
*/
private String channel;
/**
* 来源Id 订单Id或充值id
*/
@@ -104,28 +111,66 @@ public class OrderPayment implements Serializable {
public OrderPayment() {
}
public OrderPayment(@NonNull Long shopId,@NonNull Long sourceId, @NotBlank String sourceType,@NotBlank String payType, @NotBlank String orderNo,
String authCode, @NonNull BigDecimal amount) {
this.shopId = shopId;
this.sourceId = sourceId;
this.sourceType = sourceType;
this.payType = payType;
this.orderNo = orderNo;
this.authCode = authCode;
this.amount = amount;
this.payStatus = PayTypeConstants.PayStatus.INIT;
/**
* 订单专用支付
*
* @param sourceId 订单Id
* @param amount 单元 元
* @param authCode 扫码支付时必填 扫描码
*/
public static OrderPayment orderPay(@NonNull Long shopId, @NonNull Long sourceId,
@NotBlank String orderNo, @NonNull BigDecimal amount, String authCode) {
OrderPayment orderPayment = getInstance(shopId, sourceId, PayTypeConstants.SourceType.ORDER, orderNo, amount, authCode, null);
orderPayment.setPayType(PayTypeConstants.PayType.PAY);
orderPayment.setPayStatus(PayTypeConstants.PayStatus.INIT);
return orderPayment;
}
public OrderPayment(@NonNull Long shopId,@NonNull Long sourceId, @NotBlank String sourceType,@NotBlank String payType, @NotBlank String orderNo,
String authCode, @NonNull BigDecimal amount, Long relatedId) {
this.shopId = shopId;
this.sourceId = sourceId;
this.sourceType = sourceType;
this.payType = payType;
this.orderNo = orderNo;
this.authCode = authCode;
this.amount = amount;
this.relatedId = relatedId;
this.payStatus = PayTypeConstants.PayStatus.INIT;
/**
* 初始化支付参数
*
* @param sourceId 充值时为会员Id shopUserID
* 购买时为商品Id
* @param sourceType {@link PayTypeConstants.SourceType} 支付来源
* @param amount 单元 元
* @param authCode 扫码支付时必填 扫描码
* @param relatedId 霸王餐充值为 订单id 会员充值为 活动id 充值并支付时 为 MkShopRechargeDetail
*/
public static OrderPayment pay(@NonNull Long shopId, @NonNull Long sourceId, @NotBlank String sourceType,
@NotBlank String orderNo, @NonNull BigDecimal amount,
String authCode, Long relatedId) {
OrderPayment orderPayment = getInstance(shopId, sourceId, sourceType, orderNo, amount, authCode, relatedId);
orderPayment.setPayType(PayTypeConstants.PayType.PAY);
orderPayment.setPayStatus(PayTypeConstants.PayStatus.INIT);
return orderPayment;
}
public static OrderPayment refund(@NonNull Long shopId, @NonNull Long sourceId, @NotBlank String sourceType,
@NotBlank String orderNo, @NonNull BigDecimal amount, Long relatedId) {
OrderPayment orderPayment = getInstance(shopId, sourceId, sourceType, orderNo, amount, null, relatedId);
orderPayment.setPayType(PayTypeConstants.PayType.REFUND);
orderPayment.setPayStatus(PayTypeConstants.PayStatus.INIT);
return orderPayment;
}
public static OrderPayment refundCompensate(@NonNull Long shopId, @NonNull Long sourceId, @NotBlank String sourceType,
@NotBlank String orderNo, @NonNull BigDecimal amount, Long relatedId) {
OrderPayment orderPayment = getInstance(shopId, sourceId, sourceType, orderNo, amount, null, relatedId);
orderPayment.setPayType(PayTypeConstants.PayType.REFUND_COMPENSATE);
orderPayment.setPayStatus(PayTypeConstants.PayStatus.INIT);
return orderPayment;
}
private static OrderPayment getInstance(Long shopId, Long sourceId, String sourceType,
String orderNo, BigDecimal amount, String authCode, Long relatedId) {
OrderPayment orderPayment = new OrderPayment();
orderPayment.shopId = shopId;
orderPayment.sourceId = sourceId;
orderPayment.sourceType = sourceType;
orderPayment.orderNo = orderNo;
orderPayment.authCode = authCode;
orderPayment.amount = amount;
orderPayment.relatedId = relatedId;
return orderPayment;
}
}

View File

@@ -44,7 +44,6 @@ public class ShopDirectMerchant implements Serializable {
/**
* 营业执照编号
*/
@Id
private String licenceNo;
/**
* 支付宝账号
@@ -124,11 +123,6 @@ public class ShopDirectMerchant implements Serializable {
*/
private String alipayStatus;
/**
* 支付宝授信息
*/
private String alipayAuthInfo;
/**
* 支付宝进件错误信息
*/
@@ -138,4 +132,18 @@ public class ShopDirectMerchant implements Serializable {
*/
private String alipaySignUrl;
/**
* 支付宝授信息
*/
private String alipayAuthInfo;
/**
* 微信商户id
*/
private String wechatMerchantId;
/**
* 支付宝商户id
*/
private String alipayMerchantId;
}

View File

@@ -1,4 +1,4 @@
package com.czg.account.entity;
package com.czg.order.entity;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
@@ -18,57 +18,45 @@ import java.time.LocalDateTime;
* @since 2025-02-11
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Table("tb_shop_merchant")
@Table("tb_shop_merchant2")
public class ShopMerchant implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Id
private Long id;
/**
* 店铺id
*/
@Id
private Long shopId;
/**
* 支付系统商户id
* poly 聚合(支付平台) native 原生(wx/ali 原生)
* {@link com.czg.constant.PayChannelCst}
*/
private String storeId;
private String merchantName;
private String channel;
/**
* 商户应用id
* 聚合支付商户
* native 必填 对应 tb_shop_direct_merchant licence_no 营业执照
*/
private String appId;
private String relatedLicenceNo;
/**
* 商户token
* 聚合支付参数
*/
private String appSecret;
private String polyPayJson;
/**
* 微信小程序appid
* 原生支付参数
*/
private String wechatSmallAppid;
/**
* 支付宝小程序appid
*/
private String alipaySmallAppid;
/**
* 支付密码
*/
private String payPassword;
private String nativePayJson;
@Column(onInsertValue = "now()")
private LocalDateTime createTime;
@Column(onInsertValue = "now()", onUpdateValue = "now()")
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,30 @@
package com.czg.order.service;
import com.czg.order.dto.ShopMerchantDTO;
import com.czg.order.entity.ShopDirectMerchant;
import com.czg.order.entity.ShopMerchant;
import com.mybatisflex.core.service.IService;
import java.io.Serializable;
/**
* 第三方商户进件 服务层。
*
* @author Administrator
* @since 2025-02-11
*/
public interface ShopMerchantService extends IService<ShopMerchant> {
ShopMerchantDTO detail(Long shopId);
/**
* 进件结果保存/ 支付参数修改
*/
Boolean editEntry(ShopMerchantDTO shopMerchantParam, boolean isUp);
@Override
ShopMerchant getById(Serializable id);
ShopDirectMerchant getMainMerchant(Long shopId);
}

View File

@@ -0,0 +1,63 @@
package com.czg.pay;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 支付宝授权信息
* @author yjjie
* @date 2026/1/9 11:31
*/
@Data
@Accessors(chain = true)
public class AlipayAuthInfoDto {
/**
* 授权商户的user_id
*/
@JSONField(name = "user_id")
private String userId;
/**
* 授权商户的open_id
*/
@JSONField(name = "open_id")
private String openId;
/**
* 授权商户的appid
*/
@JSONField(name = "auth_app_id")
private String authAppId;
/**
* 应用授权令牌
*/
@JSONField(name = "app_auth_token")
private String appAuthToken;
/**
* 应用授权令牌有效期
*/
@JSONField(name = "expires_in")
private String expiresIn;
/**
* 刷新令牌
*/
@JSONField(name = "app_refresh_token")
private String appRefreshToken;
/**
* 刷新令牌的有效时间
*/
@JSONField(name = "re_expires_in")
private String reExpiresIn;
/**
* 签约单号
*/
@JSONField(name = "order_no")
private String orderNo;
}

View File

@@ -0,0 +1,132 @@
package com.czg.pay;
import lombok.Data;
import lombok.NonNull;
/**
* @author ww
*/
@Data
public class CzgPayBaseReq<T> {
//必填范围
/**
* 订单标题
*/
private String subject;
/**
* 订单描述 String(256)
*/
private String body;
/**
* 交易金额 分
*/
private Long amount;
/**
* 货币类型 cny
*/
private String currency = "cny";
/**
* 商户订单号 String(30)
* 操作方式+雪花算法
* 收银机客户端 PC+雪花ID
* 微信小程序 WX+雪花ID
* 支付宝小程序 ALI+雪花ID
* PC管理端 WEB+雪花ID
* APP管理端 APP+雪花ID
* <p>
* 退款 re+雪花ID
*/
private String mchOrderNo;
/**
* 异步通知地址 String(128)
* 支付结果异步回调URL,只有传了该值才会发起回调
*/
private String notifyUrl;
/**
* 扩展参数 String(512)
* 商户扩展参数,回调时会原样返回
* * 扩展参数
* * {
* * "pay_type": "order/vip"
* * }
*/
private String extParam;
/**
* 原生支付 不需要 store_id
*/
private String storeId;
/**
* 支付类型
*/
private String payType;
/**
* 用户唯一标识 String(30)
* 微信支付时传入用户的openId
* 支付宝支付和银联支付时传入用户的userId
*/
private String userId;
/**
* 用户IP
* 需要传付款用户客户端IP地址
*/
private String clientIp;
/**
* 子商户 appid ,微信付款支付的时候 需要上送
* isScreen 为 false 的情况下需要传入
*/
private String subAppid;
/**
* 额外参数
*/
private T data;
public CzgPayBaseReq() {
}
public CzgPayBaseReq(String mchOrderNo, String detail, Long amount, String payType, String userId, String clientIp) {
this.mchOrderNo = mchOrderNo;
this.subject = detail;
this.body = detail;
this.amount = amount;
this.payType = payType;
this.userId = userId;
this.clientIp = clientIp;
}
public void polyBase(@NonNull String storeId, @NonNull String notifyUrl) {
this.storeId = storeId;
this.notifyUrl = notifyUrl;
}
public static CzgPayBaseReq<?> ltPayReq(@NonNull String mchOrderNo, @NonNull String detail, @NonNull Long amount
, @NonNull String payType, @NonNull String openId, @NonNull String clientIp) {
return new CzgPayBaseReq<>(mchOrderNo, detail, amount, payType, openId, clientIp);
}
public static CzgPayBaseReq<?> h5PayReq(@NonNull String mchOrderNo, @NonNull String detail, @NonNull Long amount, @NonNull String clientIp) {
return new CzgPayBaseReq<>(mchOrderNo, detail, amount, null, null, clientIp);
}
public static CzgPayBaseReq<?> jsPayReq(@NonNull String mchOrderNo, @NonNull String detail, @NonNull Long amount
, @NonNull String payType, @NonNull String openId, @NonNull String clientIp) {
return new CzgPayBaseReq<>(mchOrderNo, detail, amount, payType, openId, clientIp);
}
public static CzgPayBaseReq<?> scanPayReq(@NonNull String mchOrderNo, @NonNull String detail, @NonNull Long amount, @NonNull String clientIp) {
return new CzgPayBaseReq<>(mchOrderNo, detail, amount, null, null, clientIp);
}
public static CzgPayBaseReq<String> microPay(@NonNull String mchOrderNo, @NonNull String detail, @NonNull Long amount, @NonNull String authCode) {
CzgPayBaseReq<String> stringReq = new CzgPayBaseReq<>(mchOrderNo, detail, amount, null, null, null);
stringReq.setData(authCode);
return stringReq;
}
}

View File

@@ -0,0 +1,65 @@
package com.czg.pay;
import lombok.Data;
import lombok.NonNull;
/**
* @author ww
*/
@Data
public class CzgRefundReq {
//必填范围
/**
* 退款订单号
* 商户退款订单号
*/
private String mchRefundNo;
/**
* 退款原因
*/
private String refundReason;
/**
* 退款金额
* 单位为分
*/
private Long refundAmount;
/**
* 原订单总金额 单位 分
*/
private Long orderTotalAmount;
//非必填范围
/**
* 原平台订单号 (二选一)
*/
private String payOrderId;
/**
* 原商户订单号 (二选一)
*/
private String mchOrderNo;
/**
* 扩展参数
* * 扩展参数
* * {
* * "pay_type": "order/vip"
* * }
*/
private String extParam;
/**
* 回调地址
*/
private String notifyUrl;
/**
* payOrderId和mchOrderNo 二选一 必填
*/
public CzgRefundReq(@NonNull String mchRefundNo, @NonNull String refundReason, @NonNull Long refundAmount,
@NonNull Long orderTotalAmount, String mchOrderNo, String extParam) {
this.mchRefundNo = mchRefundNo;
this.refundReason = refundReason;
this.refundAmount = refundAmount;
this.orderTotalAmount = orderTotalAmount;
this.mchOrderNo = mchOrderNo;
this.extParam = extParam;
}
}

View File

@@ -0,0 +1,17 @@
package com.czg.pay;
import lombok.Data;
/**
* 原生支付参数
* @author ww
*/
@Data
public class NativeMerchantDTO {
private String wechatMerchantId;
private String alipayMerchantId;
/**
* 支付宝 授权信息解析
*/
private AlipayAuthInfoDto alipayAuthInfo;
}

View File

@@ -1,16 +1,14 @@
package com.czg.account.dto.merchant;
package com.czg.pay;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* @author Administrator
* 聚合支付参数
* @author ww
*/
@Data
public class ShopMerchantEditDTO {
@NotNull(message = "店铺id不为空")
private Long shopId;
public class PolyMerchantDTO {
@NotEmpty(message = "支付系统商户id不为空")
private String storeId;
@NotEmpty(message = "支付系统商户名称不为空")

View File

@@ -0,0 +1,18 @@
package com.czg.constant;
/**
* 支付渠道常量
* @author ww
*/
public interface PayChannelCst {
/**
* 聚合支付
* 对应 类 PolyPay
*/
String POLY = "poly";
/**
* 原生支付
* 对应 类 NativePay
*/
String NATIVE = "native";
}