package cart import ( "fmt" "strings" "time" messages "git.k6n.net/go-cart-actor/pkg/messages" ) // PaymentStarted registers the beginning of a payment attempt for a cart. // It either upserts the payment entry (based on paymentId) or creates a new one, // marks the cart as having an in-progress payment, and recalculates the PaidInFull flag. func PaymentStarted(grain *CartGrain, msg *messages.PaymentStarted) error { if msg == nil { return fmt.Errorf("PaymentStarted: nil payload") } paymentID := strings.TrimSpace(msg.PaymentId) if paymentID == "" { return fmt.Errorf("PaymentStarted: missing paymentId") } if msg.Amount < 0 { return fmt.Errorf("PaymentStarted: amount cannot be negative") } currency := strings.TrimSpace(msg.Currency) provider := strings.TrimSpace(msg.Provider) method := copyOptionalString(msg.Method) startedAt := time.Now().UTC() if msg.StartedAt != nil { startedAt = msg.StartedAt.AsTime() } payment, found := grain.FindPayment(paymentID) if found { if payment.Status != PaymentStatusPending { return fmt.Errorf("PaymentStarted: payment already started") } if payment.PaymentId != paymentID { payment.PaymentId = paymentID } payment.Status = PaymentStatusPending payment.Amount = msg.Amount if currency != "" { payment.Currency = currency } if provider != "" { payment.Provider = provider } if method != nil { payment.Method = method } payment.StartedAt = &startedAt payment.CompletedAt = nil payment.ProcessorReference = nil } else { grain.Payments = append(grain.Payments, &CartPayment{ PaymentId: paymentID, Status: PaymentStatusPending, Amount: msg.Amount, Currency: currency, Provider: provider, Method: method, StartedAt: &startedAt, }) } grain.PaymentInProgress++ grain.PaymentStatus = PaymentStatusPending return nil } func copyOptionalString(src *string) *string { if src == nil { return nil } trimmed := strings.TrimSpace(*src) if trimmed == "" { return nil } dst := trimmed return &dst }