feat(payment): add complete payment system with multi-provider support
Add a full payment and subscription system supporting EasyPay (Alipay/WeChat), Stripe, and direct Alipay/WeChat Pay providers with multi-instance load balancing.
This commit is contained in:
@@ -485,6 +485,158 @@ var (
|
||||
},
|
||||
},
|
||||
}
|
||||
// PaymentAuditLogsColumns holds the columns for the "payment_audit_logs" table.
|
||||
PaymentAuditLogsColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt64, Increment: true},
|
||||
{Name: "order_id", Type: field.TypeString, Size: 64},
|
||||
{Name: "action", Type: field.TypeString, Size: 50},
|
||||
{Name: "detail", Type: field.TypeString, Default: "", SchemaType: map[string]string{"postgres": "text"}},
|
||||
{Name: "operator", Type: field.TypeString, Size: 100, Default: "system"},
|
||||
{Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
}
|
||||
// PaymentAuditLogsTable holds the schema information for the "payment_audit_logs" table.
|
||||
PaymentAuditLogsTable = &schema.Table{
|
||||
Name: "payment_audit_logs",
|
||||
Columns: PaymentAuditLogsColumns,
|
||||
PrimaryKey: []*schema.Column{PaymentAuditLogsColumns[0]},
|
||||
Indexes: []*schema.Index{
|
||||
{
|
||||
Name: "paymentauditlog_order_id",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{PaymentAuditLogsColumns[1]},
|
||||
},
|
||||
},
|
||||
}
|
||||
// PaymentOrdersColumns holds the columns for the "payment_orders" table.
|
||||
PaymentOrdersColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt64, Increment: true},
|
||||
{Name: "user_email", Type: field.TypeString, Size: 255},
|
||||
{Name: "user_name", Type: field.TypeString, Size: 100},
|
||||
{Name: "user_notes", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}},
|
||||
{Name: "amount", Type: field.TypeFloat64, SchemaType: map[string]string{"postgres": "decimal(20,2)"}},
|
||||
{Name: "pay_amount", Type: field.TypeFloat64, SchemaType: map[string]string{"postgres": "decimal(20,2)"}},
|
||||
{Name: "fee_rate", Type: field.TypeFloat64, Default: 0, SchemaType: map[string]string{"postgres": "decimal(10,4)"}},
|
||||
{Name: "recharge_code", Type: field.TypeString, Size: 64},
|
||||
{Name: "out_trade_no", Type: field.TypeString, Size: 64, Default: ""},
|
||||
{Name: "payment_type", Type: field.TypeString, Size: 30},
|
||||
{Name: "payment_trade_no", Type: field.TypeString, Size: 128},
|
||||
{Name: "pay_url", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}},
|
||||
{Name: "qr_code", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}},
|
||||
{Name: "qr_code_img", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}},
|
||||
{Name: "order_type", Type: field.TypeString, Size: 20, Default: "balance"},
|
||||
{Name: "plan_id", Type: field.TypeInt64, Nullable: true},
|
||||
{Name: "subscription_group_id", Type: field.TypeInt64, Nullable: true},
|
||||
{Name: "subscription_days", Type: field.TypeInt, Nullable: true},
|
||||
{Name: "provider_instance_id", Type: field.TypeString, Nullable: true, Size: 64},
|
||||
{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_reason", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}},
|
||||
{Name: "refund_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "force_refund", Type: field.TypeBool, Default: false},
|
||||
{Name: "refund_requested_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "refund_request_reason", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}},
|
||||
{Name: "refund_requested_by", Type: field.TypeString, Nullable: true, Size: 20},
|
||||
{Name: "expires_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "paid_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "completed_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "failed_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "failed_reason", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}},
|
||||
{Name: "client_ip", Type: field.TypeString, Size: 50},
|
||||
{Name: "src_host", Type: field.TypeString, Size: 255},
|
||||
{Name: "src_url", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}},
|
||||
{Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "user_id", Type: field.TypeInt64},
|
||||
}
|
||||
// PaymentOrdersTable holds the schema information for the "payment_orders" table.
|
||||
PaymentOrdersTable = &schema.Table{
|
||||
Name: "payment_orders",
|
||||
Columns: PaymentOrdersColumns,
|
||||
PrimaryKey: []*schema.Column{PaymentOrdersColumns[0]},
|
||||
ForeignKeys: []*schema.ForeignKey{
|
||||
{
|
||||
Symbol: "payment_orders_users_payment_orders",
|
||||
Columns: []*schema.Column{PaymentOrdersColumns[37]},
|
||||
RefColumns: []*schema.Column{UsersColumns[0]},
|
||||
OnDelete: schema.NoAction,
|
||||
},
|
||||
},
|
||||
Indexes: []*schema.Index{
|
||||
{
|
||||
Name: "paymentorder_out_trade_no",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{PaymentOrdersColumns[8]},
|
||||
},
|
||||
{
|
||||
Name: "paymentorder_user_id",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{PaymentOrdersColumns[37]},
|
||||
},
|
||||
{
|
||||
Name: "paymentorder_status",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{PaymentOrdersColumns[19]},
|
||||
},
|
||||
{
|
||||
Name: "paymentorder_expires_at",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{PaymentOrdersColumns[27]},
|
||||
},
|
||||
{
|
||||
Name: "paymentorder_created_at",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{PaymentOrdersColumns[35]},
|
||||
},
|
||||
{
|
||||
Name: "paymentorder_paid_at",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{PaymentOrdersColumns[28]},
|
||||
},
|
||||
{
|
||||
Name: "paymentorder_payment_type_paid_at",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{PaymentOrdersColumns[9], PaymentOrdersColumns[28]},
|
||||
},
|
||||
{
|
||||
Name: "paymentorder_order_type",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{PaymentOrdersColumns[14]},
|
||||
},
|
||||
},
|
||||
}
|
||||
// PaymentProviderInstancesColumns holds the columns for the "payment_provider_instances" table.
|
||||
PaymentProviderInstancesColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt64, Increment: true},
|
||||
{Name: "provider_key", Type: field.TypeString, Size: 30},
|
||||
{Name: "name", Type: field.TypeString, Size: 100, Default: ""},
|
||||
{Name: "config", Type: field.TypeString, SchemaType: map[string]string{"postgres": "text"}},
|
||||
{Name: "supported_types", Type: field.TypeString, Size: 200, Default: ""},
|
||||
{Name: "enabled", Type: field.TypeBool, Default: true},
|
||||
{Name: "payment_mode", Type: field.TypeString, Size: 20, Default: ""},
|
||||
{Name: "sort_order", Type: field.TypeInt, Default: 0},
|
||||
{Name: "limits", Type: field.TypeString, Default: "", SchemaType: map[string]string{"postgres": "text"}},
|
||||
{Name: "refund_enabled", Type: field.TypeBool, Default: false},
|
||||
{Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
}
|
||||
// PaymentProviderInstancesTable holds the schema information for the "payment_provider_instances" table.
|
||||
PaymentProviderInstancesTable = &schema.Table{
|
||||
Name: "payment_provider_instances",
|
||||
Columns: PaymentProviderInstancesColumns,
|
||||
PrimaryKey: []*schema.Column{PaymentProviderInstancesColumns[0]},
|
||||
Indexes: []*schema.Index{
|
||||
{
|
||||
Name: "paymentproviderinstance_provider_key",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{PaymentProviderInstancesColumns[1]},
|
||||
},
|
||||
{
|
||||
Name: "paymentproviderinstance_enabled",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{PaymentProviderInstancesColumns[5]},
|
||||
},
|
||||
},
|
||||
}
|
||||
// PromoCodesColumns holds the columns for the "promo_codes" table.
|
||||
PromoCodesColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt64, Increment: true},
|
||||
@@ -671,6 +823,41 @@ var (
|
||||
Columns: SettingsColumns,
|
||||
PrimaryKey: []*schema.Column{SettingsColumns[0]},
|
||||
}
|
||||
// SubscriptionPlansColumns holds the columns for the "subscription_plans" table.
|
||||
SubscriptionPlansColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt64, Increment: true},
|
||||
{Name: "group_id", Type: field.TypeInt64},
|
||||
{Name: "name", Type: field.TypeString, Size: 100},
|
||||
{Name: "description", Type: field.TypeString, Default: "", SchemaType: map[string]string{"postgres": "text"}},
|
||||
{Name: "price", Type: field.TypeFloat64, SchemaType: map[string]string{"postgres": "decimal(20,2)"}},
|
||||
{Name: "original_price", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,2)"}},
|
||||
{Name: "validity_days", Type: field.TypeInt, Default: 30},
|
||||
{Name: "validity_unit", Type: field.TypeString, Size: 10, Default: "day"},
|
||||
{Name: "features", Type: field.TypeString, Default: "", SchemaType: map[string]string{"postgres": "text"}},
|
||||
{Name: "product_name", Type: field.TypeString, Size: 100, Default: ""},
|
||||
{Name: "for_sale", Type: field.TypeBool, Default: true},
|
||||
{Name: "sort_order", Type: field.TypeInt, Default: 0},
|
||||
{Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
}
|
||||
// SubscriptionPlansTable holds the schema information for the "subscription_plans" table.
|
||||
SubscriptionPlansTable = &schema.Table{
|
||||
Name: "subscription_plans",
|
||||
Columns: SubscriptionPlansColumns,
|
||||
PrimaryKey: []*schema.Column{SubscriptionPlansColumns[0]},
|
||||
Indexes: []*schema.Index{
|
||||
{
|
||||
Name: "subscriptionplan_group_id",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{SubscriptionPlansColumns[1]},
|
||||
},
|
||||
{
|
||||
Name: "subscriptionplan_for_sale",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{SubscriptionPlansColumns[10]},
|
||||
},
|
||||
},
|
||||
}
|
||||
// TLSFingerprintProfilesColumns holds the columns for the "tls_fingerprint_profiles" table.
|
||||
TLSFingerprintProfilesColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt64, Increment: true},
|
||||
@@ -1128,12 +1315,16 @@ var (
|
||||
ErrorPassthroughRulesTable,
|
||||
GroupsTable,
|
||||
IdempotencyRecordsTable,
|
||||
PaymentAuditLogsTable,
|
||||
PaymentOrdersTable,
|
||||
PaymentProviderInstancesTable,
|
||||
PromoCodesTable,
|
||||
PromoCodeUsagesTable,
|
||||
ProxiesTable,
|
||||
RedeemCodesTable,
|
||||
SecuritySecretsTable,
|
||||
SettingsTable,
|
||||
SubscriptionPlansTable,
|
||||
TLSFingerprintProfilesTable,
|
||||
UsageCleanupTasksTable,
|
||||
UsageLogsTable,
|
||||
@@ -1177,6 +1368,16 @@ func init() {
|
||||
IdempotencyRecordsTable.Annotation = &entsql.Annotation{
|
||||
Table: "idempotency_records",
|
||||
}
|
||||
PaymentAuditLogsTable.Annotation = &entsql.Annotation{
|
||||
Table: "payment_audit_logs",
|
||||
}
|
||||
PaymentOrdersTable.ForeignKeys[0].RefTable = UsersTable
|
||||
PaymentOrdersTable.Annotation = &entsql.Annotation{
|
||||
Table: "payment_orders",
|
||||
}
|
||||
PaymentProviderInstancesTable.Annotation = &entsql.Annotation{
|
||||
Table: "payment_provider_instances",
|
||||
}
|
||||
PromoCodesTable.Annotation = &entsql.Annotation{
|
||||
Table: "promo_codes",
|
||||
}
|
||||
@@ -1199,6 +1400,9 @@ func init() {
|
||||
SettingsTable.Annotation = &entsql.Annotation{
|
||||
Table: "settings",
|
||||
}
|
||||
SubscriptionPlansTable.Annotation = &entsql.Annotation{
|
||||
Table: "subscription_plans",
|
||||
}
|
||||
TLSFingerprintProfilesTable.Annotation = &entsql.Annotation{
|
||||
Table: "tls_fingerprint_profiles",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user