From ca677bd92a913c676ab53db9f2efe46060738b70 Mon Sep 17 00:00:00 2001 From: Paul Nicolas Date: Fri, 1 Dec 2023 12:00:33 +0100 Subject: [PATCH] feat(fctl): add fixes with payments 1.0.0 (#935) --- components/fctl/cmd/payments/accounts/list.go | 2 +- .../fctl/cmd/payments/bankaccounts/create.go | 18 ++- .../fctl/cmd/payments/bankaccounts/list.go | 18 ++- .../fctl/cmd/payments/bankaccounts/show.go | 27 +++- .../fctl/cmd/payments/connectors/getconfig.go | 136 ++++++++++-------- .../connectors/install/bankingcircle.go | 35 ++++- .../connectors/install/currencycloud.go | 21 ++- .../payments/connectors/install/mangopay.go | 21 ++- .../cmd/payments/connectors/install/modulr.go | 21 ++- .../payments/connectors/install/moneycorp.go | 21 ++- .../cmd/payments/connectors/install/stripe.go | 36 +++-- .../cmd/payments/connectors/install/wise.go | 23 ++- .../connectors/internal/connectors.go | 4 +- .../fctl/cmd/payments/connectors/list.go | 38 ++++- .../fctl/cmd/payments/connectors/uninstall.go | 102 +++++++++---- .../cmd/payments/connectors/views/banking.go | 30 ---- .../connectors/views/banking_circle.go | 56 ++++++++ .../views/{currency.go => currency_cloud.go} | 35 +++-- .../cmd/payments/connectors/views/mangopay.go | 49 +++++++ .../cmd/payments/connectors/views/modulr.go | 36 +++-- .../payments/connectors/views/moneycorp.go | 49 +++++++ .../cmd/payments/connectors/views/stripe.go | 22 ++- .../cmd/payments/connectors/views/wise.go | 22 ++- components/fctl/cmd/payments/payments/list.go | 2 +- .../cmd/payments/transferinitiation/create.go | 17 ++- .../cmd/payments/transferinitiation/delete.go | 18 ++- .../cmd/payments/transferinitiation/list.go | 22 ++- .../cmd/payments/transferinitiation/retry.go | 18 ++- .../cmd/payments/transferinitiation/show.go | 18 ++- .../transferinitiation/update_status.go | 18 ++- .../fctl/cmd/payments/versions/versions.go | 60 ++++++++ components/payments/openapi.yaml | 2 + openapi/build/generate.json | 5 +- .../pkg/models/shared/connectorsresponse.go | 1 + .../models/shared/ConnectorsResponseData.java | 11 ++ .../Models/Shared/ConnectorsResponseData.php | 6 + .../sdk/models/shared/connectorsresponse.py | 2 + .../sdk/models/shared/connectorsresponse.ts | 4 + 38 files changed, 826 insertions(+), 200 deletions(-) delete mode 100644 components/fctl/cmd/payments/connectors/views/banking.go create mode 100644 components/fctl/cmd/payments/connectors/views/banking_circle.go rename components/fctl/cmd/payments/connectors/views/{currency.go => currency_cloud.go} (55%) create mode 100644 components/fctl/cmd/payments/connectors/views/mangopay.go create mode 100644 components/fctl/cmd/payments/connectors/views/moneycorp.go create mode 100644 components/fctl/cmd/payments/versions/versions.go diff --git a/components/fctl/cmd/payments/accounts/list.go b/components/fctl/cmd/payments/accounts/list.go index ba2d4a271c..38baed78d6 100644 --- a/components/fctl/cmd/payments/accounts/list.go +++ b/components/fctl/cmd/payments/accounts/list.go @@ -81,7 +81,7 @@ func (c *ListController) Render(cmd *cobra.Command, args []string) error { acc.ID, acc.AccountName, acc.CreatedAt.Format(time.RFC3339), - string(acc.ConnectorID), + acc.ConnectorID, acc.DefaultAsset, acc.DefaultCurrency, acc.Reference, diff --git a/components/fctl/cmd/payments/bankaccounts/create.go b/components/fctl/cmd/payments/bankaccounts/create.go index 832d4c0389..91432ce16a 100644 --- a/components/fctl/cmd/payments/bankaccounts/create.go +++ b/components/fctl/cmd/payments/bankaccounts/create.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" + "github.com/formancehq/fctl/cmd/payments/versions" fctl "github.com/formancehq/fctl/pkg" "github.com/formancehq/formance-sdk-go/pkg/models/shared" "github.com/pkg/errors" @@ -15,9 +16,15 @@ type CreateStore struct { BankAccountID string `json:"bankAccountId"` } type CreateController struct { + PaymentsVersion versions.Version + store *CreateStore } +func (c *CreateController) SetVersion(version versions.Version) { + c.PaymentsVersion = version +} + var _ fctl.Controller[*CreateStore] = (*CreateController)(nil) func NewCreateStore() *CreateStore { @@ -31,11 +38,12 @@ func NewCreateController() *CreateController { } func NewCreateCommand() *cobra.Command { + c := NewCreateController() return fctl.NewCommand("create |-", fctl.WithShortDescription("Create a bank account"), fctl.WithAliases("cr", "c"), fctl.WithArgs(cobra.ExactArgs(1)), - fctl.WithController[*CreateStore](NewCreateController()), + fctl.WithController[*CreateStore](c), ) } @@ -44,6 +52,14 @@ func (c *CreateController) GetStore() *CreateStore { } func (c *CreateController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) { + if err := versions.GetPaymentsVersion(cmd, args, c); err != nil { + return nil, err + } + + if c.PaymentsVersion < versions.V1 { + return nil, fmt.Errorf("bank accounts are only supported in >= v1.0.0") + } + soc, err := fctl.GetStackOrganizationConfig(cmd) if err != nil { return nil, err diff --git a/components/fctl/cmd/payments/bankaccounts/list.go b/components/fctl/cmd/payments/bankaccounts/list.go index 78ada59a71..00e9a61700 100644 --- a/components/fctl/cmd/payments/bankaccounts/list.go +++ b/components/fctl/cmd/payments/bankaccounts/list.go @@ -4,6 +4,7 @@ import ( "fmt" "time" + "github.com/formancehq/fctl/cmd/payments/versions" fctl "github.com/formancehq/fctl/pkg" "github.com/formancehq/formance-sdk-go/pkg/models/operations" "github.com/formancehq/formance-sdk-go/pkg/models/shared" @@ -16,9 +17,15 @@ type ListStore struct { } type ListController struct { + PaymentsVersion versions.Version + store *ListStore } +func (c *ListController) SetVersion(version versions.Version) { + c.PaymentsVersion = version +} + var _ fctl.Controller[*ListStore] = (*ListController)(nil) func NewListStore() *ListStore { @@ -38,6 +45,14 @@ func (c *ListController) GetStore() *ListStore { } func (c *ListController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) { + if err := versions.GetPaymentsVersion(cmd, args, c); err != nil { + return nil, err + } + + if c.PaymentsVersion < versions.V1 { + return nil, fmt.Errorf("bank accounts are only supported in >= v1.0.0") + } + cfg, err := fctl.GetConfig(cmd) if err != nil { return nil, err @@ -93,10 +108,11 @@ func (c *ListController) Render(cmd *cobra.Command, args []string) error { } func NewListCommand() *cobra.Command { + c := NewListController() return fctl.NewCommand("list", fctl.WithAliases("ls", "l"), fctl.WithArgs(cobra.ExactArgs(0)), fctl.WithShortDescription("List bank accounts"), - fctl.WithController[*ListStore](NewListController()), + fctl.WithController[*ListStore](c), ) } diff --git a/components/fctl/cmd/payments/bankaccounts/show.go b/components/fctl/cmd/payments/bankaccounts/show.go index 73642f968c..1c848b4606 100644 --- a/components/fctl/cmd/payments/bankaccounts/show.go +++ b/components/fctl/cmd/payments/bankaccounts/show.go @@ -4,6 +4,7 @@ import ( "fmt" "time" + "github.com/formancehq/fctl/cmd/payments/versions" fctl "github.com/formancehq/fctl/pkg" "github.com/formancehq/formance-sdk-go/pkg/models/operations" "github.com/formancehq/formance-sdk-go/pkg/models/shared" @@ -15,9 +16,15 @@ type ShowStore struct { BankAccount *shared.BankAccount `json:"bankAccount"` } type ShowController struct { + PaymentsVersion versions.Version + store *ShowStore } +func (c *ShowController) SetVersion(version versions.Version) { + c.PaymentsVersion = version +} + var _ fctl.Controller[*ShowStore] = (*ShowController)(nil) func NewShowStore() *ShowStore { @@ -31,11 +38,12 @@ func NewShowController() *ShowController { } func NewShowCommand() *cobra.Command { + c := NewShowController() return fctl.NewCommand("get ", fctl.WithShortDescription("Get bank account"), fctl.WithArgs(cobra.ExactArgs(1)), fctl.WithAliases("sh", "s"), - fctl.WithController[*ShowStore](NewShowController()), + fctl.WithController[*ShowStore](c), ) } @@ -44,6 +52,14 @@ func (c *ShowController) GetStore() *ShowStore { } func (c *ShowController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) { + if err := versions.GetPaymentsVersion(cmd, args, c); err != nil { + return nil, err + } + + if c.PaymentsVersion < versions.V1 { + return nil, fmt.Errorf("bank accounts are only supported in >= v1.0.0") + } + cfg, err := fctl.GetConfig(cmd) if err != nil { return nil, err @@ -87,6 +103,15 @@ func (c *ShowController) Render(cmd *cobra.Command, args []string) error { tableData = append(tableData, []string{pterm.LightCyan("CreatedAt"), c.store.BankAccount.CreatedAt.Format(time.RFC3339)}) tableData = append(tableData, []string{pterm.LightCyan("Country"), c.store.BankAccount.Country}) tableData = append(tableData, []string{pterm.LightCyan("ConnectorID"), string(c.store.BankAccount.ConnectorID)}) + if c.store.BankAccount.AccountNumber != nil { + tableData = append(tableData, []string{pterm.LightCyan("AccountNumber"), *c.store.BankAccount.AccountNumber}) + } + if c.store.BankAccount.Iban != nil { + tableData = append(tableData, []string{pterm.LightCyan("Iban"), *c.store.BankAccount.Iban}) + } + if c.store.BankAccount.SwiftBicCode != nil { + tableData = append(tableData, []string{pterm.LightCyan("SwiftBicCode"), *c.store.BankAccount.SwiftBicCode}) + } if err := pterm.DefaultTable. WithWriter(cmd.OutOrStdout()). diff --git a/components/fctl/cmd/payments/connectors/getconfig.go b/components/fctl/cmd/payments/connectors/getconfig.go index f21708cec2..1f0bcb9072 100644 --- a/components/fctl/cmd/payments/connectors/getconfig.go +++ b/components/fctl/cmd/payments/connectors/getconfig.go @@ -1,11 +1,12 @@ package connectors import ( - "errors" "fmt" + "strings" "github.com/formancehq/fctl/cmd/payments/connectors/internal" "github.com/formancehq/fctl/cmd/payments/connectors/views" + "github.com/formancehq/fctl/cmd/payments/versions" fctl "github.com/formancehq/fctl/pkg" "github.com/formancehq/formance-sdk-go/pkg/models/operations" "github.com/formancehq/formance-sdk-go/pkg/models/shared" @@ -19,10 +20,20 @@ var ( type PaymentsGetConfigStore struct { ConnectorConfig *shared.ConnectorConfigResponse `json:"connectorConfig"` + Provider string `json:"provider"` + ConnectorID string `json:"connectorId"` } type PaymentsGetConfigController struct { + PaymentsVersion versions.Version + store *PaymentsGetConfigStore - args []string + + providerNameFlag string + connectorIDFlag string +} + +func (c *PaymentsGetConfigController) SetVersion(version versions.Version) { + c.PaymentsVersion = version } var _ fctl.Controller[*PaymentsGetConfigStore] = (*PaymentsGetConfigController)(nil) @@ -33,17 +44,22 @@ func NewDefaultPaymentsGetConfigStore() *PaymentsGetConfigStore { func NewPaymentsGetConfigController() *PaymentsGetConfigController { return &PaymentsGetConfigController{ - store: NewDefaultPaymentsGetConfigStore(), + store: NewDefaultPaymentsGetConfigStore(), + providerNameFlag: "provider", + connectorIDFlag: "connector-id", } } func NewGetConfigCommand() *cobra.Command { - return fctl.NewCommand("get-config ", + c := NewPaymentsGetConfigController() + return fctl.NewCommand("get-config", fctl.WithAliases("getconfig", "getconf", "gc", "get", "g"), - fctl.WithArgs(cobra.ExactArgs(1)), + fctl.WithArgs(cobra.ExactArgs(0)), fctl.WithValidArgs(connectorsAvailable...), + fctl.WithStringFlag("provider", "", "Provider name"), + fctl.WithStringFlag("connector-id", "", "Connector ID"), fctl.WithShortDescription(fmt.Sprintf("Read a connector config (Connectors available: %s)", connectorsAvailable)), - fctl.WithController[*PaymentsGetConfigStore](NewPaymentsGetConfigController()), + fctl.WithController[*PaymentsGetConfigStore](c), ) } @@ -52,6 +68,12 @@ func (c *PaymentsGetConfigController) GetStore() *PaymentsGetConfigStore { } func (c *PaymentsGetConfigController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) { + if err := versions.GetPaymentsVersion(cmd, args, c); err != nil { + return nil, err + } + + provider := fctl.GetString(cmd, c.providerNameFlag) + connectorID := fctl.GetString(cmd, c.connectorIDFlag) cfg, err := fctl.GetConfig(cmd) if err != nil { @@ -73,20 +95,52 @@ func (c *PaymentsGetConfigController) Run(cmd *cobra.Command, args []string) (fc return nil, err } - response, err := client.Payments.ReadConnectorConfig(cmd.Context(), operations.ReadConnectorConfigRequest{ - Connector: shared.Connector(args[0]), - }) - if err != nil { - return nil, err - } - - if response.StatusCode >= 300 { - return nil, fmt.Errorf("unexpected status code: %d", response.StatusCode) + switch c.PaymentsVersion { + case versions.V0: + if provider == "" { + return nil, fmt.Errorf("provider is required") + } + + response, err := client.Payments.ReadConnectorConfig(cmd.Context(), operations.ReadConnectorConfigRequest{ + Connector: shared.Connector(provider), + }) + if err != nil { + return nil, err + } + + if response.StatusCode >= 300 { + return nil, fmt.Errorf("unexpected status code: %d", response.StatusCode) + } + + c.store.Provider = provider + c.store.ConnectorConfig = response.ConnectorConfigResponse + + case versions.V1: + if provider == "" { + return nil, fmt.Errorf("provider is required") + } + + if connectorID == "" { + return nil, fmt.Errorf("connector-id is required") + } + + response, err := client.Payments.ReadConnectorConfigV1(cmd.Context(), operations.ReadConnectorConfigV1Request{ + Connector: shared.Connector(provider), + ConnectorID: connectorID, + }) + if err != nil { + return nil, err + } + + if response.StatusCode >= 300 { + return nil, fmt.Errorf("unexpected status code: %d", response.StatusCode) + } + + c.store.Provider = provider + c.store.ConnectorID = connectorID + c.store.ConnectorConfig = response.ConnectorConfigResponse } - c.args = args - c.store.ConnectorConfig = response.ConnectorConfigResponse - return c, err } @@ -95,7 +149,7 @@ func (c *PaymentsGetConfigController) Run(cmd *cobra.Command, args []string) (fc func (c *PaymentsGetConfigController) Render(cmd *cobra.Command, args []string) error { var err error - switch c.args[0] { + switch strings.ToLower(c.store.Provider) { case internal.StripeConnector: err = views.DisplayStripeConfig(cmd, c.store.ConnectorConfig) case internal.ModulrConnector: @@ -106,6 +160,10 @@ func (c *PaymentsGetConfigController) Render(cmd *cobra.Command, args []string) err = views.DisplayCurrencyCloudConfig(cmd, c.store.ConnectorConfig) case internal.WiseConnector: err = views.DisplayWiseConfig(cmd, c.store.ConnectorConfig) + case internal.MangoPayConnector: + err = views.DisplayMangopayConfig(cmd, c.store.ConnectorConfig) + case internal.MoneycorpConnector: + err = views.DisplayMoneycorpConfig(cmd, c.store.ConnectorConfig) default: pterm.Error.WithWriter(cmd.OutOrStderr()).Printfln("Connection unknown.") } @@ -113,43 +171,3 @@ func (c *PaymentsGetConfigController) Render(cmd *cobra.Command, args []string) return err } - -func displayMangoPayConfig(cmd *cobra.Command, connectorConfig *shared.ConnectorConfigResponse) error { - config, ok := connectorConfig.Data.(*shared.MangoPayConfig) - if !ok { - return errors.New("invalid currency cloud connector config") - } - - tableData := pterm.TableData{} - tableData = append(tableData, []string{pterm.LightCyan("API key:"), config.APIKey}) - tableData = append(tableData, []string{pterm.LightCyan("Client ID:"), config.ClientID}) - tableData = append(tableData, []string{pterm.LightCyan("Endpoint:"), config.Endpoint}) - - if err := pterm.DefaultTable. - WithWriter(cmd.OutOrStdout()). - WithData(tableData). - Render(); err != nil { - return err - } - return nil -} - -func displayMoneycorpConfig(cmd *cobra.Command, connectorConfig *shared.ConnectorConfigResponse) error { - config, ok := connectorConfig.Data.(*shared.MoneycorpConfig) - if !ok { - return errors.New("invalid currency cloud connector config") - } - - tableData := pterm.TableData{} - tableData = append(tableData, []string{pterm.LightCyan("API key:"), config.APIKey}) - tableData = append(tableData, []string{pterm.LightCyan("Client ID:"), config.ClientID}) - tableData = append(tableData, []string{pterm.LightCyan("Endpoint:"), config.Endpoint}) - - if err := pterm.DefaultTable. - WithWriter(cmd.OutOrStdout()). - WithData(tableData). - Render(); err != nil { - return err - } - return nil -} diff --git a/components/fctl/cmd/payments/connectors/install/bankingcircle.go b/components/fctl/cmd/payments/connectors/install/bankingcircle.go index 9a71695b5a..3a6bc41cb3 100644 --- a/components/fctl/cmd/payments/connectors/install/bankingcircle.go +++ b/components/fctl/cmd/payments/connectors/install/bankingcircle.go @@ -15,6 +15,7 @@ import ( type PaymentsConnectorsBankingCircleStore struct { Success bool `json:"success"` ConnectorName string `json:"connectorName"` + ConnectorID string `json:"connectorId"` } type PaymentsConnectorsBankingCircleController struct { store *PaymentsConnectorsBankingCircleStore @@ -24,6 +25,8 @@ type PaymentsConnectorsBankingCircleController struct { defaultAuthorizationEndpoint string pollingPeriodFlag string defaultpollingPeriod string + nameFlag string + defaultName string } var _ fctl.Controller[*PaymentsConnectorsBankingCircleStore] = (*PaymentsConnectorsBankingCircleController)(nil) @@ -43,17 +46,20 @@ func NewPaymentsConnectorsBankingCircleController() *PaymentsConnectorsBankingCi defaultAuthorizationEndpoint: "https://authorizationsandbox.bankingcircleconnect.com", pollingPeriodFlag: "polling-period", defaultpollingPeriod: "2m", + nameFlag: "name", + defaultName: "bankingcircle", } } func NewBankingCircleCommand() *cobra.Command { c := NewPaymentsConnectorsBankingCircleController() - return fctl.NewCommand(internal.BankingCircleConnector+" ", + return fctl.NewCommand(internal.BankingCircleConnector+" ", fctl.WithShortDescription("Install a Banking Circle connector"), - fctl.WithArgs(cobra.ExactArgs(2)), + fctl.WithArgs(cobra.ExactArgs(4)), fctl.WithStringFlag(c.endpointFlag, c.defaultEndpoint, "API endpoint"), fctl.WithStringFlag(c.authorizationEndpointFlag, c.defaultAuthorizationEndpoint, "Authorization endpoint"), fctl.WithStringFlag(c.pollingPeriodFlag, c.defaultpollingPeriod, "Polling duration"), + fctl.WithStringFlag(c.nameFlag, c.defaultName, "Connector name"), fctl.WithController[*PaymentsConnectorsBankingCircleStore](c), ) } @@ -73,11 +79,23 @@ func (c *PaymentsConnectorsBankingCircleController) Run(cmd *cobra.Command, args return nil, err } + cert, err := fctl.ReadFile(cmd, soc.Stack, args[2]) + if err != nil { + return nil, err + } + + certKey, err := fctl.ReadFile(cmd, soc.Stack, args[3]) + if err != nil { + return nil, err + } + request := operations.InstallConnectorRequest{ Connector: shared.ConnectorBankingCircle, - RequestBody: shared.BankingCircleConfig{ + RequestBody: &shared.BankingCircleConfig{ Username: args[0], Password: args[1], + UserCertificate: cert, + UserCertificateKey: certKey, Endpoint: fctl.GetString(cmd, c.endpointFlag), AuthorizationEndpoint: fctl.GetString(cmd, c.authorizationEndpointFlag), PollingPeriod: fctl.Ptr(fctl.GetString(cmd, c.pollingPeriodFlag)), @@ -95,12 +113,19 @@ func (c *PaymentsConnectorsBankingCircleController) Run(cmd *cobra.Command, args c.store.Success = true c.store.ConnectorName = internal.BankingCircleConnector + if response.ConnectorResponse != nil { + c.store.ConnectorID = response.ConnectorResponse.Data.ConnectorID + } + return c, nil } func (c *PaymentsConnectorsBankingCircleController) Render(cmd *cobra.Command, args []string) error { - - pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("Connector '%s' installed!", c.store.ConnectorName) + if c.store.ConnectorID == "" { + pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("%s: connector installed!", c.store.ConnectorName) + } else { + pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("%s: connector '%s' installed!", c.store.ConnectorName, c.store.ConnectorID) + } return nil } diff --git a/components/fctl/cmd/payments/connectors/install/currencycloud.go b/components/fctl/cmd/payments/connectors/install/currencycloud.go index 45dc96f0e1..a34a39cb60 100644 --- a/components/fctl/cmd/payments/connectors/install/currencycloud.go +++ b/components/fctl/cmd/payments/connectors/install/currencycloud.go @@ -15,6 +15,7 @@ import ( type PaymentsConnectorsCurrencyCloudStore struct { Success bool `json:"success"` ConnectorName string `json:"connectorName"` + ConnectorID string `json:"connectorId"` } type PaymentsConnectorsCurrencyCloudController struct { store *PaymentsConnectorsCurrencyCloudStore @@ -22,6 +23,8 @@ type PaymentsConnectorsCurrencyCloudController struct { defaultEndpoint string pollingPeriodFlag string defaultpollingPeriod string + nameFlag string + defaultName string } var _ fctl.Controller[*PaymentsConnectorsCurrencyCloudStore] = (*PaymentsConnectorsCurrencyCloudController)(nil) @@ -39,6 +42,8 @@ func NewPaymentsConnectorsCurrencyCloudController() *PaymentsConnectorsCurrencyC defaultEndpoint: "https://devapi.currencycloud.com", pollingPeriodFlag: "polling-period", defaultpollingPeriod: "2m", + nameFlag: "name", + defaultName: "currencycloud", } } @@ -49,6 +54,7 @@ func NewCurrencyCloudCommand() *cobra.Command { fctl.WithArgs(cobra.ExactArgs(2)), fctl.WithStringFlag(c.endpointFlag, c.defaultEndpoint, "API endpoint"), fctl.WithStringFlag(c.pollingPeriodFlag, c.defaultpollingPeriod, "Polling duration"), + fctl.WithStringFlag(c.nameFlag, c.defaultName, "Connector name"), fctl.WithController[*PaymentsConnectorsCurrencyCloudStore](c), ) } @@ -58,7 +64,6 @@ func (c *PaymentsConnectorsCurrencyCloudController) GetStore() *PaymentsConnecto } func (c *PaymentsConnectorsCurrencyCloudController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) { - soc, err := fctl.GetStackOrganizationConfigApprobation(cmd, "You are about to install connector '%s'", internal.CurrencyCloudConnector) if err != nil { return nil, fctl.ErrMissingApproval @@ -75,7 +80,8 @@ func (c *PaymentsConnectorsCurrencyCloudController) Run(cmd *cobra.Command, args } response, err := paymentsClient.Payments.InstallConnector(cmd.Context(), operations.InstallConnectorRequest{ - RequestBody: shared.CurrencyCloudConfig{ + RequestBody: &shared.CurrencyCloudConfig{ + Name: fctl.GetString(cmd, c.nameFlag), APIKey: args[1], LoginID: args[0], Endpoint: endpoint, @@ -94,12 +100,19 @@ func (c *PaymentsConnectorsCurrencyCloudController) Run(cmd *cobra.Command, args c.store.Success = true c.store.ConnectorName = internal.CurrencyCloudConnector + if response.ConnectorResponse != nil { + c.store.ConnectorID = response.ConnectorResponse.Data.ConnectorID + } + return c, nil } func (c *PaymentsConnectorsCurrencyCloudController) Render(cmd *cobra.Command, args []string) error { - - pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("Connector '%s' installed!", c.store.ConnectorName) + if c.store.ConnectorID == "" { + pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("%s: connector installed!", c.store.ConnectorName) + } else { + pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("%s: connector '%s' installed!", c.store.ConnectorName, c.store.ConnectorID) + } return nil } diff --git a/components/fctl/cmd/payments/connectors/install/mangopay.go b/components/fctl/cmd/payments/connectors/install/mangopay.go index 2e1867e3ab..bb8b59944e 100644 --- a/components/fctl/cmd/payments/connectors/install/mangopay.go +++ b/components/fctl/cmd/payments/connectors/install/mangopay.go @@ -15,6 +15,7 @@ import ( type PaymentsConnectorsMangoPayStore struct { Success bool `json:"success"` ConnectorName string `json:"connectorName"` + ConnectorID string `json:"connectorId"` } type PaymentsConnectorsMangoPayController struct { store *PaymentsConnectorsMangoPayStore @@ -22,6 +23,8 @@ type PaymentsConnectorsMangoPayController struct { defaultEndpoint string pollingPeriodFlag string defaultpollingPeriod string + nameFlag string + defaultName string } func NewDefaultPaymentsConnectorsMangoPayStore() *PaymentsConnectorsMangoPayStore { @@ -37,6 +40,8 @@ func NewPaymentsConnectorsMangoPayController() *PaymentsConnectorsMangoPayContro defaultEndpoint: "https://api.sandbox.mangopay.com", pollingPeriodFlag: "polling-period", defaultpollingPeriod: "2m", + nameFlag: "name", + defaultName: "mangopay", } } @@ -47,6 +52,7 @@ func NewMangoPayCommand() *cobra.Command { fctl.WithArgs(cobra.ExactArgs(2)), fctl.WithStringFlag(c.endpointFlag, c.defaultEndpoint, "API endpoint"), fctl.WithStringFlag(c.pollingPeriodFlag, c.defaultpollingPeriod, "Polling duration"), + fctl.WithStringFlag(c.nameFlag, c.defaultName, "Connector name"), fctl.WithController[*PaymentsConnectorsMangoPayStore](c), ) } @@ -82,11 +88,12 @@ func (c *PaymentsConnectorsMangoPayController) Run(cmd *cobra.Command, args []st request := operations.InstallConnectorRequest{ Connector: shared.ConnectorMangopay, - RequestBody: shared.MangoPayConfig{ + RequestBody: &shared.MangoPayConfig{ ClientID: args[0], APIKey: args[1], Endpoint: fctl.GetString(cmd, c.endpointFlag), PollingPeriod: fctl.Ptr(fctl.GetString(cmd, c.pollingPeriodFlag)), + Name: fctl.GetString(cmd, c.nameFlag), }, } response, err := paymentsClient.Payments.InstallConnector(cmd.Context(), request) @@ -99,13 +106,21 @@ func (c *PaymentsConnectorsMangoPayController) Run(cmd *cobra.Command, args []st } c.store.Success = true + c.store.ConnectorName = internal.MangoPayConnector + + if response.ConnectorResponse != nil { + c.store.ConnectorID = response.ConnectorResponse.Data.ConnectorID + } return c, nil } func (c *PaymentsConnectorsMangoPayController) Render(cmd *cobra.Command, args []string) error { - - pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("Connector %s installed!", c.store.ConnectorName) + if c.store.ConnectorID == "" { + pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("%s: connector installed!", c.store.ConnectorName) + } else { + pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("%s: connector '%s' installed!", c.store.ConnectorName, c.store.ConnectorID) + } return nil } diff --git a/components/fctl/cmd/payments/connectors/install/modulr.go b/components/fctl/cmd/payments/connectors/install/modulr.go index 008fc88a6d..dab05c853c 100644 --- a/components/fctl/cmd/payments/connectors/install/modulr.go +++ b/components/fctl/cmd/payments/connectors/install/modulr.go @@ -15,13 +15,17 @@ import ( type PaymentsConnectorsModulrStore struct { Success bool `json:"success"` ConnectorName string `json:"connectorName"` + ConnectorID string `json:"connectorId"` } + type PaymentsConnectorsModulrController struct { store *PaymentsConnectorsModulrStore endpointFlag string defaultEndpoint string pollingPeriodFlag string defaultpollingPeriod string + nameFlag string + defaultName string } var _ fctl.Controller[*PaymentsConnectorsModulrStore] = (*PaymentsConnectorsModulrController)(nil) @@ -39,6 +43,8 @@ func NewPaymentsConnectorsModulrController() *PaymentsConnectorsModulrController defaultEndpoint: "https://api-sandbox.modulrfinance.com", pollingPeriodFlag: "polling-period", defaultpollingPeriod: "2m", + nameFlag: "name", + defaultName: "modulr", } } @@ -49,6 +55,7 @@ func NewModulrCommand() *cobra.Command { fctl.WithArgs(cobra.ExactArgs(2)), fctl.WithStringFlag(c.endpointFlag, c.defaultEndpoint, "API endpoint"), fctl.WithStringFlag(c.pollingPeriodFlag, c.defaultpollingPeriod, "Polling duration"), + fctl.WithStringFlag(c.nameFlag, c.defaultName, "Connector name"), fctl.WithController[*PaymentsConnectorsModulrStore](c), ) } @@ -74,7 +81,8 @@ func (c *PaymentsConnectorsModulrController) Run(cmd *cobra.Command, args []stri } response, err := paymentsClient.Payments.InstallConnector(cmd.Context(), operations.InstallConnectorRequest{ - RequestBody: shared.ModulrConfig{ + RequestBody: &shared.ModulrConfig{ + Name: fctl.GetString(cmd, c.nameFlag), APIKey: args[0], APISecret: args[1], Endpoint: endpoint, @@ -93,12 +101,19 @@ func (c *PaymentsConnectorsModulrController) Run(cmd *cobra.Command, args []stri c.store.Success = true c.store.ConnectorName = internal.ModulrConnector + if response.ConnectorResponse != nil { + c.store.ConnectorID = response.ConnectorResponse.Data.ConnectorID + } + return c, nil } func (c *PaymentsConnectorsModulrController) Render(cmd *cobra.Command, args []string) error { - - pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("Connector '%s' installed!", c.store.ConnectorName) + if c.store.ConnectorID == "" { + pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("%s: connector installed!", c.store.ConnectorName) + } else { + pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("%s: connector '%s' installed!", c.store.ConnectorName, c.store.ConnectorID) + } return nil } diff --git a/components/fctl/cmd/payments/connectors/install/moneycorp.go b/components/fctl/cmd/payments/connectors/install/moneycorp.go index 431befbf9c..379e445a4b 100644 --- a/components/fctl/cmd/payments/connectors/install/moneycorp.go +++ b/components/fctl/cmd/payments/connectors/install/moneycorp.go @@ -15,6 +15,7 @@ import ( type PaymentsConnectorsMoneycorpStore struct { Success bool `json:"success"` ConnectorName string `json:"connectorName"` + ConnectorID string `json:"connectorId"` } type PaymentsConnectorsMoneycorpController struct { store *PaymentsConnectorsMoneycorpStore @@ -22,6 +23,8 @@ type PaymentsConnectorsMoneycorpController struct { defaultEndpoint string pollingPeriodFlag string defaultpollingPeriod string + nameFlag string + defaultName string } func NewDefaultPaymentsConnectorsMoneycorpStore() *PaymentsConnectorsMoneycorpStore { @@ -37,6 +40,8 @@ func NewPaymentsConnectorsMoneycorpController() *PaymentsConnectorsMoneycorpCont defaultEndpoint: "https://sandbox-corpapi.moneycorp.com", pollingPeriodFlag: "polling-period", defaultpollingPeriod: "2m", + nameFlag: "name", + defaultName: "moneycorp", } } func NewMoneycorpCommand() *cobra.Command { @@ -47,6 +52,7 @@ func NewMoneycorpCommand() *cobra.Command { fctl.WithArgs(cobra.ExactArgs(2)), fctl.WithStringFlag(c.endpointFlag, c.defaultEndpoint, "API endpoint"), fctl.WithStringFlag(c.pollingPeriodFlag, c.defaultpollingPeriod, "Polling duration"), + fctl.WithStringFlag(c.nameFlag, c.defaultName, "Connector name"), fctl.WithController[*PaymentsConnectorsMoneycorpStore](c), ) } @@ -82,7 +88,8 @@ func (c *PaymentsConnectorsMoneycorpController) Run(cmd *cobra.Command, args []s request := operations.InstallConnectorRequest{ Connector: shared.ConnectorMoneycorp, - RequestBody: shared.MoneycorpConfig{ + RequestBody: &shared.MoneycorpConfig{ + Name: fctl.GetString(cmd, c.nameFlag), ClientID: args[0], APIKey: args[1], Endpoint: fctl.GetString(cmd, c.endpointFlag), @@ -101,13 +108,21 @@ func (c *PaymentsConnectorsMoneycorpController) Run(cmd *cobra.Command, args []s pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("Connector installed!") c.store.Success = true + c.store.ConnectorName = internal.MoneycorpConnector + + if response.ConnectorResponse != nil { + c.store.ConnectorID = response.ConnectorResponse.Data.ConnectorID + } return c, nil } func (c *PaymentsConnectorsMoneycorpController) Render(cmd *cobra.Command, args []string) error { - - pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("Connector %s installed!", c.store.ConnectorName) + if c.store.ConnectorID == "" { + pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("%s: connector installed!", c.store.ConnectorName) + } else { + pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("%s: connector '%s' installed!", c.store.ConnectorName, c.store.ConnectorID) + } return nil } diff --git a/components/fctl/cmd/payments/connectors/install/stripe.go b/components/fctl/cmd/payments/connectors/install/stripe.go index 17e6f4f3c5..af1d2e064a 100644 --- a/components/fctl/cmd/payments/connectors/install/stripe.go +++ b/components/fctl/cmd/payments/connectors/install/stripe.go @@ -15,10 +15,15 @@ import ( type PaymentsConnectorsStripeStore struct { Success bool `json:"success"` ConnectorName string `json:"connectorName"` + ConnectorID string `json:"connectorId"` } type PaymentsConnectorsStripeController struct { - store *PaymentsConnectorsStripeStore - stripeApiKeyFlag string + store *PaymentsConnectorsStripeStore + stripeApiKeyFlag string + pollingPeriodFlag string + defaultpollingPeriod string + nameFlag string + defaultName string } var _ fctl.Controller[*PaymentsConnectorsStripeStore] = (*PaymentsConnectorsStripeController)(nil) @@ -31,8 +36,12 @@ func NewDefaultPaymentsConnectorsStripeStore() *PaymentsConnectorsStripeStore { func NewPaymentsConnectorsStripeController() *PaymentsConnectorsStripeController { return &PaymentsConnectorsStripeController{ - store: NewDefaultPaymentsConnectorsStripeStore(), - stripeApiKeyFlag: "api-key", + store: NewDefaultPaymentsConnectorsStripeStore(), + stripeApiKeyFlag: "api-key", + pollingPeriodFlag: "polling-period", + defaultpollingPeriod: "2m", + nameFlag: "name", + defaultName: "stripe", } } @@ -43,6 +52,8 @@ func NewStripeCommand() *cobra.Command { fctl.WithConfirmFlag(), fctl.WithArgs(cobra.ExactArgs(1)), fctl.WithStringFlag(c.stripeApiKeyFlag, "", "Stripe API key"), + fctl.WithStringFlag(c.pollingPeriodFlag, c.defaultpollingPeriod, "Polling duration"), + fctl.WithStringFlag(c.nameFlag, c.defaultName, "Connector name"), fctl.WithController[*PaymentsConnectorsStripeStore](c), ) } @@ -63,8 +74,10 @@ func (c *PaymentsConnectorsStripeController) Run(cmd *cobra.Command, args []stri } response, err := paymentsClient.Payments.InstallConnector(cmd.Context(), operations.InstallConnectorRequest{ - RequestBody: shared.StripeConfig{ - APIKey: args[0], + RequestBody: &shared.StripeConfig{ + Name: fctl.GetString(cmd, c.nameFlag), + APIKey: args[0], + PollingPeriod: fctl.Ptr(fctl.GetString(cmd, c.pollingPeriodFlag)), }, Connector: shared.ConnectorStripe, }) @@ -79,12 +92,19 @@ func (c *PaymentsConnectorsStripeController) Run(cmd *cobra.Command, args []stri c.store.Success = true c.store.ConnectorName = internal.StripeConnector + if response.ConnectorResponse != nil { + c.store.ConnectorID = response.ConnectorResponse.Data.ConnectorID + } + return c, nil } func (c *PaymentsConnectorsStripeController) Render(cmd *cobra.Command, args []string) error { - - pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("Connector '%s' installed!", c.store.ConnectorName) + if c.store.ConnectorID == "" { + pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("%s: connector installed!", c.store.ConnectorName) + } else { + pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("%s: connector '%s' installed!", c.store.ConnectorName, c.store.ConnectorID) + } return nil } diff --git a/components/fctl/cmd/payments/connectors/install/wise.go b/components/fctl/cmd/payments/connectors/install/wise.go index 7fcb0b6498..827daebf4d 100644 --- a/components/fctl/cmd/payments/connectors/install/wise.go +++ b/components/fctl/cmd/payments/connectors/install/wise.go @@ -15,11 +15,14 @@ import ( type PaymentsConnectorsWiseStore struct { Success bool `json:"success"` ConnectorName string `json:"connectorName"` + ConnectorID string `json:"connectorId"` } type PaymentsConnectorsWiseController struct { store *PaymentsConnectorsWiseStore pollingPeriodFlag string defaultpollingPeriod string + nameFlag string + defaultName string } var _ fctl.Controller[*PaymentsConnectorsWiseStore] = (*PaymentsConnectorsWiseController)(nil) @@ -35,6 +38,8 @@ func NewPaymentsConnectorsWiseController() *PaymentsConnectorsWiseController { store: NewDefaultPaymentsConnectorsWiseStore(), pollingPeriodFlag: "polling-period", defaultpollingPeriod: "2m", + nameFlag: "name", + defaultName: "wise", } } @@ -44,6 +49,7 @@ func NewWiseCommand() *cobra.Command { fctl.WithShortDescription("Install a Wise connector"), fctl.WithArgs(cobra.ExactArgs(1)), fctl.WithStringFlag(c.pollingPeriodFlag, c.defaultpollingPeriod, "Polling duration"), + fctl.WithStringFlag(c.nameFlag, c.defaultName, "Connector name"), fctl.WithController[*PaymentsConnectorsWiseStore](c), ) } @@ -64,8 +70,9 @@ func (c *PaymentsConnectorsWiseController) Run(cmd *cobra.Command, args []string } response, err := paymentsClient.Payments.InstallConnector(cmd.Context(), operations.InstallConnectorRequest{ - RequestBody: shared.WiseConfig{ - APIKey: args[1], + RequestBody: &shared.WiseConfig{ + Name: fctl.GetString(cmd, c.nameFlag), + APIKey: args[0], PollingPeriod: fctl.Ptr(fctl.GetString(cmd, c.pollingPeriodFlag)), }, Connector: shared.ConnectorWise, @@ -81,12 +88,18 @@ func (c *PaymentsConnectorsWiseController) Run(cmd *cobra.Command, args []string c.store.Success = true c.store.ConnectorName = internal.WiseConnector + if response.ConnectorResponse != nil { + c.store.ConnectorID = response.ConnectorResponse.Data.ConnectorID + } + return c, nil } func (c *PaymentsConnectorsWiseController) Render(cmd *cobra.Command, args []string) error { - - pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("Connector '%s' installed!", c.store.ConnectorName) - + if c.store.ConnectorID == "" { + pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("%s: connector installed!", c.store.ConnectorName) + } else { + pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("%s: connector '%s' installed!", c.store.ConnectorName, c.store.ConnectorID) + } return nil } diff --git a/components/fctl/cmd/payments/connectors/internal/connectors.go b/components/fctl/cmd/payments/connectors/internal/connectors.go index cf967b3472..48ea74b6b9 100644 --- a/components/fctl/cmd/payments/connectors/internal/connectors.go +++ b/components/fctl/cmd/payments/connectors/internal/connectors.go @@ -1,8 +1,8 @@ package internal const ( - BankingCircleConnector = "bankingcircle" - CurrencyCloudConnector = "currencycloud" + BankingCircleConnector = "banking-circle" + CurrencyCloudConnector = "currency-cloud" ModulrConnector = "modulr" StripeConnector = "stripe" WiseConnector = "wise" diff --git a/components/fctl/cmd/payments/connectors/list.go b/components/fctl/cmd/payments/connectors/list.go index 98d4c22a90..50d7821882 100644 --- a/components/fctl/cmd/payments/connectors/list.go +++ b/components/fctl/cmd/payments/connectors/list.go @@ -3,6 +3,7 @@ package connectors import ( "fmt" + "github.com/formancehq/fctl/cmd/payments/versions" fctl "github.com/formancehq/fctl/pkg" "github.com/formancehq/formance-sdk-go/pkg/models/shared" "github.com/pterm/pterm" @@ -17,9 +18,15 @@ type PaymentsConnectorsListStore struct { Connectors []shared.ConnectorsResponseData `json:"connectors"` } type PaymentsConnectorsListController struct { + PaymentsVersion versions.Version + store *PaymentsConnectorsListStore } +func (c *PaymentsConnectorsListController) SetVersion(version versions.Version) { + c.PaymentsVersion = version +} + var _ fctl.Controller[*PaymentsConnectorsListStore] = (*PaymentsConnectorsListController)(nil) func NewDefaultPaymentsConnectorsListStore() *PaymentsConnectorsListStore { @@ -35,10 +42,11 @@ func NewPaymentsConnectorsListController() *PaymentsConnectorsListController { } func NewListCommand() *cobra.Command { + c := NewPaymentsConnectorsListController() return fctl.NewCommand("list", fctl.WithAliases("ls", "l"), fctl.WithShortDescription("List all enabled connectors"), - fctl.WithController[*PaymentsConnectorsListStore](NewPaymentsConnectorsListController()), + fctl.WithController[*PaymentsConnectorsListStore](c), ) } @@ -47,6 +55,9 @@ func (c *PaymentsConnectorsListController) GetStore() *PaymentsConnectorsListSto } func (c *PaymentsConnectorsListController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) { + if err := versions.GetPaymentsVersion(cmd, args, c); err != nil { + return nil, err + } cfg, err := fctl.GetConfig(cmd) if err != nil { @@ -88,13 +99,28 @@ func (c *PaymentsConnectorsListController) Run(cmd *cobra.Command, args []string func (c *PaymentsConnectorsListController) Render(cmd *cobra.Command, args []string) error { tableData := fctl.Map(c.store.Connectors, func(connector shared.ConnectorsResponseData) []string { - return []string{ - connector.ConnectorID, - connector.Name, - string(connector.Provider), + switch c.PaymentsVersion { + case versions.V1: + return []string{ + string(connector.Provider), + connector.Name, + connector.ConnectorID, + } + default: + // V0 + return []string{ + string(connector.Provider), + } } + }) - tableData = fctl.Prepend(tableData, []string{"ConnectorID", "Name", "Provider"}) + switch c.PaymentsVersion { + case versions.V1: + tableData = fctl.Prepend(tableData, []string{"Provider", "Name", "ConnectorID"}) + default: + tableData = fctl.Prepend(tableData, []string{"Provider"}) + } + return pterm.DefaultTable. WithHasHeader(). WithWriter(cmd.OutOrStdout()). diff --git a/components/fctl/cmd/payments/connectors/uninstall.go b/components/fctl/cmd/payments/connectors/uninstall.go index 6277c7f6ff..16d7b6d55b 100644 --- a/components/fctl/cmd/payments/connectors/uninstall.go +++ b/components/fctl/cmd/payments/connectors/uninstall.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/formancehq/fctl/cmd/payments/connectors/internal" + "github.com/formancehq/fctl/cmd/payments/versions" fctl "github.com/formancehq/fctl/pkg" "github.com/formancehq/formance-sdk-go/pkg/models/operations" "github.com/formancehq/formance-sdk-go/pkg/models/shared" @@ -16,36 +17,49 @@ var ( ) type PaymentsConnectorsUninstallStore struct { - Success bool `json:"success"` - ConnectorName string `json:"connectorName"` + Success bool `json:"success"` + Connector string `json:"connector"` } type PaymentsConnectorsUninstallController struct { - store *PaymentsConnectorsUninstallStore + PaymentsVersion versions.Version + + store *PaymentsConnectorsUninstallStore + providerFlag string + connectorIDFlag string +} + +func (c *PaymentsConnectorsUninstallController) SetVersion(version versions.Version) { + c.PaymentsVersion = version } var _ fctl.Controller[*PaymentsConnectorsUninstallStore] = (*PaymentsConnectorsUninstallController)(nil) func NewDefaultPaymentsConnectorsUninstallStore() *PaymentsConnectorsUninstallStore { return &PaymentsConnectorsUninstallStore{ - Success: false, - ConnectorName: "", + Success: false, + Connector: "", } } func NewPaymentsConnectorsUninstallController() *PaymentsConnectorsUninstallController { return &PaymentsConnectorsUninstallController{ - store: NewDefaultPaymentsConnectorsUninstallStore(), + store: NewDefaultPaymentsConnectorsUninstallStore(), + providerFlag: "provider", + connectorIDFlag: "connector-id", } } func NewUninstallCommand() *cobra.Command { - return fctl.NewCommand("uninstall ", + c := NewPaymentsConnectorsUninstallController() + return fctl.NewCommand("uninstall", fctl.WithAliases("uninstall", "u", "un"), fctl.WithConfirmFlag(), - fctl.WithArgs(cobra.ExactArgs(1)), + fctl.WithArgs(cobra.ExactArgs(0)), fctl.WithValidArgs(internal.AllConnectors...), + fctl.WithStringFlag(c.providerFlag, "", "Provider name"), + fctl.WithStringFlag(c.connectorIDFlag, "", "Connector ID"), fctl.WithShortDescription("Uninstall a connector"), - fctl.WithController[*PaymentsConnectorsUninstallStore](NewPaymentsConnectorsUninstallController()), + fctl.WithController[*PaymentsConnectorsUninstallStore](c), ) } @@ -54,6 +68,10 @@ func (c *PaymentsConnectorsUninstallController) GetStore() *PaymentsConnectorsUn } func (c *PaymentsConnectorsUninstallController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) { + if err := versions.GetPaymentsVersion(cmd, args, c); err != nil { + return nil, err + } + cfg, err := fctl.GetConfig(cmd) if err != nil { return nil, err @@ -69,34 +87,70 @@ func (c *PaymentsConnectorsUninstallController) Run(cmd *cobra.Command, args []s return nil, err } - if !fctl.CheckStackApprobation(cmd, stack, "You are about to uninstall connector '%s'", args[0]) { - return nil, fctl.ErrMissingApproval - } - client, err := fctl.NewStackClient(cmd, cfg, stack) if err != nil { return nil, err } - response, err := client.Payments.UninstallConnector(cmd.Context(), operations.UninstallConnectorRequest{ - Connector: shared.Connector(args[0]), - }) - if err != nil { - return nil, err - } - - if response.StatusCode >= 300 { - return nil, fmt.Errorf("unexpected status code: %d", response.StatusCode) + provider := fctl.GetString(cmd, c.providerFlag) + connectorID := fctl.GetString(cmd, c.connectorIDFlag) + switch c.PaymentsVersion { + case versions.V1: + if provider == "" { + return nil, fmt.Errorf("missing provider") + } + + if connectorID == "" { + return nil, fmt.Errorf("missing connector ID") + } + + if !fctl.CheckStackApprobation(cmd, stack, "You are about to uninstall connector '%s' from provider '%s'", connectorID, provider) { + return nil, fctl.ErrMissingApproval + } + + response, err := client.Payments.UninstallConnectorV1(cmd.Context(), operations.UninstallConnectorV1Request{ + ConnectorID: connectorID, + Connector: shared.Connector(provider), + }) + if err != nil { + return nil, err + } + + if response.StatusCode >= 300 { + return nil, fmt.Errorf("unexpected status code: %d", response.StatusCode) + } + + c.store.Connector = connectorID + case versions.V0: + if provider == "" { + return nil, fmt.Errorf("missing provider") + } + + if !fctl.CheckStackApprobation(cmd, stack, "You are about to uninstall connector '%s'", provider) { + return nil, fctl.ErrMissingApproval + } + + response, err := client.Payments.UninstallConnector(cmd.Context(), operations.UninstallConnectorRequest{ + Connector: shared.Connector(provider), + }) + if err != nil { + return nil, err + } + + if response.StatusCode >= 300 { + return nil, fmt.Errorf("unexpected status code: %d", response.StatusCode) + } + + c.store.Connector = provider } c.store.Success = true - c.store.ConnectorName = args[0] return c, nil } // TODO: This need to use the ui.NewListModel func (c *PaymentsConnectorsUninstallController) Render(cmd *cobra.Command, args []string) error { - pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("Connector '%s' uninstalled!", c.store.ConnectorName) + pterm.Success.WithWriter(cmd.OutOrStdout()).Printfln("Connector '%s' uninstalled!", c.store.Connector) return nil } diff --git a/components/fctl/cmd/payments/connectors/views/banking.go b/components/fctl/cmd/payments/connectors/views/banking.go deleted file mode 100644 index 351228e092..0000000000 --- a/components/fctl/cmd/payments/connectors/views/banking.go +++ /dev/null @@ -1,30 +0,0 @@ -package views - -import ( - "errors" - - "github.com/formancehq/formance-sdk-go/pkg/models/shared" - "github.com/pterm/pterm" - "github.com/spf13/cobra" -) - -func DisplayBankingCircleConfig(cmd *cobra.Command, connectorConfig *shared.ConnectorConfigResponse) error { - config, ok := connectorConfig.Data.(*shared.BankingCircleConfig) - if !ok { - return errors.New("invalid banking circle connector config") - } - - tableData := pterm.TableData{} - tableData = append(tableData, []string{pterm.LightCyan("Username:"), config.Username}) - tableData = append(tableData, []string{pterm.LightCyan("Password:"), config.Password}) - tableData = append(tableData, []string{pterm.LightCyan("Endpoint:"), config.Endpoint}) - tableData = append(tableData, []string{pterm.LightCyan("Authorization endpoint:"), config.AuthorizationEndpoint}) - - if err := pterm.DefaultTable. - WithWriter(cmd.OutOrStdout()). - WithData(tableData). - Render(); err != nil { - return err - } - return nil -} diff --git a/components/fctl/cmd/payments/connectors/views/banking_circle.go b/components/fctl/cmd/payments/connectors/views/banking_circle.go new file mode 100644 index 0000000000..4ee373285e --- /dev/null +++ b/components/fctl/cmd/payments/connectors/views/banking_circle.go @@ -0,0 +1,56 @@ +package views + +import ( + "github.com/formancehq/formance-sdk-go/pkg/models/shared" + "github.com/pterm/pterm" + "github.com/spf13/cobra" +) + +func DisplayBankingCircleConfig(cmd *cobra.Command, connectorConfig *shared.ConnectorConfigResponse) error { + config := connectorConfig.Data.(map[string]interface{}) + + tableData := pterm.TableData{} + tableData = append(tableData, []string{pterm.LightCyan("Name:"), func() string { + name, ok := config["name"].(string) + if !ok { + return "" + } + return name + }()}) + tableData = append(tableData, []string{pterm.LightCyan("Username:"), func() string { + username, ok := config["username"].(string) + if !ok { + return "" + } + return username + }()}) + tableData = append(tableData, []string{pterm.LightCyan("Password:"), func() string { + password, ok := config["password"].(string) + if !ok { + return "" + } + return password + }()}) + tableData = append(tableData, []string{pterm.LightCyan("Endpoint:"), func() string { + endpoint, ok := config["endpoint"].(string) + if !ok { + return "" + } + return endpoint + }()}) + tableData = append(tableData, []string{pterm.LightCyan("Authorization endpoint:"), func() string { + authorizationEndpoint, ok := config["authorizationEndpoint"].(string) + if !ok { + return "" + } + return authorizationEndpoint + }()}) + + if err := pterm.DefaultTable. + WithWriter(cmd.OutOrStdout()). + WithData(tableData). + Render(); err != nil { + return err + } + return nil +} diff --git a/components/fctl/cmd/payments/connectors/views/currency.go b/components/fctl/cmd/payments/connectors/views/currency_cloud.go similarity index 55% rename from components/fctl/cmd/payments/connectors/views/currency.go rename to components/fctl/cmd/payments/connectors/views/currency_cloud.go index 274ddad871..67995d5d0a 100644 --- a/components/fctl/cmd/payments/connectors/views/currency.go +++ b/components/fctl/cmd/payments/connectors/views/currency_cloud.go @@ -1,27 +1,42 @@ package views import ( - "errors" - "github.com/formancehq/formance-sdk-go/pkg/models/shared" "github.com/pterm/pterm" "github.com/spf13/cobra" ) func DisplayCurrencyCloudConfig(cmd *cobra.Command, connectorConfig *shared.ConnectorConfigResponse) error { - config, ok := connectorConfig.Data.(*shared.CurrencyCloudConfig) - if !ok { - return errors.New("invalid currency cloud connector config") - } + config := connectorConfig.Data.(map[string]interface{}) tableData := pterm.TableData{} - tableData = append(tableData, []string{pterm.LightCyan("API key:"), config.APIKey}) - tableData = append(tableData, []string{pterm.LightCyan("Login ID:"), config.LoginID}) + tableData = append(tableData, []string{pterm.LightCyan("Name:"), func() string { + name, ok := config["name"].(string) + if !ok { + return "" + } + return name + }()}) + tableData = append(tableData, []string{pterm.LightCyan("API key:"), func() string { + apiKey, ok := config["apiKey"].(string) + if !ok { + return "" + } + return apiKey + }()}) + tableData = append(tableData, []string{pterm.LightCyan("Login ID:"), func() string { + loginID, ok := config["loginID"].(string) + if !ok { + return "" + } + return loginID + }()}) tableData = append(tableData, []string{pterm.LightCyan("Endpoint:"), func() string { - if config.Endpoint == nil { + endpoint, ok := config["endpoint"].(string) + if !ok { return "" } - return *config.Endpoint + return endpoint }()}) if err := pterm.DefaultTable. diff --git a/components/fctl/cmd/payments/connectors/views/mangopay.go b/components/fctl/cmd/payments/connectors/views/mangopay.go new file mode 100644 index 0000000000..e1113366f7 --- /dev/null +++ b/components/fctl/cmd/payments/connectors/views/mangopay.go @@ -0,0 +1,49 @@ +package views + +import ( + "github.com/formancehq/formance-sdk-go/pkg/models/shared" + "github.com/pterm/pterm" + "github.com/spf13/cobra" +) + +func DisplayMangopayConfig(cmd *cobra.Command, connectorConfig *shared.ConnectorConfigResponse) error { + config := connectorConfig.Data.(map[string]interface{}) + + tableData := pterm.TableData{} + tableData = append(tableData, []string{pterm.LightCyan("Name:"), func() string { + name, ok := config["name"].(string) + if !ok { + return "" + } + return name + }()}) + tableData = append(tableData, []string{pterm.LightCyan("ClientID:"), func() string { + clientID, ok := config["clientID"].(string) + if !ok { + return "" + } + return clientID + }()}) + tableData = append(tableData, []string{pterm.LightCyan("API key:"), func() string { + apiKey, ok := config["apiKey"].(string) + if !ok { + return "" + } + return apiKey + }()}) + tableData = append(tableData, []string{pterm.LightCyan("Endpoint:"), func() string { + endpoint, ok := config["endpoint"].(string) + if !ok { + return "" + } + return endpoint + }()}) + + if err := pterm.DefaultTable. + WithWriter(cmd.OutOrStdout()). + WithData(tableData). + Render(); err != nil { + return err + } + return nil +} diff --git a/components/fctl/cmd/payments/connectors/views/modulr.go b/components/fctl/cmd/payments/connectors/views/modulr.go index a39d16b2ba..cc32b9f7f4 100644 --- a/components/fctl/cmd/payments/connectors/views/modulr.go +++ b/components/fctl/cmd/payments/connectors/views/modulr.go @@ -1,27 +1,43 @@ package views import ( - "errors" - "github.com/formancehq/formance-sdk-go/pkg/models/shared" "github.com/pterm/pterm" "github.com/spf13/cobra" ) func DisplayModulrConfig(cmd *cobra.Command, connectorConfig *shared.ConnectorConfigResponse) error { - config, ok := connectorConfig.Data.(*shared.ModulrConfig) - if !ok { - return errors.New("invalid modulr connector config") - } + config := connectorConfig.Data.(map[string]interface{}) tableData := pterm.TableData{} - tableData = append(tableData, []string{pterm.LightCyan("API key:"), config.APIKey}) - tableData = append(tableData, []string{pterm.LightCyan("API secret:"), config.APISecret}) + tableData = append(tableData, []string{pterm.LightCyan("Name:"), func() string { + name, ok := config["name"].(string) + if !ok { + return "" + } + return name + }()}) + tableData = append(tableData, []string{pterm.LightCyan("API key:"), func() string { + apiKey, ok := config["apiKey"].(string) + if !ok { + return "" + } + + return apiKey + }()}) + tableData = append(tableData, []string{pterm.LightCyan("API secret:"), func() string { + apiSecret, ok := config["apiSecret"].(string) + if !ok { + return "" + } + return apiSecret + }()}) tableData = append(tableData, []string{pterm.LightCyan("Endpoint:"), func() string { - if config.Endpoint == nil { + endpoint, ok := config["endpoint"].(string) + if !ok { return "" } - return *config.Endpoint + return endpoint }()}) if err := pterm.DefaultTable. diff --git a/components/fctl/cmd/payments/connectors/views/moneycorp.go b/components/fctl/cmd/payments/connectors/views/moneycorp.go new file mode 100644 index 0000000000..b3f99cabcd --- /dev/null +++ b/components/fctl/cmd/payments/connectors/views/moneycorp.go @@ -0,0 +1,49 @@ +package views + +import ( + "github.com/formancehq/formance-sdk-go/pkg/models/shared" + "github.com/pterm/pterm" + "github.com/spf13/cobra" +) + +func DisplayMoneycorpConfig(cmd *cobra.Command, connectorConfig *shared.ConnectorConfigResponse) error { + config := connectorConfig.Data.(map[string]interface{}) + + tableData := pterm.TableData{} + tableData = append(tableData, []string{pterm.LightCyan("Name:"), func() string { + name, ok := config["name"].(string) + if !ok { + return "" + } + return name + }()}) + tableData = append(tableData, []string{pterm.LightCyan("ClientID:"), func() string { + clientID, ok := config["clientID"].(string) + if !ok { + return "" + } + return clientID + }()}) + tableData = append(tableData, []string{pterm.LightCyan("API key:"), func() string { + apiKey, ok := config["apiKey"].(string) + if !ok { + return "" + } + return apiKey + }()}) + tableData = append(tableData, []string{pterm.LightCyan("Endpoint:"), func() string { + endpoint, ok := config["endpoint"].(string) + if !ok { + return "" + } + return endpoint + }()}) + + if err := pterm.DefaultTable. + WithWriter(cmd.OutOrStdout()). + WithData(tableData). + Render(); err != nil { + return err + } + return nil +} diff --git a/components/fctl/cmd/payments/connectors/views/stripe.go b/components/fctl/cmd/payments/connectors/views/stripe.go index 9d963a07fe..d3920b8261 100644 --- a/components/fctl/cmd/payments/connectors/views/stripe.go +++ b/components/fctl/cmd/payments/connectors/views/stripe.go @@ -1,21 +1,29 @@ package views import ( - "errors" - "github.com/formancehq/formance-sdk-go/pkg/models/shared" "github.com/pterm/pterm" "github.com/spf13/cobra" ) func DisplayStripeConfig(cmd *cobra.Command, connectorConfig *shared.ConnectorConfigResponse) error { - config, ok := connectorConfig.Data.(*shared.StripeConfig) - if !ok { - return errors.New("invalid stripe connector config") - } + config := connectorConfig.Data.(map[string]interface{}) tableData := pterm.TableData{} - tableData = append(tableData, []string{pterm.LightCyan("API key:"), config.APIKey}) + tableData = append(tableData, []string{pterm.LightCyan("Name:"), func() string { + name, ok := config["name"].(string) + if !ok { + return "" + } + return name + }()}) + tableData = append(tableData, []string{pterm.LightCyan("API key:"), func() string { + apiKey, ok := config["apiKey"].(string) + if !ok { + return "" + } + return apiKey + }()}) if err := pterm.DefaultTable. WithWriter(cmd.OutOrStdout()). diff --git a/components/fctl/cmd/payments/connectors/views/wise.go b/components/fctl/cmd/payments/connectors/views/wise.go index d1c52a3635..d86b29209d 100644 --- a/components/fctl/cmd/payments/connectors/views/wise.go +++ b/components/fctl/cmd/payments/connectors/views/wise.go @@ -1,21 +1,29 @@ package views import ( - "errors" - "github.com/formancehq/formance-sdk-go/pkg/models/shared" "github.com/pterm/pterm" "github.com/spf13/cobra" ) func DisplayWiseConfig(cmd *cobra.Command, connectorConfig *shared.ConnectorConfigResponse) error { - config, ok := connectorConfig.Data.(*shared.WiseConfig) - if !ok { - return errors.New("invalid wise connector config") - } + config := connectorConfig.Data.(map[string]interface{}) tableData := pterm.TableData{} - tableData = append(tableData, []string{pterm.LightCyan("API key:"), config.APIKey}) + tableData = append(tableData, []string{pterm.LightCyan("Name:"), func() string { + name, ok := config["name"].(string) + if !ok { + return "" + } + return name + }()}) + tableData = append(tableData, []string{pterm.LightCyan("API key:"), func() string { + apiKey, ok := config["apiKey"].(string) + if !ok { + return "" + } + return apiKey + }()}) if err := pterm.DefaultTable. WithWriter(cmd.OutOrStdout()). diff --git a/components/fctl/cmd/payments/payments/list.go b/components/fctl/cmd/payments/payments/list.go index f516b41523..bf826f7450 100644 --- a/components/fctl/cmd/payments/payments/list.go +++ b/components/fctl/cmd/payments/payments/list.go @@ -87,7 +87,7 @@ func (c *ListController) Render(cmd *cobra.Command, args []string) error { payment.Reference, payment.SourceAccountID, payment.DestinationAccountID, - string(payment.ConnectorID), + payment.ConnectorID, payment.CreatedAt.Format(time.RFC3339), } }) diff --git a/components/fctl/cmd/payments/transferinitiation/create.go b/components/fctl/cmd/payments/transferinitiation/create.go index 67578bf290..0c65da5efe 100644 --- a/components/fctl/cmd/payments/transferinitiation/create.go +++ b/components/fctl/cmd/payments/transferinitiation/create.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" + "github.com/formancehq/fctl/cmd/payments/versions" fctl "github.com/formancehq/fctl/pkg" "github.com/formancehq/formance-sdk-go/pkg/models/shared" "github.com/pkg/errors" @@ -15,9 +16,15 @@ type CreateStore struct { TransferInitiationId string `json:"transferInitiationId"` } type CreateController struct { + PaymentsVersion versions.Version + store *CreateStore } +func (c *CreateController) SetVersion(version versions.Version) { + c.PaymentsVersion = version +} + var _ fctl.Controller[*CreateStore] = (*CreateController)(nil) func NewCreateStore() *CreateStore { @@ -31,11 +38,12 @@ func NewCreateController() *CreateController { } func NewCreateCommand() *cobra.Command { + c := NewCreateController() return fctl.NewCommand("create |-", fctl.WithShortDescription("Create a transfer initiation"), fctl.WithAliases("cr", "c"), fctl.WithArgs(cobra.ExactArgs(1)), - fctl.WithController[*CreateStore](NewCreateController()), + fctl.WithController[*CreateStore](c), ) } @@ -44,6 +52,13 @@ func (c *CreateController) GetStore() *CreateStore { } func (c *CreateController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) { + if err := versions.GetPaymentsVersion(cmd, args, c); err != nil { + return nil, err + } + + if c.PaymentsVersion < versions.V1 { + return nil, fmt.Errorf("transfer initiation are only supported in >= v1.0.0") + } soc, err := fctl.GetStackOrganizationConfig(cmd) if err != nil { diff --git a/components/fctl/cmd/payments/transferinitiation/delete.go b/components/fctl/cmd/payments/transferinitiation/delete.go index 6e7d679287..7e6e1e904d 100644 --- a/components/fctl/cmd/payments/transferinitiation/delete.go +++ b/components/fctl/cmd/payments/transferinitiation/delete.go @@ -3,6 +3,7 @@ package transferinitiation import ( "fmt" + "github.com/formancehq/fctl/cmd/payments/versions" fctl "github.com/formancehq/fctl/pkg" "github.com/formancehq/formance-sdk-go/pkg/models/operations" "github.com/pkg/errors" @@ -16,9 +17,15 @@ type DeleteStore struct { } type DeleteController struct { + PaymentsVersion versions.Version + store *DeleteStore } +func (c *DeleteController) SetVersion(version versions.Version) { + c.PaymentsVersion = version +} + var _ fctl.Controller[*DeleteStore] = (*DeleteController)(nil) func NewDeleteStore() *DeleteStore { @@ -31,11 +38,12 @@ func NewDeleteController() *DeleteController { } } func NewDeleteCommand() *cobra.Command { + c := NewDeleteController() return fctl.NewCommand("delete ", fctl.WithAliases("d"), fctl.WithShortDescription("Delete a transfer Initiation"), fctl.WithArgs(cobra.ExactArgs(1)), - fctl.WithController[*DeleteStore](NewDeleteController()), + fctl.WithController[*DeleteStore](c), ) } @@ -44,6 +52,14 @@ func (c *DeleteController) GetStore() *DeleteStore { } func (c *DeleteController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) { + if err := versions.GetPaymentsVersion(cmd, args, c); err != nil { + return nil, err + } + + if c.PaymentsVersion < versions.V1 { + return nil, fmt.Errorf("transfer initiation are only supported in >= v1.0.0") + } + cfg, err := fctl.GetConfig(cmd) if err != nil { return nil, errors.Wrap(err, "retrieving config") diff --git a/components/fctl/cmd/payments/transferinitiation/list.go b/components/fctl/cmd/payments/transferinitiation/list.go index d466ba03c0..a425d18778 100644 --- a/components/fctl/cmd/payments/transferinitiation/list.go +++ b/components/fctl/cmd/payments/transferinitiation/list.go @@ -4,6 +4,7 @@ import ( "fmt" "time" + "github.com/formancehq/fctl/cmd/payments/versions" fctl "github.com/formancehq/fctl/pkg" "github.com/formancehq/formance-sdk-go/pkg/models/operations" "github.com/formancehq/formance-sdk-go/pkg/models/shared" @@ -16,9 +17,15 @@ type ListStore struct { } type ListController struct { + PaymentsVersion versions.Version + store *ListStore } +func (c *ListController) SetVersion(version versions.Version) { + c.PaymentsVersion = version +} + var _ fctl.Controller[*ListStore] = (*ListController)(nil) func NewListStore() *ListStore { @@ -38,6 +45,13 @@ func (c *ListController) GetStore() *ListStore { } func (c *ListController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) { + if err := versions.GetPaymentsVersion(cmd, args, c); err != nil { + return nil, err + } + + if c.PaymentsVersion < versions.V1 { + return nil, fmt.Errorf("transfer initiation are only supported in >= v1.0.0") + } cfg, err := fctl.GetConfig(cmd) if err != nil { @@ -82,10 +96,11 @@ func (c *ListController) Render(cmd *cobra.Command, args []string) error { tf.ID, tf.CreatedAt.Format(time.RFC3339), tf.UpdatedAt.Format(time.RFC3339), + tf.ScheduledAt.Format(time.RFC3339), tf.Description, tf.SourceAccountID, tf.DestinationAccountID, - string(tf.ConnectorID), + tf.ConnectorID, string(tf.Type), fmt.Sprint(tf.Amount), tf.Asset, @@ -93,7 +108,7 @@ func (c *ListController) Render(cmd *cobra.Command, args []string) error { tf.Error, } }) - tableData = fctl.Prepend(tableData, []string{"ID", "CreatedAt", "UpdatedAt", "Description", "Source Account ID", + tableData = fctl.Prepend(tableData, []string{"ID", "CreatedAt", "UpdatedAt", "ScheduledAt", "Description", "Source Account ID", "Destination Account ID", "ConnectorID", "Type", "Amount", "Asset", "Status", "Error"}) return pterm.DefaultTable. WithHasHeader(). @@ -103,10 +118,11 @@ func (c *ListController) Render(cmd *cobra.Command, args []string) error { } func NewListCommand() *cobra.Command { + c := NewListController() return fctl.NewCommand("list", fctl.WithAliases("ls", "l"), fctl.WithArgs(cobra.ExactArgs(0)), fctl.WithShortDescription("List transfer initiation"), - fctl.WithController[*ListStore](NewListController()), + fctl.WithController[*ListStore](c), ) } diff --git a/components/fctl/cmd/payments/transferinitiation/retry.go b/components/fctl/cmd/payments/transferinitiation/retry.go index 3e6d30d69c..be5367e469 100644 --- a/components/fctl/cmd/payments/transferinitiation/retry.go +++ b/components/fctl/cmd/payments/transferinitiation/retry.go @@ -3,6 +3,7 @@ package transferinitiation import ( "fmt" + "github.com/formancehq/fctl/cmd/payments/versions" fctl "github.com/formancehq/fctl/pkg" "github.com/formancehq/formance-sdk-go/pkg/models/operations" "github.com/pkg/errors" @@ -15,9 +16,15 @@ type RetryStore struct { Success bool `json:"success"` } type RetryController struct { + PaymentsVersion versions.Version + store *RetryStore } +func (c *RetryController) SetVersion(version versions.Version) { + c.PaymentsVersion = version +} + var _ fctl.Controller[*RetryStore] = (*RetryController)(nil) func NewRetryStore() *RetryStore { @@ -31,11 +38,12 @@ func NewRetryController() *RetryController { } func NewRetryCommand() *cobra.Command { + c := NewRetryController() return fctl.NewCommand("retry ", fctl.WithShortDescription("Retry a failed transfer initiation"), fctl.WithAliases("r"), fctl.WithArgs(cobra.ExactArgs(1)), - fctl.WithController[*RetryStore](NewRetryController()), + fctl.WithController[*RetryStore](c), ) } @@ -44,6 +52,14 @@ func (c *RetryController) GetStore() *RetryStore { } func (c *RetryController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) { + if err := versions.GetPaymentsVersion(cmd, args, c); err != nil { + return nil, err + } + + if c.PaymentsVersion < versions.V1 { + return nil, fmt.Errorf("transfer initiation are only supported in >= v1.0.0") + } + soc, err := fctl.GetStackOrganizationConfig(cmd) if err != nil { return nil, err diff --git a/components/fctl/cmd/payments/transferinitiation/show.go b/components/fctl/cmd/payments/transferinitiation/show.go index e6ca398ede..49d5da0b86 100644 --- a/components/fctl/cmd/payments/transferinitiation/show.go +++ b/components/fctl/cmd/payments/transferinitiation/show.go @@ -4,6 +4,7 @@ import ( "fmt" "time" + "github.com/formancehq/fctl/cmd/payments/versions" fctl "github.com/formancehq/fctl/pkg" "github.com/formancehq/formance-sdk-go/pkg/models/operations" "github.com/formancehq/formance-sdk-go/pkg/models/shared" @@ -15,9 +16,15 @@ type ShowStore struct { TransferInitiation *shared.TransferInitiation `json:"transferInitiation"` } type ShowController struct { + PaymentsVersion versions.Version + store *ShowStore } +func (c *ShowController) SetVersion(version versions.Version) { + c.PaymentsVersion = version +} + var _ fctl.Controller[*ShowStore] = (*ShowController)(nil) func NewDefaultShowStore() *ShowStore { @@ -31,11 +38,12 @@ func NewShowController() *ShowController { } func NewShowCommand() *cobra.Command { + c := NewShowController() return fctl.NewCommand("get ", fctl.WithShortDescription("Get transfer initiation"), fctl.WithArgs(cobra.ExactArgs(1)), fctl.WithAliases("sh", "s"), - fctl.WithController[*ShowStore](NewShowController()), + fctl.WithController[*ShowStore](c), ) } @@ -44,6 +52,13 @@ func (c *ShowController) GetStore() *ShowStore { } func (c *ShowController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) { + if err := versions.GetPaymentsVersion(cmd, args, c); err != nil { + return nil, err + } + + if c.PaymentsVersion < versions.V1 { + return nil, fmt.Errorf("transfer initiation are only supported in >= v1.0.0") + } cfg, err := fctl.GetConfig(cmd) if err != nil { @@ -87,6 +102,7 @@ func (c *ShowController) Render(cmd *cobra.Command, args []string) error { tableData = append(tableData, []string{pterm.LightCyan("ID"), c.store.TransferInitiation.ID}) tableData = append(tableData, []string{pterm.LightCyan("CreatedAt"), c.store.TransferInitiation.CreatedAt.Format(time.RFC3339)}) tableData = append(tableData, []string{pterm.LightCyan("UpdatedAt"), c.store.TransferInitiation.UpdatedAt.Format(time.RFC3339)}) + tableData = append(tableData, []string{pterm.LightCyan("ScheduledAt"), c.store.TransferInitiation.ScheduledAt.Format(time.RFC3339)}) tableData = append(tableData, []string{pterm.LightCyan("Description"), c.store.TransferInitiation.Description}) tableData = append(tableData, []string{pterm.LightCyan("SourceAccountID"), c.store.TransferInitiation.SourceAccountID}) tableData = append(tableData, []string{pterm.LightCyan("DestinationAccountID"), c.store.TransferInitiation.DestinationAccountID}) diff --git a/components/fctl/cmd/payments/transferinitiation/update_status.go b/components/fctl/cmd/payments/transferinitiation/update_status.go index a937466565..fdcffcda1c 100644 --- a/components/fctl/cmd/payments/transferinitiation/update_status.go +++ b/components/fctl/cmd/payments/transferinitiation/update_status.go @@ -3,6 +3,7 @@ package transferinitiation import ( "fmt" + "github.com/formancehq/fctl/cmd/payments/versions" fctl "github.com/formancehq/fctl/pkg" "github.com/formancehq/formance-sdk-go/pkg/models/operations" "github.com/formancehq/formance-sdk-go/pkg/models/shared" @@ -17,9 +18,15 @@ type UpdateStatusStore struct { Success bool `json:"success"` } type UpdateStatusController struct { + PaymentsVersion versions.Version + store *UpdateStatusStore } +func (c *UpdateStatusController) SetVersion(version versions.Version) { + c.PaymentsVersion = version +} + var _ fctl.Controller[*UpdateStatusStore] = (*UpdateStatusController)(nil) func NewUpdateStatusStore() *UpdateStatusStore { @@ -33,11 +40,12 @@ func NewUpdateStatusController() *UpdateStatusController { } func NewUpdateStatusCommand() *cobra.Command { + c := NewUpdateStatusController() return fctl.NewCommand("update_status ", fctl.WithShortDescription("Update the status of a transfer initiation"), fctl.WithAliases("u"), fctl.WithArgs(cobra.ExactArgs(2)), - fctl.WithController[*UpdateStatusStore](NewUpdateStatusController()), + fctl.WithController[*UpdateStatusStore](c), ) } @@ -46,6 +54,14 @@ func (c *UpdateStatusController) GetStore() *UpdateStatusStore { } func (c *UpdateStatusController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) { + if err := versions.GetPaymentsVersion(cmd, args, c); err != nil { + return nil, err + } + + if c.PaymentsVersion < versions.V1 { + return nil, fmt.Errorf("transfer initiation are only supported in >= v1.0.0") + } + soc, err := fctl.GetStackOrganizationConfig(cmd) if err != nil { return nil, err diff --git a/components/fctl/cmd/payments/versions/versions.go b/components/fctl/cmd/payments/versions/versions.go new file mode 100644 index 0000000000..98743eed61 --- /dev/null +++ b/components/fctl/cmd/payments/versions/versions.go @@ -0,0 +1,60 @@ +package versions + +import ( + "fmt" + + fctl "github.com/formancehq/fctl/pkg" + "github.com/pkg/errors" + "github.com/spf13/cobra" + "golang.org/x/mod/semver" +) + +type Version int + +const ( + V0 Version = iota + V1 +) + +type VersionController interface { + SetVersion(Version) +} + +func GetPaymentsVersion(cmd *cobra.Command, args []string, controller VersionController) error { + soc, err := fctl.GetStackOrganizationConfig(cmd) + if err != nil { + return err + } + + client, err := fctl.NewStackClient(cmd, soc.Config, soc.Stack) + if err != nil { + return errors.Wrap(err, "creating stack client") + } + + response, err := client.Payments.PaymentsgetServerInfo(cmd.Context()) + if err != nil { + return err + } + + if response.StatusCode >= 300 { + return fmt.Errorf("unexpected status code: %d", response.StatusCode) + } + + version := "v" + response.ServerInfo.Version + + if !semver.IsValid(version) { + // last version for commits + controller.SetVersion(V1) + return nil + } + + res := semver.Compare(version, "v1.0.0-rc.1") + switch res { + case 0, 1: + controller.SetVersion(V1) + default: + controller.SetVersion(V0) + } + + return nil +} diff --git a/components/payments/openapi.yaml b/components/payments/openapi.yaml index 18c3515f63..ba96c27ebf 100644 --- a/components/payments/openapi.yaml +++ b/components/payments/openapi.yaml @@ -883,6 +883,8 @@ components: type: string connectorID: type: string + enabled: + type: boolean BankAccountResponse: type: object required: diff --git a/openapi/build/generate.json b/openapi/build/generate.json index c547b36aff..c5e19454f5 100644 --- a/openapi/build/generate.json +++ b/openapi/build/generate.json @@ -12,7 +12,7 @@ "url": "https://avatars.githubusercontent.com/u/84325077?s=200&v=4", "altText": "Formance" }, - "version": "v1.0.20231114" + "version": "v1.0.20231130" }, "servers": [ { @@ -5719,6 +5719,9 @@ }, "connectorID": { "type": "string" + }, + "enabled": { + "type": "boolean" } } } diff --git a/sdks/go/pkg/models/shared/connectorsresponse.go b/sdks/go/pkg/models/shared/connectorsresponse.go index 84b6996e45..2dd75ea30c 100755 --- a/sdks/go/pkg/models/shared/connectorsresponse.go +++ b/sdks/go/pkg/models/shared/connectorsresponse.go @@ -4,6 +4,7 @@ package shared type ConnectorsResponseData struct { ConnectorID string `json:"connectorID"` + Enabled *bool `json:"enabled,omitempty"` Name string `json:"name"` Provider Connector `json:"provider"` } diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/ConnectorsResponseData.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/ConnectorsResponseData.java index 9191dd0e37..d9ed567381 100755 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/ConnectorsResponseData.java +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/ConnectorsResponseData.java @@ -4,6 +4,8 @@ package com.formance.formance_sdk.models.shared; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; public class ConnectorsResponseData { @@ -15,6 +17,15 @@ public ConnectorsResponseData withConnectorID(String connectorID) { return this; } + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("enabled") + public Boolean enabled; + + public ConnectorsResponseData withEnabled(Boolean enabled) { + this.enabled = enabled; + return this; + } + @JsonProperty("name") public String name; diff --git a/sdks/php/src/Models/Shared/ConnectorsResponseData.php b/sdks/php/src/Models/Shared/ConnectorsResponseData.php index 2da714ae2f..c5307638fa 100755 --- a/sdks/php/src/Models/Shared/ConnectorsResponseData.php +++ b/sdks/php/src/Models/Shared/ConnectorsResponseData.php @@ -15,6 +15,11 @@ class ConnectorsResponseData #[\JMS\Serializer\Annotation\Type('string')] public string $connectorID; + #[\JMS\Serializer\Annotation\SerializedName('enabled')] + #[\JMS\Serializer\Annotation\Type('bool')] + #[\JMS\Serializer\Annotation\SkipWhenEmpty] + public ?bool $enabled = null; + #[\JMS\Serializer\Annotation\SerializedName('name')] #[\JMS\Serializer\Annotation\Type('string')] public string $name; @@ -26,6 +31,7 @@ class ConnectorsResponseData public function __construct() { $this->connectorID = ""; + $this->enabled = null; $this->name = ""; $this->provider = \formance\stack\Models\Shared\Connector::STRIPE; } diff --git a/sdks/python/src/sdk/models/shared/connectorsresponse.py b/sdks/python/src/sdk/models/shared/connectorsresponse.py index 1a0e3b2bac..9e9a76a51a 100755 --- a/sdks/python/src/sdk/models/shared/connectorsresponse.py +++ b/sdks/python/src/sdk/models/shared/connectorsresponse.py @@ -5,6 +5,7 @@ from ..shared import connector as shared_connector from dataclasses_json import Undefined, dataclass_json from sdk import utils +from typing import Optional @dataclass_json(undefined=Undefined.EXCLUDE) @@ -14,6 +15,7 @@ class ConnectorsResponseData: connector_id: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('connectorID') }}) name: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('name') }}) provider: shared_connector.Connector = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('provider') }}) + enabled: Optional[bool] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('enabled'), 'exclude': lambda f: f is None }}) @dataclass_json(undefined=Undefined.EXCLUDE) diff --git a/sdks/typescript/src/sdk/models/shared/connectorsresponse.ts b/sdks/typescript/src/sdk/models/shared/connectorsresponse.ts index 9a583b62e0..9d760da5db 100755 --- a/sdks/typescript/src/sdk/models/shared/connectorsresponse.ts +++ b/sdks/typescript/src/sdk/models/shared/connectorsresponse.ts @@ -11,6 +11,10 @@ export class ConnectorsResponseData extends SpeakeasyBase { @Expose({ name: "connectorID" }) connectorID: string; + @SpeakeasyMetadata() + @Expose({ name: "enabled" }) + enabled?: boolean; + @SpeakeasyMetadata() @Expose({ name: "name" }) name: string;