feat: snapshot payment provider keys on orders

This commit is contained in:
IanShaw027
2026-04-20 20:47:14 +08:00
parent e3f69e0246
commit c0b24aefba
14 changed files with 400 additions and 24 deletions

View File

@@ -654,6 +654,7 @@ var (
{Name: "subscription_group_id", Type: field.TypeInt64, Nullable: true}, {Name: "subscription_group_id", Type: field.TypeInt64, Nullable: true},
{Name: "subscription_days", Type: field.TypeInt, Nullable: true}, {Name: "subscription_days", Type: field.TypeInt, Nullable: true},
{Name: "provider_instance_id", Type: field.TypeString, Nullable: true, Size: 64}, {Name: "provider_instance_id", Type: field.TypeString, Nullable: true, Size: 64},
{Name: "provider_key", Type: field.TypeString, Nullable: true, Size: 30},
{Name: "status", Type: field.TypeString, Size: 30, Default: "PENDING"}, {Name: "status", Type: field.TypeString, Size: 30, Default: "PENDING"},
{Name: "refund_amount", Type: field.TypeFloat64, Default: 0, SchemaType: map[string]string{"postgres": "decimal(20,2)"}}, {Name: "refund_amount", Type: field.TypeFloat64, Default: 0, SchemaType: map[string]string{"postgres": "decimal(20,2)"}},
{Name: "refund_reason", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}}, {Name: "refund_reason", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}},
@@ -682,7 +683,7 @@ var (
ForeignKeys: []*schema.ForeignKey{ ForeignKeys: []*schema.ForeignKey{
{ {
Symbol: "payment_orders_users_payment_orders", Symbol: "payment_orders_users_payment_orders",
Columns: []*schema.Column{PaymentOrdersColumns[37]}, Columns: []*schema.Column{PaymentOrdersColumns[38]},
RefColumns: []*schema.Column{UsersColumns[0]}, RefColumns: []*schema.Column{UsersColumns[0]},
OnDelete: schema.NoAction, OnDelete: schema.NoAction,
}, },
@@ -696,32 +697,32 @@ var (
{ {
Name: "paymentorder_user_id", Name: "paymentorder_user_id",
Unique: false, Unique: false,
Columns: []*schema.Column{PaymentOrdersColumns[37]}, Columns: []*schema.Column{PaymentOrdersColumns[38]},
}, },
{ {
Name: "paymentorder_status", Name: "paymentorder_status",
Unique: false, Unique: false,
Columns: []*schema.Column{PaymentOrdersColumns[19]}, Columns: []*schema.Column{PaymentOrdersColumns[20]},
}, },
{ {
Name: "paymentorder_expires_at", Name: "paymentorder_expires_at",
Unique: false, Unique: false,
Columns: []*schema.Column{PaymentOrdersColumns[27]}, Columns: []*schema.Column{PaymentOrdersColumns[28]},
}, },
{ {
Name: "paymentorder_created_at", Name: "paymentorder_created_at",
Unique: false, Unique: false,
Columns: []*schema.Column{PaymentOrdersColumns[35]}, Columns: []*schema.Column{PaymentOrdersColumns[36]},
}, },
{ {
Name: "paymentorder_paid_at", Name: "paymentorder_paid_at",
Unique: false, Unique: false,
Columns: []*schema.Column{PaymentOrdersColumns[28]}, Columns: []*schema.Column{PaymentOrdersColumns[29]},
}, },
{ {
Name: "paymentorder_payment_type_paid_at", Name: "paymentorder_payment_type_paid_at",
Unique: false, Unique: false,
Columns: []*schema.Column{PaymentOrdersColumns[9], PaymentOrdersColumns[28]}, Columns: []*schema.Column{PaymentOrdersColumns[9], PaymentOrdersColumns[29]},
}, },
{ {
Name: "paymentorder_order_type", Name: "paymentorder_order_type",

View File

@@ -15385,6 +15385,7 @@ type PaymentOrderMutation struct {
subscription_days *int subscription_days *int
addsubscription_days *int addsubscription_days *int
provider_instance_id *string provider_instance_id *string
provider_key *string
status *string status *string
refund_amount *float64 refund_amount *float64
addrefund_amount *float64 addrefund_amount *float64
@@ -16421,6 +16422,55 @@ func (m *PaymentOrderMutation) ResetProviderInstanceID() {
delete(m.clearedFields, paymentorder.FieldProviderInstanceID) delete(m.clearedFields, paymentorder.FieldProviderInstanceID)
} }
// SetProviderKey sets the "provider_key" field.
func (m *PaymentOrderMutation) SetProviderKey(s string) {
m.provider_key = &s
}
// ProviderKey returns the value of the "provider_key" field in the mutation.
func (m *PaymentOrderMutation) ProviderKey() (r string, exists bool) {
v := m.provider_key
if v == nil {
return
}
return *v, true
}
// OldProviderKey returns the old "provider_key" field's value of the PaymentOrder entity.
// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *PaymentOrderMutation) OldProviderKey(ctx context.Context) (v *string, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldProviderKey is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldProviderKey requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldProviderKey: %w", err)
}
return oldValue.ProviderKey, nil
}
// ClearProviderKey clears the value of the "provider_key" field.
func (m *PaymentOrderMutation) ClearProviderKey() {
m.provider_key = nil
m.clearedFields[paymentorder.FieldProviderKey] = struct{}{}
}
// ProviderKeyCleared returns if the "provider_key" field was cleared in this mutation.
func (m *PaymentOrderMutation) ProviderKeyCleared() bool {
_, ok := m.clearedFields[paymentorder.FieldProviderKey]
return ok
}
// ResetProviderKey resets all changes to the "provider_key" field.
func (m *PaymentOrderMutation) ResetProviderKey() {
m.provider_key = nil
delete(m.clearedFields, paymentorder.FieldProviderKey)
}
// SetStatus sets the "status" field. // SetStatus sets the "status" field.
func (m *PaymentOrderMutation) SetStatus(s string) { func (m *PaymentOrderMutation) SetStatus(s string) {
m.status = &s m.status = &s
@@ -17280,7 +17330,7 @@ func (m *PaymentOrderMutation) Type() string {
// order to get all numeric fields that were incremented/decremented, call // order to get all numeric fields that were incremented/decremented, call
// AddedFields(). // AddedFields().
func (m *PaymentOrderMutation) Fields() []string { func (m *PaymentOrderMutation) Fields() []string {
fields := make([]string, 0, 37) fields := make([]string, 0, 38)
if m.user != nil { if m.user != nil {
fields = append(fields, paymentorder.FieldUserID) fields = append(fields, paymentorder.FieldUserID)
} }
@@ -17338,6 +17388,9 @@ func (m *PaymentOrderMutation) Fields() []string {
if m.provider_instance_id != nil { if m.provider_instance_id != nil {
fields = append(fields, paymentorder.FieldProviderInstanceID) fields = append(fields, paymentorder.FieldProviderInstanceID)
} }
if m.provider_key != nil {
fields = append(fields, paymentorder.FieldProviderKey)
}
if m.status != nil { if m.status != nil {
fields = append(fields, paymentorder.FieldStatus) fields = append(fields, paymentorder.FieldStatus)
} }
@@ -17438,6 +17491,8 @@ func (m *PaymentOrderMutation) Field(name string) (ent.Value, bool) {
return m.SubscriptionDays() return m.SubscriptionDays()
case paymentorder.FieldProviderInstanceID: case paymentorder.FieldProviderInstanceID:
return m.ProviderInstanceID() return m.ProviderInstanceID()
case paymentorder.FieldProviderKey:
return m.ProviderKey()
case paymentorder.FieldStatus: case paymentorder.FieldStatus:
return m.Status() return m.Status()
case paymentorder.FieldRefundAmount: case paymentorder.FieldRefundAmount:
@@ -17521,6 +17576,8 @@ func (m *PaymentOrderMutation) OldField(ctx context.Context, name string) (ent.V
return m.OldSubscriptionDays(ctx) return m.OldSubscriptionDays(ctx)
case paymentorder.FieldProviderInstanceID: case paymentorder.FieldProviderInstanceID:
return m.OldProviderInstanceID(ctx) return m.OldProviderInstanceID(ctx)
case paymentorder.FieldProviderKey:
return m.OldProviderKey(ctx)
case paymentorder.FieldStatus: case paymentorder.FieldStatus:
return m.OldStatus(ctx) return m.OldStatus(ctx)
case paymentorder.FieldRefundAmount: case paymentorder.FieldRefundAmount:
@@ -17699,6 +17756,13 @@ func (m *PaymentOrderMutation) SetField(name string, value ent.Value) error {
} }
m.SetProviderInstanceID(v) m.SetProviderInstanceID(v)
return nil return nil
case paymentorder.FieldProviderKey:
v, ok := value.(string)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetProviderKey(v)
return nil
case paymentorder.FieldStatus: case paymentorder.FieldStatus:
v, ok := value.(string) v, ok := value.(string)
if !ok { if !ok {
@@ -17966,6 +18030,9 @@ func (m *PaymentOrderMutation) ClearedFields() []string {
if m.FieldCleared(paymentorder.FieldProviderInstanceID) { if m.FieldCleared(paymentorder.FieldProviderInstanceID) {
fields = append(fields, paymentorder.FieldProviderInstanceID) fields = append(fields, paymentorder.FieldProviderInstanceID)
} }
if m.FieldCleared(paymentorder.FieldProviderKey) {
fields = append(fields, paymentorder.FieldProviderKey)
}
if m.FieldCleared(paymentorder.FieldRefundReason) { if m.FieldCleared(paymentorder.FieldRefundReason) {
fields = append(fields, paymentorder.FieldRefundReason) fields = append(fields, paymentorder.FieldRefundReason)
} }
@@ -18034,6 +18101,9 @@ func (m *PaymentOrderMutation) ClearField(name string) error {
case paymentorder.FieldProviderInstanceID: case paymentorder.FieldProviderInstanceID:
m.ClearProviderInstanceID() m.ClearProviderInstanceID()
return nil return nil
case paymentorder.FieldProviderKey:
m.ClearProviderKey()
return nil
case paymentorder.FieldRefundReason: case paymentorder.FieldRefundReason:
m.ClearRefundReason() m.ClearRefundReason()
return nil return nil
@@ -18129,6 +18199,9 @@ func (m *PaymentOrderMutation) ResetField(name string) error {
case paymentorder.FieldProviderInstanceID: case paymentorder.FieldProviderInstanceID:
m.ResetProviderInstanceID() m.ResetProviderInstanceID()
return nil return nil
case paymentorder.FieldProviderKey:
m.ResetProviderKey()
return nil
case paymentorder.FieldStatus: case paymentorder.FieldStatus:
m.ResetStatus() m.ResetStatus()
return nil return nil

View File

@@ -56,6 +56,8 @@ type PaymentOrder struct {
SubscriptionDays *int `json:"subscription_days,omitempty"` SubscriptionDays *int `json:"subscription_days,omitempty"`
// ProviderInstanceID holds the value of the "provider_instance_id" field. // ProviderInstanceID holds the value of the "provider_instance_id" field.
ProviderInstanceID *string `json:"provider_instance_id,omitempty"` ProviderInstanceID *string `json:"provider_instance_id,omitempty"`
// ProviderKey holds the value of the "provider_key" field.
ProviderKey *string `json:"provider_key,omitempty"`
// Status holds the value of the "status" field. // Status holds the value of the "status" field.
Status string `json:"status,omitempty"` Status string `json:"status,omitempty"`
// RefundAmount holds the value of the "refund_amount" field. // RefundAmount holds the value of the "refund_amount" field.
@@ -129,7 +131,7 @@ func (*PaymentOrder) scanValues(columns []string) ([]any, error) {
values[i] = new(sql.NullFloat64) values[i] = new(sql.NullFloat64)
case paymentorder.FieldID, paymentorder.FieldUserID, paymentorder.FieldPlanID, paymentorder.FieldSubscriptionGroupID, paymentorder.FieldSubscriptionDays: case paymentorder.FieldID, paymentorder.FieldUserID, paymentorder.FieldPlanID, paymentorder.FieldSubscriptionGroupID, paymentorder.FieldSubscriptionDays:
values[i] = new(sql.NullInt64) values[i] = new(sql.NullInt64)
case paymentorder.FieldUserEmail, paymentorder.FieldUserName, paymentorder.FieldUserNotes, paymentorder.FieldRechargeCode, paymentorder.FieldOutTradeNo, paymentorder.FieldPaymentType, paymentorder.FieldPaymentTradeNo, paymentorder.FieldPayURL, paymentorder.FieldQrCode, paymentorder.FieldQrCodeImg, paymentorder.FieldOrderType, paymentorder.FieldProviderInstanceID, paymentorder.FieldStatus, paymentorder.FieldRefundReason, paymentorder.FieldRefundRequestReason, paymentorder.FieldRefundRequestedBy, paymentorder.FieldFailedReason, paymentorder.FieldClientIP, paymentorder.FieldSrcHost, paymentorder.FieldSrcURL: case paymentorder.FieldUserEmail, paymentorder.FieldUserName, paymentorder.FieldUserNotes, paymentorder.FieldRechargeCode, paymentorder.FieldOutTradeNo, paymentorder.FieldPaymentType, paymentorder.FieldPaymentTradeNo, paymentorder.FieldPayURL, paymentorder.FieldQrCode, paymentorder.FieldQrCodeImg, paymentorder.FieldOrderType, paymentorder.FieldProviderInstanceID, paymentorder.FieldProviderKey, paymentorder.FieldStatus, paymentorder.FieldRefundReason, paymentorder.FieldRefundRequestReason, paymentorder.FieldRefundRequestedBy, paymentorder.FieldFailedReason, paymentorder.FieldClientIP, paymentorder.FieldSrcHost, paymentorder.FieldSrcURL:
values[i] = new(sql.NullString) values[i] = new(sql.NullString)
case paymentorder.FieldRefundAt, paymentorder.FieldRefundRequestedAt, paymentorder.FieldExpiresAt, paymentorder.FieldPaidAt, paymentorder.FieldCompletedAt, paymentorder.FieldFailedAt, paymentorder.FieldCreatedAt, paymentorder.FieldUpdatedAt: case paymentorder.FieldRefundAt, paymentorder.FieldRefundRequestedAt, paymentorder.FieldExpiresAt, paymentorder.FieldPaidAt, paymentorder.FieldCompletedAt, paymentorder.FieldFailedAt, paymentorder.FieldCreatedAt, paymentorder.FieldUpdatedAt:
values[i] = new(sql.NullTime) values[i] = new(sql.NullTime)
@@ -276,6 +278,13 @@ func (_m *PaymentOrder) assignValues(columns []string, values []any) error {
_m.ProviderInstanceID = new(string) _m.ProviderInstanceID = new(string)
*_m.ProviderInstanceID = value.String *_m.ProviderInstanceID = value.String
} }
case paymentorder.FieldProviderKey:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field provider_key", values[i])
} else if value.Valid {
_m.ProviderKey = new(string)
*_m.ProviderKey = value.String
}
case paymentorder.FieldStatus: case paymentorder.FieldStatus:
if value, ok := values[i].(*sql.NullString); !ok { if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field status", values[i]) return fmt.Errorf("unexpected type %T for field status", values[i])
@@ -508,6 +517,11 @@ func (_m *PaymentOrder) String() string {
builder.WriteString(*v) builder.WriteString(*v)
} }
builder.WriteString(", ") builder.WriteString(", ")
if v := _m.ProviderKey; v != nil {
builder.WriteString("provider_key=")
builder.WriteString(*v)
}
builder.WriteString(", ")
builder.WriteString("status=") builder.WriteString("status=")
builder.WriteString(_m.Status) builder.WriteString(_m.Status)
builder.WriteString(", ") builder.WriteString(", ")

View File

@@ -52,6 +52,8 @@ const (
FieldSubscriptionDays = "subscription_days" FieldSubscriptionDays = "subscription_days"
// FieldProviderInstanceID holds the string denoting the provider_instance_id field in the database. // FieldProviderInstanceID holds the string denoting the provider_instance_id field in the database.
FieldProviderInstanceID = "provider_instance_id" FieldProviderInstanceID = "provider_instance_id"
// FieldProviderKey holds the string denoting the provider_key field in the database.
FieldProviderKey = "provider_key"
// FieldStatus holds the string denoting the status field in the database. // FieldStatus holds the string denoting the status field in the database.
FieldStatus = "status" FieldStatus = "status"
// FieldRefundAmount holds the string denoting the refund_amount field in the database. // FieldRefundAmount holds the string denoting the refund_amount field in the database.
@@ -123,6 +125,7 @@ var Columns = []string{
FieldSubscriptionGroupID, FieldSubscriptionGroupID,
FieldSubscriptionDays, FieldSubscriptionDays,
FieldProviderInstanceID, FieldProviderInstanceID,
FieldProviderKey,
FieldStatus, FieldStatus,
FieldRefundAmount, FieldRefundAmount,
FieldRefundReason, FieldRefundReason,
@@ -176,6 +179,8 @@ var (
OrderTypeValidator func(string) error OrderTypeValidator func(string) error
// ProviderInstanceIDValidator is a validator for the "provider_instance_id" field. It is called by the builders before save. // ProviderInstanceIDValidator is a validator for the "provider_instance_id" field. It is called by the builders before save.
ProviderInstanceIDValidator func(string) error ProviderInstanceIDValidator func(string) error
// ProviderKeyValidator is a validator for the "provider_key" field. It is called by the builders before save.
ProviderKeyValidator func(string) error
// DefaultStatus holds the default value on creation for the "status" field. // DefaultStatus holds the default value on creation for the "status" field.
DefaultStatus string DefaultStatus string
// StatusValidator is a validator for the "status" field. It is called by the builders before save. // StatusValidator is a validator for the "status" field. It is called by the builders before save.
@@ -301,6 +306,11 @@ func ByProviderInstanceID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldProviderInstanceID, opts...).ToFunc() return sql.OrderByField(FieldProviderInstanceID, opts...).ToFunc()
} }
// ByProviderKey orders the results by the provider_key field.
func ByProviderKey(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldProviderKey, opts...).ToFunc()
}
// ByStatus orders the results by the status field. // ByStatus orders the results by the status field.
func ByStatus(opts ...sql.OrderTermOption) OrderOption { func ByStatus(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldStatus, opts...).ToFunc() return sql.OrderByField(FieldStatus, opts...).ToFunc()

View File

@@ -150,6 +150,11 @@ func ProviderInstanceID(v string) predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldEQ(FieldProviderInstanceID, v)) return predicate.PaymentOrder(sql.FieldEQ(FieldProviderInstanceID, v))
} }
// ProviderKey applies equality check predicate on the "provider_key" field. It's identical to ProviderKeyEQ.
func ProviderKey(v string) predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldEQ(FieldProviderKey, v))
}
// Status applies equality check predicate on the "status" field. It's identical to StatusEQ. // Status applies equality check predicate on the "status" field. It's identical to StatusEQ.
func Status(v string) predicate.PaymentOrder { func Status(v string) predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldEQ(FieldStatus, v)) return predicate.PaymentOrder(sql.FieldEQ(FieldStatus, v))
@@ -1360,6 +1365,81 @@ func ProviderInstanceIDContainsFold(v string) predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldContainsFold(FieldProviderInstanceID, v)) return predicate.PaymentOrder(sql.FieldContainsFold(FieldProviderInstanceID, v))
} }
// ProviderKeyEQ applies the EQ predicate on the "provider_key" field.
func ProviderKeyEQ(v string) predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldEQ(FieldProviderKey, v))
}
// ProviderKeyNEQ applies the NEQ predicate on the "provider_key" field.
func ProviderKeyNEQ(v string) predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldNEQ(FieldProviderKey, v))
}
// ProviderKeyIn applies the In predicate on the "provider_key" field.
func ProviderKeyIn(vs ...string) predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldIn(FieldProviderKey, vs...))
}
// ProviderKeyNotIn applies the NotIn predicate on the "provider_key" field.
func ProviderKeyNotIn(vs ...string) predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldNotIn(FieldProviderKey, vs...))
}
// ProviderKeyGT applies the GT predicate on the "provider_key" field.
func ProviderKeyGT(v string) predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldGT(FieldProviderKey, v))
}
// ProviderKeyGTE applies the GTE predicate on the "provider_key" field.
func ProviderKeyGTE(v string) predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldGTE(FieldProviderKey, v))
}
// ProviderKeyLT applies the LT predicate on the "provider_key" field.
func ProviderKeyLT(v string) predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldLT(FieldProviderKey, v))
}
// ProviderKeyLTE applies the LTE predicate on the "provider_key" field.
func ProviderKeyLTE(v string) predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldLTE(FieldProviderKey, v))
}
// ProviderKeyContains applies the Contains predicate on the "provider_key" field.
func ProviderKeyContains(v string) predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldContains(FieldProviderKey, v))
}
// ProviderKeyHasPrefix applies the HasPrefix predicate on the "provider_key" field.
func ProviderKeyHasPrefix(v string) predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldHasPrefix(FieldProviderKey, v))
}
// ProviderKeyHasSuffix applies the HasSuffix predicate on the "provider_key" field.
func ProviderKeyHasSuffix(v string) predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldHasSuffix(FieldProviderKey, v))
}
// ProviderKeyIsNil applies the IsNil predicate on the "provider_key" field.
func ProviderKeyIsNil() predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldIsNull(FieldProviderKey))
}
// ProviderKeyNotNil applies the NotNil predicate on the "provider_key" field.
func ProviderKeyNotNil() predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldNotNull(FieldProviderKey))
}
// ProviderKeyEqualFold applies the EqualFold predicate on the "provider_key" field.
func ProviderKeyEqualFold(v string) predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldEqualFold(FieldProviderKey, v))
}
// ProviderKeyContainsFold applies the ContainsFold predicate on the "provider_key" field.
func ProviderKeyContainsFold(v string) predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldContainsFold(FieldProviderKey, v))
}
// StatusEQ applies the EQ predicate on the "status" field. // StatusEQ applies the EQ predicate on the "status" field.
func StatusEQ(v string) predicate.PaymentOrder { func StatusEQ(v string) predicate.PaymentOrder {
return predicate.PaymentOrder(sql.FieldEQ(FieldStatus, v)) return predicate.PaymentOrder(sql.FieldEQ(FieldStatus, v))

View File

@@ -225,6 +225,20 @@ func (_c *PaymentOrderCreate) SetNillableProviderInstanceID(v *string) *PaymentO
return _c return _c
} }
// SetProviderKey sets the "provider_key" field.
func (_c *PaymentOrderCreate) SetProviderKey(v string) *PaymentOrderCreate {
_c.mutation.SetProviderKey(v)
return _c
}
// SetNillableProviderKey sets the "provider_key" field if the given value is not nil.
func (_c *PaymentOrderCreate) SetNillableProviderKey(v *string) *PaymentOrderCreate {
if v != nil {
_c.SetProviderKey(*v)
}
return _c
}
// SetStatus sets the "status" field. // SetStatus sets the "status" field.
func (_c *PaymentOrderCreate) SetStatus(v string) *PaymentOrderCreate { func (_c *PaymentOrderCreate) SetStatus(v string) *PaymentOrderCreate {
_c.mutation.SetStatus(v) _c.mutation.SetStatus(v)
@@ -602,6 +616,11 @@ func (_c *PaymentOrderCreate) check() error {
return &ValidationError{Name: "provider_instance_id", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.provider_instance_id": %w`, err)} return &ValidationError{Name: "provider_instance_id", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.provider_instance_id": %w`, err)}
} }
} }
if v, ok := _c.mutation.ProviderKey(); ok {
if err := paymentorder.ProviderKeyValidator(v); err != nil {
return &ValidationError{Name: "provider_key", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.provider_key": %w`, err)}
}
}
if _, ok := _c.mutation.Status(); !ok { if _, ok := _c.mutation.Status(); !ok {
return &ValidationError{Name: "status", err: errors.New(`ent: missing required field "PaymentOrder.status"`)} return &ValidationError{Name: "status", err: errors.New(`ent: missing required field "PaymentOrder.status"`)}
} }
@@ -748,6 +767,10 @@ func (_c *PaymentOrderCreate) createSpec() (*PaymentOrder, *sqlgraph.CreateSpec)
_spec.SetField(paymentorder.FieldProviderInstanceID, field.TypeString, value) _spec.SetField(paymentorder.FieldProviderInstanceID, field.TypeString, value)
_node.ProviderInstanceID = &value _node.ProviderInstanceID = &value
} }
if value, ok := _c.mutation.ProviderKey(); ok {
_spec.SetField(paymentorder.FieldProviderKey, field.TypeString, value)
_node.ProviderKey = &value
}
if value, ok := _c.mutation.Status(); ok { if value, ok := _c.mutation.Status(); ok {
_spec.SetField(paymentorder.FieldStatus, field.TypeString, value) _spec.SetField(paymentorder.FieldStatus, field.TypeString, value)
_node.Status = value _node.Status = value
@@ -1201,6 +1224,24 @@ func (u *PaymentOrderUpsert) ClearProviderInstanceID() *PaymentOrderUpsert {
return u return u
} }
// SetProviderKey sets the "provider_key" field.
func (u *PaymentOrderUpsert) SetProviderKey(v string) *PaymentOrderUpsert {
u.Set(paymentorder.FieldProviderKey, v)
return u
}
// UpdateProviderKey sets the "provider_key" field to the value that was provided on create.
func (u *PaymentOrderUpsert) UpdateProviderKey() *PaymentOrderUpsert {
u.SetExcluded(paymentorder.FieldProviderKey)
return u
}
// ClearProviderKey clears the value of the "provider_key" field.
func (u *PaymentOrderUpsert) ClearProviderKey() *PaymentOrderUpsert {
u.SetNull(paymentorder.FieldProviderKey)
return u
}
// SetStatus sets the "status" field. // SetStatus sets the "status" field.
func (u *PaymentOrderUpsert) SetStatus(v string) *PaymentOrderUpsert { func (u *PaymentOrderUpsert) SetStatus(v string) *PaymentOrderUpsert {
u.Set(paymentorder.FieldStatus, v) u.Set(paymentorder.FieldStatus, v)
@@ -1880,6 +1921,27 @@ func (u *PaymentOrderUpsertOne) ClearProviderInstanceID() *PaymentOrderUpsertOne
}) })
} }
// SetProviderKey sets the "provider_key" field.
func (u *PaymentOrderUpsertOne) SetProviderKey(v string) *PaymentOrderUpsertOne {
return u.Update(func(s *PaymentOrderUpsert) {
s.SetProviderKey(v)
})
}
// UpdateProviderKey sets the "provider_key" field to the value that was provided on create.
func (u *PaymentOrderUpsertOne) UpdateProviderKey() *PaymentOrderUpsertOne {
return u.Update(func(s *PaymentOrderUpsert) {
s.UpdateProviderKey()
})
}
// ClearProviderKey clears the value of the "provider_key" field.
func (u *PaymentOrderUpsertOne) ClearProviderKey() *PaymentOrderUpsertOne {
return u.Update(func(s *PaymentOrderUpsert) {
s.ClearProviderKey()
})
}
// SetStatus sets the "status" field. // SetStatus sets the "status" field.
func (u *PaymentOrderUpsertOne) SetStatus(v string) *PaymentOrderUpsertOne { func (u *PaymentOrderUpsertOne) SetStatus(v string) *PaymentOrderUpsertOne {
return u.Update(func(s *PaymentOrderUpsert) { return u.Update(func(s *PaymentOrderUpsert) {
@@ -2770,6 +2832,27 @@ func (u *PaymentOrderUpsertBulk) ClearProviderInstanceID() *PaymentOrderUpsertBu
}) })
} }
// SetProviderKey sets the "provider_key" field.
func (u *PaymentOrderUpsertBulk) SetProviderKey(v string) *PaymentOrderUpsertBulk {
return u.Update(func(s *PaymentOrderUpsert) {
s.SetProviderKey(v)
})
}
// UpdateProviderKey sets the "provider_key" field to the value that was provided on create.
func (u *PaymentOrderUpsertBulk) UpdateProviderKey() *PaymentOrderUpsertBulk {
return u.Update(func(s *PaymentOrderUpsert) {
s.UpdateProviderKey()
})
}
// ClearProviderKey clears the value of the "provider_key" field.
func (u *PaymentOrderUpsertBulk) ClearProviderKey() *PaymentOrderUpsertBulk {
return u.Update(func(s *PaymentOrderUpsert) {
s.ClearProviderKey()
})
}
// SetStatus sets the "status" field. // SetStatus sets the "status" field.
func (u *PaymentOrderUpsertBulk) SetStatus(v string) *PaymentOrderUpsertBulk { func (u *PaymentOrderUpsertBulk) SetStatus(v string) *PaymentOrderUpsertBulk {
return u.Update(func(s *PaymentOrderUpsert) { return u.Update(func(s *PaymentOrderUpsert) {

View File

@@ -385,6 +385,26 @@ func (_u *PaymentOrderUpdate) ClearProviderInstanceID() *PaymentOrderUpdate {
return _u return _u
} }
// SetProviderKey sets the "provider_key" field.
func (_u *PaymentOrderUpdate) SetProviderKey(v string) *PaymentOrderUpdate {
_u.mutation.SetProviderKey(v)
return _u
}
// SetNillableProviderKey sets the "provider_key" field if the given value is not nil.
func (_u *PaymentOrderUpdate) SetNillableProviderKey(v *string) *PaymentOrderUpdate {
if v != nil {
_u.SetProviderKey(*v)
}
return _u
}
// ClearProviderKey clears the value of the "provider_key" field.
func (_u *PaymentOrderUpdate) ClearProviderKey() *PaymentOrderUpdate {
_u.mutation.ClearProviderKey()
return _u
}
// SetStatus sets the "status" field. // SetStatus sets the "status" field.
func (_u *PaymentOrderUpdate) SetStatus(v string) *PaymentOrderUpdate { func (_u *PaymentOrderUpdate) SetStatus(v string) *PaymentOrderUpdate {
_u.mutation.SetStatus(v) _u.mutation.SetStatus(v)
@@ -776,6 +796,11 @@ func (_u *PaymentOrderUpdate) check() error {
return &ValidationError{Name: "provider_instance_id", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.provider_instance_id": %w`, err)} return &ValidationError{Name: "provider_instance_id", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.provider_instance_id": %w`, err)}
} }
} }
if v, ok := _u.mutation.ProviderKey(); ok {
if err := paymentorder.ProviderKeyValidator(v); err != nil {
return &ValidationError{Name: "provider_key", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.provider_key": %w`, err)}
}
}
if v, ok := _u.mutation.Status(); ok { if v, ok := _u.mutation.Status(); ok {
if err := paymentorder.StatusValidator(v); err != nil { if err := paymentorder.StatusValidator(v); err != nil {
return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.status": %w`, err)} return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.status": %w`, err)}
@@ -910,6 +935,12 @@ func (_u *PaymentOrderUpdate) sqlSave(ctx context.Context) (_node int, err error
if _u.mutation.ProviderInstanceIDCleared() { if _u.mutation.ProviderInstanceIDCleared() {
_spec.ClearField(paymentorder.FieldProviderInstanceID, field.TypeString) _spec.ClearField(paymentorder.FieldProviderInstanceID, field.TypeString)
} }
if value, ok := _u.mutation.ProviderKey(); ok {
_spec.SetField(paymentorder.FieldProviderKey, field.TypeString, value)
}
if _u.mutation.ProviderKeyCleared() {
_spec.ClearField(paymentorder.FieldProviderKey, field.TypeString)
}
if value, ok := _u.mutation.Status(); ok { if value, ok := _u.mutation.Status(); ok {
_spec.SetField(paymentorder.FieldStatus, field.TypeString, value) _spec.SetField(paymentorder.FieldStatus, field.TypeString, value)
} }
@@ -1399,6 +1430,26 @@ func (_u *PaymentOrderUpdateOne) ClearProviderInstanceID() *PaymentOrderUpdateOn
return _u return _u
} }
// SetProviderKey sets the "provider_key" field.
func (_u *PaymentOrderUpdateOne) SetProviderKey(v string) *PaymentOrderUpdateOne {
_u.mutation.SetProviderKey(v)
return _u
}
// SetNillableProviderKey sets the "provider_key" field if the given value is not nil.
func (_u *PaymentOrderUpdateOne) SetNillableProviderKey(v *string) *PaymentOrderUpdateOne {
if v != nil {
_u.SetProviderKey(*v)
}
return _u
}
// ClearProviderKey clears the value of the "provider_key" field.
func (_u *PaymentOrderUpdateOne) ClearProviderKey() *PaymentOrderUpdateOne {
_u.mutation.ClearProviderKey()
return _u
}
// SetStatus sets the "status" field. // SetStatus sets the "status" field.
func (_u *PaymentOrderUpdateOne) SetStatus(v string) *PaymentOrderUpdateOne { func (_u *PaymentOrderUpdateOne) SetStatus(v string) *PaymentOrderUpdateOne {
_u.mutation.SetStatus(v) _u.mutation.SetStatus(v)
@@ -1803,6 +1854,11 @@ func (_u *PaymentOrderUpdateOne) check() error {
return &ValidationError{Name: "provider_instance_id", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.provider_instance_id": %w`, err)} return &ValidationError{Name: "provider_instance_id", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.provider_instance_id": %w`, err)}
} }
} }
if v, ok := _u.mutation.ProviderKey(); ok {
if err := paymentorder.ProviderKeyValidator(v); err != nil {
return &ValidationError{Name: "provider_key", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.provider_key": %w`, err)}
}
}
if v, ok := _u.mutation.Status(); ok { if v, ok := _u.mutation.Status(); ok {
if err := paymentorder.StatusValidator(v); err != nil { if err := paymentorder.StatusValidator(v); err != nil {
return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.status": %w`, err)} return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.status": %w`, err)}
@@ -1954,6 +2010,12 @@ func (_u *PaymentOrderUpdateOne) sqlSave(ctx context.Context) (_node *PaymentOrd
if _u.mutation.ProviderInstanceIDCleared() { if _u.mutation.ProviderInstanceIDCleared() {
_spec.ClearField(paymentorder.FieldProviderInstanceID, field.TypeString) _spec.ClearField(paymentorder.FieldProviderInstanceID, field.TypeString)
} }
if value, ok := _u.mutation.ProviderKey(); ok {
_spec.SetField(paymentorder.FieldProviderKey, field.TypeString, value)
}
if _u.mutation.ProviderKeyCleared() {
_spec.ClearField(paymentorder.FieldProviderKey, field.TypeString)
}
if value, ok := _u.mutation.Status(); ok { if value, ok := _u.mutation.Status(); ok {
_spec.SetField(paymentorder.FieldStatus, field.TypeString, value) _spec.SetField(paymentorder.FieldStatus, field.TypeString, value)
} }

View File

@@ -723,38 +723,42 @@ func init() {
paymentorderDescProviderInstanceID := paymentorderFields[18].Descriptor() paymentorderDescProviderInstanceID := paymentorderFields[18].Descriptor()
// paymentorder.ProviderInstanceIDValidator is a validator for the "provider_instance_id" field. It is called by the builders before save. // paymentorder.ProviderInstanceIDValidator is a validator for the "provider_instance_id" field. It is called by the builders before save.
paymentorder.ProviderInstanceIDValidator = paymentorderDescProviderInstanceID.Validators[0].(func(string) error) paymentorder.ProviderInstanceIDValidator = paymentorderDescProviderInstanceID.Validators[0].(func(string) error)
// paymentorderDescProviderKey is the schema descriptor for provider_key field.
paymentorderDescProviderKey := paymentorderFields[19].Descriptor()
// paymentorder.ProviderKeyValidator is a validator for the "provider_key" field. It is called by the builders before save.
paymentorder.ProviderKeyValidator = paymentorderDescProviderKey.Validators[0].(func(string) error)
// paymentorderDescStatus is the schema descriptor for status field. // paymentorderDescStatus is the schema descriptor for status field.
paymentorderDescStatus := paymentorderFields[19].Descriptor() paymentorderDescStatus := paymentorderFields[20].Descriptor()
// paymentorder.DefaultStatus holds the default value on creation for the status field. // paymentorder.DefaultStatus holds the default value on creation for the status field.
paymentorder.DefaultStatus = paymentorderDescStatus.Default.(string) paymentorder.DefaultStatus = paymentorderDescStatus.Default.(string)
// paymentorder.StatusValidator is a validator for the "status" field. It is called by the builders before save. // paymentorder.StatusValidator is a validator for the "status" field. It is called by the builders before save.
paymentorder.StatusValidator = paymentorderDescStatus.Validators[0].(func(string) error) paymentorder.StatusValidator = paymentorderDescStatus.Validators[0].(func(string) error)
// paymentorderDescRefundAmount is the schema descriptor for refund_amount field. // paymentorderDescRefundAmount is the schema descriptor for refund_amount field.
paymentorderDescRefundAmount := paymentorderFields[20].Descriptor() paymentorderDescRefundAmount := paymentorderFields[21].Descriptor()
// paymentorder.DefaultRefundAmount holds the default value on creation for the refund_amount field. // paymentorder.DefaultRefundAmount holds the default value on creation for the refund_amount field.
paymentorder.DefaultRefundAmount = paymentorderDescRefundAmount.Default.(float64) paymentorder.DefaultRefundAmount = paymentorderDescRefundAmount.Default.(float64)
// paymentorderDescForceRefund is the schema descriptor for force_refund field. // paymentorderDescForceRefund is the schema descriptor for force_refund field.
paymentorderDescForceRefund := paymentorderFields[23].Descriptor() paymentorderDescForceRefund := paymentorderFields[24].Descriptor()
// paymentorder.DefaultForceRefund holds the default value on creation for the force_refund field. // paymentorder.DefaultForceRefund holds the default value on creation for the force_refund field.
paymentorder.DefaultForceRefund = paymentorderDescForceRefund.Default.(bool) paymentorder.DefaultForceRefund = paymentorderDescForceRefund.Default.(bool)
// paymentorderDescRefundRequestedBy is the schema descriptor for refund_requested_by field. // paymentorderDescRefundRequestedBy is the schema descriptor for refund_requested_by field.
paymentorderDescRefundRequestedBy := paymentorderFields[26].Descriptor() paymentorderDescRefundRequestedBy := paymentorderFields[27].Descriptor()
// paymentorder.RefundRequestedByValidator is a validator for the "refund_requested_by" field. It is called by the builders before save. // paymentorder.RefundRequestedByValidator is a validator for the "refund_requested_by" field. It is called by the builders before save.
paymentorder.RefundRequestedByValidator = paymentorderDescRefundRequestedBy.Validators[0].(func(string) error) paymentorder.RefundRequestedByValidator = paymentorderDescRefundRequestedBy.Validators[0].(func(string) error)
// paymentorderDescClientIP is the schema descriptor for client_ip field. // paymentorderDescClientIP is the schema descriptor for client_ip field.
paymentorderDescClientIP := paymentorderFields[32].Descriptor() paymentorderDescClientIP := paymentorderFields[33].Descriptor()
// paymentorder.ClientIPValidator is a validator for the "client_ip" field. It is called by the builders before save. // paymentorder.ClientIPValidator is a validator for the "client_ip" field. It is called by the builders before save.
paymentorder.ClientIPValidator = paymentorderDescClientIP.Validators[0].(func(string) error) paymentorder.ClientIPValidator = paymentorderDescClientIP.Validators[0].(func(string) error)
// paymentorderDescSrcHost is the schema descriptor for src_host field. // paymentorderDescSrcHost is the schema descriptor for src_host field.
paymentorderDescSrcHost := paymentorderFields[33].Descriptor() paymentorderDescSrcHost := paymentorderFields[34].Descriptor()
// paymentorder.SrcHostValidator is a validator for the "src_host" field. It is called by the builders before save. // paymentorder.SrcHostValidator is a validator for the "src_host" field. It is called by the builders before save.
paymentorder.SrcHostValidator = paymentorderDescSrcHost.Validators[0].(func(string) error) paymentorder.SrcHostValidator = paymentorderDescSrcHost.Validators[0].(func(string) error)
// paymentorderDescCreatedAt is the schema descriptor for created_at field. // paymentorderDescCreatedAt is the schema descriptor for created_at field.
paymentorderDescCreatedAt := paymentorderFields[35].Descriptor() paymentorderDescCreatedAt := paymentorderFields[36].Descriptor()
// paymentorder.DefaultCreatedAt holds the default value on creation for the created_at field. // paymentorder.DefaultCreatedAt holds the default value on creation for the created_at field.
paymentorder.DefaultCreatedAt = paymentorderDescCreatedAt.Default.(func() time.Time) paymentorder.DefaultCreatedAt = paymentorderDescCreatedAt.Default.(func() time.Time)
// paymentorderDescUpdatedAt is the schema descriptor for updated_at field. // paymentorderDescUpdatedAt is the schema descriptor for updated_at field.
paymentorderDescUpdatedAt := paymentorderFields[36].Descriptor() paymentorderDescUpdatedAt := paymentorderFields[37].Descriptor()
// paymentorder.DefaultUpdatedAt holds the default value on creation for the updated_at field. // paymentorder.DefaultUpdatedAt holds the default value on creation for the updated_at field.
paymentorder.DefaultUpdatedAt = paymentorderDescUpdatedAt.Default.(func() time.Time) paymentorder.DefaultUpdatedAt = paymentorderDescUpdatedAt.Default.(func() time.Time)
// paymentorder.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field. // paymentorder.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.

View File

@@ -91,6 +91,10 @@ func (PaymentOrder) Fields() []ent.Field {
Optional(). Optional().
Nillable(). Nillable().
MaxLen(64), MaxLen(64),
field.String("provider_key").
Optional().
Nillable().
MaxLen(30),
// 状态 // 状态
field.String("status"). field.String("status").

View File

@@ -45,7 +45,7 @@ func (s *PaymentService) confirmPayment(ctx context.Context, oid int64, tradeNo
if inst, instErr := s.getOrderProviderInstance(ctx, o); instErr == nil && inst != nil { if inst, instErr := s.getOrderProviderInstance(ctx, o); instErr == nil && inst != nil {
instanceProviderKey = inst.ProviderKey instanceProviderKey = inst.ProviderKey
} }
expectedProviderKey := expectedNotificationProviderKey(s.registry, o.PaymentType, instanceProviderKey) expectedProviderKey := expectedNotificationProviderKey(s.registry, o.PaymentType, psStringValue(o.ProviderKey), instanceProviderKey)
if expectedProviderKey != "" && strings.TrimSpace(pk) != "" && !strings.EqualFold(expectedProviderKey, strings.TrimSpace(pk)) { if expectedProviderKey != "" && strings.TrimSpace(pk) != "" && !strings.EqualFold(expectedProviderKey, strings.TrimSpace(pk)) {
s.writeAuditLog(ctx, o.ID, "PAYMENT_PROVIDER_MISMATCH", pk, map[string]any{ s.writeAuditLog(ctx, o.ID, "PAYMENT_PROVIDER_MISMATCH", pk, map[string]any{
"expectedProvider": expectedProviderKey, "expectedProvider": expectedProviderKey,
@@ -69,10 +69,13 @@ func (s *PaymentService) confirmPayment(ctx context.Context, oid int64, tradeNo
return s.toPaid(ctx, o, tradeNo, paid, pk) return s.toPaid(ctx, o, tradeNo, paid, pk)
} }
func expectedNotificationProviderKey(registry *payment.Registry, orderPaymentType string, instanceProviderKey string) string { func expectedNotificationProviderKey(registry *payment.Registry, orderPaymentType string, orderProviderKey string, instanceProviderKey string) string {
if key := strings.TrimSpace(instanceProviderKey); key != "" { if key := strings.TrimSpace(instanceProviderKey); key != "" {
return key return key
} }
if key := strings.TrimSpace(orderProviderKey); key != "" {
return key
}
if registry != nil { if registry != nil {
if key := strings.TrimSpace(registry.GetProviderKey(payment.PaymentType(orderPaymentType))); key != "" { if key := strings.TrimSpace(registry.GetProviderKey(payment.PaymentType(orderPaymentType))); key != "" {
return key return key

View File

@@ -198,7 +198,7 @@ func TestExpectedNotificationProviderKeyPrefersOrderInstanceProvider(t *testing.
assert.Equal(t, assert.Equal(t,
payment.TypeEasyPay, payment.TypeEasyPay,
expectedNotificationProviderKey(registry, payment.TypeAlipay, payment.TypeEasyPay), expectedNotificationProviderKey(registry, payment.TypeAlipay, "", payment.TypeEasyPay),
) )
} }
@@ -213,7 +213,7 @@ func TestExpectedNotificationProviderKeyUsesRegistryMappingForLegacyOrders(t *te
assert.Equal(t, assert.Equal(t,
payment.TypeEasyPay, payment.TypeEasyPay,
expectedNotificationProviderKey(registry, payment.TypeAlipay, ""), expectedNotificationProviderKey(registry, payment.TypeAlipay, "", ""),
) )
} }
@@ -222,6 +222,21 @@ func TestExpectedNotificationProviderKeyFallsBackToPaymentType(t *testing.T) {
assert.Equal(t, assert.Equal(t,
payment.TypeWxpay, payment.TypeWxpay,
expectedNotificationProviderKey(nil, payment.TypeWxpay, ""), expectedNotificationProviderKey(nil, payment.TypeWxpay, "", ""),
)
}
func TestExpectedNotificationProviderKeyPrefersOrderSnapshotProviderKey(t *testing.T) {
t.Parallel()
registry := payment.NewRegistry()
registry.Register(paymentFulfillmentTestProvider{
key: payment.TypeAlipay,
supportedTypes: []payment.PaymentType{payment.TypeAlipay},
})
assert.Equal(t,
payment.TypeEasyPay,
expectedNotificationProviderKey(registry, payment.TypeAlipay, payment.TypeEasyPay, ""),
) )
} }

View File

@@ -251,7 +251,13 @@ func (s *PaymentService) invokeProvider(ctx context.Context, order *dbent.Paymen
slog.Error("[PaymentService] CreatePayment failed", "provider", sel.ProviderKey, "instance", sel.InstanceID, "error", err) slog.Error("[PaymentService] CreatePayment failed", "provider", sel.ProviderKey, "instance", sel.InstanceID, "error", err)
return nil, infraerrors.ServiceUnavailable("PAYMENT_GATEWAY_ERROR", fmt.Sprintf("payment gateway error: %s", err.Error())) return nil, infraerrors.ServiceUnavailable("PAYMENT_GATEWAY_ERROR", fmt.Sprintf("payment gateway error: %s", err.Error()))
} }
_, err = s.entClient.PaymentOrder.UpdateOneID(order.ID).SetNillablePaymentTradeNo(psNilIfEmpty(pr.TradeNo)).SetNillablePayURL(psNilIfEmpty(pr.PayURL)).SetNillableQrCode(psNilIfEmpty(pr.QRCode)).SetNillableProviderInstanceID(psNilIfEmpty(sel.InstanceID)).Save(ctx) _, err = s.entClient.PaymentOrder.UpdateOneID(order.ID).
SetNillablePaymentTradeNo(psNilIfEmpty(pr.TradeNo)).
SetNillablePayURL(psNilIfEmpty(pr.PayURL)).
SetNillableQrCode(psNilIfEmpty(pr.QRCode)).
SetNillableProviderInstanceID(psNilIfEmpty(sel.InstanceID)).
SetNillableProviderKey(psNilIfEmpty(sel.ProviderKey)).
Save(ctx)
if err != nil { if err != nil {
return nil, fmt.Errorf("update order with payment details: %w", err) return nil, fmt.Errorf("update order with payment details: %w", err)
} }

View File

@@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"log/slog" "log/slog"
"strconv" "strconv"
"strings"
"time" "time"
dbent "github.com/Wei-Shaw/sub2api/ent" dbent "github.com/Wei-Shaw/sub2api/ent"
@@ -241,7 +242,10 @@ func (s *PaymentService) getOrderProvider(ctx context.Context, o *dbent.PaymentO
if err == nil { if err == nil {
cfg, err := s.loadBalancer.GetInstanceConfig(ctx, instID) cfg, err := s.loadBalancer.GetInstanceConfig(ctx, instID)
if err == nil { if err == nil {
providerKey := s.registry.GetProviderKey(o.PaymentType) providerKey := strings.TrimSpace(psStringValue(o.ProviderKey))
if providerKey == "" {
providerKey = s.registry.GetProviderKey(o.PaymentType)
}
if providerKey == "" { if providerKey == "" {
providerKey = o.PaymentType providerKey = o.PaymentType
} }
@@ -255,3 +259,10 @@ func (s *PaymentService) getOrderProvider(ctx context.Context, o *dbent.PaymentO
s.EnsureProviders(ctx) s.EnsureProviders(ctx)
return s.registry.GetProvider(o.PaymentType) return s.registry.GetProvider(o.PaymentType)
} }
func psStringValue(value *string) string {
if value == nil {
return ""
}
return *value
}

View File

@@ -0,0 +1,10 @@
ALTER TABLE payment_orders ADD COLUMN provider_key VARCHAR(30);
UPDATE payment_orders
SET provider_key = (
SELECT provider_key
FROM payment_provider_instances
WHERE CAST(id AS TEXT) = payment_orders.provider_instance_id
)
WHERE provider_key IS NULL
AND provider_instance_id IS NOT NULL;