package booking import ( "context" "errors" "log/slog" "strings" "time" "github.com/rjNemo/rentease/internal/config" stripeclient "github.com/rjNemo/rentease/internal/driver/stripe" ) // ErrStripeClientNotConfigured indicates the service was asked to run a Stripe operation without a configured client. var ErrStripeClientNotConfigured = errors.New("stripe client not configured") // SyncStripePayments pulls Stripe payments within the provided time window and // upserts them into the local datastore. Payments lacking booking metadata are // skipped to avoid incorrect associations. func (bs Service) SyncStripePayments(ctx context.Context, from, to time.Time) error { if bs.stripe == nil { return ErrStripeClientNotConfigured } payments, err := bs.stripe.ListPayments(ctx, stripeclient.ListPaymentsParams{From: from, To: to}) if err != nil { return err } var multi error for _, payment := range payments { if payment.BookingID == nil { bs.logger.Warn("stripe payment missing booking metadata", slog.String("payment_id", payment.ID)) continue } bookingID := uint(*payment.BookingID) stripeID := payment.ID status := strings.ToLower(payment.Status) _, err = bs.store.UpsertStripePayment(&Payment{ BookingID: bookingID, Amount: payment.Amount, PaymentMethod: mapStripeMethod(payment.PaymentMethod), StripePaymentID: &stripeID, StripeStatus: &status, }) if err != nil { multi = errors.Join(multi, err) bs.logger.Error("failed to upsert stripe payment", slog.String("payment_id", payment.ID), slog.Any("error", err)) } } return multi } func mapStripeMethod(method string) config.PaymentMethod { switch strings.ToLower(method) { case "card", "link", "apple_pay", "google_pay", "cashapp": return config.PaymentMethod("Card") case "ach_credit_transfer", "ach_debit", "us_bank_account", "sepa_debit", "bank_transfer", "blik", "bancontact": return config.PaymentMethod("Transfer") case "cash": return config.PaymentMethod("Cash") case "check": return config.PaymentMethod("Cheque") default: return config.PaymentMethod("Card") } }