mirror of
https://github.com/hanzo-fi/payments.git
synced 2026-10-30 20:31:20 +00:00
243 lines
7.0 KiB
Go
243 lines
7.0 KiB
Go
package models
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/hanzo-fi/go-libs/v5/pkg/types/pointer"
|
|
"github.com/hanzo-fi/payments/pkg/domain/assets"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
// Internal struct used by the plugins
|
|
type PSPAccount struct {
|
|
// PSP reference of the account. Should be unique.
|
|
Reference string
|
|
|
|
// Account's creation date
|
|
CreatedAt time.Time
|
|
|
|
// Optional, human readable name of the account (if existing)
|
|
Name *string
|
|
// Optional, if provided the default asset of the account
|
|
// in minor currencies unit.
|
|
DefaultAsset *string
|
|
// Optional, can be filled if the account is related to an open banking connector
|
|
PsuID *uuid.UUID
|
|
// Optional, can be filled if the account is related to an open banking connector
|
|
OpenBankingConnectionID *string
|
|
|
|
// Additional metadata
|
|
Metadata map[string]string
|
|
|
|
// PSP response in raw
|
|
Raw json.RawMessage
|
|
}
|
|
|
|
func (p *PSPAccount) Validate() error {
|
|
if p.Reference == "" {
|
|
return fmt.Errorf("missing account reference: %w", ErrValidation)
|
|
}
|
|
|
|
if p.CreatedAt.IsZero() {
|
|
return fmt.Errorf("missing account createdAt: %w", ErrValidation)
|
|
}
|
|
|
|
if p.Raw == nil {
|
|
return fmt.Errorf("missing account raw: %w", ErrValidation)
|
|
}
|
|
|
|
if p.DefaultAsset != nil && !assets.IsValid(*p.DefaultAsset) {
|
|
return fmt.Errorf("invalid default asset: %w", ErrValidation)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type Account struct {
|
|
// Unique Account ID generated from account information
|
|
ID AccountID `json:"id"`
|
|
// Related Connector ID
|
|
ConnectorID ConnectorID `json:"connectorID"`
|
|
Connector *ConnectorBase `json:"connector"`
|
|
|
|
// PSP reference of the account. Should be unique.
|
|
Reference string `json:"reference"`
|
|
|
|
// Account's creation date
|
|
CreatedAt time.Time `json:"createdAt"`
|
|
|
|
// Type of account: INTERNAL, EXTERNAL...
|
|
Type AccountType `json:"type"`
|
|
|
|
// Optional, human readable name of the account (if existing)
|
|
Name *string `json:"name"`
|
|
// Optional, if provided the default asset of the account
|
|
// in minor currencies unit.
|
|
DefaultAsset *string `json:"defaultAsset"`
|
|
// Optional, can be filled if the account is related to an open banking connector
|
|
PsuID *uuid.UUID `json:"psuID,omitempty"`
|
|
// Optional, can be filled if the account is related to an open banking connector
|
|
OpenBankingConnectionID *string `json:"openBankingConnectionID,omitempty"`
|
|
|
|
// Additional metadata
|
|
Metadata map[string]string `json:"metadata"`
|
|
|
|
// PSP response in raw
|
|
Raw json.RawMessage `json:"raw"`
|
|
}
|
|
|
|
func (a Account) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(&struct {
|
|
ID string `json:"id"`
|
|
ConnectorID string `json:"connectorID"`
|
|
Connector *ConnectorBase `json:"connector"`
|
|
Provider string `json:"provider"`
|
|
Reference string `json:"reference"`
|
|
CreatedAt time.Time `json:"createdAt"`
|
|
Type AccountType `json:"type"`
|
|
Name *string `json:"name"`
|
|
DefaultAsset *string `json:"defaultAsset"`
|
|
PsuID *string `json:"psuID,omitempty"`
|
|
OpenBankingConnectionID *string `json:"openBankingConnectionID,omitempty"`
|
|
Metadata map[string]string `json:"metadata"`
|
|
Raw json.RawMessage `json:"raw"`
|
|
}{
|
|
ID: a.ID.String(),
|
|
ConnectorID: a.ConnectorID.String(),
|
|
Connector: a.Connector,
|
|
Provider: ToV3Provider(a.ConnectorID.Provider),
|
|
Reference: a.Reference,
|
|
CreatedAt: a.CreatedAt,
|
|
Type: a.Type,
|
|
Name: a.Name,
|
|
DefaultAsset: a.DefaultAsset,
|
|
PsuID: func() *string {
|
|
if a.PsuID == nil {
|
|
return nil
|
|
}
|
|
return pointer.For(a.PsuID.String())
|
|
}(),
|
|
OpenBankingConnectionID: a.OpenBankingConnectionID,
|
|
Metadata: a.Metadata,
|
|
Raw: a.Raw,
|
|
})
|
|
}
|
|
|
|
func (a *Account) IdempotencyKey() string {
|
|
return IdempotencyKey(a.ID)
|
|
}
|
|
|
|
func (a *Account) UnmarshalJSON(data []byte) error {
|
|
var aux struct {
|
|
ID string `json:"id"`
|
|
ConnectorID string `json:"connectorID"`
|
|
Connector *ConnectorBase `json:"connector"`
|
|
Reference string `json:"reference"`
|
|
CreatedAt time.Time `json:"createdAt"`
|
|
Type AccountType `json:"type"`
|
|
Name *string `json:"name"`
|
|
DefaultAsset *string `json:"defaultAsset"`
|
|
PsuID *string `json:"psuID,omitempty"`
|
|
OpenBankingConnectionID *string `json:"openBankingConnectionID,omitempty"`
|
|
Metadata map[string]string `json:"metadata"`
|
|
Raw json.RawMessage `json:"raw"`
|
|
}
|
|
|
|
if err := json.Unmarshal(data, &aux); err != nil {
|
|
return err
|
|
}
|
|
|
|
id, err := AccountIDFromString(aux.ID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
connectorID, err := ConnectorIDFromString(aux.ConnectorID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if aux.PsuID != nil {
|
|
psuID, err := uuid.Parse(*aux.PsuID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
a.PsuID = &psuID
|
|
}
|
|
|
|
if aux.OpenBankingConnectionID != nil {
|
|
a.OpenBankingConnectionID = aux.OpenBankingConnectionID
|
|
}
|
|
|
|
a.ID = id
|
|
a.ConnectorID = connectorID
|
|
a.Connector = aux.Connector
|
|
a.Reference = aux.Reference
|
|
a.CreatedAt = aux.CreatedAt
|
|
a.Type = aux.Type
|
|
a.Name = aux.Name
|
|
a.DefaultAsset = aux.DefaultAsset
|
|
a.Metadata = aux.Metadata
|
|
a.Raw = aux.Raw
|
|
|
|
return nil
|
|
}
|
|
|
|
func FromPSPAccount(from PSPAccount, accountType AccountType, connectorID ConnectorID) (Account, error) {
|
|
if err := from.Validate(); err != nil {
|
|
return Account{}, err
|
|
}
|
|
|
|
return Account{
|
|
ID: AccountID{
|
|
Reference: from.Reference,
|
|
ConnectorID: connectorID,
|
|
},
|
|
ConnectorID: connectorID,
|
|
Reference: from.Reference,
|
|
CreatedAt: from.CreatedAt,
|
|
Type: accountType,
|
|
Name: from.Name,
|
|
DefaultAsset: from.DefaultAsset,
|
|
Metadata: from.Metadata,
|
|
PsuID: from.PsuID,
|
|
OpenBankingConnectionID: from.OpenBankingConnectionID,
|
|
Raw: from.Raw,
|
|
}, nil
|
|
}
|
|
|
|
func FromPSPAccounts(from []PSPAccount, accountType AccountType, connectorID ConnectorID) ([]Account, error) {
|
|
accounts := make([]Account, 0, len(from))
|
|
for _, a := range from {
|
|
account, err := FromPSPAccount(a, accountType, connectorID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if account.Metadata == nil {
|
|
account.Metadata = make(map[string]string)
|
|
}
|
|
|
|
accounts = append(accounts, account)
|
|
}
|
|
return accounts, nil
|
|
}
|
|
|
|
func ToPSPAccount(from *Account) *PSPAccount {
|
|
if from == nil {
|
|
return nil
|
|
}
|
|
return &PSPAccount{
|
|
Reference: from.Reference,
|
|
CreatedAt: from.CreatedAt,
|
|
Name: from.Name,
|
|
DefaultAsset: from.DefaultAsset,
|
|
PsuID: from.PsuID,
|
|
OpenBankingConnectionID: from.OpenBankingConnectionID,
|
|
Metadata: from.Metadata,
|
|
Raw: from.Raw,
|
|
}
|
|
}
|