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 }