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:
erio
2026-04-10 21:08:51 +08:00
parent 00c08c574e
commit 63d1860dc0
166 changed files with 42743 additions and 220 deletions

View File

@@ -14,6 +14,7 @@ import (
"github.com/Wei-Shaw/sub2api/ent/announcementread"
"github.com/Wei-Shaw/sub2api/ent/apikey"
"github.com/Wei-Shaw/sub2api/ent/group"
"github.com/Wei-Shaw/sub2api/ent/paymentorder"
"github.com/Wei-Shaw/sub2api/ent/predicate"
"github.com/Wei-Shaw/sub2api/ent/promocodeusage"
"github.com/Wei-Shaw/sub2api/ent/redeemcode"
@@ -377,6 +378,21 @@ func (_u *UserUpdate) AddPromoCodeUsages(v ...*PromoCodeUsage) *UserUpdate {
return _u.AddPromoCodeUsageIDs(ids...)
}
// AddPaymentOrderIDs adds the "payment_orders" edge to the PaymentOrder entity by IDs.
func (_u *UserUpdate) AddPaymentOrderIDs(ids ...int64) *UserUpdate {
_u.mutation.AddPaymentOrderIDs(ids...)
return _u
}
// AddPaymentOrders adds the "payment_orders" edges to the PaymentOrder entity.
func (_u *UserUpdate) AddPaymentOrders(v ...*PaymentOrder) *UserUpdate {
ids := make([]int64, len(v))
for i := range v {
ids[i] = v[i].ID
}
return _u.AddPaymentOrderIDs(ids...)
}
// Mutation returns the UserMutation object of the builder.
func (_u *UserUpdate) Mutation() *UserMutation {
return _u.mutation
@@ -571,6 +587,27 @@ func (_u *UserUpdate) RemovePromoCodeUsages(v ...*PromoCodeUsage) *UserUpdate {
return _u.RemovePromoCodeUsageIDs(ids...)
}
// ClearPaymentOrders clears all "payment_orders" edges to the PaymentOrder entity.
func (_u *UserUpdate) ClearPaymentOrders() *UserUpdate {
_u.mutation.ClearPaymentOrders()
return _u
}
// RemovePaymentOrderIDs removes the "payment_orders" edge to PaymentOrder entities by IDs.
func (_u *UserUpdate) RemovePaymentOrderIDs(ids ...int64) *UserUpdate {
_u.mutation.RemovePaymentOrderIDs(ids...)
return _u
}
// RemovePaymentOrders removes "payment_orders" edges to PaymentOrder entities.
func (_u *UserUpdate) RemovePaymentOrders(v ...*PaymentOrder) *UserUpdate {
ids := make([]int64, len(v))
for i := range v {
ids[i] = v[i].ID
}
return _u.RemovePaymentOrderIDs(ids...)
}
// Save executes the query and returns the number of nodes affected by the update operation.
func (_u *UserUpdate) Save(ctx context.Context) (int, error) {
if err := _u.defaults(); err != nil {
@@ -1126,6 +1163,51 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) {
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if _u.mutation.PaymentOrdersCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: user.PaymentOrdersTable,
Columns: []string{user.PaymentOrdersColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(paymentorder.FieldID, field.TypeInt64),
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := _u.mutation.RemovedPaymentOrdersIDs(); len(nodes) > 0 && !_u.mutation.PaymentOrdersCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: user.PaymentOrdersTable,
Columns: []string{user.PaymentOrdersColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(paymentorder.FieldID, field.TypeInt64),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := _u.mutation.PaymentOrdersIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: user.PaymentOrdersTable,
Columns: []string{user.PaymentOrdersColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(paymentorder.FieldID, field.TypeInt64),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{user.Label}
@@ -1487,6 +1569,21 @@ func (_u *UserUpdateOne) AddPromoCodeUsages(v ...*PromoCodeUsage) *UserUpdateOne
return _u.AddPromoCodeUsageIDs(ids...)
}
// AddPaymentOrderIDs adds the "payment_orders" edge to the PaymentOrder entity by IDs.
func (_u *UserUpdateOne) AddPaymentOrderIDs(ids ...int64) *UserUpdateOne {
_u.mutation.AddPaymentOrderIDs(ids...)
return _u
}
// AddPaymentOrders adds the "payment_orders" edges to the PaymentOrder entity.
func (_u *UserUpdateOne) AddPaymentOrders(v ...*PaymentOrder) *UserUpdateOne {
ids := make([]int64, len(v))
for i := range v {
ids[i] = v[i].ID
}
return _u.AddPaymentOrderIDs(ids...)
}
// Mutation returns the UserMutation object of the builder.
func (_u *UserUpdateOne) Mutation() *UserMutation {
return _u.mutation
@@ -1681,6 +1778,27 @@ func (_u *UserUpdateOne) RemovePromoCodeUsages(v ...*PromoCodeUsage) *UserUpdate
return _u.RemovePromoCodeUsageIDs(ids...)
}
// ClearPaymentOrders clears all "payment_orders" edges to the PaymentOrder entity.
func (_u *UserUpdateOne) ClearPaymentOrders() *UserUpdateOne {
_u.mutation.ClearPaymentOrders()
return _u
}
// RemovePaymentOrderIDs removes the "payment_orders" edge to PaymentOrder entities by IDs.
func (_u *UserUpdateOne) RemovePaymentOrderIDs(ids ...int64) *UserUpdateOne {
_u.mutation.RemovePaymentOrderIDs(ids...)
return _u
}
// RemovePaymentOrders removes "payment_orders" edges to PaymentOrder entities.
func (_u *UserUpdateOne) RemovePaymentOrders(v ...*PaymentOrder) *UserUpdateOne {
ids := make([]int64, len(v))
for i := range v {
ids[i] = v[i].ID
}
return _u.RemovePaymentOrderIDs(ids...)
}
// Where appends a list predicates to the UserUpdate builder.
func (_u *UserUpdateOne) Where(ps ...predicate.User) *UserUpdateOne {
_u.mutation.Where(ps...)
@@ -2266,6 +2384,51 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) {
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if _u.mutation.PaymentOrdersCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: user.PaymentOrdersTable,
Columns: []string{user.PaymentOrdersColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(paymentorder.FieldID, field.TypeInt64),
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := _u.mutation.RemovedPaymentOrdersIDs(); len(nodes) > 0 && !_u.mutation.PaymentOrdersCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: user.PaymentOrdersTable,
Columns: []string{user.PaymentOrdersColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(paymentorder.FieldID, field.TypeInt64),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := _u.mutation.PaymentOrdersIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: user.PaymentOrdersTable,
Columns: []string{user.PaymentOrdersColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(paymentorder.FieldID, field.TypeInt64),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
_node = &User{config: _u.config}
_spec.Assign = _node.assignValues
_spec.ScanValues = _node.scanValues