mirror of
https://gitee.com/wanwujie/sub2api
synced 2026-05-05 05:30:44 +08:00
feat: add payment order provider snapshots
This commit is contained in:
@@ -655,6 +655,7 @@ var (
|
|||||||
{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: "provider_key", Type: field.TypeString, Nullable: true, Size: 30},
|
||||||
|
{Name: "provider_snapshot", Type: field.TypeJSON, Nullable: true, SchemaType: map[string]string{"postgres": "jsonb"}},
|
||||||
{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"}},
|
||||||
@@ -683,7 +684,7 @@ var (
|
|||||||
ForeignKeys: []*schema.ForeignKey{
|
ForeignKeys: []*schema.ForeignKey{
|
||||||
{
|
{
|
||||||
Symbol: "payment_orders_users_payment_orders",
|
Symbol: "payment_orders_users_payment_orders",
|
||||||
Columns: []*schema.Column{PaymentOrdersColumns[38]},
|
Columns: []*schema.Column{PaymentOrdersColumns[39]},
|
||||||
RefColumns: []*schema.Column{UsersColumns[0]},
|
RefColumns: []*schema.Column{UsersColumns[0]},
|
||||||
OnDelete: schema.NoAction,
|
OnDelete: schema.NoAction,
|
||||||
},
|
},
|
||||||
@@ -697,32 +698,32 @@ var (
|
|||||||
{
|
{
|
||||||
Name: "paymentorder_user_id",
|
Name: "paymentorder_user_id",
|
||||||
Unique: false,
|
Unique: false,
|
||||||
Columns: []*schema.Column{PaymentOrdersColumns[38]},
|
Columns: []*schema.Column{PaymentOrdersColumns[39]},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "paymentorder_status",
|
Name: "paymentorder_status",
|
||||||
Unique: false,
|
Unique: false,
|
||||||
Columns: []*schema.Column{PaymentOrdersColumns[20]},
|
Columns: []*schema.Column{PaymentOrdersColumns[21]},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "paymentorder_expires_at",
|
Name: "paymentorder_expires_at",
|
||||||
Unique: false,
|
Unique: false,
|
||||||
Columns: []*schema.Column{PaymentOrdersColumns[28]},
|
Columns: []*schema.Column{PaymentOrdersColumns[29]},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "paymentorder_created_at",
|
Name: "paymentorder_created_at",
|
||||||
Unique: false,
|
Unique: false,
|
||||||
Columns: []*schema.Column{PaymentOrdersColumns[36]},
|
Columns: []*schema.Column{PaymentOrdersColumns[37]},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "paymentorder_paid_at",
|
Name: "paymentorder_paid_at",
|
||||||
Unique: false,
|
Unique: false,
|
||||||
Columns: []*schema.Column{PaymentOrdersColumns[29]},
|
Columns: []*schema.Column{PaymentOrdersColumns[30]},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "paymentorder_payment_type_paid_at",
|
Name: "paymentorder_payment_type_paid_at",
|
||||||
Unique: false,
|
Unique: false,
|
||||||
Columns: []*schema.Column{PaymentOrdersColumns[9], PaymentOrdersColumns[29]},
|
Columns: []*schema.Column{PaymentOrdersColumns[9], PaymentOrdersColumns[30]},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "paymentorder_order_type",
|
Name: "paymentorder_order_type",
|
||||||
|
|||||||
@@ -15386,6 +15386,7 @@ type PaymentOrderMutation struct {
|
|||||||
addsubscription_days *int
|
addsubscription_days *int
|
||||||
provider_instance_id *string
|
provider_instance_id *string
|
||||||
provider_key *string
|
provider_key *string
|
||||||
|
provider_snapshot *map[string]interface{}
|
||||||
status *string
|
status *string
|
||||||
refund_amount *float64
|
refund_amount *float64
|
||||||
addrefund_amount *float64
|
addrefund_amount *float64
|
||||||
@@ -16471,6 +16472,55 @@ func (m *PaymentOrderMutation) ResetProviderKey() {
|
|||||||
delete(m.clearedFields, paymentorder.FieldProviderKey)
|
delete(m.clearedFields, paymentorder.FieldProviderKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetProviderSnapshot sets the "provider_snapshot" field.
|
||||||
|
func (m *PaymentOrderMutation) SetProviderSnapshot(value map[string]interface{}) {
|
||||||
|
m.provider_snapshot = &value
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProviderSnapshot returns the value of the "provider_snapshot" field in the mutation.
|
||||||
|
func (m *PaymentOrderMutation) ProviderSnapshot() (r map[string]interface{}, exists bool) {
|
||||||
|
v := m.provider_snapshot
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldProviderSnapshot returns the old "provider_snapshot" 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) OldProviderSnapshot(ctx context.Context) (v map[string]interface{}, err error) {
|
||||||
|
if !m.op.Is(OpUpdateOne) {
|
||||||
|
return v, errors.New("OldProviderSnapshot is only allowed on UpdateOne operations")
|
||||||
|
}
|
||||||
|
if m.id == nil || m.oldValue == nil {
|
||||||
|
return v, errors.New("OldProviderSnapshot requires an ID field in the mutation")
|
||||||
|
}
|
||||||
|
oldValue, err := m.oldValue(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("querying old value for OldProviderSnapshot: %w", err)
|
||||||
|
}
|
||||||
|
return oldValue.ProviderSnapshot, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearProviderSnapshot clears the value of the "provider_snapshot" field.
|
||||||
|
func (m *PaymentOrderMutation) ClearProviderSnapshot() {
|
||||||
|
m.provider_snapshot = nil
|
||||||
|
m.clearedFields[paymentorder.FieldProviderSnapshot] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProviderSnapshotCleared returns if the "provider_snapshot" field was cleared in this mutation.
|
||||||
|
func (m *PaymentOrderMutation) ProviderSnapshotCleared() bool {
|
||||||
|
_, ok := m.clearedFields[paymentorder.FieldProviderSnapshot]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetProviderSnapshot resets all changes to the "provider_snapshot" field.
|
||||||
|
func (m *PaymentOrderMutation) ResetProviderSnapshot() {
|
||||||
|
m.provider_snapshot = nil
|
||||||
|
delete(m.clearedFields, paymentorder.FieldProviderSnapshot)
|
||||||
|
}
|
||||||
|
|
||||||
// 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
|
||||||
@@ -17330,7 +17380,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, 38)
|
fields := make([]string, 0, 39)
|
||||||
if m.user != nil {
|
if m.user != nil {
|
||||||
fields = append(fields, paymentorder.FieldUserID)
|
fields = append(fields, paymentorder.FieldUserID)
|
||||||
}
|
}
|
||||||
@@ -17391,6 +17441,9 @@ func (m *PaymentOrderMutation) Fields() []string {
|
|||||||
if m.provider_key != nil {
|
if m.provider_key != nil {
|
||||||
fields = append(fields, paymentorder.FieldProviderKey)
|
fields = append(fields, paymentorder.FieldProviderKey)
|
||||||
}
|
}
|
||||||
|
if m.provider_snapshot != nil {
|
||||||
|
fields = append(fields, paymentorder.FieldProviderSnapshot)
|
||||||
|
}
|
||||||
if m.status != nil {
|
if m.status != nil {
|
||||||
fields = append(fields, paymentorder.FieldStatus)
|
fields = append(fields, paymentorder.FieldStatus)
|
||||||
}
|
}
|
||||||
@@ -17493,6 +17546,8 @@ func (m *PaymentOrderMutation) Field(name string) (ent.Value, bool) {
|
|||||||
return m.ProviderInstanceID()
|
return m.ProviderInstanceID()
|
||||||
case paymentorder.FieldProviderKey:
|
case paymentorder.FieldProviderKey:
|
||||||
return m.ProviderKey()
|
return m.ProviderKey()
|
||||||
|
case paymentorder.FieldProviderSnapshot:
|
||||||
|
return m.ProviderSnapshot()
|
||||||
case paymentorder.FieldStatus:
|
case paymentorder.FieldStatus:
|
||||||
return m.Status()
|
return m.Status()
|
||||||
case paymentorder.FieldRefundAmount:
|
case paymentorder.FieldRefundAmount:
|
||||||
@@ -17578,6 +17633,8 @@ func (m *PaymentOrderMutation) OldField(ctx context.Context, name string) (ent.V
|
|||||||
return m.OldProviderInstanceID(ctx)
|
return m.OldProviderInstanceID(ctx)
|
||||||
case paymentorder.FieldProviderKey:
|
case paymentorder.FieldProviderKey:
|
||||||
return m.OldProviderKey(ctx)
|
return m.OldProviderKey(ctx)
|
||||||
|
case paymentorder.FieldProviderSnapshot:
|
||||||
|
return m.OldProviderSnapshot(ctx)
|
||||||
case paymentorder.FieldStatus:
|
case paymentorder.FieldStatus:
|
||||||
return m.OldStatus(ctx)
|
return m.OldStatus(ctx)
|
||||||
case paymentorder.FieldRefundAmount:
|
case paymentorder.FieldRefundAmount:
|
||||||
@@ -17763,6 +17820,13 @@ func (m *PaymentOrderMutation) SetField(name string, value ent.Value) error {
|
|||||||
}
|
}
|
||||||
m.SetProviderKey(v)
|
m.SetProviderKey(v)
|
||||||
return nil
|
return nil
|
||||||
|
case paymentorder.FieldProviderSnapshot:
|
||||||
|
v, ok := value.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.SetProviderSnapshot(v)
|
||||||
|
return nil
|
||||||
case paymentorder.FieldStatus:
|
case paymentorder.FieldStatus:
|
||||||
v, ok := value.(string)
|
v, ok := value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -18033,6 +18097,9 @@ func (m *PaymentOrderMutation) ClearedFields() []string {
|
|||||||
if m.FieldCleared(paymentorder.FieldProviderKey) {
|
if m.FieldCleared(paymentorder.FieldProviderKey) {
|
||||||
fields = append(fields, paymentorder.FieldProviderKey)
|
fields = append(fields, paymentorder.FieldProviderKey)
|
||||||
}
|
}
|
||||||
|
if m.FieldCleared(paymentorder.FieldProviderSnapshot) {
|
||||||
|
fields = append(fields, paymentorder.FieldProviderSnapshot)
|
||||||
|
}
|
||||||
if m.FieldCleared(paymentorder.FieldRefundReason) {
|
if m.FieldCleared(paymentorder.FieldRefundReason) {
|
||||||
fields = append(fields, paymentorder.FieldRefundReason)
|
fields = append(fields, paymentorder.FieldRefundReason)
|
||||||
}
|
}
|
||||||
@@ -18104,6 +18171,9 @@ func (m *PaymentOrderMutation) ClearField(name string) error {
|
|||||||
case paymentorder.FieldProviderKey:
|
case paymentorder.FieldProviderKey:
|
||||||
m.ClearProviderKey()
|
m.ClearProviderKey()
|
||||||
return nil
|
return nil
|
||||||
|
case paymentorder.FieldProviderSnapshot:
|
||||||
|
m.ClearProviderSnapshot()
|
||||||
|
return nil
|
||||||
case paymentorder.FieldRefundReason:
|
case paymentorder.FieldRefundReason:
|
||||||
m.ClearRefundReason()
|
m.ClearRefundReason()
|
||||||
return nil
|
return nil
|
||||||
@@ -18202,6 +18272,9 @@ func (m *PaymentOrderMutation) ResetField(name string) error {
|
|||||||
case paymentorder.FieldProviderKey:
|
case paymentorder.FieldProviderKey:
|
||||||
m.ResetProviderKey()
|
m.ResetProviderKey()
|
||||||
return nil
|
return nil
|
||||||
|
case paymentorder.FieldProviderSnapshot:
|
||||||
|
m.ResetProviderSnapshot()
|
||||||
|
return nil
|
||||||
case paymentorder.FieldStatus:
|
case paymentorder.FieldStatus:
|
||||||
m.ResetStatus()
|
m.ResetStatus()
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
package ent
|
package ent
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -58,6 +59,8 @@ type PaymentOrder struct {
|
|||||||
ProviderInstanceID *string `json:"provider_instance_id,omitempty"`
|
ProviderInstanceID *string `json:"provider_instance_id,omitempty"`
|
||||||
// ProviderKey holds the value of the "provider_key" field.
|
// ProviderKey holds the value of the "provider_key" field.
|
||||||
ProviderKey *string `json:"provider_key,omitempty"`
|
ProviderKey *string `json:"provider_key,omitempty"`
|
||||||
|
// ProviderSnapshot holds the value of the "provider_snapshot" field.
|
||||||
|
ProviderSnapshot map[string]interface{} `json:"provider_snapshot,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.
|
||||||
@@ -125,6 +128,8 @@ func (*PaymentOrder) scanValues(columns []string) ([]any, error) {
|
|||||||
values := make([]any, len(columns))
|
values := make([]any, len(columns))
|
||||||
for i := range columns {
|
for i := range columns {
|
||||||
switch columns[i] {
|
switch columns[i] {
|
||||||
|
case paymentorder.FieldProviderSnapshot:
|
||||||
|
values[i] = new([]byte)
|
||||||
case paymentorder.FieldForceRefund:
|
case paymentorder.FieldForceRefund:
|
||||||
values[i] = new(sql.NullBool)
|
values[i] = new(sql.NullBool)
|
||||||
case paymentorder.FieldAmount, paymentorder.FieldPayAmount, paymentorder.FieldFeeRate, paymentorder.FieldRefundAmount:
|
case paymentorder.FieldAmount, paymentorder.FieldPayAmount, paymentorder.FieldFeeRate, paymentorder.FieldRefundAmount:
|
||||||
@@ -285,6 +290,14 @@ func (_m *PaymentOrder) assignValues(columns []string, values []any) error {
|
|||||||
_m.ProviderKey = new(string)
|
_m.ProviderKey = new(string)
|
||||||
*_m.ProviderKey = value.String
|
*_m.ProviderKey = value.String
|
||||||
}
|
}
|
||||||
|
case paymentorder.FieldProviderSnapshot:
|
||||||
|
if value, ok := values[i].(*[]byte); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field provider_snapshot", values[i])
|
||||||
|
} else if value != nil && len(*value) > 0 {
|
||||||
|
if err := json.Unmarshal(*value, &_m.ProviderSnapshot); err != nil {
|
||||||
|
return fmt.Errorf("unmarshal field provider_snapshot: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
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])
|
||||||
@@ -522,6 +535,9 @@ func (_m *PaymentOrder) String() string {
|
|||||||
builder.WriteString(*v)
|
builder.WriteString(*v)
|
||||||
}
|
}
|
||||||
builder.WriteString(", ")
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("provider_snapshot=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", _m.ProviderSnapshot))
|
||||||
|
builder.WriteString(", ")
|
||||||
builder.WriteString("status=")
|
builder.WriteString("status=")
|
||||||
builder.WriteString(_m.Status)
|
builder.WriteString(_m.Status)
|
||||||
builder.WriteString(", ")
|
builder.WriteString(", ")
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ const (
|
|||||||
FieldProviderInstanceID = "provider_instance_id"
|
FieldProviderInstanceID = "provider_instance_id"
|
||||||
// FieldProviderKey holds the string denoting the provider_key field in the database.
|
// FieldProviderKey holds the string denoting the provider_key field in the database.
|
||||||
FieldProviderKey = "provider_key"
|
FieldProviderKey = "provider_key"
|
||||||
|
// FieldProviderSnapshot holds the string denoting the provider_snapshot field in the database.
|
||||||
|
FieldProviderSnapshot = "provider_snapshot"
|
||||||
// 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.
|
||||||
@@ -126,6 +128,7 @@ var Columns = []string{
|
|||||||
FieldSubscriptionDays,
|
FieldSubscriptionDays,
|
||||||
FieldProviderInstanceID,
|
FieldProviderInstanceID,
|
||||||
FieldProviderKey,
|
FieldProviderKey,
|
||||||
|
FieldProviderSnapshot,
|
||||||
FieldStatus,
|
FieldStatus,
|
||||||
FieldRefundAmount,
|
FieldRefundAmount,
|
||||||
FieldRefundReason,
|
FieldRefundReason,
|
||||||
|
|||||||
@@ -1440,6 +1440,16 @@ func ProviderKeyContainsFold(v string) predicate.PaymentOrder {
|
|||||||
return predicate.PaymentOrder(sql.FieldContainsFold(FieldProviderKey, v))
|
return predicate.PaymentOrder(sql.FieldContainsFold(FieldProviderKey, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProviderSnapshotIsNil applies the IsNil predicate on the "provider_snapshot" field.
|
||||||
|
func ProviderSnapshotIsNil() predicate.PaymentOrder {
|
||||||
|
return predicate.PaymentOrder(sql.FieldIsNull(FieldProviderSnapshot))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProviderSnapshotNotNil applies the NotNil predicate on the "provider_snapshot" field.
|
||||||
|
func ProviderSnapshotNotNil() predicate.PaymentOrder {
|
||||||
|
return predicate.PaymentOrder(sql.FieldNotNull(FieldProviderSnapshot))
|
||||||
|
}
|
||||||
|
|
||||||
// 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))
|
||||||
|
|||||||
@@ -239,6 +239,12 @@ func (_c *PaymentOrderCreate) SetNillableProviderKey(v *string) *PaymentOrderCre
|
|||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetProviderSnapshot sets the "provider_snapshot" field.
|
||||||
|
func (_c *PaymentOrderCreate) SetProviderSnapshot(v map[string]interface{}) *PaymentOrderCreate {
|
||||||
|
_c.mutation.SetProviderSnapshot(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)
|
||||||
@@ -771,6 +777,10 @@ func (_c *PaymentOrderCreate) createSpec() (*PaymentOrder, *sqlgraph.CreateSpec)
|
|||||||
_spec.SetField(paymentorder.FieldProviderKey, field.TypeString, value)
|
_spec.SetField(paymentorder.FieldProviderKey, field.TypeString, value)
|
||||||
_node.ProviderKey = &value
|
_node.ProviderKey = &value
|
||||||
}
|
}
|
||||||
|
if value, ok := _c.mutation.ProviderSnapshot(); ok {
|
||||||
|
_spec.SetField(paymentorder.FieldProviderSnapshot, field.TypeJSON, value)
|
||||||
|
_node.ProviderSnapshot = 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
|
||||||
@@ -1242,6 +1252,24 @@ func (u *PaymentOrderUpsert) ClearProviderKey() *PaymentOrderUpsert {
|
|||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetProviderSnapshot sets the "provider_snapshot" field.
|
||||||
|
func (u *PaymentOrderUpsert) SetProviderSnapshot(v map[string]interface{}) *PaymentOrderUpsert {
|
||||||
|
u.Set(paymentorder.FieldProviderSnapshot, v)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateProviderSnapshot sets the "provider_snapshot" field to the value that was provided on create.
|
||||||
|
func (u *PaymentOrderUpsert) UpdateProviderSnapshot() *PaymentOrderUpsert {
|
||||||
|
u.SetExcluded(paymentorder.FieldProviderSnapshot)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearProviderSnapshot clears the value of the "provider_snapshot" field.
|
||||||
|
func (u *PaymentOrderUpsert) ClearProviderSnapshot() *PaymentOrderUpsert {
|
||||||
|
u.SetNull(paymentorder.FieldProviderSnapshot)
|
||||||
|
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)
|
||||||
@@ -1942,6 +1970,27 @@ func (u *PaymentOrderUpsertOne) ClearProviderKey() *PaymentOrderUpsertOne {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetProviderSnapshot sets the "provider_snapshot" field.
|
||||||
|
func (u *PaymentOrderUpsertOne) SetProviderSnapshot(v map[string]interface{}) *PaymentOrderUpsertOne {
|
||||||
|
return u.Update(func(s *PaymentOrderUpsert) {
|
||||||
|
s.SetProviderSnapshot(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateProviderSnapshot sets the "provider_snapshot" field to the value that was provided on create.
|
||||||
|
func (u *PaymentOrderUpsertOne) UpdateProviderSnapshot() *PaymentOrderUpsertOne {
|
||||||
|
return u.Update(func(s *PaymentOrderUpsert) {
|
||||||
|
s.UpdateProviderSnapshot()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearProviderSnapshot clears the value of the "provider_snapshot" field.
|
||||||
|
func (u *PaymentOrderUpsertOne) ClearProviderSnapshot() *PaymentOrderUpsertOne {
|
||||||
|
return u.Update(func(s *PaymentOrderUpsert) {
|
||||||
|
s.ClearProviderSnapshot()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 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) {
|
||||||
@@ -2853,6 +2902,27 @@ func (u *PaymentOrderUpsertBulk) ClearProviderKey() *PaymentOrderUpsertBulk {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetProviderSnapshot sets the "provider_snapshot" field.
|
||||||
|
func (u *PaymentOrderUpsertBulk) SetProviderSnapshot(v map[string]interface{}) *PaymentOrderUpsertBulk {
|
||||||
|
return u.Update(func(s *PaymentOrderUpsert) {
|
||||||
|
s.SetProviderSnapshot(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateProviderSnapshot sets the "provider_snapshot" field to the value that was provided on create.
|
||||||
|
func (u *PaymentOrderUpsertBulk) UpdateProviderSnapshot() *PaymentOrderUpsertBulk {
|
||||||
|
return u.Update(func(s *PaymentOrderUpsert) {
|
||||||
|
s.UpdateProviderSnapshot()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearProviderSnapshot clears the value of the "provider_snapshot" field.
|
||||||
|
func (u *PaymentOrderUpsertBulk) ClearProviderSnapshot() *PaymentOrderUpsertBulk {
|
||||||
|
return u.Update(func(s *PaymentOrderUpsert) {
|
||||||
|
s.ClearProviderSnapshot()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 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) {
|
||||||
|
|||||||
@@ -405,6 +405,18 @@ func (_u *PaymentOrderUpdate) ClearProviderKey() *PaymentOrderUpdate {
|
|||||||
return _u
|
return _u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetProviderSnapshot sets the "provider_snapshot" field.
|
||||||
|
func (_u *PaymentOrderUpdate) SetProviderSnapshot(v map[string]interface{}) *PaymentOrderUpdate {
|
||||||
|
_u.mutation.SetProviderSnapshot(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearProviderSnapshot clears the value of the "provider_snapshot" field.
|
||||||
|
func (_u *PaymentOrderUpdate) ClearProviderSnapshot() *PaymentOrderUpdate {
|
||||||
|
_u.mutation.ClearProviderSnapshot()
|
||||||
|
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)
|
||||||
@@ -941,6 +953,12 @@ func (_u *PaymentOrderUpdate) sqlSave(ctx context.Context) (_node int, err error
|
|||||||
if _u.mutation.ProviderKeyCleared() {
|
if _u.mutation.ProviderKeyCleared() {
|
||||||
_spec.ClearField(paymentorder.FieldProviderKey, field.TypeString)
|
_spec.ClearField(paymentorder.FieldProviderKey, field.TypeString)
|
||||||
}
|
}
|
||||||
|
if value, ok := _u.mutation.ProviderSnapshot(); ok {
|
||||||
|
_spec.SetField(paymentorder.FieldProviderSnapshot, field.TypeJSON, value)
|
||||||
|
}
|
||||||
|
if _u.mutation.ProviderSnapshotCleared() {
|
||||||
|
_spec.ClearField(paymentorder.FieldProviderSnapshot, field.TypeJSON)
|
||||||
|
}
|
||||||
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)
|
||||||
}
|
}
|
||||||
@@ -1450,6 +1468,18 @@ func (_u *PaymentOrderUpdateOne) ClearProviderKey() *PaymentOrderUpdateOne {
|
|||||||
return _u
|
return _u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetProviderSnapshot sets the "provider_snapshot" field.
|
||||||
|
func (_u *PaymentOrderUpdateOne) SetProviderSnapshot(v map[string]interface{}) *PaymentOrderUpdateOne {
|
||||||
|
_u.mutation.SetProviderSnapshot(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearProviderSnapshot clears the value of the "provider_snapshot" field.
|
||||||
|
func (_u *PaymentOrderUpdateOne) ClearProviderSnapshot() *PaymentOrderUpdateOne {
|
||||||
|
_u.mutation.ClearProviderSnapshot()
|
||||||
|
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)
|
||||||
@@ -2016,6 +2046,12 @@ func (_u *PaymentOrderUpdateOne) sqlSave(ctx context.Context) (_node *PaymentOrd
|
|||||||
if _u.mutation.ProviderKeyCleared() {
|
if _u.mutation.ProviderKeyCleared() {
|
||||||
_spec.ClearField(paymentorder.FieldProviderKey, field.TypeString)
|
_spec.ClearField(paymentorder.FieldProviderKey, field.TypeString)
|
||||||
}
|
}
|
||||||
|
if value, ok := _u.mutation.ProviderSnapshot(); ok {
|
||||||
|
_spec.SetField(paymentorder.FieldProviderSnapshot, field.TypeJSON, value)
|
||||||
|
}
|
||||||
|
if _u.mutation.ProviderSnapshotCleared() {
|
||||||
|
_spec.ClearField(paymentorder.FieldProviderSnapshot, field.TypeJSON)
|
||||||
|
}
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -728,37 +728,37 @@ func init() {
|
|||||||
// paymentorder.ProviderKeyValidator is a validator for the "provider_key" field. It is called by the builders before save.
|
// 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)
|
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[20].Descriptor()
|
paymentorderDescStatus := paymentorderFields[21].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[21].Descriptor()
|
paymentorderDescRefundAmount := paymentorderFields[22].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[24].Descriptor()
|
paymentorderDescForceRefund := paymentorderFields[25].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[27].Descriptor()
|
paymentorderDescRefundRequestedBy := paymentorderFields[28].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[33].Descriptor()
|
paymentorderDescClientIP := paymentorderFields[34].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[34].Descriptor()
|
paymentorderDescSrcHost := paymentorderFields[35].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[36].Descriptor()
|
paymentorderDescCreatedAt := paymentorderFields[37].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[37].Descriptor()
|
paymentorderDescUpdatedAt := paymentorderFields[38].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.
|
||||||
|
|||||||
@@ -95,6 +95,9 @@ func (PaymentOrder) Fields() []ent.Field {
|
|||||||
Optional().
|
Optional().
|
||||||
Nillable().
|
Nillable().
|
||||||
MaxLen(30),
|
MaxLen(30),
|
||||||
|
field.JSON("provider_snapshot", map[string]any{}).
|
||||||
|
Optional().
|
||||||
|
SchemaType(map[string]string{dialect.Postgres: "jsonb"}),
|
||||||
|
|
||||||
// 状态
|
// 状态
|
||||||
field.String("status").
|
field.String("status").
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package admin
|
|||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
dbent "github.com/Wei-Shaw/sub2api/ent"
|
||||||
"github.com/Wei-Shaw/sub2api/internal/pkg/response"
|
"github.com/Wei-Shaw/sub2api/internal/pkg/response"
|
||||||
"github.com/Wei-Shaw/sub2api/internal/service"
|
"github.com/Wei-Shaw/sub2api/internal/service"
|
||||||
|
|
||||||
@@ -66,7 +67,7 @@ func (h *PaymentHandler) ListOrders(c *gin.Context) {
|
|||||||
response.ErrorFrom(c, err)
|
response.ErrorFrom(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
response.Paginated(c, orders, int64(total), page, pageSize)
|
response.Paginated(c, sanitizeAdminPaymentOrdersForResponse(orders), int64(total), page, pageSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOrderDetail returns detailed information about a single order.
|
// GetOrderDetail returns detailed information about a single order.
|
||||||
@@ -82,7 +83,7 @@ func (h *PaymentHandler) GetOrderDetail(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
auditLogs, _ := h.paymentService.GetOrderAuditLogs(c.Request.Context(), orderID)
|
auditLogs, _ := h.paymentService.GetOrderAuditLogs(c.Request.Context(), orderID)
|
||||||
response.Success(c, gin.H{"order": order, "auditLogs": auditLogs})
|
response.Success(c, gin.H{"order": sanitizeAdminPaymentOrderForResponse(order), "auditLogs": auditLogs})
|
||||||
}
|
}
|
||||||
|
|
||||||
// CancelOrder cancels a pending order (admin).
|
// CancelOrder cancels a pending order (admin).
|
||||||
@@ -114,6 +115,26 @@ func (h *PaymentHandler) RetryFulfillment(c *gin.Context) {
|
|||||||
response.Success(c, gin.H{"message": "fulfillment retried"})
|
response.Success(c, gin.H{"message": "fulfillment retried"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sanitizeAdminPaymentOrdersForResponse(orders []*dbent.PaymentOrder) []*dbent.PaymentOrder {
|
||||||
|
if len(orders) == 0 {
|
||||||
|
return orders
|
||||||
|
}
|
||||||
|
out := make([]*dbent.PaymentOrder, 0, len(orders))
|
||||||
|
for _, order := range orders {
|
||||||
|
out = append(out, sanitizeAdminPaymentOrderForResponse(order))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func sanitizeAdminPaymentOrderForResponse(order *dbent.PaymentOrder) *dbent.PaymentOrder {
|
||||||
|
if order == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
cloned := *order
|
||||||
|
cloned.ProviderSnapshot = nil
|
||||||
|
return &cloned
|
||||||
|
}
|
||||||
|
|
||||||
// AdminProcessRefundRequest is the request body for admin refund processing.
|
// AdminProcessRefundRequest is the request body for admin refund processing.
|
||||||
type AdminProcessRefundRequest struct {
|
type AdminProcessRefundRequest struct {
|
||||||
Amount float64 `json:"amount"`
|
Amount float64 `json:"amount"`
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
dbent "github.com/Wei-Shaw/sub2api/ent"
|
||||||
"github.com/Wei-Shaw/sub2api/internal/payment"
|
"github.com/Wei-Shaw/sub2api/internal/payment"
|
||||||
infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors"
|
infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors"
|
||||||
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
|
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
|
||||||
@@ -327,7 +328,7 @@ func (h *PaymentHandler) GetMyOrders(c *gin.Context) {
|
|||||||
response.ErrorFrom(c, err)
|
response.ErrorFrom(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
response.Paginated(c, orders, int64(total), page, pageSize)
|
response.Paginated(c, sanitizePaymentOrdersForResponse(orders), int64(total), page, pageSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOrder returns a single order for the authenticated user.
|
// GetOrder returns a single order for the authenticated user.
|
||||||
@@ -349,7 +350,7 @@ func (h *PaymentHandler) GetOrder(c *gin.Context) {
|
|||||||
response.ErrorFrom(c, err)
|
response.ErrorFrom(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
response.Success(c, order)
|
response.Success(c, sanitizePaymentOrderForResponse(order))
|
||||||
}
|
}
|
||||||
|
|
||||||
// CancelOrder cancels a pending order for the authenticated user.
|
// CancelOrder cancels a pending order for the authenticated user.
|
||||||
@@ -445,7 +446,7 @@ func (h *PaymentHandler) VerifyOrder(c *gin.Context) {
|
|||||||
response.ErrorFrom(c, err)
|
response.ErrorFrom(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
response.Success(c, order)
|
response.Success(c, sanitizePaymentOrderForResponse(order))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicOrderResult is the limited order info returned by the public verify endpoint.
|
// PublicOrderResult is the limited order info returned by the public verify endpoint.
|
||||||
@@ -523,6 +524,26 @@ func isMobile(c *gin.Context) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sanitizePaymentOrdersForResponse(orders []*dbent.PaymentOrder) []*dbent.PaymentOrder {
|
||||||
|
if len(orders) == 0 {
|
||||||
|
return orders
|
||||||
|
}
|
||||||
|
out := make([]*dbent.PaymentOrder, 0, len(orders))
|
||||||
|
for _, order := range orders {
|
||||||
|
out = append(out, sanitizePaymentOrderForResponse(order))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func sanitizePaymentOrderForResponse(order *dbent.PaymentOrder) *dbent.PaymentOrder {
|
||||||
|
if order == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
cloned := *order
|
||||||
|
cloned.ProviderSnapshot = nil
|
||||||
|
return &cloned
|
||||||
|
}
|
||||||
|
|
||||||
func isWeChatBrowser(c *gin.Context) bool {
|
func isWeChatBrowser(c *gin.Context) bool {
|
||||||
return strings.Contains(strings.ToLower(c.GetHeader("User-Agent")), "micromessenger")
|
return strings.Contains(strings.ToLower(c.GetHeader("User-Agent")), "micromessenger")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ func (s *PaymentService) CreateOrder(ctx context.Context, req CreateOrderRequest
|
|||||||
if oauthResp != nil {
|
if oauthResp != nil {
|
||||||
return oauthResp, nil
|
return oauthResp, nil
|
||||||
}
|
}
|
||||||
order, err := s.createOrderInTx(ctx, req, user, plan, cfg, orderAmount, limitAmount, feeRate, payAmount)
|
order, err := s.createOrderInTx(ctx, req, user, plan, cfg, orderAmount, limitAmount, feeRate, payAmount, sel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ func (s *PaymentService) validateSubOrder(ctx context.Context, req CreateOrderRe
|
|||||||
return plan, nil
|
return plan, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PaymentService) createOrderInTx(ctx context.Context, req CreateOrderRequest, user *User, plan *dbent.SubscriptionPlan, cfg *PaymentConfig, orderAmount, limitAmount, feeRate, payAmount float64) (*dbent.PaymentOrder, error) {
|
func (s *PaymentService) createOrderInTx(ctx context.Context, req CreateOrderRequest, user *User, plan *dbent.SubscriptionPlan, cfg *PaymentConfig, orderAmount, limitAmount, feeRate, payAmount float64, sel *payment.InstanceSelection) (*dbent.PaymentOrder, error) {
|
||||||
tx, err := s.entClient.Tx(ctx)
|
tx, err := s.entClient.Tx(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("begin transaction: %w", err)
|
return nil, fmt.Errorf("begin transaction: %w", err)
|
||||||
@@ -139,6 +139,13 @@ func (s *PaymentService) createOrderInTx(ctx context.Context, req CreateOrderReq
|
|||||||
tm = defaultOrderTimeoutMin
|
tm = defaultOrderTimeoutMin
|
||||||
}
|
}
|
||||||
exp := time.Now().Add(time.Duration(tm) * time.Minute)
|
exp := time.Now().Add(time.Duration(tm) * time.Minute)
|
||||||
|
providerSnapshot := buildPaymentOrderProviderSnapshot(sel)
|
||||||
|
selectedInstanceID := ""
|
||||||
|
selectedProviderKey := ""
|
||||||
|
if sel != nil {
|
||||||
|
selectedInstanceID = strings.TrimSpace(sel.InstanceID)
|
||||||
|
selectedProviderKey = strings.TrimSpace(sel.ProviderKey)
|
||||||
|
}
|
||||||
b := tx.PaymentOrder.Create().
|
b := tx.PaymentOrder.Create().
|
||||||
SetUserID(req.UserID).
|
SetUserID(req.UserID).
|
||||||
SetUserEmail(user.Email).
|
SetUserEmail(user.Email).
|
||||||
@@ -159,6 +166,15 @@ func (s *PaymentService) createOrderInTx(ctx context.Context, req CreateOrderReq
|
|||||||
if req.SrcURL != "" {
|
if req.SrcURL != "" {
|
||||||
b.SetSrcURL(req.SrcURL)
|
b.SetSrcURL(req.SrcURL)
|
||||||
}
|
}
|
||||||
|
if selectedInstanceID != "" {
|
||||||
|
b.SetProviderInstanceID(selectedInstanceID)
|
||||||
|
}
|
||||||
|
if selectedProviderKey != "" {
|
||||||
|
b.SetProviderKey(selectedProviderKey)
|
||||||
|
}
|
||||||
|
if providerSnapshot != nil {
|
||||||
|
b.SetProviderSnapshot(providerSnapshot)
|
||||||
|
}
|
||||||
if plan != nil {
|
if plan != nil {
|
||||||
b.SetPlanID(plan.ID).SetSubscriptionGroupID(plan.GroupID).SetSubscriptionDays(psComputeValidityDays(plan.ValidityDays, plan.ValidityUnit))
|
b.SetPlanID(plan.ID).SetSubscriptionGroupID(plan.GroupID).SetSubscriptionDays(psComputeValidityDays(plan.ValidityDays, plan.ValidityUnit))
|
||||||
}
|
}
|
||||||
@@ -192,6 +208,35 @@ func (s *PaymentService) checkPendingLimit(ctx context.Context, tx *dbent.Tx, us
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func buildPaymentOrderProviderSnapshot(sel *payment.InstanceSelection) map[string]any {
|
||||||
|
if sel == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshot := map[string]any{}
|
||||||
|
snapshot["schema_version"] = 1
|
||||||
|
|
||||||
|
instanceID := strings.TrimSpace(sel.InstanceID)
|
||||||
|
if instanceID != "" {
|
||||||
|
snapshot["provider_instance_id"] = instanceID
|
||||||
|
}
|
||||||
|
|
||||||
|
providerKey := strings.TrimSpace(sel.ProviderKey)
|
||||||
|
if providerKey != "" {
|
||||||
|
snapshot["provider_key"] = providerKey
|
||||||
|
}
|
||||||
|
|
||||||
|
paymentMode := strings.TrimSpace(sel.PaymentMode)
|
||||||
|
if paymentMode != "" {
|
||||||
|
snapshot["payment_mode"] = paymentMode
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(snapshot) == 1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return snapshot
|
||||||
|
}
|
||||||
|
|
||||||
func (s *PaymentService) checkDailyLimit(ctx context.Context, tx *dbent.Tx, userID int64, amount, limit float64) error {
|
func (s *PaymentService) checkDailyLimit(ctx context.Context, tx *dbent.Tx, userID int64, amount, limit float64) error {
|
||||||
if limit <= 0 {
|
if limit <= 0 {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
116
backend/internal/service/payment_order_provider_snapshot_test.go
Normal file
116
backend/internal/service/payment_order_provider_snapshot_test.go
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
//go:build unit
|
||||||
|
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/Wei-Shaw/sub2api/internal/payment"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBuildPaymentOrderProviderSnapshot_ExcludesSensitiveConfig(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
sel := &payment.InstanceSelection{
|
||||||
|
InstanceID: "12",
|
||||||
|
ProviderKey: payment.TypeWxpay,
|
||||||
|
SupportedTypes: "wxpay,wxpay_direct",
|
||||||
|
PaymentMode: "popup",
|
||||||
|
Config: map[string]string{
|
||||||
|
"privateKey": "secret",
|
||||||
|
"apiV3Key": "secret-v3",
|
||||||
|
"appId": "wx-app-id",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshot := buildPaymentOrderProviderSnapshot(sel)
|
||||||
|
require.Equal(t, map[string]any{
|
||||||
|
"schema_version": 1,
|
||||||
|
"provider_instance_id": "12",
|
||||||
|
"provider_key": payment.TypeWxpay,
|
||||||
|
"payment_mode": "popup",
|
||||||
|
}, snapshot)
|
||||||
|
require.NotContains(t, snapshot, "config")
|
||||||
|
require.NotContains(t, snapshot, "privateKey")
|
||||||
|
require.NotContains(t, snapshot, "apiV3Key")
|
||||||
|
require.NotContains(t, snapshot, "supported_types")
|
||||||
|
require.NotContains(t, snapshot, "instance_name")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateOrderInTx_WritesProviderSnapshot(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
client := newPaymentConfigServiceTestClient(t)
|
||||||
|
|
||||||
|
user, err := client.User.Create().
|
||||||
|
SetEmail("snapshot@example.com").
|
||||||
|
SetPasswordHash("hash").
|
||||||
|
SetUsername("snapshot-user").
|
||||||
|
Save(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
instance, err := client.PaymentProviderInstance.Create().
|
||||||
|
SetProviderKey(payment.TypeAlipay).
|
||||||
|
SetName("Primary Alipay").
|
||||||
|
SetConfig(`{"secretKey":"do-not-copy"}`).
|
||||||
|
SetSupportedTypes("alipay,alipay_direct").
|
||||||
|
SetPaymentMode("redirect").
|
||||||
|
SetEnabled(true).
|
||||||
|
Save(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
svc := &PaymentService{entClient: client}
|
||||||
|
order, err := svc.createOrderInTx(
|
||||||
|
ctx,
|
||||||
|
CreateOrderRequest{
|
||||||
|
UserID: user.ID,
|
||||||
|
PaymentType: payment.TypeAlipay,
|
||||||
|
OrderType: payment.OrderTypeBalance,
|
||||||
|
ClientIP: "127.0.0.1",
|
||||||
|
SrcHost: "app.example.com",
|
||||||
|
},
|
||||||
|
&User{
|
||||||
|
ID: user.ID,
|
||||||
|
Email: user.Email,
|
||||||
|
Username: user.Username,
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
&PaymentConfig{
|
||||||
|
MaxPendingOrders: 3,
|
||||||
|
OrderTimeoutMin: 30,
|
||||||
|
},
|
||||||
|
88,
|
||||||
|
88,
|
||||||
|
0,
|
||||||
|
88,
|
||||||
|
&payment.InstanceSelection{
|
||||||
|
InstanceID: strconv.FormatInt(instance.ID, 10),
|
||||||
|
ProviderKey: payment.TypeAlipay,
|
||||||
|
SupportedTypes: "alipay,alipay_direct",
|
||||||
|
PaymentMode: "redirect",
|
||||||
|
Config: map[string]string{
|
||||||
|
"secretKey": "do-not-copy",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, strconv.FormatInt(instance.ID, 10), valueOrEmpty(order.ProviderInstanceID))
|
||||||
|
require.Equal(t, payment.TypeAlipay, valueOrEmpty(order.ProviderKey))
|
||||||
|
require.Equal(t, float64(1), order.ProviderSnapshot["schema_version"])
|
||||||
|
require.Equal(t, strconv.FormatInt(instance.ID, 10), order.ProviderSnapshot["provider_instance_id"])
|
||||||
|
require.Equal(t, payment.TypeAlipay, order.ProviderSnapshot["provider_key"])
|
||||||
|
require.Equal(t, "redirect", order.ProviderSnapshot["payment_mode"])
|
||||||
|
require.NotContains(t, order.ProviderSnapshot, "config")
|
||||||
|
require.NotContains(t, order.ProviderSnapshot, "secretKey")
|
||||||
|
require.NotContains(t, order.ProviderSnapshot, "supported_types")
|
||||||
|
require.NotContains(t, order.ProviderSnapshot, "instance_name")
|
||||||
|
}
|
||||||
|
|
||||||
|
func valueOrEmpty(v *string) string {
|
||||||
|
if v == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return *v
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE payment_orders
|
||||||
|
ADD COLUMN IF NOT EXISTS provider_snapshot JSONB;
|
||||||
Reference in New Issue
Block a user