216 lines
6.4 KiB
Go
216 lines
6.4 KiB
Go
package repository
|
|
|
|
import (
|
|
dbgen "Yimaru-Backend/gen/db"
|
|
"Yimaru-Backend/internal/domain"
|
|
"context"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
func (s *Store) CreatePayment(ctx context.Context, input domain.CreatePaymentInput) (*domain.Payment, error) {
|
|
payment, err := s.queries.CreatePayment(ctx, dbgen.CreatePaymentParams{
|
|
UserID: input.UserID,
|
|
PlanID: int64PtrToPgInt8(input.PlanID),
|
|
SubscriptionID: pgtype.Int8{Valid: false},
|
|
SessionID: pgtype.Text{Valid: false},
|
|
TransactionID: pgtype.Text{Valid: false},
|
|
Nonce: input.Nonce,
|
|
Amount: toPgNumeric(input.Amount),
|
|
Currency: input.Currency,
|
|
PaymentMethod: toPgText(input.PaymentMethod),
|
|
Column10: string(domain.PaymentStatusPending), // status with COALESCE
|
|
PaymentUrl: pgtype.Text{Valid: false},
|
|
ExpiresAt: toPgTimestamptzPtr(input.ExpiresAt),
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return paymentToDomain(payment), nil
|
|
}
|
|
|
|
func (s *Store) GetPaymentByID(ctx context.Context, id int64) (*domain.Payment, error) {
|
|
payment, err := s.queries.GetPaymentByID(ctx, id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return paymentToDomain(payment), nil
|
|
}
|
|
|
|
func (s *Store) GetPaymentBySessionID(ctx context.Context, sessionID string) (*domain.Payment, error) {
|
|
payment, err := s.queries.GetPaymentBySessionID(ctx, toPgText(&sessionID))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return paymentToDomain(payment), nil
|
|
}
|
|
|
|
func (s *Store) GetPaymentByNonce(ctx context.Context, nonce string) (*domain.Payment, error) {
|
|
payment, err := s.queries.GetPaymentByNonce(ctx, nonce)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return paymentToDomain(payment), nil
|
|
}
|
|
|
|
func (s *Store) GetPaymentByTransactionID(ctx context.Context, transactionID string) (*domain.Payment, error) {
|
|
payment, err := s.queries.GetPaymentByTransactionID(ctx, toPgText(&transactionID))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return paymentToDomain(payment), nil
|
|
}
|
|
|
|
func (s *Store) GetPaymentsByUserID(ctx context.Context, userID int64, limit, offset int32) ([]domain.Payment, error) {
|
|
payments, err := s.queries.GetPaymentsByUserID(ctx, dbgen.GetPaymentsByUserIDParams{
|
|
UserID: userID,
|
|
Limit: pgtype.Int4{Int32: limit, Valid: true},
|
|
Offset: pgtype.Int4{Int32: offset, Valid: true},
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
result := make([]domain.Payment, len(payments))
|
|
for i, p := range payments {
|
|
result[i] = domain.Payment{
|
|
ID: p.ID,
|
|
UserID: p.UserID,
|
|
PlanID: int8PtrToInt64Ptr(p.PlanID),
|
|
SubscriptionID: int8PtrToInt64Ptr(p.SubscriptionID),
|
|
SessionID: fromPgTextPtr(p.SessionID),
|
|
TransactionID: fromPgTextPtr(p.TransactionID),
|
|
Nonce: p.Nonce,
|
|
Amount: fromPgNumeric(p.Amount),
|
|
Currency: p.Currency,
|
|
PaymentMethod: fromPgTextPtr(p.PaymentMethod),
|
|
Status: p.Status,
|
|
PaymentURL: fromPgTextPtr(p.PaymentUrl),
|
|
PaidAt: timePtr(p.PaidAt),
|
|
ExpiresAt: timePtr(p.ExpiresAt),
|
|
CreatedAt: p.CreatedAt.Time,
|
|
UpdatedAt: timePtr(p.UpdatedAt),
|
|
PlanName: fromPgTextPtr(p.PlanName),
|
|
}
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (s *Store) GetPendingPaymentsByUserID(ctx context.Context, userID int64) ([]domain.Payment, error) {
|
|
payments, err := s.queries.GetPendingPaymentsByUserID(ctx, userID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
result := make([]domain.Payment, len(payments))
|
|
for i, p := range payments {
|
|
result[i] = *paymentToDomain(p)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (s *Store) UpdatePaymentStatus(ctx context.Context, id int64, status string) error {
|
|
return s.queries.UpdatePaymentStatus(ctx, dbgen.UpdatePaymentStatusParams{
|
|
Status: status,
|
|
ID: id,
|
|
})
|
|
}
|
|
|
|
func (s *Store) UpdatePaymentStatusBySessionID(ctx context.Context, sessionID, status, transactionID, paymentMethod string) error {
|
|
return s.queries.UpdatePaymentStatusBySessionID(ctx, dbgen.UpdatePaymentStatusBySessionIDParams{
|
|
Status: status,
|
|
TransactionID: toPgText(&transactionID),
|
|
PaymentMethod: toPgText(&paymentMethod),
|
|
SessionID: toPgText(&sessionID),
|
|
})
|
|
}
|
|
|
|
func (s *Store) UpdatePaymentStatusByNonce(ctx context.Context, nonce, status, transactionID, paymentMethod string) error {
|
|
return s.queries.UpdatePaymentStatusByNonce(ctx, dbgen.UpdatePaymentStatusByNonceParams{
|
|
Status: status,
|
|
TransactionID: toPgText(&transactionID),
|
|
PaymentMethod: toPgText(&paymentMethod),
|
|
Nonce: nonce,
|
|
})
|
|
}
|
|
|
|
func (s *Store) UpdatePaymentSessionID(ctx context.Context, id int64, sessionID, paymentURL string) error {
|
|
return s.queries.UpdatePaymentSessionID(ctx, dbgen.UpdatePaymentSessionIDParams{
|
|
SessionID: toPgText(&sessionID),
|
|
PaymentUrl: toPgText(&paymentURL),
|
|
ID: id,
|
|
})
|
|
}
|
|
|
|
func (s *Store) LinkPaymentToSubscription(ctx context.Context, paymentID, subscriptionID int64) error {
|
|
return s.queries.LinkPaymentToSubscription(ctx, dbgen.LinkPaymentToSubscriptionParams{
|
|
SubscriptionID: pgtype.Int8{Int64: subscriptionID, Valid: true},
|
|
ID: paymentID,
|
|
})
|
|
}
|
|
|
|
func (s *Store) GetExpiredPendingPayments(ctx context.Context) ([]domain.Payment, error) {
|
|
payments, err := s.queries.GetExpiredPendingPayments(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
result := make([]domain.Payment, len(payments))
|
|
for i, p := range payments {
|
|
result[i] = *paymentToDomain(p)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (s *Store) ExpirePayment(ctx context.Context, id int64) error {
|
|
return s.queries.ExpirePayment(ctx, id)
|
|
}
|
|
|
|
// Helper functions
|
|
|
|
func paymentToDomain(p dbgen.Payment) *domain.Payment {
|
|
return &domain.Payment{
|
|
ID: p.ID,
|
|
UserID: p.UserID,
|
|
PlanID: int8PtrToInt64Ptr(p.PlanID),
|
|
SubscriptionID: int8PtrToInt64Ptr(p.SubscriptionID),
|
|
SessionID: fromPgTextPtr(p.SessionID),
|
|
TransactionID: fromPgTextPtr(p.TransactionID),
|
|
Nonce: p.Nonce,
|
|
Amount: fromPgNumeric(p.Amount),
|
|
Currency: p.Currency,
|
|
PaymentMethod: fromPgTextPtr(p.PaymentMethod),
|
|
Status: p.Status,
|
|
PaymentURL: fromPgTextPtr(p.PaymentUrl),
|
|
PaidAt: timePtr(p.PaidAt),
|
|
ExpiresAt: timePtr(p.ExpiresAt),
|
|
CreatedAt: p.CreatedAt.Time,
|
|
UpdatedAt: timePtr(p.UpdatedAt),
|
|
}
|
|
}
|
|
|
|
func int64PtrToPgInt8(val *int64) pgtype.Int8 {
|
|
if val == nil {
|
|
return pgtype.Int8{Valid: false}
|
|
}
|
|
return pgtype.Int8{Int64: *val, Valid: true}
|
|
}
|
|
|
|
func int8PtrToInt64Ptr(val pgtype.Int8) *int64 {
|
|
if !val.Valid {
|
|
return nil
|
|
}
|
|
return &val.Int64
|
|
}
|
|
|
|
func fromPgTextPtr(t pgtype.Text) *string {
|
|
if !t.Valid {
|
|
return nil
|
|
}
|
|
return &t.String
|
|
}
|
|
|
|
func strPtr(s string) *string {
|
|
return &s
|
|
}
|