fix currencies validation
This commit is contained in:
@@ -33,7 +33,8 @@ func (p *PaymentIntent) Validate() error {
|
||||
if p.Amount == nil {
|
||||
return merrors.InvalidArgument("amount is required", "intent.amount")
|
||||
}
|
||||
if err := ValidateMoney(p.Amount); err != nil {
|
||||
//TODO: collect supported currencies and validate against them
|
||||
if err := ValidateMoney(p.Amount, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -1,30 +1,76 @@
|
||||
package srequest
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
"github.com/tech/sendico/pkg/merrors"
|
||||
"github.com/tech/sendico/pkg/model"
|
||||
)
|
||||
|
||||
func ValidateMoney(m *model.Money) error {
|
||||
if m.Amount == "" {
|
||||
// AssetResolver defines environment-specific supported assets.
|
||||
// Implementations should check:
|
||||
// - fiat assets (ISO-4217)
|
||||
// - crypto assets supported by gateways / FX providers
|
||||
type AssetResolver interface {
|
||||
IsSupported(ticker string) bool
|
||||
}
|
||||
|
||||
// Precompile regex for efficiency.
|
||||
var currencySyntax = regexp.MustCompile(`^[A-Z0-9]{2,10}$`)
|
||||
|
||||
func ValidateMoney(m *model.Money, assetResolver AssetResolver) error {
|
||||
if m == nil {
|
||||
return merrors.InvalidArgument("money is required", "intent.amount")
|
||||
}
|
||||
|
||||
//
|
||||
// 1) Basic presence
|
||||
//
|
||||
if strings.TrimSpace(m.Amount) == "" {
|
||||
return merrors.InvalidArgument("amount is required", "intent.amount")
|
||||
}
|
||||
if m.Currency == "" {
|
||||
if strings.TrimSpace(m.Currency) == "" {
|
||||
return merrors.InvalidArgument("currency is required", "intent.currency")
|
||||
}
|
||||
|
||||
if _, err := decimal.NewFromString(m.Amount); err != nil {
|
||||
return merrors.InvalidArgument("invalid amount decimal", "intent.amount")
|
||||
//
|
||||
// 2) Validate decimal amount
|
||||
//
|
||||
amount, err := decimal.NewFromString(m.Amount)
|
||||
if err != nil {
|
||||
return merrors.InvalidArgument("invalid decimal amount", "intent.amount")
|
||||
}
|
||||
|
||||
if len(m.Currency) != 3 {
|
||||
return merrors.InvalidArgument("currency must be 3 letters", "intent.currency")
|
||||
if amount.IsNegative() {
|
||||
return merrors.InvalidArgument("amount must be >= 0", "intent.amount")
|
||||
}
|
||||
for _, c := range m.Currency {
|
||||
if c < 'A' || c > 'Z' {
|
||||
return merrors.InvalidArgument("currency must be uppercase A-Z", "intent.currency")
|
||||
}
|
||||
|
||||
//
|
||||
// 3) Normalize currency
|
||||
//
|
||||
cur := strings.ToUpper(strings.TrimSpace(m.Currency))
|
||||
|
||||
//
|
||||
// 4) Syntax validation first — reject malformed tickers early
|
||||
//
|
||||
if !currencySyntax.MatchString(cur) {
|
||||
return merrors.InvalidArgument(
|
||||
"invalid currency format (must be A–Z0–9, length 2–10)",
|
||||
"intent.currency",
|
||||
)
|
||||
}
|
||||
|
||||
//
|
||||
// 5) Dictionary / environment validation
|
||||
//
|
||||
if assetResolver == nil {
|
||||
return merrors.InvalidArgument("asset resolver is not configured", "intent.currency")
|
||||
}
|
||||
|
||||
if !assetResolver.IsSupported(cur) {
|
||||
return merrors.InvalidArgument("unsupported currency/asset", "intent.currency")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -82,6 +82,9 @@ enum ResourceType {
|
||||
@JsonValue('payment_methods')
|
||||
paymentMethods,
|
||||
|
||||
@JsonValue('payment_orchestrator')
|
||||
paymentOrchestrator,
|
||||
|
||||
/// Represents permissions service
|
||||
@JsonValue('permissions')
|
||||
permissions,
|
||||
|
||||
Reference in New Issue
Block a user