package model import ( "bytes" "encoding/json" "fmt" "github.com/tech/sendico/pkg/merrors" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" ) type PaymentType int const ( PaymentTypeIban PaymentType = iota PaymentTypeCard PaymentTypeCardToken PaymentTypeBankAccount PaymentTypeWallet PaymentTypeCryptoAddress PaymentTypeLedger ) var paymentTypeToString = map[PaymentType]string{ PaymentTypeIban: "iban", PaymentTypeCard: "card", PaymentTypeCardToken: "cardToken", PaymentTypeBankAccount: "bankAccount", PaymentTypeWallet: "wallet", PaymentTypeCryptoAddress: "cryptoAddress", PaymentTypeLedger: "ledger", } var paymentTypeFromString = map[string]PaymentType{ "iban": PaymentTypeIban, "card": PaymentTypeCard, "cardToken": PaymentTypeCardToken, "bankAccount": PaymentTypeBankAccount, "wallet": PaymentTypeWallet, "cryptoAddress": PaymentTypeCryptoAddress, "ledger": PaymentTypeLedger, } func (t PaymentType) String() string { if v, ok := paymentTypeToString[t]; ok { return v } return "iban" } func (t PaymentType) MarshalJSON() ([]byte, error) { return json.Marshal(t.String()) } func (t *PaymentType) UnmarshalJSON(data []byte) error { var val string if err := json.Unmarshal(data, &val); err != nil { return err } v, ok := paymentTypeFromString[val] if !ok { return merrors.InvalidArgument(fmt.Sprintf("unknown PaymentType: %q", val)) } *t = v return nil } type PaymentMethod struct { PermissionBound `bson:",inline" json:",inline"` Describable `bson:",inline" json:",inline"` RecipientRef primitive.ObjectID `bson:"recipientRef" json:"recipientRef"` Type PaymentType `bson:"type" json:"type"` Data bson.Raw `bson:"data" json:"data"` IsMain bool `bson:"isMain" json:"isMain"` } type paymentMethodJSON struct { PermissionBound `json:",inline"` Describable `json:",inline"` RecipientRef primitive.ObjectID `json:"recipientRef"` Type PaymentType `json:"type"` Data json.RawMessage `json:"data"` IsMain bool `json:"isMain"` } func (m PaymentMethod) MarshalJSON() ([]byte, error) { var marshaledData json.RawMessage if len(m.Data) > 0 { var data bson.M if err := bson.Unmarshal(m.Data, &data); err != nil { return nil, err } if data != nil { b, err := json.Marshal(data) if err != nil { return nil, err } marshaledData = b } } payload := paymentMethodJSON{ PermissionBound: m.PermissionBound, Describable: m.Describable, RecipientRef: m.RecipientRef, Type: m.Type, Data: marshaledData, IsMain: m.IsMain, } return json.Marshal(payload) } func (m *PaymentMethod) UnmarshalJSON(data []byte) error { var payload paymentMethodJSON if err := json.Unmarshal(data, &payload); err != nil { return err } m.PermissionBound = payload.PermissionBound m.Describable = payload.Describable m.RecipientRef = payload.RecipientRef m.Type = payload.Type m.IsMain = payload.IsMain if len(payload.Data) == 0 || bytes.Equal(payload.Data, []byte("null")) { m.Data = nil return nil } var rawData map[string]any if err := json.Unmarshal(payload.Data, &rawData); err != nil { return err } raw, err := bson.Marshal(rawData) if err != nil { return err } m.Data = raw return nil }