支持拉卡拉多渠道支付和测试充值

This commit is contained in:
yml
2026-06-06 21:46:41 +08:00
parent 4d40883da6
commit ba4c56c0cc
16 changed files with 1917 additions and 157 deletions
@@ -18,6 +18,9 @@ var (
ErrNotifyKeyRequired = errors.New("notify_key is required for leshua provider")
ErrNotifyURLRequired = errors.New("notify_url is required for leshua provider")
ErrInvalidSignType = errors.New("invalid sign_type")
ErrAppIDRequired = errors.New("extra_config.app_id is required for lakala provider")
ErrSerialNoRequired = errors.New("extra_config.serial_no is required for lakala provider")
ErrTermNoRequired = errors.New("extra_config.term_no is required for lakala provider")
)
// DTO 数据传输对象
@@ -51,7 +54,7 @@ type ConfigDTO struct {
// CreateRequest 创建支付配置请求
type CreateRequest struct {
Name string `json:"name" binding:"required"`
Provider string `json:"provider" binding:"required,oneof=leshua mock"`
Provider string `json:"provider" binding:"required,oneof=leshua lakala mock"`
MerchantID string `json:"merchant_id" binding:"required"`
GatewayURL string `json:"gateway_url"`
SignKey string `json:"sign_key"`
@@ -95,7 +95,8 @@ func (h *Handler) Create(c *gin.Context) {
config, err := h.service.Create(req, adminID, auditMeta(c))
if err == ErrNameRequired || err == ErrMerchantIDRequired || err == ErrGatewayURLRequired ||
err == ErrSignKeyRequired || err == ErrNotifyKeyRequired || err == ErrInvalidProvider ||
err == ErrNotifyURLRequired || err == ErrInvalidSignType {
err == ErrNotifyURLRequired || err == ErrInvalidSignType || err == ErrAppIDRequired ||
err == ErrSerialNoRequired || err == ErrTermNoRequired {
response.BadRequest(c, err.Error())
return
}
@@ -210,7 +210,7 @@ func (r *Repository) Create(req CreateRequest, actorID uint64, meta AuditMeta) (
JumpURL: req.JumpURL,
PayWay: firstNonEmpty(req.PayWay, "ZFBZF"),
JSPayFlag: firstNonEmpty(req.JSPayFlag, "2"),
SignType: firstNonEmpty(req.SignType, "MD5"),
SignType: firstNonEmpty(req.SignType, defaultSignType(req.Provider)),
ExtraConfig: req.ExtraConfig,
IsDefault: req.IsDefault,
Status: status,
@@ -244,7 +244,7 @@ func (r *Repository) Create(req CreateRequest, actorID uint64, meta AuditMeta) (
// Update 更新配置
func (r *Repository) Update(id uint64, req UpdateRequest, actorID uint64, meta AuditMeta) (*ConfigDTO, error) {
if req.SignType != nil && *req.SignType != "" && *req.SignType != "MD5" {
if req.SignType != nil && *req.SignType != "" && !isValidSignType(*req.SignType) {
return nil, ErrInvalidSignType
}
if req.NotifyURL != nil && *req.NotifyURL == "" {
@@ -310,7 +310,7 @@ func (r *Repository) Update(id uint64, req UpdateRequest, actorID uint64, meta A
updates["sign_type"] = *req.SignType
}
if req.ExtraConfig != nil {
updates["extra_config"] = req.ExtraConfig
updates["extra_config"] = model.JSONMap(req.ExtraConfig)
}
if req.IsDefault != nil {
updates["is_default"] = *req.IsDefault
@@ -322,7 +322,7 @@ func (r *Repository) Update(id uint64, req UpdateRequest, actorID uint64, meta A
updates["environment"] = *req.Environment
}
if req.BusinessTags != nil {
updates["business_tags"] = req.BusinessTags
updates["business_tags"] = model.JSONArray(req.BusinessTags)
}
updates["updated_by"] = actorID
@@ -489,7 +489,7 @@ func (r *Repository) validateCreateRequest(req CreateRequest) error {
if req.MerchantID == "" {
return ErrMerchantIDRequired
}
if req.SignType != "" && req.SignType != "MD5" {
if req.SignType != "" && !isValidSignType(req.SignType) {
return ErrInvalidSignType
}
@@ -508,6 +508,29 @@ func (r *Repository) validateCreateRequest(req CreateRequest) error {
return ErrNotifyURLRequired
}
}
if req.Provider == "lakala" {
if req.GatewayURL == "" {
return ErrGatewayURLRequired
}
if req.SignKey == "" {
return ErrSignKeyRequired
}
if req.NotifyKey == "" {
return ErrNotifyKeyRequired
}
if req.NotifyURL == "" {
return ErrNotifyURLRequired
}
if extraString(req.ExtraConfig, "app_id") == "" {
return ErrAppIDRequired
}
if extraString(req.ExtraConfig, "serial_no") == "" {
return ErrSerialNoRequired
}
if extraString(req.ExtraConfig, "term_no") == "" {
return ErrTermNoRequired
}
}
return nil
}
@@ -521,6 +544,31 @@ func firstNonEmpty(vals ...string) string {
return ""
}
func defaultSignType(provider string) string {
if provider == "lakala" {
return "SHA256withRSA"
}
return "MD5"
}
func isValidSignType(value string) bool {
return value == "MD5" || value == "SHA256withRSA"
}
func extraString(config map[string]any, key string) string {
if config == nil {
return ""
}
value, ok := config[key]
if !ok || value == nil {
return ""
}
if s, ok := value.(string); ok {
return s
}
return ""
}
func appendAuditLog(tx *gorm.DB, actorID uint64, action string, bizID uint64, meta AuditMeta, detail map[string]any) error {
detailJSON, err := json.Marshal(detail)
if err != nil {