Files
payments/pkg/domain/models/open_banking_connections.go
CrimsonandGitHub 538a2d0de2 chore: Refactor models and other shareable packages into importable pkg (#762)
* Move models and other shareable code to pkg/domain and add own go.mod

* Update all references to use pkg/domain paths

* Fix generated file

* Ensure pkg/domain tests are run by just tests

* Use new models path in connector templates

* Copy local pkg/domain in dockerfile

* Ensure pkg/domain is subject to go generate
2026-06-23 13:08:32 +00:00

246 lines
7.9 KiB
Go

package models
import (
"encoding/json"
"time"
"github.com/google/uuid"
)
const (
StateQueryParamID = "state"
NoRedirectQueryParamID = "noRedirect"
)
type OpenBankingConnectionAttemptStatus string
const (
OpenBankingConnectionAttemptStatusPending OpenBankingConnectionAttemptStatus = "pending"
OpenBankingConnectionAttemptStatusCompleted OpenBankingConnectionAttemptStatus = "completed"
OpenBankingConnectionAttemptStatusExited OpenBankingConnectionAttemptStatus = "exited"
)
// When a user tries to create a connection via an link, we will create an attempt
// in order to save some crucial information.
type OpenBankingConnectionAttempt struct {
// ID of the attempt
ID uuid.UUID `json:"id"`
// ID of the psu
PsuID uuid.UUID `json:"psuID"`
// Related connector ID
ConnectorID ConnectorID `json:"connectorID"`
// Creation date of the attempt
CreatedAt time.Time `json:"createdAt"`
// Status of the attempt
Status OpenBankingConnectionAttemptStatus `json:"status"`
// State given to the url in order to be able to verify that the callback
// is valid.
State CallbackState `json:"state"`
// Client redirect URL, given by the user
ClientRedirectURL *string `json:"clientRedirectURL"`
// Optional
// Temporary token generated by the provider in order to create an
// url.
TemporaryToken *Token `json:"temporaryToken"`
// Error message in case of failure
Error *string `json:"error"`
}
func (a OpenBankingConnectionAttempt) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
ID uuid.UUID `json:"id"`
PsuID uuid.UUID `json:"psuID"`
ConnectorID string `json:"connectorID"`
CreatedAt time.Time `json:"createdAt"`
Status string `json:"status"`
State CallbackState `json:"state"`
ClientRedirectURL *string `json:"clientRedirectURL,omitempty"`
TemporaryToken *Token `json:"temporaryToken,omitempty"`
Error *string `json:"error,omitempty"`
}{
ID: a.ID,
PsuID: a.PsuID,
ConnectorID: a.ConnectorID.String(),
CreatedAt: a.CreatedAt,
Status: string(a.Status),
State: a.State,
ClientRedirectURL: a.ClientRedirectURL,
TemporaryToken: a.TemporaryToken,
Error: a.Error,
})
}
func (a *OpenBankingConnectionAttempt) UnmarshalJSON(data []byte) error {
var aux struct {
ID uuid.UUID `json:"id"`
PsuID uuid.UUID `json:"psuID"`
ConnectorID string `json:"connectorID"`
CreatedAt time.Time `json:"createdAt"`
Status string `json:"status"`
State CallbackState `json:"state"`
ClientRedirectURL *string `json:"clientRedirectURL,omitempty"`
TemporaryToken *Token `json:"temporaryToken,omitempty"`
Error *string `json:"error,omitempty"`
}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
connectorID, err := ConnectorIDFromString(aux.ConnectorID)
if err != nil {
return err
}
a.ID = aux.ID
a.PsuID = aux.PsuID
a.ConnectorID = connectorID
a.CreatedAt = aux.CreatedAt
a.Status = OpenBankingConnectionAttemptStatus(aux.Status)
a.State = aux.State
a.ClientRedirectURL = aux.ClientRedirectURL
a.TemporaryToken = aux.TemporaryToken
a.Error = aux.Error
return nil
}
// Represents a psu forwarded to an open banking provider
type OpenBankingForwardedUser struct {
// ID of the psu
PsuID uuid.UUID `json:"psuID"`
// ID of the connector
ConnectorID ConnectorID `json:"connectorID"`
// Optional
// AccessToken is optional for some providers, like Powens, where we
// have a notion of connection, but we only have one token for all of them.
AccessToken *Token `json:"authToken"`
// ID of the user on the provider
PSPUserID *string `json:"pspUserID,omitempty"`
// per provider additional information
Metadata map[string]string `json:"metadata"`
}
type ConnectionStatus string
const (
ConnectionStatusActive ConnectionStatus = "ACTIVE"
ConnectionStatusError ConnectionStatus = "ERROR"
)
type PSPOpenBankingConnection struct {
// ID of the connection, given by the provider
ConnectionID string `json:"connectionID"`
// Creation date of the connection
CreatedAt time.Time `json:"createdAt"`
// Optional
// AccessToken is optional for some providers, like Powens, where we
// have a notion of connection, but we only have one token for all of them.
AccessToken *Token `json:"accessToken"`
// Additional information about the connection depending on the connector
Metadata map[string]string `json:"metadata"`
}
type OpenBankingConnection struct {
// ID of the connection, given by the provider
ConnectionID string `json:"connectionID"`
// Connector ID
ConnectorID ConnectorID `json:"connectorID"`
// Creation date of the connection
CreatedAt time.Time `json:"createdAt"`
// Date of the last update of the connection's data
DataUpdatedAt time.Time `json:"dataUpdatedAt"`
// Status of the connection
Status ConnectionStatus `json:"status"`
// Provider's Updated At
UpdatedAt time.Time `json:"updatedAt"`
// Optional
// AccessToken is optional for some provider, like Powens, where we
// have a notion of connection, but we only have one token for all of them.
AccessToken *Token `json:"accessToken"`
// Error message in case of failure
Error *string `json:"error"`
// Additional information about the connection depending on the connector
Metadata map[string]string `json:"metadata"`
}
func (connection OpenBankingConnection) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
ConnectionID string `json:"connectionID"`
ConnectorID string `json:"connectorID"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Status string `json:"status"`
AccessToken *Token `json:"accessToken"`
Metadata map[string]string `json:"metadata"`
Error *string `json:"error,omitempty"`
}{
ConnectionID: connection.ConnectionID,
ConnectorID: connection.ConnectorID.String(),
CreatedAt: connection.CreatedAt,
UpdatedAt: connection.UpdatedAt,
Status: string(connection.Status),
AccessToken: connection.AccessToken,
Metadata: connection.Metadata,
Error: connection.Error,
})
}
func (connection *OpenBankingConnection) UnmarshalJSON(data []byte) error {
var aux struct {
ConnectionID string `json:"connectionID"`
ConnectorID string `json:"connectorID"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Status string `json:"status"`
AccessToken *Token `json:"accessToken"`
Metadata map[string]string `json:"metadata"`
Error *string `json:"error,omitempty"`
}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
connectorID, err := ConnectorIDFromString(aux.ConnectorID)
if err != nil {
return err
}
connection.ConnectionID = aux.ConnectionID
connection.ConnectorID = connectorID
connection.CreatedAt = aux.CreatedAt
connection.UpdatedAt = aux.UpdatedAt
connection.Status = ConnectionStatus(aux.Status)
connection.AccessToken = aux.AccessToken
connection.Metadata = aux.Metadata
connection.Error = aux.Error
return nil
}
func ToPSPOpenBankingConnection(from OpenBankingConnection) PSPOpenBankingConnection {
return PSPOpenBankingConnection{
ConnectionID: from.ConnectionID,
CreatedAt: from.CreatedAt,
AccessToken: from.AccessToken,
Metadata: from.Metadata,
}
}
func FromPSPOpenBankingConnection(from PSPOpenBankingConnection, connectorID ConnectorID) OpenBankingConnection {
return OpenBankingConnection{
ConnectionID: from.ConnectionID,
ConnectorID: connectorID,
CreatedAt: from.CreatedAt,
UpdatedAt: from.CreatedAt,
DataUpdatedAt: time.Time{},
AccessToken: from.AccessToken,
Metadata: from.Metadata,
}
}