package payments import ( "errors" "fmt" ) // Valid payment types var validPaymentTypes = map[string]bool{ "deposit": true, "full": true, "tip": true, "balance": true, "partial": true, } // ValidateAmount checks that amount is greater than 0 and has valid precision (max 2 decimal places when in pence) func ValidateAmount(amount int64) error { if amount <= 0 { return errors.New("amount must be greater than 0") } if amount > 1_000_000 { // £10,000 in pence return errors.New("amount exceeds maximum (£10,000)") } return nil } // ValidatePartialAmount checks that the partial amount doesn't exceed the remaining balance func ValidatePartialAmount(amountPence int64, remainingPence int64) error { if amountPence > remainingPence { return fmt.Errorf("partial amount (£%.2f) exceeds remaining balance (£%.2f)", float64(amountPence)/100, float64(remainingPence)/100) } if amountPence <= 0 { return errors.New("amount must be greater than 0") } return nil } // ValidatePaymentType checks that payment type is valid func ValidatePaymentType(pt string) error { if !validPaymentTypes[pt] { return errors.New("invalid payment type") } return nil } // ValidateRefundReason checks that refund reason is not empty func ValidateRefundReason(reason string) error { if reason == "" { return errors.New("refund reason is required") } return nil } // ValidateCardInfo checks that exactly one of cardID or newCardToken is provided, // non-nil, and non-empty. func ValidateCardInfo(cardID, newCardToken *string) error { hasCardID := cardID != nil && *cardID != "" hasToken := newCardToken != nil && *newCardToken != "" if hasCardID && hasToken { return errors.New("provide either card_id or new_card_token, not both") } if !hasCardID && !hasToken { return errors.New("either card_id or new_card_token is required") } return nil } // ValidateVerificationToken checks that a Square 3DS/SCA verification token is // non-empty when present and within a sane length. Square's tokens are short // opaque strings; the bound guards against absurd/malformed payloads before // the token is forwarded to Square's API. func ValidateVerificationToken(token *string) error { if token == nil || *token == "" { return nil } if len(*token) > 512 { return errors.New("verification_token is too long") } return nil }