diff --git a/components/operator/internal/controllers/stack/testdata/monopod-latest/results/migrations-stack.formance.com-v1beta3/payments-v0.9.0-pre-upgrade.yaml b/components/operator/internal/controllers/stack/testdata/monopod-latest/results/migrations-stack.formance.com-v1beta3/payments-v0.9.0-pre-upgrade.yaml new file mode 100644 index 0000000000..889a2d9052 --- /dev/null +++ b/components/operator/internal/controllers/stack/testdata/monopod-latest/results/migrations-stack.formance.com-v1beta3/payments-v0.9.0-pre-upgrade.yaml @@ -0,0 +1,18 @@ +apiVersion: stack.formance.com/v1beta3 +kind: Migration +metadata: + annotations: + reloader.stakater.com/auto: "true" + generation: 1 + labels: + stack: "true" + name: payments-v0.9.0-pre-upgrade + namespace: monopod-latest +spec: + configuration: monopod-latest + module: payments + postUpgrade: false + targetedVersion: v0.9.0 + version: monopod-latest +status: + terminated: true diff --git a/components/operator/internal/controllers/stack/testdata/monopod-ledgerv1/results/migrations-stack.formance.com-v1beta3/payments-v0.9.0-pre-upgrade.yaml b/components/operator/internal/controllers/stack/testdata/monopod-ledgerv1/results/migrations-stack.formance.com-v1beta3/payments-v0.9.0-pre-upgrade.yaml new file mode 100644 index 0000000000..e1797d2bf8 --- /dev/null +++ b/components/operator/internal/controllers/stack/testdata/monopod-ledgerv1/results/migrations-stack.formance.com-v1beta3/payments-v0.9.0-pre-upgrade.yaml @@ -0,0 +1,18 @@ +apiVersion: stack.formance.com/v1beta3 +kind: Migration +metadata: + annotations: + reloader.stakater.com/auto: "true" + generation: 1 + labels: + stack: "true" + name: payments-v0.9.0-pre-upgrade + namespace: monopod-ledgerv1 +spec: + configuration: monopod-ledgerv1 + module: payments + postUpgrade: false + targetedVersion: v0.9.0 + version: monopod-ledgerv1 +status: + terminated: true diff --git a/components/operator/internal/controllers/stack/testdata/monopod-search-before-v0.7.0/results/migrations-stack.formance.com-v1beta3/payments-v0.9.0-pre-upgrade.yaml b/components/operator/internal/controllers/stack/testdata/monopod-search-before-v0.7.0/results/migrations-stack.formance.com-v1beta3/payments-v0.9.0-pre-upgrade.yaml new file mode 100644 index 0000000000..7407f17e29 --- /dev/null +++ b/components/operator/internal/controllers/stack/testdata/monopod-search-before-v0.7.0/results/migrations-stack.formance.com-v1beta3/payments-v0.9.0-pre-upgrade.yaml @@ -0,0 +1,18 @@ +apiVersion: stack.formance.com/v1beta3 +kind: Migration +metadata: + annotations: + reloader.stakater.com/auto: "true" + generation: 1 + labels: + stack: "true" + name: payments-v0.9.0-pre-upgrade + namespace: monopod-search-before-v0-7-0 +spec: + configuration: monopod-search-before-v0-7-0 + module: payments + postUpgrade: false + targetedVersion: v0.9.0 + version: monopod-search-before-v0-7-0 +status: + terminated: true diff --git a/components/operator/internal/controllers/stack/testdata/multipod-latest/results/migrations-stack.formance.com-v1beta3/payments-v0.9.0-pre-upgrade.yaml b/components/operator/internal/controllers/stack/testdata/multipod-latest/results/migrations-stack.formance.com-v1beta3/payments-v0.9.0-pre-upgrade.yaml new file mode 100644 index 0000000000..c0bf2993ce --- /dev/null +++ b/components/operator/internal/controllers/stack/testdata/multipod-latest/results/migrations-stack.formance.com-v1beta3/payments-v0.9.0-pre-upgrade.yaml @@ -0,0 +1,18 @@ +apiVersion: stack.formance.com/v1beta3 +kind: Migration +metadata: + annotations: + reloader.stakater.com/auto: "true" + generation: 1 + labels: + stack: "true" + name: payments-v0.9.0-pre-upgrade + namespace: multipod-latest +spec: + configuration: multipod-latest + module: payments + postUpgrade: false + targetedVersion: v0.9.0 + version: multipod-latest +status: + terminated: true diff --git a/components/operator/internal/handlers/handler_payments.go b/components/operator/internal/handlers/handler_payments.go index f51f2594f5..97df5c58aa 100644 --- a/components/operator/internal/handlers/handler_payments.go +++ b/components/operator/internal/handlers/handler_payments.go @@ -116,6 +116,15 @@ func init() { return paymentsServices(ctx, env) }, }, + "v0.9.0": { + PreUpgrade: func(ctx modules.Context) error { + // Add payment accounts + return paymentsPreUpgradeMigration(ctx) + }, + Services: func(ctx modules.ModuleContext) modules.Services { + return paymentsServices(ctx, env) + }, + }, }, }) } diff --git a/components/payments/internal/app/api/accounts.go b/components/payments/internal/app/api/accounts.go index e932752dd3..72877b79ce 100644 --- a/components/payments/internal/app/api/accounts.go +++ b/components/payments/internal/app/api/accounts.go @@ -14,7 +14,7 @@ import ( "github.com/pkg/errors" ) -type listAccountsRepository interface { +type accountsRepository interface { ListAccounts(ctx context.Context, pagination storage.Paginator) ([]*models.Account, storage.PaginationDetails, error) } @@ -28,7 +28,7 @@ type accountResponse struct { Raw interface{} `json:"raw"` } -func listAccountsHandler(repo listAccountsRepository) http.HandlerFunc { +func listAccountsHandler(repo accountsRepository) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") diff --git a/components/payments/internal/app/api/balances.go b/components/payments/internal/app/api/balances.go new file mode 100644 index 0000000000..faf33b9364 --- /dev/null +++ b/components/payments/internal/app/api/balances.go @@ -0,0 +1,168 @@ +package api + +import ( + "context" + "encoding/json" + "net/http" + "strconv" + "strings" + "time" + + "github.com/formancehq/payments/internal/app/models" + "github.com/formancehq/payments/internal/app/storage" + "github.com/formancehq/stack/libs/go-libs/api" + "github.com/gorilla/mux" + "github.com/pkg/errors" +) + +type balancesRepository interface { + ListBalances(ctx context.Context, query storage.BalanceQuery) ([]*models.Balance, storage.PaginationDetails, error) +} + +type balancesResponse struct { + AccountID string `json:"accountId"` + CreatedAt time.Time `json:"createdAt"` + LastUpdatedAt time.Time `json:"lastUpdatedAt"` + Currency string `json:"currency"` + Balance int64 `json:"balance"` +} + +func listBalancesForAccount(repo balancesRepository) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + + var sorter storage.Sorter + + if sortParams := r.URL.Query()["sort"]; sortParams != nil { + for _, s := range sortParams { + parts := strings.SplitN(s, ":", 2) + + var order storage.SortOrder + + if len(parts) > 1 { + //nolint:goconst // allow duplicate string + switch parts[1] { + case "asc", "ASC": + order = storage.SortOrderAsc + case "dsc", "desc", "DSC", "DESC": + order = storage.SortOrderDesc + default: + handleValidationError(w, r, errors.New("sort order not well specified, got "+parts[1])) + + return + } + } + + column := parts[0] + + sorter.Add(column, order) + } + } + + pageSize, err := pageSizeQueryParam(r) + if err != nil { + handleValidationError(w, r, err) + + return + } + + pagination, err := storage.Paginate(pageSize, r.URL.Query().Get("cursor"), sorter) + if err != nil { + handleValidationError(w, r, err) + + return + } + + accountID, err := models.AccountIDFromString(mux.Vars(r)["accountID"]) + if err != nil { + handleValidationError(w, r, err) + + return + } + + balanceQuery := storage.NewBalanceQuery(pagination). + WithAccountID(accountID). + WithCurrency(r.URL.Query().Get("currency")) + + var startTimeParsed, endTimeParsed time.Time + from, to := r.URL.Query().Get("from"), r.URL.Query().Get("to") + if from != "" { + startTimeParsed, err = time.Parse(time.RFC3339Nano, from) + if err != nil { + handleValidationError(w, r, err) + + return + } + } + if to != "" { + endTimeParsed, err = time.Parse(time.RFC3339Nano, to) + if err != nil { + handleValidationError(w, r, err) + + return + } + } + if r.URL.Query().Get("limit") != "" { + limit, err := strconv.ParseInt(r.URL.Query().Get("limit"), 10, 64) + if err != nil { + handleValidationError(w, r, err) + + return + } + + if limit > 0 { + balanceQuery = balanceQuery.WithLimit(int(limit)) + } + } + + switch { + case startTimeParsed.IsZero() && endTimeParsed.IsZero(): + balanceQuery = balanceQuery. + WithTo(time.Now()) + case !startTimeParsed.IsZero() && endTimeParsed.IsZero(): + balanceQuery = balanceQuery. + WithFrom(startTimeParsed). + WithTo(time.Now()) + case startTimeParsed.IsZero() && !endTimeParsed.IsZero(): + balanceQuery = balanceQuery. + WithTo(endTimeParsed) + default: + balanceQuery = balanceQuery. + WithFrom(startTimeParsed). + WithTo(endTimeParsed) + } + + ret, paginationDetails, err := repo.ListBalances(r.Context(), balanceQuery) + if err != nil { + handleServerError(w, r, err) + + return + } + + data := make([]*balancesResponse, len(ret)) + for i := range ret { + data[i] = &balancesResponse{ + AccountID: ret[i].AccountID.String(), + CreatedAt: ret[i].CreatedAt, + Currency: ret[i].Currency, + Balance: ret[i].Balance, + LastUpdatedAt: ret[i].LastUpdatedAt, + } + } + + err = json.NewEncoder(w).Encode(api.BaseResponse[*balancesResponse]{ + Cursor: &api.Cursor[*balancesResponse]{ + PageSize: paginationDetails.PageSize, + HasMore: paginationDetails.HasMore, + Previous: paginationDetails.PreviousPage, + Next: paginationDetails.NextPage, + Data: data, + }, + }) + if err != nil { + handleServerError(w, r, err) + + return + } + } +} diff --git a/components/payments/internal/app/api/router.go b/components/payments/internal/app/api/router.go index bed4ebfa05..edd5866eef 100644 --- a/components/payments/internal/app/api/router.go +++ b/components/payments/internal/app/api/router.go @@ -46,6 +46,7 @@ func httpRouter(logger logging.Logger, store *storage.Storage, serviceInfo api.S authGroup.Path("/payments/{paymentID}/metadata").Methods(http.MethodPatch).Handler(updateMetadataHandler(store)) authGroup.Path("/accounts").Methods(http.MethodGet).Handler(listAccountsHandler(store)) + authGroup.Path("/accounts/{accountID}/balances").Methods(http.MethodGet).Handler(listBalancesForAccount(store)) authGroup.HandleFunc("/connectors", readConnectorsHandler(store)) diff --git a/components/payments/internal/app/connectors/bankingcircle/task_fetch_accounts.go b/components/payments/internal/app/connectors/bankingcircle/task_fetch_accounts.go index 3fe23d7841..02eca70cda 100644 --- a/components/payments/internal/app/connectors/bankingcircle/task_fetch_accounts.go +++ b/components/payments/internal/app/connectors/bankingcircle/task_fetch_accounts.go @@ -62,8 +62,10 @@ func ingestAccountsBatch( ingester ingestion.Ingester, accounts []*client.Account, ) error { - batch := ingestion.AccountBatch{} + accountsBatch := ingestion.AccountBatch{} + balanceBatch := ingestion.BalanceBatch{} + now := time.Now() for _, account := range accounts { raw, err := json.Marshal(account) if err != nil { @@ -75,26 +77,42 @@ func ingestAccountsBatch( return fmt.Errorf("failed to parse opening date: %w", err) } - batchElement := ingestion.AccountBatchElement{ - Account: &models.Account{ - ID: models.AccountID{ + accountsBatch = append(accountsBatch, &models.Account{ + ID: models.AccountID{ + Reference: account.AccountID, + Provider: models.ConnectorProviderBankingCircle, + }, + CreatedAt: openingDate, + Reference: account.AccountID, + Provider: models.ConnectorProviderBankingCircle, + DefaultCurrency: account.Currency, + AccountName: account.AccountDescription, + Type: models.AccountTypeInternal, + RawData: raw, + }) + + for _, balance := range account.Balances { + balanceBatch = append(balanceBatch, &models.Balance{ + AccountID: models.AccountID{ Reference: account.AccountID, Provider: models.ConnectorProviderBankingCircle, }, - CreatedAt: openingDate, - Reference: account.AccountID, - Provider: models.ConnectorProviderBankingCircle, - DefaultCurrency: account.Currency, - AccountName: account.AccountDescription, - Type: models.AccountTypeInternal, - RawData: raw, - }, + // Note(polo): same thing as payments + // TODO(polo): do a complete pass on all connectors to + // normalize the currencies + Currency: balance.Currency + "/2", + Balance: int64(balance.IntraDayAmount * 100), + CreatedAt: now, + LastUpdatedAt: now, + }) } + } - batch = append(batch, batchElement) + if err := ingester.IngestAccounts(ctx, accountsBatch); err != nil { + return err } - if err := ingester.IngestAccounts(ctx, batch); err != nil { + if err := ingester.IngestBalances(ctx, balanceBatch, false); err != nil { return err } diff --git a/components/payments/internal/app/connectors/currencycloud/client/balances.go b/components/payments/internal/app/connectors/currencycloud/client/balances.go new file mode 100644 index 0000000000..10ebd3405c --- /dev/null +++ b/components/payments/internal/app/connectors/currencycloud/client/balances.go @@ -0,0 +1,53 @@ +package client + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "time" +) + +type Balance struct { + ID string `json:"id"` + AccountID string `json:"account_id"` + Currency string `json:"currency"` + Amount string `json:"amount"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +func (c *Client) GetBalances(ctx context.Context, page int) ([]*Balance, int, error) { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, + c.buildEndpoint("v2/balances/find?page=%d&per_page=25", page), http.NoBody) + if err != nil { + return nil, 0, fmt.Errorf("failed to create request: %w", err) + } + + req.Header.Add("Accept", "application/json") + + resp, err := c.httpClient.Do(req) + if err != nil { + return nil, 0, err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, 0, fmt.Errorf("unexpected status code: %d", resp.StatusCode) + } + + //nolint:tagliatelle // allow for client code + type response struct { + Balances []*Balance `json:"balances"` + Pagination struct { + NextPage int `json:"next_page"` + } `json:"pagination"` + } + + var res response + if err = json.NewDecoder(resp.Body).Decode(&res); err != nil { + return nil, 0, err + } + + return res.Balances, res.Pagination.NextPage, nil +} diff --git a/components/payments/internal/app/connectors/currencycloud/task_fetch_accounts.go b/components/payments/internal/app/connectors/currencycloud/task_fetch_accounts.go index 52103cedf4..3ea38dc25f 100644 --- a/components/payments/internal/app/connectors/currencycloud/task_fetch_accounts.go +++ b/components/payments/internal/app/connectors/currencycloud/task_fetch_accounts.go @@ -54,6 +54,22 @@ func taskFetchAccounts(logger logging.Logger, client *client.Client) task.Task { return err } + taskBalances, err := models.EncodeTaskDescriptor(TaskDescriptor{ + Name: "Fetch balances from client", + Key: taskNameFetchBalances, + }) + if err != nil { + return err + } + + err = scheduler.Schedule(ctx, taskBalances, models.TaskSchedulerOptions{ + ScheduleOption: models.OPTIONS_RUN_NOW, + Restart: true, + }) + if err != nil && !errors.Is(err, task.ErrAlreadyScheduled) { + return err + } + return nil } } @@ -70,20 +86,18 @@ func ingestAccountsBatch( return err } - batch = append(batch, ingestion.AccountBatchElement{ - Account: &models.Account{ - ID: models.AccountID{ - Reference: account.ID, - Provider: models.ConnectorProviderCurrencyCloud, - }, - // Moneycorp does not send the opening date of the account - CreatedAt: account.CreatedAt, - Reference: account.ID, - Provider: models.ConnectorProviderCurrencyCloud, - AccountName: account.AccountName, - Type: models.AccountTypeInternal, - RawData: raw, + batch = append(batch, &models.Account{ + ID: models.AccountID{ + Reference: account.ID, + Provider: models.ConnectorProviderCurrencyCloud, }, + // Moneycorp does not send the opening date of the account + CreatedAt: account.CreatedAt, + Reference: account.ID, + Provider: models.ConnectorProviderCurrencyCloud, + AccountName: account.AccountName, + Type: models.AccountTypeInternal, + RawData: raw, }) } diff --git a/components/payments/internal/app/connectors/currencycloud/task_fetch_balances.go b/components/payments/internal/app/connectors/currencycloud/task_fetch_balances.go new file mode 100644 index 0000000000..e4d2b60d77 --- /dev/null +++ b/components/payments/internal/app/connectors/currencycloud/task_fetch_balances.go @@ -0,0 +1,75 @@ +package currencycloud + +import ( + "context" + "fmt" + "strconv" + "time" + + "github.com/formancehq/payments/internal/app/connectors/currencycloud/client" + "github.com/formancehq/payments/internal/app/ingestion" + "github.com/formancehq/payments/internal/app/models" + "github.com/formancehq/payments/internal/app/task" + "github.com/formancehq/stack/libs/go-libs/logging" +) + +func taskFetchBalances(logger logging.Logger, client *client.Client) task.Task { + return func( + ctx context.Context, + ingester ingestion.Ingester, + ) error { + logger.Info(taskNameFetchAccounts) + + page := 1 + for { + if page < 0 { + break + } + + pagedBalances, nextPage, err := client.GetBalances(ctx, page) + if err != nil { + return err + } + + page = nextPage + + if err := ingestBalancesBatch(ctx, ingester, pagedBalances); err != nil { + return err + } + } + + return nil + } +} + +func ingestBalancesBatch( + ctx context.Context, + ingester ingestion.Ingester, + balances []*client.Balance, +) error { + batch := ingestion.BalanceBatch{} + now := time.Now() + for _, balance := range balances { + amount, err := strconv.ParseFloat(balance.Amount, 64) + if err != nil { + return err + } + + batch = append(batch, &models.Balance{ + AccountID: models.AccountID{ + Reference: balance.AccountID, + Provider: models.ConnectorProviderCurrencyCloud, + }, + Currency: fmt.Sprintf("%s/2", balance.Currency), + Balance: int64(amount * 100), + CreatedAt: now, + LastUpdatedAt: now, + }) + } + + if err := ingester.IngestBalances(ctx, batch, true); err != nil { + return err + } + + return nil +} diff --git a/components/payments/internal/app/connectors/currencycloud/task_resolve.go b/components/payments/internal/app/connectors/currencycloud/task_resolve.go index 69d17667f3..cea6a3be6e 100644 --- a/components/payments/internal/app/connectors/currencycloud/task_resolve.go +++ b/components/payments/internal/app/connectors/currencycloud/task_resolve.go @@ -14,6 +14,7 @@ const ( taskNameMain = "main" taskNameFetchTransactions = "fetch-transactions" taskNameFetchAccounts = "fetch-accounts" + taskNameFetchBalances = "fetch-balances" ) // TaskDescriptor is the definition of a task. @@ -46,6 +47,8 @@ func resolveTasks(logger logging.Logger, config Config) func(taskDefinition Task return taskFetchAccounts(logger, currencyCloudClient) case taskNameFetchTransactions: return taskFetchTransactions(logger, currencyCloudClient, config) + case taskNameFetchBalances: + return taskFetchBalances(logger, currencyCloudClient) } // This should never happen. diff --git a/components/payments/internal/app/connectors/mangopay/client/transactions.go b/components/payments/internal/app/connectors/mangopay/client/transactions.go index 4c47631842..c056dcb1d4 100644 --- a/components/payments/internal/app/connectors/mangopay/client/transactions.go +++ b/components/payments/internal/app/connectors/mangopay/client/transactions.go @@ -49,7 +49,7 @@ func (c *Client) GetTransactions(ctx context.Context, walletsID string, page int resp, err := c.httpClient.Do(req) if err != nil { - return nil, fmt.Errorf("failed to login: %w", err) + return nil, fmt.Errorf("failed to get transactions: %w", err) } defer func() { @@ -61,7 +61,7 @@ func (c *Client) GetTransactions(ctx context.Context, walletsID string, page int var payments []*Payment if err := json.NewDecoder(resp.Body).Decode(&payments); err != nil { - return nil, fmt.Errorf("failed to unmarshal login response body: %w", err) + return nil, fmt.Errorf("failed to unmarshal transactions response body: %w", err) } return payments, nil diff --git a/components/payments/internal/app/connectors/mangopay/client/users.go b/components/payments/internal/app/connectors/mangopay/client/users.go index 42ef952755..50b82f4841 100644 --- a/components/payments/internal/app/connectors/mangopay/client/users.go +++ b/components/payments/internal/app/connectors/mangopay/client/users.go @@ -44,7 +44,7 @@ func (c *Client) getUsers(ctx context.Context, page int) ([]*user, error) { resp, err := c.httpClient.Do(req) if err != nil { - return nil, fmt.Errorf("failed to login: %w", err) + return nil, fmt.Errorf("failed to get users: %w", err) } defer func() { @@ -56,7 +56,7 @@ func (c *Client) getUsers(ctx context.Context, page int) ([]*user, error) { var users []*user if err := json.NewDecoder(resp.Body).Decode(&users); err != nil { - return nil, fmt.Errorf("failed to unmarshal login response body: %w", err) + return nil, fmt.Errorf("failed to unmarshal users response body: %w", err) } return users, nil diff --git a/components/payments/internal/app/connectors/mangopay/client/wallets.go b/components/payments/internal/app/connectors/mangopay/client/wallets.go index f692de400b..f4a2780928 100644 --- a/components/payments/internal/app/connectors/mangopay/client/wallets.go +++ b/components/payments/internal/app/connectors/mangopay/client/wallets.go @@ -12,6 +12,10 @@ type wallet struct { Description string `json:"Description"` CreationDate int64 `json:"CreationDate"` Currency string `json:"Currency"` + Balance struct { + Currency string `json:"Currency"` + Amount int64 `json:"Amount"` + } `json:"Balance"` } func (c *Client) GetWallets(ctx context.Context, userID string, page int) ([]*wallet, error) { @@ -28,7 +32,7 @@ func (c *Client) GetWallets(ctx context.Context, userID string, page int) ([]*wa resp, err := c.httpClient.Do(req) if err != nil { - return nil, fmt.Errorf("failed to login: %w", err) + return nil, fmt.Errorf("failed to get wallets: %w", err) } defer func() { @@ -40,7 +44,7 @@ func (c *Client) GetWallets(ctx context.Context, userID string, page int) ([]*wa var wallets []*wallet if err := json.NewDecoder(resp.Body).Decode(&wallets); err != nil { - return nil, fmt.Errorf("failed to unmarshal login response body: %w", err) + return nil, fmt.Errorf("failed to unmarshal wallets response body: %w", err) } return wallets, nil diff --git a/components/payments/internal/app/connectors/mangopay/task_fetch_wallets.go b/components/payments/internal/app/connectors/mangopay/task_fetch_wallets.go index f266f52504..5dff703518 100644 --- a/components/payments/internal/app/connectors/mangopay/task_fetch_wallets.go +++ b/components/payments/internal/app/connectors/mangopay/task_fetch_wallets.go @@ -32,7 +32,9 @@ func taskFetchWallets(logger logging.Logger, client *client.Client, userID strin } var accountBatch ingestion.AccountBatch + var balanceBatch ingestion.BalanceBatch var transactionTasks []models.TaskDescriptor + now := time.Now() for _, wallet := range pagedWallets { transactionTask, err := models.EncodeTaskDescriptor(TaskDescriptor{ Name: "Fetch transactions from client by user and wallets", @@ -50,22 +52,31 @@ func taskFetchWallets(logger logging.Logger, client *client.Client, userID strin } transactionTasks = append(transactionTasks, transactionTask) - accountBatch = append(accountBatch, ingestion.AccountBatchElement{ - Account: &models.Account{ - ID: models.AccountID{ - Reference: wallet.ID, - Provider: models.ConnectorProviderMangopay, - }, - CreatedAt: time.Unix(wallet.CreationDate, 0), - Reference: wallet.ID, - Provider: models.ConnectorProviderMangopay, - DefaultCurrency: wallet.Currency, - AccountName: wallet.Description, - // Wallets are internal accounts on our side, since we - // can have their balances. - Type: models.AccountTypeInternal, - RawData: buf, + accountBatch = append(accountBatch, &models.Account{ + ID: models.AccountID{ + Reference: wallet.ID, + Provider: models.ConnectorProviderMangopay, }, + CreatedAt: time.Unix(wallet.CreationDate, 0), + Reference: wallet.ID, + Provider: models.ConnectorProviderMangopay, + DefaultCurrency: wallet.Currency, + AccountName: wallet.Description, + // Wallets are internal accounts on our side, since we + // can have their balances. + Type: models.AccountTypeInternal, + RawData: buf, + }) + + balanceBatch = append(balanceBatch, &models.Balance{ + AccountID: models.AccountID{ + Reference: wallet.ID, + Provider: models.ConnectorProviderMangopay, + }, + Currency: wallet.Balance.Currency, + Balance: wallet.Balance.Amount, + CreatedAt: now, + LastUpdatedAt: now, }) } @@ -73,6 +84,10 @@ func taskFetchWallets(logger logging.Logger, client *client.Client, userID strin return err } + if err := ingester.IngestBalances(ctx, balanceBatch, false); err != nil { + return err + } + for _, transactionTask := range transactionTasks { err = scheduler.Schedule(ctx, transactionTask, models.TaskSchedulerOptions{ ScheduleOption: models.OPTIONS_RUN_NOW, diff --git a/components/payments/internal/app/connectors/modulr/task_fetch_accounts.go b/components/payments/internal/app/connectors/modulr/task_fetch_accounts.go index 9dc83d7197..fa82c0e884 100644 --- a/components/payments/internal/app/connectors/modulr/task_fetch_accounts.go +++ b/components/payments/internal/app/connectors/modulr/task_fetch_accounts.go @@ -4,6 +4,8 @@ import ( "context" "encoding/json" "errors" + "fmt" + "strconv" "time" "github.com/formancehq/payments/internal/app/ingestion" @@ -62,7 +64,10 @@ func ingestAccountsBatch( ingester ingestion.Ingester, accounts []*client.Account, ) error { - batch := ingestion.AccountBatch{} + accountsBatch := ingestion.AccountBatch{} + balancesBatch := ingestion.BalanceBatch{} + + now := time.Now() for _, account := range accounts { raw, err := json.Marshal(account) if err != nil { @@ -74,24 +79,43 @@ func ingestAccountsBatch( return err } - batch = append(batch, ingestion.AccountBatchElement{ - Account: &models.Account{ - ID: models.AccountID{ - Reference: account.ID, - Provider: models.ConnectorProviderModulr, - }, - CreatedAt: openingDate, - Reference: account.ID, - Provider: models.ConnectorProviderModulr, - DefaultCurrency: account.Currency, - AccountName: account.Name, - Type: models.AccountTypeInternal, - RawData: raw, + accountsBatch = append(accountsBatch, &models.Account{ + ID: models.AccountID{ + Reference: account.ID, + Provider: models.ConnectorProviderModulr, }, + CreatedAt: openingDate, + Reference: account.ID, + Provider: models.ConnectorProviderModulr, + DefaultCurrency: account.Currency, + AccountName: account.Name, + Type: models.AccountTypeInternal, + RawData: raw, }) + + // TODO(polo): move to bigints + balance, err := strconv.ParseFloat(account.Balance, 64) + if err != nil { + return err + } + + balancesBatch = append(balancesBatch, &models.Balance{ + AccountID: models.AccountID{ + Reference: account.ID, + Provider: models.ConnectorProviderModulr, + }, + Currency: fmt.Sprintf("%s/2", account.Currency), + Balance: int64(balance * 100), + CreatedAt: now, + LastUpdatedAt: now, + }) + } + + if err := ingester.IngestAccounts(ctx, accountsBatch); err != nil { + return err } - if err := ingester.IngestAccounts(ctx, batch); err != nil { + if err := ingester.IngestBalances(ctx, balancesBatch, false); err != nil { return err } diff --git a/components/payments/internal/app/connectors/moneycorp/client/accounts.go b/components/payments/internal/app/connectors/moneycorp/client/accounts.go index 177f590eac..2c6ac5bb6a 100644 --- a/components/payments/internal/app/connectors/moneycorp/client/accounts.go +++ b/components/payments/internal/app/connectors/moneycorp/client/accounts.go @@ -35,7 +35,7 @@ func (c *Client) GetAccounts(ctx context.Context, page int, pageSize int) ([]*Ac resp, err := c.httpClient.Do(req) if err != nil { - return nil, fmt.Errorf("failed to login: %w", err) + return nil, fmt.Errorf("failed to get accounts: %w", err) } defer func() { @@ -47,7 +47,7 @@ func (c *Client) GetAccounts(ctx context.Context, page int, pageSize int) ([]*Ac var accounts accountsResponse if err := json.NewDecoder(resp.Body).Decode(&accounts); err != nil { - return nil, fmt.Errorf("failed to unmarshal login response body: %w", err) + return nil, fmt.Errorf("failed to unmarshal accounts response body: %w", err) } return accounts.Accounts, nil diff --git a/components/payments/internal/app/connectors/moneycorp/client/balances.go b/components/payments/internal/app/connectors/moneycorp/client/balances.go new file mode 100644 index 0000000000..35942a89de --- /dev/null +++ b/components/payments/internal/app/connectors/moneycorp/client/balances.go @@ -0,0 +1,57 @@ +package client + +import ( + "context" + "encoding/json" + "fmt" + "net/http" +) + +type balancesResponse struct { + Balances []*Balance `json:"data"` +} + +type Balance struct { + ID string `json:"id"` + Attributes struct { + CurrencyCode string `json:"currencyCode"` + OverallBalance float64 `json:"overallBalance"` + AvailableBalance float64 `json:"availableBalance"` + ClearedBalance float64 `json:"clearedBalance"` + ReservedBalance float64 `json:"reservedBalance"` + UnclearedBalance float64 `json:"unclearedBalance"` + } `json:"attributes"` +} + +func (c *Client) GetAccountBalances(ctx context.Context, accountID string) ([]*Balance, error) { + endpoint := fmt.Sprintf("%s/accounts/%s/balances", c.endpoint, accountID) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, http.NoBody) + if err != nil { + return nil, fmt.Errorf("failed to create login request: %w", err) + } + + req.Header.Set("Content-Type", "application/json") + + resp, err := c.httpClient.Do(req) + if err != nil { + return nil, fmt.Errorf("failed to get account balances: %w", err) + } + + defer func() { + err = resp.Body.Close() + if err != nil { + c.logger.Error(err) + } + }() + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("failed to get balances: %s", resp.Status) + } + + var balances balancesResponse + if err := json.NewDecoder(resp.Body).Decode(&balances); err != nil { + return nil, fmt.Errorf("failed to unmarshal balances response body: %w", err) + } + + return balances.Balances, nil +} diff --git a/components/payments/internal/app/connectors/moneycorp/client/transactions.go b/components/payments/internal/app/connectors/moneycorp/client/transactions.go index dc0ba7511e..e95778979d 100644 --- a/components/payments/internal/app/connectors/moneycorp/client/transactions.go +++ b/components/payments/internal/app/connectors/moneycorp/client/transactions.go @@ -43,7 +43,7 @@ func (c *Client) GetTransactions(ctx context.Context, accountID string, page, pa resp, err := c.httpClient.Do(req) if err != nil { - return nil, fmt.Errorf("failed to login: %w", err) + return nil, fmt.Errorf("failed to get transactions: %w", err) } defer func() { @@ -53,9 +53,13 @@ func (c *Client) GetTransactions(ctx context.Context, accountID string, page, pa } }() + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("failed to get transactions: %w", err) + } + var transactions transactionsResponse if err := json.NewDecoder(resp.Body).Decode(&transactions); err != nil { - return nil, fmt.Errorf("failed to unmarshal login response body: %w", err) + return nil, fmt.Errorf("failed to unmarshal transactions response body: %w", err) } return transactions.Transactions, nil diff --git a/components/payments/internal/app/connectors/moneycorp/task_fetch_accounts.go b/components/payments/internal/app/connectors/moneycorp/task_fetch_accounts.go index 06529c45bf..c5d30eeca0 100644 --- a/components/payments/internal/app/connectors/moneycorp/task_fetch_accounts.go +++ b/components/payments/internal/app/connectors/moneycorp/task_fetch_accounts.go @@ -54,6 +54,23 @@ func taskFetchAccounts(logger logging.Logger, client *client.Client) task.Task { if err != nil && !errors.Is(err, task.ErrAlreadyScheduled) { return err } + + balancesTask, err := models.EncodeTaskDescriptor(TaskDescriptor{ + Name: "Fetch balances from client by account", + Key: taskNameFetchBalances, + AccountID: account.ID, + }) + + if err != nil { + return err + } + err = scheduler.Schedule(ctx, balancesTask, models.TaskSchedulerOptions{ + ScheduleOption: models.OPTIONS_RUN_NOW, + Restart: true, + }) + if err != nil && !errors.Is(err, task.ErrAlreadyScheduled) { + return err + } } if len(pagedAccounts) < pageSize { @@ -77,20 +94,18 @@ func ingestAccountsBatch( return err } - batch = append(batch, ingestion.AccountBatchElement{ - Account: &models.Account{ - ID: models.AccountID{ - Reference: account.ID, - Provider: models.ConnectorProviderMoneycorp, - }, - // Moneycorp does not send the opening date of the account - CreatedAt: time.Now(), - Reference: account.ID, - Provider: models.ConnectorProviderMoneycorp, - AccountName: account.Attributes.AccountName, - Type: models.AccountTypeInternal, - RawData: raw, + batch = append(batch, &models.Account{ + ID: models.AccountID{ + Reference: account.ID, + Provider: models.ConnectorProviderMoneycorp, }, + // Moneycorp does not send the opening date of the account + CreatedAt: time.Now(), + Reference: account.ID, + Provider: models.ConnectorProviderMoneycorp, + AccountName: account.Attributes.AccountName, + Type: models.AccountTypeInternal, + RawData: raw, }) } diff --git a/components/payments/internal/app/connectors/moneycorp/task_fetch_balances.go b/components/payments/internal/app/connectors/moneycorp/task_fetch_balances.go new file mode 100644 index 0000000000..186eb3bcd2 --- /dev/null +++ b/components/payments/internal/app/connectors/moneycorp/task_fetch_balances.go @@ -0,0 +1,58 @@ +package moneycorp + +import ( + "context" + "math" + "time" + + "github.com/formancehq/payments/internal/app/connectors/currency" + "github.com/formancehq/payments/internal/app/connectors/moneycorp/client" + "github.com/formancehq/payments/internal/app/ingestion" + "github.com/formancehq/payments/internal/app/models" + "github.com/formancehq/payments/internal/app/task" + "github.com/formancehq/stack/libs/go-libs/logging" +) + +func taskFetchBalances(logger logging.Logger, client *client.Client, accountID string) task.Task { + return func( + ctx context.Context, + ingester ingestion.Ingester, + ) error { + logger.Info("Fetching transactions for account", accountID) + + balances, err := client.GetAccountBalances(ctx, accountID) + if err != nil { + return err + } + + if err := ingestBalancesBatch(ctx, ingester, accountID, balances); err != nil { + return err + } + + return nil + } +} + +func ingestBalancesBatch( + ctx context.Context, + ingester ingestion.Ingester, + accountID string, + balances []*client.Balance, +) error { + batch := ingestion.BalanceBatch{} + now := time.Now() + for _, balance := range balances { + batch = append(batch, &models.Balance{ + AccountID: models.AccountID{ + Reference: accountID, + Provider: models.ConnectorProviderMoneycorp, + }, + Currency: currency.FormatAsset(balance.Attributes.CurrencyCode).String(), + Balance: int64(balance.Attributes.AvailableBalance * math.Pow(10, float64(currency.GetPrecision(balance.Attributes.CurrencyCode)))), + CreatedAt: now, + LastUpdatedAt: now, + }) + } + + return ingester.IngestBalances(ctx, batch, false) +} diff --git a/components/payments/internal/app/connectors/moneycorp/task_resolve.go b/components/payments/internal/app/connectors/moneycorp/task_resolve.go index a616ee3724..9b08c3ee6d 100644 --- a/components/payments/internal/app/connectors/moneycorp/task_resolve.go +++ b/components/payments/internal/app/connectors/moneycorp/task_resolve.go @@ -12,6 +12,7 @@ const ( taskNameMain = "main" taskNameFetchAccounts = "fetch-accounts" taskNameFetchTransactions = "fetch-transactions" + taskNameFetchBalances = "fetch-balances" ) // TaskDescriptor is the definition of a task. @@ -43,6 +44,8 @@ func resolveTasks(logger logging.Logger, config Config) func(taskDefinition Task return taskFetchAccounts(logger, moneycorpClient) case taskNameFetchTransactions: return taskFetchTransactions(logger, moneycorpClient, taskDescriptor.AccountID) + case taskNameFetchBalances: + return taskFetchBalances(logger, moneycorpClient, taskDescriptor.AccountID) } // This should never happen. diff --git a/components/payments/internal/app/connectors/stripe/client.go b/components/payments/internal/app/connectors/stripe/client.go index f5703d80fd..955b76e0a1 100644 --- a/components/payments/internal/app/connectors/stripe/client.go +++ b/components/payments/internal/app/connectors/stripe/client.go @@ -15,6 +15,7 @@ import ( const ( balanceTransactionsEndpoint = "https://api.stripe.com/v1/balance_transactions" accountsEndpoint = "https://api.stripe.com/v1/accounts" + balanceEndpoint = "https://api.stripe.com/v1/balance" ) type ClientOption interface { @@ -37,6 +38,7 @@ func QueryParam(key, value string) ClientOptionFn { type Client interface { Accounts(ctx context.Context, options ...ClientOption) ([]*stripe.Account, bool, error) BalanceTransactions(ctx context.Context, options ...ClientOption) ([]*stripe.BalanceTransaction, bool, error) + Balance(ctx context.Context, options ...ClientOption) (*stripe.Balance, error) ForAccount(account string) Client } @@ -121,6 +123,10 @@ func (d *DefaultClient) BalanceTransactions(ctx context.Context, return asBalanceTransactions, rsp.HasMore, nil } +type BalanceResponse struct { + *stripe.Balance +} + func (d *DefaultClient) Accounts(ctx context.Context, options ...ClientOption, ) ([]*stripe.Account, bool, error) { @@ -178,6 +184,50 @@ func (d *DefaultClient) Accounts(ctx context.Context, return accounts, rsp.HasMore, nil } +func (d *DefaultClient) Balance(ctx context.Context, options ...ClientOption) (*stripe.Balance, error) { + if d.stripeAccount == "" { + return nil, errors.New("stripe account is required") + } + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, balanceEndpoint, nil) + if err != nil { + return nil, errors.Wrap(err, "creating http request") + } + + for _, opt := range options { + opt.apply(req) + } + + req.Header.Set("Stripe-Account", d.stripeAccount) + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.SetBasicAuth(d.apiKey, "") // gfyrag: really weird authentication right? + + var httpResponse *http.Response + + httpResponse, err = d.httpClient.Do(req) + if err != nil { + return nil, errors.Wrap(err, "doing request") + } + defer httpResponse.Body.Close() + + if httpResponse.StatusCode != http.StatusOK { + return nil, fmt.Errorf("unexpected status code: %d", httpResponse.StatusCode) + } + + type balanceResponse struct { + BalanceResponse + } + + rsp := &balanceResponse{} + + err = json.NewDecoder(httpResponse.Body).Decode(rsp) + if err != nil { + return nil, errors.Wrap(err, "decoding response") + } + + return rsp.Balance, nil +} + func newHTTPClient() *http.Client { return &http.Client{ Transport: otelhttp.NewTransport(http.DefaultTransport), diff --git a/components/payments/internal/app/connectors/stripe/task_fetch_accounts.go b/components/payments/internal/app/connectors/stripe/task_fetch_accounts.go index 14c76459f2..bdbc6935b7 100644 --- a/components/payments/internal/app/connectors/stripe/task_fetch_accounts.go +++ b/components/payments/internal/app/connectors/stripe/task_fetch_accounts.go @@ -34,8 +34,8 @@ func FetchAccountsTask(config Config, client *DefaultClient) task.Task { } for _, account := range batch { - descriptor, err := models.EncodeTaskDescriptor(TaskDescriptor{ - Name: "Fetch balance transactions for a specific connected account", + transactionsTask, err := models.EncodeTaskDescriptor(TaskDescriptor{ + Name: "Fetch transactions for a specific connected account", Key: taskNameFetchPaymentsForAccounts, Account: account.ID, }) @@ -43,7 +43,24 @@ func FetchAccountsTask(config Config, client *DefaultClient) task.Task { return errors.Wrap(err, "failed to transform task descriptor") } - err = scheduler.Schedule(ctx, descriptor, models.TaskSchedulerOptions{ + err = scheduler.Schedule(ctx, transactionsTask, models.TaskSchedulerOptions{ + ScheduleOption: models.OPTIONS_RUN_NOW, + Restart: true, + }) + if err != nil && !errors.Is(err, task.ErrAlreadyScheduled) { + return errors.Wrap(err, "scheduling connected account") + } + + balancesTask, err := models.EncodeTaskDescriptor(TaskDescriptor{ + Name: "Fetch balance for a specific connected account", + Key: taskNameFetchBalances, + Account: account.ID, + }) + if err != nil { + return errors.Wrap(err, "failed to transform task descriptor") + } + + err = scheduler.Schedule(ctx, balancesTask, models.TaskSchedulerOptions{ ScheduleOption: models.OPTIONS_RUN_NOW, Restart: true, }) @@ -80,19 +97,17 @@ func ingestAccountsBatch( return err } - batch = append(batch, ingestion.AccountBatchElement{ - Account: &models.Account{ - ID: models.AccountID{ - Reference: account.ID, - Provider: models.ConnectorProviderStripe, - }, - CreatedAt: time.Unix(account.Created, 0), - Reference: account.ID, - Provider: models.ConnectorProviderStripe, - DefaultCurrency: string(account.DefaultCurrency), - Type: models.AccountTypeInternal, - RawData: raw, + batch = append(batch, &models.Account{ + ID: models.AccountID{ + Reference: account.ID, + Provider: models.ConnectorProviderStripe, }, + CreatedAt: time.Unix(account.Created, 0), + Reference: account.ID, + Provider: models.ConnectorProviderStripe, + DefaultCurrency: string(account.DefaultCurrency), + Type: models.AccountTypeInternal, + RawData: raw, }) } diff --git a/components/payments/internal/app/connectors/stripe/task_fetch_balances.go b/components/payments/internal/app/connectors/stripe/task_fetch_balances.go new file mode 100644 index 0000000000..4531fd781f --- /dev/null +++ b/components/payments/internal/app/connectors/stripe/task_fetch_balances.go @@ -0,0 +1,46 @@ +package stripe + +import ( + "context" + "time" + + "github.com/formancehq/payments/internal/app/connectors/currency" + "github.com/formancehq/payments/internal/app/ingestion" + "github.com/formancehq/payments/internal/app/models" + "github.com/formancehq/payments/internal/app/task" + "github.com/formancehq/stack/libs/go-libs/logging" +) + +func BalancesTask(config Config, account string, client *DefaultClient) func(ctx context.Context, logger logging.Logger, + ingester ingestion.Ingester, resolver task.StateResolver) error { + return func(ctx context.Context, logger logging.Logger, ingester ingestion.Ingester, + resolver task.StateResolver, + ) error { + logger.Infof("Create new balances trigger for account %s", account) + balances, err := client.ForAccount(account).Balance(ctx) + if err != nil { + return err + } + + batch := ingestion.BalanceBatch{} + now := time.Now() + for _, balance := range balances.Available { + batch = append(batch, &models.Balance{ + AccountID: models.AccountID{ + Reference: account, + Provider: models.ConnectorProviderStripe, + }, + Currency: currency.FormatAsset(string(balance.Currency)).String(), + Balance: balance.Value, + CreatedAt: now, + LastUpdatedAt: now, + }) + } + + if err := ingester.IngestBalances(ctx, batch, false); err != nil { + return err + } + + return nil + } +} diff --git a/components/payments/internal/app/connectors/stripe/task_resolve.go b/components/payments/internal/app/connectors/stripe/task_resolve.go index fe9d4ac60d..7043e700a4 100644 --- a/components/payments/internal/app/connectors/stripe/task_resolve.go +++ b/components/payments/internal/app/connectors/stripe/task_resolve.go @@ -10,6 +10,7 @@ const ( taskNameFetchAccounts = "fetch_accounts" taskNameFetchPaymentsForAccounts = "fetch_transactions" taskNameFetchPayments = "fetch_payments" + taskNameFetchBalances = "fetch_balance" ) // TaskDescriptor is the definition of a task. @@ -41,6 +42,8 @@ func resolveTasks(logger logging.Logger, config Config) func(taskDefinition Task return FetchAccountsTask(config, client) case taskNameFetchPaymentsForAccounts: return ConnectedAccountTask(config, taskDescriptor.Account, client) + case taskNameFetchBalances: + return BalancesTask(config, taskDescriptor.Account, client) default: // For compatibility with old tasks return ConnectedAccountTask(config, taskDescriptor.Account, client) diff --git a/components/payments/internal/app/connectors/stripe/utils_test.go b/components/payments/internal/app/connectors/stripe/utils_test.go index 01770cf12f..912d402408 100644 --- a/components/payments/internal/app/connectors/stripe/utils_test.go +++ b/components/payments/internal/app/connectors/stripe/utils_test.go @@ -98,6 +98,12 @@ func (m *ClientMock) Accounts(ctx context.Context, return nil, false, nil } +func (m *ClientMock) Balance(ctx context.Context, + options ...ClientOption, +) (*stripe.Balance, error) { + return nil, nil +} + func (m *ClientMock) BalanceTransactions(ctx context.Context, options ...ClientOption, ) ([]*stripe.BalanceTransaction, bool, error) { diff --git a/components/payments/internal/app/connectors/wise/task_fetch_profiles.go b/components/payments/internal/app/connectors/wise/task_fetch_profiles.go index d033d61f24..c661a28f22 100644 --- a/components/payments/internal/app/connectors/wise/task_fetch_profiles.go +++ b/components/payments/internal/app/connectors/wise/task_fetch_profiles.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "fmt" + "time" "github.com/formancehq/payments/internal/app/connectors/wise/client" "github.com/formancehq/payments/internal/app/ingestion" @@ -72,32 +73,47 @@ func ingestAccountsBatch( return nil } - batch := ingestion.AccountBatch{} + accountsBatch := ingestion.AccountBatch{} + balancesBatch := ingestion.BalanceBatch{} + now := time.Now() for _, balance := range balances { raw, err := json.Marshal(balance) if err != nil { return err } - batch = append(batch, ingestion.AccountBatchElement{ - Account: &models.Account{ - ID: models.AccountID{ - Reference: fmt.Sprintf("%d", balance.ID), - Provider: models.ConnectorProviderWise, - }, - // Moneycorp does not send the opening date of the account - CreatedAt: balance.CreationTime, - Reference: fmt.Sprintf("%d", balance.ID), - Provider: models.ConnectorProviderWise, - DefaultCurrency: balance.Currency, - AccountName: balance.Name, - Type: models.AccountTypeInternal, - RawData: raw, + accountsBatch = append(accountsBatch, &models.Account{ + ID: models.AccountID{ + Reference: fmt.Sprintf("%d", balance.ID), + Provider: models.ConnectorProviderWise, }, + // Moneycorp does not send the opening date of the account + CreatedAt: balance.CreationTime, + Reference: fmt.Sprintf("%d", balance.ID), + Provider: models.ConnectorProviderWise, + DefaultCurrency: balance.Currency, + AccountName: balance.Name, + Type: models.AccountTypeInternal, + RawData: raw, }) + + balancesBatch = append(balancesBatch, &models.Balance{ + AccountID: models.AccountID{ + Reference: fmt.Sprintf("%d", balance.ID), + Provider: models.ConnectorProviderWise, + }, + Currency: models.PaymentAsset(fmt.Sprintf("%s/2", balance.Amount.Currency)).String(), + Balance: int64(balance.Amount.Value * 100), + CreatedAt: now, + LastUpdatedAt: now, + }) + } + + if err := ingester.IngestAccounts(ctx, accountsBatch); err != nil { + return err } - if err := ingester.IngestAccounts(ctx, batch); err != nil { + if err := ingester.IngestBalances(ctx, balancesBatch, false); err != nil { return err } diff --git a/components/payments/internal/app/ingestion/accounts.go b/components/payments/internal/app/ingestion/accounts.go index 88e349b3d8..9ba24dbdfc 100644 --- a/components/payments/internal/app/ingestion/accounts.go +++ b/components/payments/internal/app/ingestion/accounts.go @@ -13,11 +13,7 @@ import ( "github.com/formancehq/payments/internal/app/models" ) -type AccountBatchElement struct { - Account *models.Account -} - -type AccountBatch []AccountBatchElement +type AccountBatch []*models.Account type AccountIngesterFn func(ctx context.Context, batch AccountBatch, commitState any) error @@ -33,17 +29,12 @@ func (i *DefaultIngester) IngestAccounts(ctx context.Context, batch AccountBatch "startingAt": startingAt, }).Debugf("Ingest accounts batch") - accounts := make([]*models.Account, len(batch)) - for batchIdx := range batch { - accounts[batchIdx] = batch[batchIdx].Account - } - - if err := i.repo.UpsertAccounts(ctx, i.provider, accounts); err != nil { + if err := i.repo.UpsertAccounts(ctx, i.provider, batch); err != nil { return fmt.Errorf("error upserting accounts: %w", err) } err := i.publisher.Publish(events.TopicPayments, - publish.NewMessage(ctx, messages.NewEventSavedAccounts(accounts))) + publish.NewMessage(ctx, messages.NewEventSavedAccounts(batch))) if err != nil { logging.FromContext(ctx).Errorf("Publishing message: %w", err) } diff --git a/components/payments/internal/app/ingestion/balances.go b/components/payments/internal/app/ingestion/balances.go new file mode 100644 index 0000000000..a4a34f875b --- /dev/null +++ b/components/payments/internal/app/ingestion/balances.go @@ -0,0 +1,49 @@ +package ingestion + +import ( + "context" + "fmt" + "time" + + "github.com/formancehq/payments/internal/app/messages" + "github.com/formancehq/payments/internal/app/models" + "github.com/formancehq/payments/pkg/events" + "github.com/formancehq/stack/libs/go-libs/logging" + "github.com/formancehq/stack/libs/go-libs/publish" +) + +type BalanceBatch []*models.Balance + +type BalanceIngesterFn func(ctx context.Context, batch BalanceBatch) error + +func (fn BalanceIngesterFn) IngestBalances(ctx context.Context, batch BalanceBatch) error { + return fn(ctx, batch) +} + +func (i *DefaultIngester) IngestBalances(ctx context.Context, batch BalanceBatch, checkIfAccountExists bool) error { + startingAt := time.Now() + + logging.FromContext(ctx).WithFields(map[string]interface{}{ + "size": len(batch), + "startingAt": startingAt, + }).Debugf("Ingest balances batch") + + if err := i.repo.InsertBalances(ctx, batch, checkIfAccountExists); err != nil { + return fmt.Errorf("error inserting balances: %w", err) + } + + if err := i.publisher.Publish(events.TopicPayments, + publish.NewMessage(ctx, messages.NewEventSavedBalances(batch))); err != nil { + logging.FromContext(ctx).Errorf("Publishing message: %w", err) + } + + endedAt := time.Now() + + logging.FromContext(ctx).WithFields(map[string]interface{}{ + "size": len(batch), + "endedAt": endedAt, + "latency": endedAt.Sub(startingAt).String(), + }).Debugf("Accounts batch ingested") + + return nil +} diff --git a/components/payments/internal/app/ingestion/ingester.go b/components/payments/internal/app/ingestion/ingester.go index f858502acc..66661f37b9 100644 --- a/components/payments/internal/app/ingestion/ingester.go +++ b/components/payments/internal/app/ingestion/ingester.go @@ -13,6 +13,7 @@ import ( type Ingester interface { IngestPayments(ctx context.Context, batch PaymentBatch, commitState any) error IngestAccounts(ctx context.Context, batch AccountBatch) error + IngestBalances(ctx context.Context, batch BalanceBatch, checkIfAccountExists bool) error GetTransfer(ctx context.Context, transferID uuid.UUID) (models.Transfer, error) UpdateTransferStatus(ctx context.Context, transferID uuid.UUID, status models.TransferStatus, reference, err string) error } @@ -27,6 +28,7 @@ type DefaultIngester struct { type Repository interface { UpsertAccounts(ctx context.Context, provider models.ConnectorProvider, accounts []*models.Account) error UpsertPayments(ctx context.Context, provider models.ConnectorProvider, payments []*models.Payment) error + InsertBalances(ctx context.Context, balances []*models.Balance, checkIfAccountExists bool) error UpdateTaskState(ctx context.Context, provider models.ConnectorProvider, descriptor models.TaskDescriptor, state json.RawMessage) error GetTransfer(ctx context.Context, transferID uuid.UUID) (models.Transfer, error) diff --git a/components/payments/internal/app/messages/balances.go b/components/payments/internal/app/messages/balances.go new file mode 100644 index 0000000000..e4aa9bc6db --- /dev/null +++ b/components/payments/internal/app/messages/balances.go @@ -0,0 +1,36 @@ +package messages + +import ( + "time" + + "github.com/formancehq/payments/internal/app/models" + "github.com/formancehq/payments/pkg/events" +) + +type balanceMessagePayload struct { + CreatedAt time.Time `json:"createdAt"` + AccountID string `json:"accountID"` + Currency string `json:"currency"` + Balance int64 `json:"balance"` +} + +func NewEventSavedBalances(balances []*models.Balance) events.EventMessage { + payload := make([]balanceMessagePayload, len(balances)) + + for balanceIdx, balance := range balances { + payload[balanceIdx] = balanceMessagePayload{ + CreatedAt: balance.CreatedAt, + AccountID: balance.AccountID.String(), + Currency: balance.Currency, + Balance: balance.Balance, + } + } + + return events.EventMessage{ + Date: time.Now().UTC(), + App: events.EventApp, + Version: events.EventVersion, + Type: events.EventTypeSavedBalances, + Payload: payload, + } +} diff --git a/components/payments/internal/app/models/balance.go b/components/payments/internal/app/models/balance.go new file mode 100644 index 0000000000..16694ad96d --- /dev/null +++ b/components/payments/internal/app/models/balance.go @@ -0,0 +1,17 @@ +package models + +import ( + "time" + + "github.com/uptrace/bun" +) + +type Balance struct { + bun.BaseModel `bun:"accounts.balances"` + + AccountID AccountID `bun:"type:character varying,nullzero"` + Currency string + Balance int64 + CreatedAt time.Time + LastUpdatedAt time.Time +} diff --git a/components/payments/internal/app/storage/balances.go b/components/payments/internal/app/storage/balances.go new file mode 100644 index 0000000000..8d944018db --- /dev/null +++ b/components/payments/internal/app/storage/balances.go @@ -0,0 +1,212 @@ +package storage + +import ( + "context" + "fmt" + "sort" + "time" + + "github.com/formancehq/payments/internal/app/models" + "github.com/uptrace/bun" +) + +func (s *Storage) InsertBalances(ctx context.Context, balances []*models.Balance, checkIfAccountExists bool) error { + if len(balances) == 0 { + return nil + } + + type insertedBalance struct { + CreatedAt time.Time `bun:"created_at"` + AccountID string `bun:"account_id"` + Currency string `bun:"currency"` + } + insertedBalances := make([]insertedBalance, 0) + + query := s.db.NewInsert(). + Model((*models.Balance)(nil)). + With("cte1", s.db.NewValues(&balances)). + Column( + "created_at", + "account_id", + "balance", + "currency", + "last_updated_at", + ). + Returning("created_at, account_id, currency") + if checkIfAccountExists { + query = query.TableExpr(` + (SELECT * + FROM cte1 + WHERE EXISTS (SELECT 1 FROM accounts.account WHERE id = cte1.account_id) + AND cte1.balance != COALESCE((SELECT balance FROM accounts.balances WHERE account_id = cte1.account_id AND last_updated_at < cte1.last_updated_at AND currency = cte1.currency ORDER BY last_updated_at DESC LIMIT 1), cte1.balance+1) + ) data`) + } else { + query = query.TableExpr(` + (SELECT * + FROM cte1 + WHERE cte1.balance != COALESCE((SELECT balance FROM accounts.balances WHERE account_id = cte1.account_id AND last_updated_at < cte1.last_updated_at AND currency = cte1.currency ORDER BY last_updated_at DESC LIMIT 1), cte1.balance+1) + ) data`) + } + + err := query.Scan(ctx, &insertedBalances) + if err != nil { + return e("failed to create balances", err) + } + + if len(insertedBalances) != len(balances) { + balancesToUpdate := make([]*models.Balance, 0) + for i := range balances { + found := false + for _, insertedBalance := range insertedBalances { + if balances[i].AccountID.String() == insertedBalance.AccountID && + balances[i].Currency == insertedBalance.Currency { + found = true + break + } + } + if !found { + balancesToUpdate = append(balancesToUpdate, balances[i]) + } + } + + if len(balancesToUpdate) > 0 { + _, err := s.db.NewUpdate(). + Model((*models.Balance)(nil)). + With("cte1", s.db.NewValues(&balancesToUpdate)). + TableExpr(` + (SELECT (SELECT created_at FROM accounts.balances WHERE last_updated_at < cte1.last_updated_at AND account_id = cte1.account_id AND currency = cte1.currency ORDER BY last_updated_at DESC LIMIT 1), cte1.account_id, cte1.currency, cte1.last_updated_at FROM cte1) data + `). + Set("last_updated_at = data.last_updated_at"). + Where("balance.account_id = data.account_id AND balance.currency = data.currency AND balance.created_at = data.created_at"). + Exec(ctx) + if err != nil { + return e("failed to update balances", err) + } + } + } + + return nil +} + +func (s *Storage) ListBalances(ctx context.Context, balanceQuery BalanceQuery) ([]*models.Balance, PaginationDetails, error) { + var balances []*models.Balance + + query := s.db.NewSelect(). + Model(&balances) + + query = balanceQuery.Pagination.apply(query, "balance.created_at") + + query = applyBalanceQuery(query, balanceQuery) + + err := query.Scan(ctx) + if err != nil { + return nil, PaginationDetails{}, e("failed to list balances", err) + } + + var ( + hasMore = len(balances) > balanceQuery.Pagination.pageSize + hasPrevious bool + firstReference, lastReference string + ) + + if hasMore { + if balanceQuery.Pagination.cursor.Next || balanceQuery.Pagination.cursor.Reference == "" { + balances = balances[:balanceQuery.Pagination.pageSize] + } else { + balances = balances[1:] + } + } + + sort.Slice(balances, func(i, j int) bool { + return balances[i].CreatedAt.After(balances[j].CreatedAt) + }) + + if len(balances) > 0 { + firstReference = balances[0].CreatedAt.Format(time.RFC3339Nano) + lastReference = balances[len(balances)-1].CreatedAt.Format(time.RFC3339Nano) + + query = s.db.NewSelect().Model(&balances) + query = applyBalanceQuery(query, balanceQuery) + + hasPrevious, err = balanceQuery.Pagination.hasPrevious(ctx, query, "created_at", firstReference) + if err != nil { + return nil, PaginationDetails{}, fmt.Errorf("failed to check if there is a previous page: %w", err) + } + } + + paginationDetails, err := balanceQuery.Pagination.paginationDetails(hasMore, hasPrevious, firstReference, lastReference) + if err != nil { + return nil, PaginationDetails{}, fmt.Errorf("failed to get pagination details: %w", err) + } + + return balances, paginationDetails, nil +} + +func applyBalanceQuery(query *bun.SelectQuery, balanceQuery BalanceQuery) *bun.SelectQuery { + if balanceQuery.AccountID != nil { + query = query.Where("balance.account_id = ?", balanceQuery.AccountID) + } + + if balanceQuery.Currency != "" { + query = query.Where("balance.currency = ?", balanceQuery.Currency) + } + + if !balanceQuery.From.IsZero() { + query = query.Where("balance.last_updated_at >= ?", balanceQuery.From) + } + + if !balanceQuery.To.IsZero() { + query = query.Where("balance.last_updated_at < ?", balanceQuery.To) + } + + if balanceQuery.Limit > 0 { + query = query.Limit(balanceQuery.Limit) + } + + return query +} + +type BalanceQuery struct { + AccountID *models.AccountID + Currency string + From time.Time + To time.Time + Limit int + Pagination Paginator +} + +func NewBalanceQuery(pagination Paginator) BalanceQuery { + return BalanceQuery{ + Pagination: pagination, + } +} + +func (b BalanceQuery) WithAccountID(accountID *models.AccountID) BalanceQuery { + b.AccountID = accountID + + return b +} + +func (b BalanceQuery) WithCurrency(currency string) BalanceQuery { + b.Currency = currency + + return b +} + +func (b BalanceQuery) WithFrom(from time.Time) BalanceQuery { + b.From = from + + return b +} + +func (b BalanceQuery) WithTo(to time.Time) BalanceQuery { + b.To = to + + return b +} + +func (b BalanceQuery) WithLimit(limit int) BalanceQuery { + b.Limit = limit + + return b +} diff --git a/components/payments/internal/app/storage/migrations.go b/components/payments/internal/app/storage/migrations.go index ab4dd41895..a7d673f948 100644 --- a/components/payments/internal/app/storage/migrations.go +++ b/components/payments/internal/app/storage/migrations.go @@ -404,6 +404,38 @@ func registerMigrations(migrator *migrations.Migrator) { return err } + return nil + }, + }, + migrations.Migration{ + Up: func(tx bun.Tx) error { + // Since only one connector is inserting accounts, + // let's just delete the table, since connectors will be + // resetted. Delete it cascade, or we will have an error + _, err := tx.Exec(` + CREATE TABLE accounts.balances ( + created_at timestamp with time zone NOT NULL, + account_id CHARACTER VARYING NOT NULL, + currency text NOT NULL, + balance numeric NOT NULL DEFAULT 0, + last_updated_at timestamp with time zone NOT NULL, + PRIMARY KEY (account_id, created_at, currency) + ); + + CREATE INDEX idx_created_at_account_id_currency ON accounts.balances(account_id, last_updated_at desc, currency); + + ALTER TABLE accounts.balances ADD CONSTRAINT balances_account + FOREIGN KEY (account_id) + REFERENCES accounts.account (id) + ON DELETE CASCADE + NOT DEFERRABLE + INITIALLY IMMEDIATE + ; + `) + if err != nil { + return err + } + return nil }, }, diff --git a/components/payments/openapi.yaml b/components/payments/openapi.yaml index 6b28dd48d0..6a44f83eb7 100644 --- a/components/payments/openapi.yaml +++ b/components/payments/openapi.yaml @@ -64,6 +64,59 @@ paths: responses: '200': $ref: '#/components/responses/Accounts' + /accounts/{accountID}/balances: + get: + summary: Get account balances + operationId: getAccountBalances + tags: + - Payments + parameters: + - name: accountID + in: path + schema: + type: string + description: The account ID. + example: XXX + required: true + - name: limit + in: query + description: The maximum number of results to return per page. + required: false + schema: + type: integer + format: int64 + - name: currency + in: query + description: | + Filter balances by currency. + If not specified, all account's balances will be returned. + required: false + schema: + type: string + - name: from + in: query + description: | + Filter balances by date. + If not specified, all account's balances will be returned. + required: false + schema: + type: string + format: date-time + - name: to + in: query + description: | + Filter balances by date. + If not specified, default will be set to now. + required: false + schema: + type: string + format: date-time + - $ref: '#/components/parameters/PageSize' + - $ref: '#/components/parameters/Cursor' + - $ref: '#/components/parameters/Sort' + responses: + '200': + $ref: '#/components/responses/AccountBalances' /connectors: get: summary: List all installed connectors @@ -290,6 +343,12 @@ components: application/json: schema: $ref: '#/components/schemas/AccountsCursor' + AccountBalances: + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/BalancesCursor' Connectors: description: OK content: @@ -422,6 +481,22 @@ components: type: array items: $ref: '#/components/schemas/Account' + BalancesCursor: + type: object + required: + - cursor + properties: + cursor: + allOf: + - $ref: '#/components/schemas/CursorBase' + - type: object + required: + - data + properties: + data: + type: array + items: + $ref: '#/components/schemas/AccountBalance' TasksCursor: type: object required: @@ -880,6 +955,28 @@ components: raw: type: object nullable: true + AccountBalance: + type: object + required: + - accountId + - createdAt + - lastUpdatedAt + - currency + - balance + properties: + accountId: + type: string + createdAt: + type: string + format: date-time + lastUpdatedAt: + type: string + format: date-time + currency: + type: string + balance: + type: integer + format: int64 TaskBase: type: object required: diff --git a/components/payments/pkg/events/event.go b/components/payments/pkg/events/event.go index e063880f5b..55b26912b8 100644 --- a/components/payments/pkg/events/event.go +++ b/components/payments/pkg/events/event.go @@ -13,6 +13,7 @@ const ( EventTypeSavedPayments = "SAVED_PAYMENT" EventTypeSavedAccounts = "SAVED_ACCOUNT" + EventTypeSavedBalances = "SAVED_BALANCE" EventTypeConnectorReset = "CONNECTOR_RESET" ) diff --git a/openapi/build/generate.json b/openapi/build/generate.json index 5e3e9e4862..c7b1a6be51 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.20230725" + "version": "v1.0.20230726" }, "servers": [ { @@ -1908,6 +1908,80 @@ } } }, + "/api/payments/accounts/{accountID}/balances": { + "get": { + "summary": "Get account balances", + "operationId": "getAccountBalances", + "tags": [ + "Payments" + ], + "parameters": [ + { + "name": "accountID", + "in": "path", + "schema": { + "type": "string" + }, + "description": "The account ID.", + "example": "XXX", + "required": true + }, + { + "name": "limit", + "in": "query", + "description": "The maximum number of results to return per page.", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "currency", + "in": "query", + "description": "Filter balances by currency.\nIf not specified, all account's balances will be returned.\n", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "from", + "in": "query", + "description": "Filter balances by date.\nIf not specified, all account's balances will be returned.\n", + "required": false, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "Filter balances by date.\nIf not specified, default will be set to now.\n", + "required": false, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "$ref": "#/components/parameters/PageSize" + }, + { + "$ref": "#/components/parameters/Cursor" + }, + { + "$ref": "#/components/parameters/Sort" + } + ], + "responses": { + "200": { + "$ref": "#/components/responses/AccountBalances" + } + } + } + }, "/api/payments/connectors": { "get": { "summary": "List all installed connectors", @@ -4872,6 +4946,35 @@ } } }, + "BalancesCursor": { + "type": "object", + "required": [ + "cursor" + ], + "properties": { + "cursor": { + "allOf": [ + { + "$ref": "#/components/schemas/CursorBase" + }, + { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AccountBalance" + } + } + } + } + ] + } + } + }, "TasksCursor": { "type": "object", "required": [ @@ -5533,6 +5636,36 @@ } } }, + "AccountBalance": { + "type": "object", + "required": [ + "accountId", + "createdAt", + "lastUpdatedAt", + "currency", + "balance" + ], + "properties": { + "accountId": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "lastUpdatedAt": { + "type": "string", + "format": "date-time" + }, + "currency": { + "type": "string" + }, + "balance": { + "type": "integer", + "format": "int64" + } + } + }, "TaskBase": { "type": "object", "required": [ @@ -7657,6 +7790,16 @@ } } }, + "AccountBalances": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BalancesCursor" + } + } + } + }, "Connectors": { "description": "OK", "content": { diff --git a/sdks/go/README.md b/sdks/go/README.md index 30227012ab..962aa6c007 100755 --- a/sdks/go/README.md +++ b/sdks/go/README.md @@ -106,6 +106,7 @@ func main() { * [ConnectorsStripeTransfer](docs/payments/README.md#connectorsstripetransfer) - Transfer funds between Stripe accounts * [ConnectorsTransfer](docs/payments/README.md#connectorstransfer) - Transfer funds between Connector accounts +* [GetAccountBalances](docs/payments/README.md#getaccountbalances) - Get account balances * [GetConnectorTask](docs/payments/README.md#getconnectortask) - Read a specific task of the connector * [GetPayment](docs/payments/README.md#getpayment) - Get a payment * [InstallConnector](docs/payments/README.md#installconnector) - Install a connector diff --git a/sdks/go/docs/payments/README.md b/sdks/go/docs/payments/README.md index 3bc3babc32..0b1df16853 100755 --- a/sdks/go/docs/payments/README.md +++ b/sdks/go/docs/payments/README.md @@ -4,6 +4,7 @@ * [ConnectorsStripeTransfer](#connectorsstripetransfer) - Transfer funds between Stripe accounts * [ConnectorsTransfer](#connectorstransfer) - Transfer funds between Connector accounts +* [GetAccountBalances](#getaccountbalances) - Get account balances * [GetConnectorTask](#getconnectortask) - Read a specific task of the connector * [GetPayment](#getpayment) - Get a payment * [InstallConnector](#installconnector) - Install a connector @@ -107,6 +108,56 @@ func main() { } ``` +## GetAccountBalances + +Get account balances + +### Example Usage + +```go +package main + +import( + "context" + "log" + "github.com/formancehq/formance-sdk-go" + "github.com/formancehq/formance-sdk-go/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/pkg/types" +) + +func main() { + s := formance.New( + formance.WithSecurity(shared.Security{ + Authorization: "Bearer YOUR_ACCESS_TOKEN_HERE", + }), + ) + + ctx := context.Background() + res, err := s.Payments.GetAccountBalances(ctx, operations.GetAccountBalancesRequest{ + AccountID: "provident", + Currency: formance.String("necessitatibus"), + Cursor: formance.String("aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="), + From: types.MustTimeFromString("2021-09-21T14:06:09.271Z"), + Limit: formance.Int64(223081), + PageSize: formance.Int64(891555), + Sort: []string{ + "dolorum", + "in", + "in", + "illum", + }, + To: types.MustTimeFromString("2020-11-26T01:41:04.216Z"), + }) + if err != nil { + log.Fatal(err) + } + + if res.BalancesCursor != nil { + // handle response + } +} +``` + ## GetConnectorTask Get a specific task associated to the connector. @@ -133,8 +184,8 @@ func main() { ctx := context.Background() res, err := s.Payments.GetConnectorTask(ctx, operations.GetConnectorTaskRequest{ - Connector: shared.ConnectorCurrencyCloud, - TaskID: "necessitatibus", + Connector: shared.ConnectorStripe, + TaskID: "magnam", }) if err != nil { log.Fatal(err) @@ -171,7 +222,7 @@ func main() { ctx := context.Background() res, err := s.Payments.GetPayment(ctx, operations.GetPaymentRequest{ - PaymentID: "sint", + PaymentID: "cumque", }) if err != nil { log.Fatal(err) @@ -209,16 +260,13 @@ func main() { ctx := context.Background() res, err := s.Payments.InstallConnector(ctx, operations.InstallConnectorRequest{ - RequestBody: shared.BankingCircleConfig{ - AuthorizationEndpoint: "XXX", + RequestBody: shared.MangoPayConfig{ + APIKey: "XXX", + ClientID: "XXX", Endpoint: "XXX", - Password: "XXX", PollingPeriod: formance.String("60s"), - UserCertificate: "XXX", - UserCertificateKey: "XXX", - Username: "XXX", }, - Connector: shared.ConnectorDummyPay, + Connector: shared.ConnectorModulr, }) if err != nil { log.Fatal(err) @@ -324,9 +372,9 @@ func main() { ctx := context.Background() res, err := s.Payments.ListConnectorTasks(ctx, operations.ListConnectorTasksRequest{ - Connector: shared.ConnectorMoneycorp, + Connector: shared.ConnectorModulr, Cursor: formance.String("aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="), - PageSize: formance.Int64(952749), + PageSize: formance.Int64(675439), }) if err != nil { log.Fatal(err) @@ -364,7 +412,7 @@ func main() { ctx := context.Background() res, err := s.Payments.ListConnectorsTransfers(ctx, operations.ListConnectorsTransfersRequest{ - Connector: shared.ConnectorBankingCircle, + Connector: shared.ConnectorMoneycorp, }) if err != nil { log.Fatal(err) @@ -402,10 +450,11 @@ func main() { ctx := context.Background() res, err := s.Payments.ListPayments(ctx, operations.ListPaymentsRequest{ Cursor: formance.String("aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="), - PageSize: formance.Int64(447125), + PageSize: formance.Int64(249796), Sort: []string{ - "illum", - "maiores", + "enim", + "accusamus", + "delectus", }, }) if err != nil { @@ -478,9 +527,11 @@ func main() { ctx := context.Background() res, err := s.Payments.PaymentslistAccounts(ctx, operations.PaymentslistAccountsRequest{ Cursor: formance.String("aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="), - PageSize: formance.Int64(699479), + PageSize: formance.Int64(692532), Sort: []string{ - "magnam", + "nam", + "id", + "blanditiis", }, }) if err != nil { @@ -519,7 +570,7 @@ func main() { ctx := context.Background() res, err := s.Payments.ReadConnectorConfig(ctx, operations.ReadConnectorConfigRequest{ - Connector: shared.ConnectorMangopay, + Connector: shared.ConnectorCurrencyCloud, }) if err != nil { log.Fatal(err) @@ -559,7 +610,7 @@ func main() { ctx := context.Background() res, err := s.Payments.ResetConnector(ctx, operations.ResetConnectorRequest{ - Connector: shared.ConnectorMangopay, + Connector: shared.ConnectorMoneycorp, }) if err != nil { log.Fatal(err) @@ -597,7 +648,7 @@ func main() { ctx := context.Background() res, err := s.Payments.UninstallConnector(ctx, operations.UninstallConnectorRequest{ - Connector: shared.ConnectorModulr, + Connector: shared.ConnectorDummyPay, }) if err != nil { log.Fatal(err) @@ -636,9 +687,9 @@ func main() { ctx := context.Background() res, err := s.Payments.UpdateMetadata(ctx, operations.UpdateMetadataRequest{ PaymentMetadata: shared.PaymentMetadata{ - Key: formance.String("aliquid"), + Key: formance.String("deserunt"), }, - PaymentID: "laborum", + PaymentID: "nisi", }) if err != nil { log.Fatal(err) diff --git a/sdks/go/docs/search/README.md b/sdks/go/docs/search/README.md index 8fcaf40967..b567c6f160 100755 --- a/sdks/go/docs/search/README.md +++ b/sdks/go/docs/search/README.md @@ -33,25 +33,24 @@ func main() { After: []string{ "users:002", "users:002", - "users:002", - "users:002", }, Cursor: formance.String("YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol="), Ledgers: []string{ "quickstart", + "quickstart", + "quickstart", }, - PageSize: formance.Int64(581273), + PageSize: formance.Int64(606393), Policy: formance.String("OR"), Raw: map[string]interface{}{ - "accusamus": "delectus", - "quidem": "provident", + "perferendis": "nihil", + "magnam": "distinctio", }, Sort: formance.String("txid:asc"), - Target: formance.String("nam"), + Target: formance.String("id"), Terms: []string{ "destination=central_bank1", "destination=central_bank1", - "destination=central_bank1", }, }) if err != nil { diff --git a/sdks/go/docs/wallets/README.md b/sdks/go/docs/wallets/README.md index afcf59cd31..c03aef3f3b 100755 --- a/sdks/go/docs/wallets/README.md +++ b/sdks/go/docs/wallets/README.md @@ -50,7 +50,7 @@ func main() { Amount: big.NewInt(100), Final: formance.Bool(true), }, - HoldID: "blanditiis", + HoldID: "labore", }) if err != nil { log.Fatal(err) @@ -91,11 +91,11 @@ func main() { ctx := context.Background() res, err := s.Wallets.CreateBalance(ctx, operations.CreateBalanceRequest{ CreateBalanceRequest: &shared.CreateBalanceRequest{ - ExpiresAt: types.MustTimeFromString("2021-02-02T01:24:52.629Z"), - Name: "Sandy Huels", - Priority: big.NewInt(606393), + ExpiresAt: types.MustTimeFromString("2022-05-20T10:11:05.115Z"), + Name: "Duane Thiel II", + Priority: big.NewInt(92373), }, - ID: "7074ba44-69b6-4e21-8195-9890afa563e2", + ID: "959890af-a563-4e25-96fe-4c8b711e5b7f", }) if err != nil { log.Fatal(err) @@ -133,10 +133,12 @@ func main() { ctx := context.Background() res, err := s.Wallets.CreateWallet(ctx, shared.CreateWalletRequest{ Metadata: map[string]string{ - "quasi": "iure", - "doloribus": "debitis", + "sed": "saepe", + "pariatur": "accusantium", + "consequuntur": "praesentium", + "natus": "magni", }, - Name: "Jasmine Lind", + Name: "Angelica Stanton", }) if err != nil { log.Fatal(err) @@ -177,23 +179,21 @@ func main() { res, err := s.Wallets.CreditWallet(ctx, operations.CreditWalletRequest{ CreditWalletRequest: &shared.CreditWalletRequest{ Amount: shared.Monetary{ - Amount: big.NewInt(100226), - Asset: "architecto", + Amount: big.NewInt(411397), + Asset: "excepturi", }, - Balance: formance.String("repudiandae"), + Balance: formance.String("odit"), Metadata: map[string]string{ - "expedita": "nihil", - "repellat": "quibusdam", + "accusantium": "ab", + "maiores": "quidem", }, - Reference: formance.String("sed"), + Reference: formance.String("ipsam"), Sources: []shared.Subject{ shared.Subject{}, shared.Subject{}, - shared.Subject{}, - shared.Subject{}, }, }, - ID: "d028921c-ddc6-4926-81fb-576b0d5f0d30", + ID: "6b0d5f0d-30c5-4fbb-a587-053202c73d5f", }) if err != nil { log.Fatal(err) @@ -234,24 +234,24 @@ func main() { res, err := s.Wallets.DebitWallet(ctx, operations.DebitWalletRequest{ DebitWalletRequest: &shared.DebitWalletRequest{ Amount: shared.Monetary{ - Amount: big.NewInt(764912), - Asset: "corporis", + Amount: big.NewInt(928082), + Asset: "omnis", }, Balances: []string{ - "libero", - "nobis", - "dolores", - "quis", + "perspiciatis", + "voluptatem", + "porro", }, - Description: formance.String("totam"), + Description: formance.String("consequuntur"), Destination: &shared.Subject{}, Metadata: map[string]string{ - "eaque": "quis", - "nesciunt": "eos", + "error": "eaque", + "occaecati": "rerum", + "adipisci": "asperiores", }, Pending: formance.Bool(false), }, - ID: "02c73d5f-e9b9-40c2-8909-b3fe49a8d9cb", + ID: "e49a8d9c-bf48-4633-b23f-9b77f3a41006", }) if err != nil { log.Fatal(err) @@ -288,8 +288,8 @@ func main() { ctx := context.Background() res, err := s.Wallets.GetBalance(ctx, operations.GetBalanceRequest{ - BalanceName: "delectus", - ID: "48633323-f9b7-47f3-a410-0674ebf69280", + BalanceName: "odio", + ID: "4ebf6928-0d1b-4a77-a89e-bf737ae4203c", }) if err != nil { log.Fatal(err) @@ -326,7 +326,7 @@ func main() { ctx := context.Background() res, err := s.Wallets.GetHold(ctx, operations.GetHoldRequest{ - HoldID: "fugiat", + HoldID: "accusamus", }) if err != nil { log.Fatal(err) @@ -365,10 +365,11 @@ func main() { res, err := s.Wallets.GetHolds(ctx, operations.GetHoldsRequest{ Cursor: formance.String("aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="), Metadata: map[string]string{ - "soluta": "dolorum", + "saepe": "suscipit", + "deserunt": "provident", }, - PageSize: formance.Int64(478596), - WalletID: formance.String("voluptate"), + PageSize: formance.Int64(324683), + WalletID: formance.String("repellendus"), }) if err != nil { log.Fatal(err) @@ -404,8 +405,8 @@ func main() { ctx := context.Background() res, err := s.Wallets.GetTransactions(ctx, operations.GetTransactionsRequest{ Cursor: formance.String("aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="), - PageSize: formance.Int64(677082), - WalletID: formance.String("deleniti"), + PageSize: formance.Int64(519711), + WalletID: formance.String("similique"), }) if err != nil { log.Fatal(err) @@ -442,7 +443,7 @@ func main() { ctx := context.Background() res, err := s.Wallets.GetWallet(ctx, operations.GetWalletRequest{ - ID: "9ebf737a-e420-43ce-9e6a-95d8a0d446ce", + ID: "0d446ce2-af7a-473c-b3be-453f870b326b", }) if err != nil { log.Fatal(err) @@ -479,7 +480,7 @@ func main() { ctx := context.Background() res, err := s.Wallets.GetWalletSummary(ctx, operations.GetWalletSummaryRequest{ - ID: "2af7a73c-f3be-4453-b870-b326b5a73429", + ID: "5a73429c-db1a-4842-abb6-79d2322715bf", }) if err != nil { log.Fatal(err) @@ -516,7 +517,7 @@ func main() { ctx := context.Background() res, err := s.Wallets.ListBalances(ctx, operations.ListBalancesRequest{ - ID: "cdb1a842-2bb6-479d-a322-715bf0cbb1e3", + ID: "0cbb1e31-b8b9-40f3-843a-1108e0adcf4b", }) if err != nil { log.Fatal(err) @@ -555,10 +556,12 @@ func main() { res, err := s.Wallets.ListWallets(ctx, operations.ListWalletsRequest{ Cursor: formance.String("aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="), Metadata: map[string]string{ - "nobis": "quos", + "qui": "quae", + "laudantium": "odio", + "occaecati": "voluptatibus", }, - Name: formance.String("Kent Bayer"), - PageSize: formance.Int64(292147), + Name: formance.String("Ignacio Moen"), + PageSize: formance.Int64(961571), }) if err != nil { log.Fatal(err) @@ -597,11 +600,11 @@ func main() { res, err := s.Wallets.UpdateWallet(ctx, operations.UpdateWalletRequest{ RequestBody: &operations.UpdateWalletRequestBody{ Metadata: map[string]string{ - "adipisci": "dolorum", - "architecto": "quae", + "consectetur": "vero", + "tenetur": "dignissimos", }, }, - ID: "08e0adcf-4b92-4187-9fce-953f73ef7fbc", + ID: "fbc7abd7-4dd3-49c0-b5d2-cff7c70a4562", }) if err != nil { log.Fatal(err) @@ -638,7 +641,7 @@ func main() { ctx := context.Background() res, err := s.Wallets.VoidHold(ctx, operations.VoidHoldRequest{ - HoldID: "odio", + HoldID: "vel", }) if err != nil { log.Fatal(err) diff --git a/sdks/go/docs/webhooks/README.md b/sdks/go/docs/webhooks/README.md index f545ef3822..a0d2cb73c8 100755 --- a/sdks/go/docs/webhooks/README.md +++ b/sdks/go/docs/webhooks/README.md @@ -243,6 +243,7 @@ func main() { "TYPE1", "TYPE1", "TYPE1", + "TYPE1", }, Secret: formance.String("V0bivxRWveaoz08afqjU6Ko/jwO0Cb+3"), }) diff --git a/sdks/go/files.gen b/sdks/go/files.gen index 589cc2b855..2f547aa109 100755 --- a/sdks/go/files.gen +++ b/sdks/go/files.gen @@ -69,6 +69,7 @@ pkg/models/operations/runworkflow.go pkg/models/operations/sendevent.go pkg/models/operations/connectorsstripetransfer.go pkg/models/operations/connectorstransfer.go +pkg/models/operations/getaccountbalances.go pkg/models/operations/getconnectortask.go pkg/models/operations/getpayment.go pkg/models/operations/installconnector.go @@ -221,6 +222,8 @@ pkg/models/shared/runworkflowresponse.go pkg/models/shared/stripetransferrequest.go pkg/models/shared/transferresponse.go pkg/models/shared/transferrequest.go +pkg/models/shared/balancescursor.go +pkg/models/shared/accountbalance.go pkg/models/shared/taskresponse.go pkg/models/shared/taskstripe.go pkg/models/shared/taskwise.go diff --git a/sdks/go/payments.go b/sdks/go/payments.go index ebdcc3672a..3e4e482b97 100755 --- a/sdks/go/payments.go +++ b/sdks/go/payments.go @@ -149,6 +149,59 @@ func (s *payments) ConnectorsTransfer(ctx context.Context, request operations.Co return res, nil } +// GetAccountBalances - Get account balances +func (s *payments) GetAccountBalances(ctx context.Context, request operations.GetAccountBalancesRequest) (*operations.GetAccountBalancesResponse, error) { + baseURL := s.serverURL + url, err := utils.GenerateURL(ctx, baseURL, "/api/payments/accounts/{accountID}/balances", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", url, nil) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s", s.language, s.sdkVersion, s.genVersion)) + + if err := utils.PopulateQueryParams(ctx, req, request, nil); err != nil { + return nil, fmt.Errorf("error populating query params: %w", err) + } + + client := s.securityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + defer httpRes.Body.Close() + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetAccountBalancesResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out *shared.BalancesCursor + if err := utils.UnmarshalJsonFromResponseBody(httpRes.Body, &out); err != nil { + return nil, err + } + + res.BalancesCursor = out + } + } + + return res, nil +} + // GetConnectorTask - Read a specific task of the connector // Get a specific task associated to the connector. func (s *payments) GetConnectorTask(ctx context.Context, request operations.GetConnectorTaskRequest) (*operations.GetConnectorTaskResponse, error) { diff --git a/sdks/go/pkg/models/operations/getaccountbalances.go b/sdks/go/pkg/models/operations/getaccountbalances.go new file mode 100755 index 0000000000..5a180072e8 --- /dev/null +++ b/sdks/go/pkg/models/operations/getaccountbalances.go @@ -0,0 +1,47 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "github.com/formancehq/formance-sdk-go/pkg/models/shared" + "net/http" + "time" +) + +type GetAccountBalancesRequest struct { + // The account ID. + AccountID string `pathParam:"style=simple,explode=false,name=accountID"` + // Filter balances by currency. + // If not specified, all account's balances will be returned. + // + Currency *string `queryParam:"style=form,explode=true,name=currency"` + // Parameter used in pagination requests. Maximum page size is set to 15. + // Set to the value of next for the next page of results. + // Set to the value of previous for the previous page of results. + // No other parameters can be set when this parameter is set. + // + Cursor *string `queryParam:"style=form,explode=true,name=cursor"` + // Filter balances by date. + // If not specified, all account's balances will be returned. + // + From *time.Time `queryParam:"style=form,explode=true,name=from"` + // The maximum number of results to return per page. + Limit *int64 `queryParam:"style=form,explode=true,name=limit"` + // The maximum number of results to return per page. + // + PageSize *int64 `queryParam:"style=form,explode=true,name=pageSize"` + // Fields used to sort payments (default is date:desc). + Sort []string `queryParam:"style=form,explode=true,name=sort"` + // Filter balances by date. + // If not specified, default will be set to now. + // + To *time.Time `queryParam:"style=form,explode=true,name=to"` +} + +type GetAccountBalancesResponse struct { + // OK + BalancesCursor *shared.BalancesCursor + ContentType string + StatusCode int + RawResponse *http.Response +} diff --git a/sdks/go/pkg/models/shared/accountbalance.go b/sdks/go/pkg/models/shared/accountbalance.go new file mode 100755 index 0000000000..9525ce498b --- /dev/null +++ b/sdks/go/pkg/models/shared/accountbalance.go @@ -0,0 +1,15 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package shared + +import ( + "time" +) + +type AccountBalance struct { + AccountID string `json:"accountId"` + Balance int64 `json:"balance"` + CreatedAt time.Time `json:"createdAt"` + Currency string `json:"currency"` + LastUpdatedAt time.Time `json:"lastUpdatedAt"` +} diff --git a/sdks/go/pkg/models/shared/balancescursor.go b/sdks/go/pkg/models/shared/balancescursor.go new file mode 100755 index 0000000000..e1abc24ec9 --- /dev/null +++ b/sdks/go/pkg/models/shared/balancescursor.go @@ -0,0 +1,16 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package shared + +type BalancesCursorCursor struct { + Data []AccountBalance `json:"data"` + HasMore bool `json:"hasMore"` + Next *string `json:"next,omitempty"` + PageSize int64 `json:"pageSize"` + Previous *string `json:"previous,omitempty"` +} + +// BalancesCursor - OK +type BalancesCursor struct { + Cursor BalancesCursorCursor `json:"cursor"` +} diff --git a/sdks/go/pkg/models/shared/walletsposting.go b/sdks/go/pkg/models/shared/walletsposting.go new file mode 100755 index 0000000000..3e789acefb --- /dev/null +++ b/sdks/go/pkg/models/shared/walletsposting.go @@ -0,0 +1,14 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package shared + +import ( + "math/big" +) + +type WalletsPosting struct { + Amount *big.Int `json:"amount"` + Asset string `json:"asset"` + Destination string `json:"destination"` + Source string `json:"source"` +} diff --git a/sdks/java/README.md b/sdks/java/README.md index 22da6a35e6..62ff57acef 100755 --- a/sdks/java/README.md +++ b/sdks/java/README.md @@ -119,6 +119,7 @@ public class Application { * [connectorsStripeTransfer](docs/payments/README.md#connectorsstripetransfer) - Transfer funds between Stripe accounts * [connectorsTransfer](docs/payments/README.md#connectorstransfer) - Transfer funds between Connector accounts +* [getAccountBalances](docs/payments/README.md#getaccountbalances) - Get account balances * [getConnectorTask](docs/payments/README.md#getconnectortask) - Read a specific task of the connector * [getPayment](docs/payments/README.md#getpayment) - Get a payment * [installConnector](docs/payments/README.md#installconnector) - Install a connector diff --git a/sdks/java/docs/payments/README.md b/sdks/java/docs/payments/README.md index c563464718..ebd69cb87a 100755 --- a/sdks/java/docs/payments/README.md +++ b/sdks/java/docs/payments/README.md @@ -4,6 +4,7 @@ * [connectorsStripeTransfer](#connectorsstripetransfer) - Transfer funds between Stripe accounts * [connectorsTransfer](#connectorstransfer) - Transfer funds between Connector accounts +* [getAccountBalances](#getaccountbalances) - Get account balances * [getConnectorTask](#getconnectortask) - Read a specific task of the connector * [getPayment](#getpayment) - Get a payment * [installConnector](#installconnector) - Install a connector @@ -105,6 +106,56 @@ public class Application { } ``` +## getAccountBalances + +Get account balances + +### Example Usage + +```java +package hello.world; + +import com.formance.formance_sdk.SDK; +import com.formance.formance_sdk.models.operations.GetAccountBalancesRequest; +import com.formance.formance_sdk.models.operations.GetAccountBalancesResponse; +import com.formance.formance_sdk.models.shared.Security; +import java.time.OffsetDateTime; + +public class Application { + public static void main(String[] args) { + try { + SDK sdk = SDK.builder() + .setSecurity(new Security("blanditiis") {{ + authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; + }}) + .build(); + + GetAccountBalancesRequest req = new GetAccountBalancesRequest("deleniti") {{ + currency = "sapiente"; + cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; + from = OffsetDateTime.parse("2022-05-10T22:38:44.806Z"); + limit = 394869L; + pageSize = 423855L; + sort = new String[]{{ + add("omnis"), + add("molestiae"), + add("perferendis"), + }}; + to = OffsetDateTime.parse("2022-09-12T22:12:15.897Z"); + }}; + + GetAccountBalancesResponse res = sdk.payments.getAccountBalances(req); + + if (res.balancesCursor != null) { + // handle response + } + } catch (Exception e) { + // handle exception + } + } +} +``` + ## getConnectorTask Get a specific task associated to the connector. @@ -124,12 +175,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("blanditiis") {{ + .setSecurity(new Security("distinctio") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - GetConnectorTaskRequest req = new GetConnectorTaskRequest(Connector.CURRENCY_CLOUD, "sapiente"); + GetConnectorTaskRequest req = new GetConnectorTaskRequest(Connector.BANKING_CIRCLE, "labore"); GetConnectorTaskResponse res = sdk.payments.getConnectorTask(req); @@ -161,12 +212,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("amet") {{ + .setSecurity(new Security("labore") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - GetPaymentRequest req = new GetPaymentRequest("deserunt"); + GetPaymentRequest req = new GetPaymentRequest("suscipit"); GetPaymentResponse res = sdk.payments.getPayment(req); @@ -207,17 +258,20 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("nisi") {{ + .setSecurity(new Security("natus") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - InstallConnectorRequest req = new InstallConnectorRequest( new ModulrConfig("XXX", "XXX") {{ - apiKey = "XXX"; - apiSecret = "XXX"; + InstallConnectorRequest req = new InstallConnectorRequest( new BankingCircleConfig("XXX", "XXX", "XXX", "XXX", "XXX", "XXX") {{ + authorizationEndpoint = "XXX"; endpoint = "XXX"; + password = "XXX"; pollingPeriod = "60s"; - }}, Connector.CURRENCY_CLOUD); + userCertificate = "XXX"; + userCertificateKey = "XXX"; + username = "XXX"; + }}, Connector.MODULR); InstallConnectorResponse res = sdk.payments.installConnector(req); @@ -248,7 +302,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("omnis") {{ + .setSecurity(new Security("vero") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); @@ -282,7 +336,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("molestiae") {{ + .setSecurity(new Security("aspernatur") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); @@ -318,14 +372,14 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("perferendis") {{ + .setSecurity(new Security("architecto") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - ListConnectorTasksRequest req = new ListConnectorTasksRequest(Connector.MODULR) {{ + ListConnectorTasksRequest req = new ListConnectorTasksRequest(Connector.WISE) {{ cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; - pageSize = 301575L; + pageSize = 92373L; }}; ListConnectorTasksResponse res = sdk.payments.listConnectorTasks(req); @@ -359,12 +413,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("distinctio") {{ + .setSecurity(new Security("excepturi") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - ListConnectorsTransfersRequest req = new ListConnectorsTransfersRequest(Connector.BANKING_CIRCLE); + ListConnectorsTransfersRequest req = new ListConnectorsTransfersRequest(Connector.WISE); ListConnectorsTransfersResponse res = sdk.payments.listConnectorsTransfers(req); @@ -396,17 +450,18 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("labore") {{ + .setSecurity(new Security("provident") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); ListPaymentsRequest req = new ListPaymentsRequest() {{ cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; - pageSize = 290077L; + pageSize = 551816L; sort = new String[]{{ - add("natus"), - add("nobis"), + add("accusantium"), + add("mollitia"), + add("reiciendis"), }}; }}; @@ -439,7 +494,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("eum") {{ + .setSecurity(new Security("mollitia") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); @@ -474,16 +529,16 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("vero") {{ + .setSecurity(new Security("ad") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); PaymentslistAccountsRequest req = new PaymentslistAccountsRequest() {{ cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; - pageSize = 135474L; + pageSize = 431418L; sort = new String[]{{ - add("magnam"), + add("necessitatibus"), }}; }}; @@ -518,12 +573,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("et") {{ + .setSecurity(new Security("odit") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - ReadConnectorConfigRequest req = new ReadConnectorConfigRequest(Connector.CURRENCY_CLOUD); + ReadConnectorConfigRequest req = new ReadConnectorConfigRequest(Connector.WISE); ReadConnectorConfigResponse res = sdk.payments.readConnectorConfig(req); @@ -558,12 +613,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("ullam") {{ + .setSecurity(new Security("quasi") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - ResetConnectorRequest req = new ResetConnectorRequest(Connector.CURRENCY_CLOUD); + ResetConnectorRequest req = new ResetConnectorRequest(Connector.MODULR); ResetConnectorResponse res = sdk.payments.resetConnector(req); @@ -596,12 +651,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("quos") {{ + .setSecurity(new Security("doloribus") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - UninstallConnectorRequest req = new UninstallConnectorRequest(Connector.CURRENCY_CLOUD); + UninstallConnectorRequest req = new UninstallConnectorRequest(Connector.MONEYCORP); UninstallConnectorResponse res = sdk.payments.uninstallConnector(req); @@ -634,14 +689,14 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("accusantium") {{ + .setSecurity(new Security("eius") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); UpdateMetadataRequest req = new UpdateMetadataRequest( new PaymentMetadata() {{ - key = "mollitia"; - }};, "reiciendis"); + key = "maxime"; + }};, "deleniti"); UpdateMetadataResponse res = sdk.payments.updateMetadata(req); diff --git a/sdks/java/docs/search/README.md b/sdks/java/docs/search/README.md index 3c1470c2c6..c602fe3b80 100755 --- a/sdks/java/docs/search/README.md +++ b/sdks/java/docs/search/README.md @@ -23,7 +23,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("mollitia") {{ + .setSecurity(new Security("facilis") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); @@ -36,22 +36,19 @@ public class Application { cursor = "YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol="; ledgers = new String[]{{ add("quickstart"), - add("quickstart"), }}; - pageSize = 221262L; + pageSize = 99569L; policy = "OR"; raw = new java.util.HashMap() {{ - put("odit", "nemo"); - put("quasi", "iure"); - put("doloribus", "debitis"); - put("eius", "maxime"); + put("ullam", "expedita"); + put("nihil", "repellat"); + put("quibusdam", "sed"); + put("saepe", "pariatur"); }}; sort = "txid:asc"; - target = "deleniti"; + target = "accusantium"; terms = new String[]{{ add("destination=central_bank1"), - add("destination=central_bank1"), - add("destination=central_bank1"), }}; }}; @@ -84,7 +81,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("in") {{ + .setSecurity(new Security("praesentium") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); diff --git a/sdks/java/docs/wallets/README.md b/sdks/java/docs/wallets/README.md index c9e503a968..28dbc6ba4d 100755 --- a/sdks/java/docs/wallets/README.md +++ b/sdks/java/docs/wallets/README.md @@ -38,12 +38,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("architecto") {{ + .setSecurity(new Security("natus") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - ConfirmHoldRequest req = new ConfirmHoldRequest("architecto") {{ + ConfirmHoldRequest req = new ConfirmHoldRequest("magni") {{ confirmHoldRequest = new ConfirmHoldRequest() {{ amount = 100L; final_ = true; @@ -82,15 +82,15 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("repudiandae") {{ + .setSecurity(new Security("sunt") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - CreateBalanceRequest req = new CreateBalanceRequest("ullam") {{ - createBalanceRequest = new CreateBalanceRequest("expedita") {{ - expiresAt = OffsetDateTime.parse("2022-01-01T10:06:00.916Z"); - priority = 841140L; + CreateBalanceRequest req = new CreateBalanceRequest("quo") {{ + createBalanceRequest = new CreateBalanceRequest("illum") {{ + expiresAt = OffsetDateTime.parse("2020-07-30T23:39:27.609Z"); + priority = 411397L; }};; }}; @@ -124,17 +124,14 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("sed") {{ + .setSecurity(new Security("excepturi") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); com.formance.formance_sdk.models.shared.CreateWalletRequest req = new CreateWalletRequest( new java.util.HashMap() {{ - put("pariatur", "accusantium"); - put("consequuntur", "praesentium"); - put("natus", "magni"); - put("sunt", "quo"); - }}, "illum"); + put("ea", "accusantium"); + }}, "ab"); CreateWalletResponse res = sdk.wallets.createWallet(req); @@ -170,23 +167,35 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("pariatur") {{ + .setSecurity(new Security("maiores") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - CreditWalletRequest req = new CreditWalletRequest("maxime") {{ - creditWalletRequest = new CreditWalletRequest( new Monetary(411397L, "excepturi");, new java.util.HashMap() {{ - put("ea", "accusantium"); + CreditWalletRequest req = new CreditWalletRequest("quidem") {{ + creditWalletRequest = new CreditWalletRequest( new Monetary(373291L, "voluptate");, new java.util.HashMap() {{ + put("nam", "eaque"); + put("pariatur", "nemo"); }}, new Object[]{{ - add(new WalletSubject("autem", "nam") {{ - balance = "quidem"; - identifier = "ipsam"; - type = "voluptate"; + add(new LedgerAccountSubject("aut", "cumque") {{ + identifier = "fugiat"; + type = "amet"; + }}), + add(new LedgerAccountSubject("nobis", "dolores") {{ + identifier = "hic"; + type = "libero"; + }}), + add(new LedgerAccountSubject("eaque", "quis") {{ + identifier = "totam"; + type = "dignissimos"; + }}), + add(new LedgerAccountSubject("dolores", "minus") {{ + identifier = "eos"; + type = "perferendis"; }}), }}) {{ - balance = "eaque"; - reference = "pariatur"; + balance = "quam"; + reference = "dolor"; }};; }}; @@ -224,21 +233,26 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("nemo") {{ + .setSecurity(new Security("vero") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - DebitWalletRequest req = new DebitWalletRequest("voluptatibus") {{ - debitWalletRequest = new DebitWalletRequest( new Monetary(16627L, "fugiat");, new java.util.HashMap() {{ - put("aut", "cumque"); + DebitWalletRequest req = new DebitWalletRequest("nostrum") {{ + debitWalletRequest = new DebitWalletRequest( new Monetary(944120L, "recusandae");, new java.util.HashMap() {{ + put("facilis", "perspiciatis"); + put("voluptatem", "porro"); + put("consequuntur", "blanditiis"); }}) {{ balances = new String[]{{ - add("hic"), - add("libero"), + add("eaque"), + add("occaecati"), + add("rerum"), }}; - description = "nobis"; - destination = new LedgerAccountSubject("quis", "totam");; + description = "adipisci"; + destination = new WalletSubject("earum", "modi") {{ + balance = "iste"; + }};; pending = false; }};; }}; @@ -273,12 +287,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("dignissimos") {{ + .setSecurity(new Security("dolorum") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - GetBalanceRequest req = new GetBalanceRequest("eaque", "quis"); + GetBalanceRequest req = new GetBalanceRequest("deleniti", "pariatur"); GetBalanceResponse res = sdk.wallets.getBalance(req); @@ -310,12 +324,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("nesciunt") {{ + .setSecurity(new Security("provident") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - GetHoldRequest req = new GetHoldRequest("eos"); + GetHoldRequest req = new GetHoldRequest("nobis"); GetHoldResponse res = sdk.wallets.getHold(req); @@ -347,7 +361,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("perferendis") {{ + .setSecurity(new Security("libero") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); @@ -355,10 +369,13 @@ public class Application { GetHoldsRequest req = new GetHoldsRequest() {{ cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; metadata = new java.util.HashMap() {{ - put("minus", "quam"); + put("quaerat", "quos"); + put("aliquid", "dolorem"); + put("dolorem", "dolor"); + put("qui", "ipsum"); }}; - pageSize = 223924L; - walletID = "vero"; + pageSize = 944373L; + walletID = "excepturi"; }}; GetHoldsResponse res = sdk.wallets.getHolds(req); @@ -389,15 +406,15 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("nostrum") {{ + .setSecurity(new Security("cum") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); GetTransactionsRequest req = new GetTransactionsRequest() {{ cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; - pageSize = 944120L; - walletID = "recusandae"; + pageSize = 452109L; + walletID = "dignissimos"; }}; GetTransactionsResponse res = sdk.wallets.getTransactions(req); @@ -430,12 +447,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("omnis") {{ + .setSecurity(new Security("reiciendis") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - GetWalletRequest req = new GetWalletRequest("facilis"); + GetWalletRequest req = new GetWalletRequest("amet"); GetWalletResponse res = sdk.wallets.getWallet(req); @@ -467,12 +484,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("perspiciatis") {{ + .setSecurity(new Security("dolorum") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - GetWalletSummaryRequest req = new GetWalletSummaryRequest("voluptatem"); + GetWalletSummaryRequest req = new GetWalletSummaryRequest("numquam"); GetWalletSummaryResponse res = sdk.wallets.getWalletSummary(req); @@ -504,12 +521,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("porro") {{ + .setSecurity(new Security("veritatis") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - ListBalancesRequest req = new ListBalancesRequest("consequuntur"); + ListBalancesRequest req = new ListBalancesRequest("ipsa"); ListBalancesResponse res = sdk.wallets.listBalances(req); @@ -541,7 +558,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("blanditiis") {{ + .setSecurity(new Security("ipsa") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); @@ -549,12 +566,11 @@ public class Application { ListWalletsRequest req = new ListWalletsRequest() {{ cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; metadata = new java.util.HashMap() {{ - put("eaque", "occaecati"); - put("rerum", "adipisci"); - put("asperiores", "earum"); + put("odio", "quaerat"); + put("accusamus", "quidem"); }}; - name = "Sheryl Parisian"; - pageSize = 589910L; + name = "Hector Mosciski"; + pageSize = 24678L; }}; ListWalletsResponse res = sdk.wallets.listWallets(req); @@ -588,17 +604,16 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("nobis") {{ + .setSecurity(new Security("fugiat") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - UpdateWalletRequest req = new UpdateWalletRequest("libero") {{ + UpdateWalletRequest req = new UpdateWalletRequest("ab") {{ requestBody = new UpdateWalletRequestBody( new java.util.HashMap() {{ - put("quaerat", "quos"); - put("aliquid", "dolorem"); - put("dolorem", "dolor"); - put("qui", "ipsum"); + put("dolorum", "iusto"); + put("voluptate", "dolorum"); + put("deleniti", "omnis"); }});; }}; @@ -632,12 +647,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("hic") {{ + .setSecurity(new Security("necessitatibus") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); - VoidHoldRequest req = new VoidHoldRequest("excepturi"); + VoidHoldRequest req = new VoidHoldRequest("distinctio"); VoidHoldResponse res = sdk.wallets.voidHold(req); @@ -668,7 +683,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("cum") {{ + .setSecurity(new Security("asperiores") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); diff --git a/sdks/java/docs/webhooks/README.md b/sdks/java/docs/webhooks/README.md index a0a236493e..38f8ca1f95 100755 --- a/sdks/java/docs/webhooks/README.md +++ b/sdks/java/docs/webhooks/README.md @@ -28,7 +28,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("voluptate") {{ + .setSecurity(new Security("nihil") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); @@ -70,7 +70,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("dignissimos") {{ + .setSecurity(new Security("ipsum") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); @@ -109,7 +109,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("reiciendis") {{ + .setSecurity(new Security("voluptate") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); @@ -146,7 +146,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("amet") {{ + .setSecurity(new Security("id") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); @@ -183,7 +183,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("dolorum") {{ + .setSecurity(new Security("saepe") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); @@ -232,7 +232,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("numquam") {{ + .setSecurity(new Security("eius") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); @@ -273,7 +273,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("ipsa") {{ + .setSecurity(new Security("perferendis") {{ authorization = "Bearer YOUR_ACCESS_TOKEN_HERE"; }}) .build(); diff --git a/sdks/java/files.gen b/sdks/java/files.gen index 62ca688fb2..780df4be08 100755 --- a/sdks/java/files.gen +++ b/sdks/java/files.gen @@ -124,6 +124,8 @@ lib/src/main/java/com/formance/formance_sdk/models/operations/SendEventResponse. lib/src/main/java/com/formance/formance_sdk/models/operations/ConnectorsStripeTransferResponse.java lib/src/main/java/com/formance/formance_sdk/models/operations/ConnectorsTransferRequest.java lib/src/main/java/com/formance/formance_sdk/models/operations/ConnectorsTransferResponse.java +lib/src/main/java/com/formance/formance_sdk/models/operations/GetAccountBalancesRequest.java +lib/src/main/java/com/formance/formance_sdk/models/operations/GetAccountBalancesResponse.java lib/src/main/java/com/formance/formance_sdk/models/operations/GetConnectorTaskRequest.java lib/src/main/java/com/formance/formance_sdk/models/operations/GetConnectorTaskResponse.java lib/src/main/java/com/formance/formance_sdk/models/operations/GetPaymentRequest.java @@ -319,6 +321,9 @@ lib/src/main/java/com/formance/formance_sdk/models/shared/RunWorkflowResponse.ja lib/src/main/java/com/formance/formance_sdk/models/shared/StripeTransferRequest.java lib/src/main/java/com/formance/formance_sdk/models/shared/TransferResponse.java lib/src/main/java/com/formance/formance_sdk/models/shared/TransferRequest.java +lib/src/main/java/com/formance/formance_sdk/models/shared/BalancesCursorCursor.java +lib/src/main/java/com/formance/formance_sdk/models/shared/BalancesCursor.java +lib/src/main/java/com/formance/formance_sdk/models/shared/AccountBalance.java lib/src/main/java/com/formance/formance_sdk/models/shared/TaskResponse.java lib/src/main/java/com/formance/formance_sdk/models/shared/TaskStripeDescriptor.java lib/src/main/java/com/formance/formance_sdk/models/shared/TaskStripe.java diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/Payments.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/Payments.java index d43cb51c25..8da6670778 100755 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/Payments.java +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/Payments.java @@ -122,6 +122,51 @@ public com.formance.formance_sdk.models.operations.ConnectorsTransferResponse co return res; } + /** + * Get account balances + * @param request the request object containing all of the parameters for the API call + * @return the response from the API call + * @throws Exception if the API call fails + */ + public com.formance.formance_sdk.models.operations.GetAccountBalancesResponse getAccountBalances(com.formance.formance_sdk.models.operations.GetAccountBalancesRequest request) throws Exception { + String baseUrl = this._serverUrl; + String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.GetAccountBalancesRequest.class, baseUrl, "/api/payments/accounts/{accountID}/balances", request, null); + + HTTPRequest req = new HTTPRequest(); + req.setMethod("GET"); + req.setURL(url); + + req.addHeader("Accept", "application/json"); + req.addHeader("user-agent", String.format("speakeasy-sdk/%s %s %s", this._language, this._sdkVersion, this._genVersion)); + java.util.List queryParams = com.formance.formance_sdk.utils.Utils.getQueryParams(com.formance.formance_sdk.models.operations.GetAccountBalancesRequest.class, request, null); + if (queryParams != null) { + for (NameValuePair queryParam : queryParams) { + req.addQueryParam(queryParam); + } + } + + HTTPClient client = this._securityClient; + + HttpResponse httpRes = client.send(req); + + String contentType = httpRes.headers().firstValue("Content-Type").orElse("application/octet-stream"); + + com.formance.formance_sdk.models.operations.GetAccountBalancesResponse res = new com.formance.formance_sdk.models.operations.GetAccountBalancesResponse(contentType, httpRes.statusCode()) {{ + balancesCursor = null; + }}; + res.rawResponse = httpRes; + + if (httpRes.statusCode() == 200) { + if (com.formance.formance_sdk.utils.Utils.matchContentType(contentType, "application/json")) { + ObjectMapper mapper = JSON.getMapper(); + com.formance.formance_sdk.models.shared.BalancesCursor out = mapper.readValue(new String(httpRes.body(), StandardCharsets.UTF_8), com.formance.formance_sdk.models.shared.BalancesCursor.class); + res.balancesCursor = out; + } + } + + return res; + } + /** * Read a specific task of the connector * Get a specific task associated to the connector. diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/GetAccountBalancesRequest.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/GetAccountBalancesRequest.java new file mode 100755 index 0000000000..e7ff1d7da8 --- /dev/null +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/GetAccountBalancesRequest.java @@ -0,0 +1,114 @@ +/* + * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + */ + +package com.formance.formance_sdk.models.operations; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.formance.formance_sdk.utils.SpeakeasyMetadata; +import java.time.OffsetDateTime; + +public class GetAccountBalancesRequest { + /** + * The account ID. + */ + @SpeakeasyMetadata("pathParam:style=simple,explode=false,name=accountID") + public String accountID; + + public GetAccountBalancesRequest withAccountID(String accountID) { + this.accountID = accountID; + return this; + } + + /** + * Filter balances by currency. + * If not specified, all account's balances will be returned. + * + */ + @SpeakeasyMetadata("queryParam:style=form,explode=true,name=currency") + public String currency; + + public GetAccountBalancesRequest withCurrency(String currency) { + this.currency = currency; + return this; + } + + /** + * Parameter used in pagination requests. Maximum page size is set to 15. + * Set to the value of next for the next page of results. + * Set to the value of previous for the previous page of results. + * No other parameters can be set when this parameter is set. + * + */ + @SpeakeasyMetadata("queryParam:style=form,explode=true,name=cursor") + public String cursor; + + public GetAccountBalancesRequest withCursor(String cursor) { + this.cursor = cursor; + return this; + } + + /** + * Filter balances by date. + * If not specified, all account's balances will be returned. + * + */ + @SpeakeasyMetadata("queryParam:style=form,explode=true,name=from") + public OffsetDateTime from; + + public GetAccountBalancesRequest withFrom(OffsetDateTime from) { + this.from = from; + return this; + } + + /** + * The maximum number of results to return per page. + */ + @SpeakeasyMetadata("queryParam:style=form,explode=true,name=limit") + public Long limit; + + public GetAccountBalancesRequest withLimit(Long limit) { + this.limit = limit; + return this; + } + + /** + * The maximum number of results to return per page. + * + */ + @SpeakeasyMetadata("queryParam:style=form,explode=true,name=pageSize") + public Long pageSize; + + public GetAccountBalancesRequest withPageSize(Long pageSize) { + this.pageSize = pageSize; + return this; + } + + /** + * Fields used to sort payments (default is date:desc). + */ + @SpeakeasyMetadata("queryParam:style=form,explode=true,name=sort") + public String[] sort; + + public GetAccountBalancesRequest withSort(String[] sort) { + this.sort = sort; + return this; + } + + /** + * Filter balances by date. + * If not specified, default will be set to now. + * + */ + @SpeakeasyMetadata("queryParam:style=form,explode=true,name=to") + public OffsetDateTime to; + + public GetAccountBalancesRequest withTo(OffsetDateTime to) { + this.to = to; + return this; + } + + public GetAccountBalancesRequest(@JsonProperty("accountID") String accountID) { + this.accountID = accountID; + } +} diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/GetAccountBalancesResponse.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/GetAccountBalancesResponse.java new file mode 100755 index 0000000000..57eeb89ae6 --- /dev/null +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/GetAccountBalancesResponse.java @@ -0,0 +1,50 @@ +/* + * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + */ + +package com.formance.formance_sdk.models.operations; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.net.http.HttpResponse; + +public class GetAccountBalancesResponse { + /** + * OK + */ + + public com.formance.formance_sdk.models.shared.BalancesCursor balancesCursor; + + public GetAccountBalancesResponse withBalancesCursor(com.formance.formance_sdk.models.shared.BalancesCursor balancesCursor) { + this.balancesCursor = balancesCursor; + return this; + } + + + public String contentType; + + public GetAccountBalancesResponse withContentType(String contentType) { + this.contentType = contentType; + return this; + } + + + public Integer statusCode; + + public GetAccountBalancesResponse withStatusCode(Integer statusCode) { + this.statusCode = statusCode; + return this; + } + + + public HttpResponse rawResponse; + + public GetAccountBalancesResponse withRawResponse(HttpResponse rawResponse) { + this.rawResponse = rawResponse; + return this; + } + + public GetAccountBalancesResponse(@JsonProperty("ContentType") String contentType, @JsonProperty("StatusCode") Integer statusCode) { + this.contentType = contentType; + this.statusCode = statusCode; + } +} diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/AccountBalance.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/AccountBalance.java new file mode 100755 index 0000000000..5dfb3e003e --- /dev/null +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/AccountBalance.java @@ -0,0 +1,66 @@ +/* + * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + */ + +package com.formance.formance_sdk.models.shared; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.formance.formance_sdk.utils.DateTimeDeserializer; +import com.formance.formance_sdk.utils.DateTimeSerializer; +import java.time.OffsetDateTime; + +public class AccountBalance { + @JsonProperty("accountId") + public String accountId; + + public AccountBalance withAccountId(String accountId) { + this.accountId = accountId; + return this; + } + + @JsonProperty("balance") + public Long balance; + + public AccountBalance withBalance(Long balance) { + this.balance = balance; + return this; + } + + @JsonSerialize(using = DateTimeSerializer.class) + @JsonDeserialize(using = DateTimeDeserializer.class) + @JsonProperty("createdAt") + public OffsetDateTime createdAt; + + public AccountBalance withCreatedAt(OffsetDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + @JsonProperty("currency") + public String currency; + + public AccountBalance withCurrency(String currency) { + this.currency = currency; + return this; + } + + @JsonSerialize(using = DateTimeSerializer.class) + @JsonDeserialize(using = DateTimeDeserializer.class) + @JsonProperty("lastUpdatedAt") + public OffsetDateTime lastUpdatedAt; + + public AccountBalance withLastUpdatedAt(OffsetDateTime lastUpdatedAt) { + this.lastUpdatedAt = lastUpdatedAt; + return this; + } + + public AccountBalance(@JsonProperty("accountId") String accountId, @JsonProperty("balance") Long balance, @JsonProperty("createdAt") OffsetDateTime createdAt, @JsonProperty("currency") String currency, @JsonProperty("lastUpdatedAt") OffsetDateTime lastUpdatedAt) { + this.accountId = accountId; + this.balance = balance; + this.createdAt = createdAt; + this.currency = currency; + this.lastUpdatedAt = lastUpdatedAt; + } +} diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/BalancesCursor.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/BalancesCursor.java new file mode 100755 index 0000000000..256eb49a3d --- /dev/null +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/BalancesCursor.java @@ -0,0 +1,24 @@ +/* + * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + */ + +package com.formance.formance_sdk.models.shared; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * BalancesCursor - OK + */ +public class BalancesCursor { + @JsonProperty("cursor") + public BalancesCursorCursor cursor; + + public BalancesCursor withCursor(BalancesCursorCursor cursor) { + this.cursor = cursor; + return this; + } + + public BalancesCursor(@JsonProperty("cursor") BalancesCursorCursor cursor) { + this.cursor = cursor; + } +} diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/BalancesCursorCursor.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/BalancesCursorCursor.java new file mode 100755 index 0000000000..122501fcb5 --- /dev/null +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/BalancesCursorCursor.java @@ -0,0 +1,59 @@ +/* + * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + */ + +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 BalancesCursorCursor { + @JsonProperty("data") + public AccountBalance[] data; + + public BalancesCursorCursor withData(AccountBalance[] data) { + this.data = data; + return this; + } + + @JsonProperty("hasMore") + public Boolean hasMore; + + public BalancesCursorCursor withHasMore(Boolean hasMore) { + this.hasMore = hasMore; + return this; + } + + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("next") + public String next; + + public BalancesCursorCursor withNext(String next) { + this.next = next; + return this; + } + + @JsonProperty("pageSize") + public Long pageSize; + + public BalancesCursorCursor withPageSize(Long pageSize) { + this.pageSize = pageSize; + return this; + } + + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("previous") + public String previous; + + public BalancesCursorCursor withPrevious(String previous) { + this.previous = previous; + return this; + } + + public BalancesCursorCursor(@JsonProperty("data") AccountBalance[] data, @JsonProperty("hasMore") Boolean hasMore, @JsonProperty("pageSize") Long pageSize) { + this.data = data; + this.hasMore = hasMore; + this.pageSize = pageSize; + } +} diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/WalletsPosting.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/WalletsPosting.java new file mode 100755 index 0000000000..781642f71f --- /dev/null +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/WalletsPosting.java @@ -0,0 +1,48 @@ +/* + * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + */ + +package com.formance.formance_sdk.models.shared; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class WalletsPosting { + @JsonProperty("amount") + public Long amount; + + public WalletsPosting withAmount(Long amount) { + this.amount = amount; + return this; + } + + @JsonProperty("asset") + public String asset; + + public WalletsPosting withAsset(String asset) { + this.asset = asset; + return this; + } + + @JsonProperty("destination") + public String destination; + + public WalletsPosting withDestination(String destination) { + this.destination = destination; + return this; + } + + @JsonProperty("source") + public String source; + + public WalletsPosting withSource(String source) { + this.source = source; + return this; + } + + public WalletsPosting(@JsonProperty("amount") Long amount, @JsonProperty("asset") String asset, @JsonProperty("destination") String destination, @JsonProperty("source") String source) { + this.amount = amount; + this.asset = asset; + this.destination = destination; + this.source = source; + } +} diff --git a/sdks/php/README.md b/sdks/php/README.md index e3e4057850..6785479508 100755 --- a/sdks/php/README.md +++ b/sdks/php/README.md @@ -131,6 +131,7 @@ try { * [connectorsStripeTransfer](docs/payments/README.md#connectorsstripetransfer) - Transfer funds between Stripe accounts * [connectorsTransfer](docs/payments/README.md#connectorstransfer) - Transfer funds between Connector accounts +* [getAccountBalances](docs/payments/README.md#getaccountbalances) - Get account balances * [getConnectorTask](docs/payments/README.md#getconnectortask) - Read a specific task of the connector * [getPayment](docs/payments/README.md#getpayment) - Get a payment * [installConnector](docs/payments/README.md#installconnector) - Install a connector diff --git a/sdks/php/docs/payments/README.md b/sdks/php/docs/payments/README.md index ea06509fcf..66acd7dc6f 100755 --- a/sdks/php/docs/payments/README.md +++ b/sdks/php/docs/payments/README.md @@ -4,6 +4,7 @@ * [connectorsStripeTransfer](#connectorsstripetransfer) - Transfer funds between Stripe accounts * [connectorsTransfer](#connectorstransfer) - Transfer funds between Connector accounts +* [getAccountBalances](#getaccountbalances) - Get account balances * [getConnectorTask](#getconnectortask) - Read a specific task of the connector * [getPayment](#getpayment) - Get a payment * [installConnector](#installconnector) - Install a connector @@ -99,6 +100,51 @@ try { } ``` +## getAccountBalances + +Get account balances + +### Example Usage + +```php +build(); + +try { + $request = new GetAccountBalancesRequest(); + $request->accountID = 'provident'; + $request->currency = 'necessitatibus'; + $request->cursor = 'aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=='; + $request->from = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2021-09-21T14:06:09.271Z'); + $request->limit = 223081; + $request->pageSize = 891555; + $request->sort = [ + 'dolorum', + 'in', + 'in', + 'illum', + ]; + $request->to = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2020-11-26T01:41:04.216Z'); + + $response = $sdk->payments->getAccountBalances($request); + + if ($response->balancesCursor !== null) { + // handle response + } +} catch (Exception $e) { + // handle exception +} +``` + ## getConnectorTask Get a specific task associated to the connector. @@ -121,8 +167,8 @@ $sdk = SDK::builder() try { $request = new GetConnectorTaskRequest(); - $request->connector = Connector::CURRENCY_CLOUD; - $request->taskId = 'necessitatibus'; + $request->connector = Connector::STRIPE; + $request->taskId = 'magnam'; $response = $sdk->payments->getConnectorTask($request); @@ -155,7 +201,7 @@ $sdk = SDK::builder() try { $request = new GetPaymentRequest(); - $request->paymentId = 'sint'; + $request->paymentId = 'cumque'; $response = $sdk->payments->getPayment($request); @@ -189,15 +235,12 @@ $sdk = SDK::builder() try { $request = new InstallConnectorRequest(); - $request->requestBody = new BankingCircleConfig(); - $request->requestBody->authorizationEndpoint = 'XXX'; + $request->requestBody = new MangoPayConfig(); + $request->requestBody->apiKey = 'XXX'; + $request->requestBody->clientID = 'XXX'; $request->requestBody->endpoint = 'XXX'; - $request->requestBody->password = 'XXX'; $request->requestBody->pollingPeriod = '60s'; - $request->requestBody->userCertificate = 'XXX'; - $request->requestBody->userCertificateKey = 'XXX'; - $request->requestBody->username = 'XXX'; - $request->connector = Connector::DUMMY_PAY; + $request->connector = Connector::MODULR; $response = $sdk->payments->installConnector($request); @@ -289,9 +332,9 @@ $sdk = SDK::builder() try { $request = new ListConnectorTasksRequest(); - $request->connector = Connector::MONEYCORP; + $request->connector = Connector::MODULR; $request->cursor = 'aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=='; - $request->pageSize = 952749; + $request->pageSize = 675439; $response = $sdk->payments->listConnectorTasks($request); @@ -325,7 +368,7 @@ $sdk = SDK::builder() try { $request = new ListConnectorsTransfersRequest(); - $request->connector = Connector::BANKING_CIRCLE; + $request->connector = Connector::MONEYCORP; $response = $sdk->payments->listConnectorsTransfers($request); @@ -359,10 +402,11 @@ $sdk = SDK::builder() try { $request = new ListPaymentsRequest(); $request->cursor = 'aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=='; - $request->pageSize = 447125; + $request->pageSize = 249796; $request->sort = [ - 'illum', - 'maiores', + 'enim', + 'accusamus', + 'delectus', ]; $response = $sdk->payments->listPayments($request); @@ -426,9 +470,11 @@ $sdk = SDK::builder() try { $request = new PaymentslistAccountsRequest(); $request->cursor = 'aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=='; - $request->pageSize = 699479; + $request->pageSize = 692532; $request->sort = [ - 'magnam', + 'nam', + 'id', + 'blanditiis', ]; $response = $sdk->payments->paymentslistAccounts($request); @@ -463,7 +509,7 @@ $sdk = SDK::builder() try { $request = new ReadConnectorConfigRequest(); - $request->connector = Connector::MANGOPAY; + $request->connector = Connector::CURRENCY_CLOUD; $response = $sdk->payments->readConnectorConfig($request); @@ -499,7 +545,7 @@ $sdk = SDK::builder() try { $request = new ResetConnectorRequest(); - $request->connector = Connector::MANGOPAY; + $request->connector = Connector::MONEYCORP; $response = $sdk->payments->resetConnector($request); @@ -533,7 +579,7 @@ $sdk = SDK::builder() try { $request = new UninstallConnectorRequest(); - $request->connector = Connector::MODULR; + $request->connector = Connector::DUMMY_PAY; $response = $sdk->payments->uninstallConnector($request); @@ -568,8 +614,8 @@ $sdk = SDK::builder() try { $request = new UpdateMetadataRequest(); $request->paymentMetadata = new PaymentMetadata(); - $request->paymentMetadata->key = 'aliquid'; - $request->paymentId = 'laborum'; + $request->paymentMetadata->key = 'deserunt'; + $request->paymentId = 'nisi'; $response = $sdk->payments->updateMetadata($request); diff --git a/sdks/php/docs/search/README.md b/sdks/php/docs/search/README.md index d4cbc530bd..2e5e5fd399 100755 --- a/sdks/php/docs/search/README.md +++ b/sdks/php/docs/search/README.md @@ -29,25 +29,24 @@ try { $request->after = [ 'users:002', 'users:002', - 'users:002', - 'users:002', ]; $request->cursor = 'YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol='; $request->ledgers = [ 'quickstart', + 'quickstart', + 'quickstart', ]; - $request->pageSize = 581273; + $request->pageSize = 606393; $request->policy = 'OR'; $request->raw = [ - 'accusamus' => 'delectus', - 'quidem' => 'provident', + 'perferendis' => 'nihil', + 'magnam' => 'distinctio', ]; $request->sort = 'txid:asc'; - $request->target = 'nam'; + $request->target = 'id'; $request->terms = [ 'destination=central_bank1', 'destination=central_bank1', - 'destination=central_bank1', ]; $response = $sdk->search->search($request); diff --git a/sdks/php/docs/wallets/README.md b/sdks/php/docs/wallets/README.md index 63d5e813f8..cd8be06266 100755 --- a/sdks/php/docs/wallets/README.md +++ b/sdks/php/docs/wallets/README.md @@ -44,7 +44,7 @@ try { $request->confirmHoldRequest = new ConfirmHoldRequest(); $request->confirmHoldRequest->amount = 100; $request->confirmHoldRequest->final = true; - $request->holdId = 'blanditiis'; + $request->holdId = 'labore'; $response = $sdk->wallets->confirmHold($request); @@ -79,10 +79,10 @@ $sdk = SDK::builder() try { $request = new CreateBalanceRequest(); $request->createBalanceRequest = new CreateBalanceRequest(); - $request->createBalanceRequest->expiresAt = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2021-02-02T01:24:52.629Z'); - $request->createBalanceRequest->name = 'Sandy Huels'; - $request->createBalanceRequest->priority = 606393; - $request->id = '7074ba44-69b6-4e21-8195-9890afa563e2'; + $request->createBalanceRequest->expiresAt = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2022-05-20T10:11:05.115Z'); + $request->createBalanceRequest->name = 'Duane Thiel II'; + $request->createBalanceRequest->priority = 92373; + $request->id = '959890af-a563-4e25-96fe-4c8b711e5b7f'; $response = $sdk->wallets->createBalance($request); @@ -116,10 +116,12 @@ $sdk = SDK::builder() try { $request = new CreateWalletRequest(); $request->metadata = [ - 'quasi' => 'iure', - 'doloribus' => 'debitis', + 'sed' => 'saepe', + 'pariatur' => 'accusantium', + 'consequuntur' => 'praesentium', + 'natus' => 'magni', ]; - $request->name = 'Jasmine Lind'; + $request->name = 'Angelica Stanton'; $response = $sdk->wallets->createWallet($request); @@ -156,21 +158,19 @@ try { $request = new CreditWalletRequest(); $request->creditWalletRequest = new CreditWalletRequest(); $request->creditWalletRequest->amount = new Monetary(); - $request->creditWalletRequest->amount->amount = 100226; - $request->creditWalletRequest->amount->asset = 'architecto'; - $request->creditWalletRequest->balance = 'repudiandae'; + $request->creditWalletRequest->amount->amount = 411397; + $request->creditWalletRequest->amount->asset = 'excepturi'; + $request->creditWalletRequest->balance = 'odit'; $request->creditWalletRequest->metadata = [ - 'expedita' => 'nihil', - 'repellat' => 'quibusdam', + 'accusantium' => 'ab', + 'maiores' => 'quidem', ]; - $request->creditWalletRequest->reference = 'sed'; + $request->creditWalletRequest->reference = 'ipsam'; $request->creditWalletRequest->sources = [ - new WalletSubject(), - new LedgerAccountSubject(), new LedgerAccountSubject(), new WalletSubject(), ]; - $request->id = '921cddc6-9260-41fb-976b-0d5f0d30c5fb'; + $request->id = '0d5f0d30-c5fb-4b25-8705-3202c73d5fe9'; $response = $sdk->wallets->creditWallet($request); @@ -207,21 +207,23 @@ try { $request = new DebitWalletRequest(); $request->debitWalletRequest = new DebitWalletRequest(); $request->debitWalletRequest->amount = new Monetary(); - $request->debitWalletRequest->amount->amount = 749999; - $request->debitWalletRequest->amount->asset = 'dolores'; + $request->debitWalletRequest->amount->amount = 704415; + $request->debitWalletRequest->amount->asset = 'perspiciatis'; $request->debitWalletRequest->balances = [ - 'totam', - 'dignissimos', + 'porro', ]; - $request->debitWalletRequest->description = 'eaque'; - $request->debitWalletRequest->destination = new LedgerAccountSubject(); - $request->debitWalletRequest->destination->identifier = 'nesciunt'; - $request->debitWalletRequest->destination->type = 'eos'; + $request->debitWalletRequest->description = 'consequuntur'; + $request->debitWalletRequest->destination = new WalletSubject(); + $request->debitWalletRequest->destination->balance = 'error'; + $request->debitWalletRequest->destination->identifier = 'eaque'; + $request->debitWalletRequest->destination->type = 'occaecati'; $request->debitWalletRequest->metadata = [ - 'dolores' => 'minus', + 'adipisci' => 'asperiores', + 'earum' => 'modi', + 'iste' => 'dolorum', ]; $request->debitWalletRequest->pending = false; - $request->id = '73d5fe9b-90c2-4890-9b3f-e49a8d9cbf48'; + $request->id = '8d9cbf48-6333-423f-9b77-f3a4100674eb'; $response = $sdk->wallets->debitWallet($request); @@ -254,8 +256,8 @@ $sdk = SDK::builder() try { $request = new GetBalanceRequest(); - $request->balanceName = 'aliquid'; - $request->id = '33323f9b-77f3-4a41-8067-4ebf69280d1b'; + $request->balanceName = 'voluptatibus'; + $request->id = '69280d1b-a77a-489e-bf73-7ae4203ce5e6'; $response = $sdk->wallets->getBalance($request); @@ -288,7 +290,7 @@ $sdk = SDK::builder() try { $request = new GetHoldRequest(); - $request->holdID = 'dolorum'; + $request->holdID = 'deserunt'; $response = $sdk->wallets->getHold($request); @@ -323,11 +325,12 @@ try { $request = new GetHoldsRequest(); $request->cursor = 'aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=='; $request->metadata = [ - 'voluptate' => 'dolorum', - 'deleniti' => 'omnis', + 'minima' => 'repellendus', + 'totam' => 'similique', + 'alias' => 'at', ]; - $request->pageSize = 896672; - $request->walletID = 'distinctio'; + $request->pageSize = 311860; + $request->walletID = 'tempora'; $response = $sdk->wallets->getHolds($request); @@ -359,8 +362,8 @@ $sdk = SDK::builder() try { $request = new GetTransactionsRequest(); $request->cursor = 'aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=='; - $request->pageSize = 990339; - $request->walletID = 'nihil'; + $request->pageSize = 425451; + $request->walletID = 'quod'; $response = $sdk->wallets->getTransactions($request); @@ -393,7 +396,7 @@ $sdk = SDK::builder() try { $request = new GetWalletRequest(); - $request->id = '37ae4203-ce5e-46a9-9d8a-0d446ce2af7a'; + $request->id = 'e2af7a73-cf3b-4e45-bf87-0b326b5a7342'; $response = $sdk->wallets->getWallet($request); @@ -426,7 +429,7 @@ $sdk = SDK::builder() try { $request = new GetWalletSummaryRequest(); - $request->id = '73cf3be4-53f8-470b-b26b-5a73429cdb1a'; + $request->id = '9cdb1a84-22bb-4679-9232-2715bf0cbb1e'; $response = $sdk->wallets->getWalletSummary($request); @@ -459,7 +462,7 @@ $sdk = SDK::builder() try { $request = new ListBalancesRequest(); - $request->id = '8422bb67-9d23-4227-95bf-0cbb1e31b8b9'; + $request->id = '31b8b90f-3443-4a11-88e0-adcf4b921879'; $response = $sdk->wallets->listBalances($request); @@ -494,10 +497,13 @@ try { $request = new ListWalletsRequest(); $request->cursor = 'aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=='; $request->metadata = [ - 'delectus' => 'dolorem', + 'quisquam' => 'vero', + 'omnis' => 'quis', + 'ipsum' => 'delectus', + 'voluptate' => 'consectetur', ]; - $request->name = 'Clara Fisher Jr.'; - $request->pageSize = 16429; + $request->name = 'Roman Kulas'; + $request->pageSize = 799203; $response = $sdk->wallets->listWallets($request); @@ -533,11 +539,10 @@ try { $request = new UpdateWalletRequest(); $request->requestBody = new UpdateWalletRequestBody(); $request->requestBody->metadata = [ - 'itaque' => 'consequatur', - 'est' => 'repellendus', - 'porro' => 'doloribus', + 'similique' => 'facilis', + 'vero' => 'ducimus', ]; - $request->id = '4b921879-fce9-453f-b3ef-7fbc7abd74dd'; + $request->id = '4dd39c0f-5d2c-4ff7-870a-45626d436813'; $response = $sdk->wallets->updateWallet($request); @@ -570,7 +575,7 @@ $sdk = SDK::builder() try { $request = new VoidHoldRequest(); - $request->holdId = 'sequi'; + $request->holdId = 'maiores'; $response = $sdk->wallets->voidHold($request); diff --git a/sdks/php/docs/webhooks/README.md b/sdks/php/docs/webhooks/README.md index bd873af7f3..29f7933f9e 100755 --- a/sdks/php/docs/webhooks/README.md +++ b/sdks/php/docs/webhooks/README.md @@ -216,8 +216,6 @@ try { $request->endpoint = 'https://example.com'; $request->eventTypes = [ 'TYPE1', - 'TYPE1', - 'TYPE1', ]; $request->secret = 'V0bivxRWveaoz08afqjU6Ko/jwO0Cb+3'; diff --git a/sdks/php/files.gen b/sdks/php/files.gen index 533ec85713..f044f8fa9b 100755 --- a/sdks/php/files.gen +++ b/sdks/php/files.gen @@ -113,6 +113,8 @@ src/Models/Operations/SendEventResponse.php src/Models/Operations/ConnectorsStripeTransferResponse.php src/Models/Operations/ConnectorsTransferRequest.php src/Models/Operations/ConnectorsTransferResponse.php +src/Models/Operations/GetAccountBalancesRequest.php +src/Models/Operations/GetAccountBalancesResponse.php src/Models/Operations/GetConnectorTaskRequest.php src/Models/Operations/GetConnectorTaskResponse.php src/Models/Operations/GetPaymentRequest.php @@ -308,6 +310,9 @@ src/Models/Shared/RunWorkflowResponse.php src/Models/Shared/StripeTransferRequest.php src/Models/Shared/TransferResponse.php src/Models/Shared/TransferRequest.php +src/Models/Shared/BalancesCursorCursor.php +src/Models/Shared/BalancesCursor.php +src/Models/Shared/AccountBalance.php src/Models/Shared/TaskResponse.php src/Models/Shared/TaskStripeDescriptor.php src/Models/Shared/TaskStripe.php diff --git a/sdks/php/src/Models/Operations/GetAccountBalancesRequest.php b/sdks/php/src/Models/Operations/GetAccountBalancesRequest.php new file mode 100755 index 0000000000..d2a1ac5b7c --- /dev/null +++ b/sdks/php/src/Models/Operations/GetAccountBalancesRequest.php @@ -0,0 +1,105 @@ + $sort + */ + #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=sort')] + public ?array $sort = null; + + /** + * Filter balances by date. + * + * If not specified, default will be set to now. + * + * + * @var ?\DateTime $to + */ + #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=to,dateTimeFormat=Y-m-d\TH:i:s.up')] + public ?\DateTime $to = null; + + public function __construct() + { + $this->accountID = ""; + $this->currency = null; + $this->cursor = null; + $this->from = null; + $this->limit = null; + $this->pageSize = null; + $this->sort = null; + $this->to = null; + } +} diff --git a/sdks/php/src/Models/Operations/GetAccountBalancesResponse.php b/sdks/php/src/Models/Operations/GetAccountBalancesResponse.php new file mode 100755 index 0000000000..7adf1e7f43 --- /dev/null +++ b/sdks/php/src/Models/Operations/GetAccountBalancesResponse.php @@ -0,0 +1,38 @@ +balancesCursor = null; + $this->contentType = ""; + $this->statusCode = 0; + $this->rawResponse = null; + } +} diff --git a/sdks/php/src/Models/Shared/AccountBalance.php b/sdks/php/src/Models/Shared/AccountBalance.php new file mode 100755 index 0000000000..75445cbb02 --- /dev/null +++ b/sdks/php/src/Models/Shared/AccountBalance.php @@ -0,0 +1,42 @@ +")] + public \DateTime $createdAt; + + #[\JMS\Serializer\Annotation\SerializedName('currency')] + #[\JMS\Serializer\Annotation\Type('string')] + public string $currency; + + #[\JMS\Serializer\Annotation\SerializedName('lastUpdatedAt')] + #[\JMS\Serializer\Annotation\Type("DateTime<'Y-m-d\TH:i:s.up'>")] + public \DateTime $lastUpdatedAt; + + public function __construct() + { + $this->accountId = ""; + $this->balance = 0; + $this->createdAt = new \DateTime(); + $this->currency = ""; + $this->lastUpdatedAt = new \DateTime(); + } +} diff --git a/sdks/php/src/Models/Shared/BalancesCursor.php b/sdks/php/src/Models/Shared/BalancesCursor.php new file mode 100755 index 0000000000..ceee337cb0 --- /dev/null +++ b/sdks/php/src/Models/Shared/BalancesCursor.php @@ -0,0 +1,28 @@ +cursor = new \formance\stack\Models\Shared\BalancesCursorCursor(); + } +} diff --git a/sdks/php/src/Models/Shared/BalancesCursorCursor.php b/sdks/php/src/Models/Shared/BalancesCursorCursor.php new file mode 100755 index 0000000000..ddc3377349 --- /dev/null +++ b/sdks/php/src/Models/Shared/BalancesCursorCursor.php @@ -0,0 +1,49 @@ + $data + */ + #[\JMS\Serializer\Annotation\SerializedName('data')] + #[\JMS\Serializer\Annotation\Type('array')] + public array $data; + + #[\JMS\Serializer\Annotation\SerializedName('hasMore')] + #[\JMS\Serializer\Annotation\Type('bool')] + public bool $hasMore; + + #[\JMS\Serializer\Annotation\SerializedName('next')] + #[\JMS\Serializer\Annotation\Type('string')] + #[\JMS\Serializer\Annotation\SkipWhenEmpty] + public ?string $next = null; + + #[\JMS\Serializer\Annotation\SerializedName('pageSize')] + #[\JMS\Serializer\Annotation\Type('int')] + public int $pageSize; + + #[\JMS\Serializer\Annotation\SerializedName('previous')] + #[\JMS\Serializer\Annotation\Type('string')] + #[\JMS\Serializer\Annotation\SkipWhenEmpty] + public ?string $previous = null; + + public function __construct() + { + $this->data = []; + $this->hasMore = false; + $this->next = null; + $this->pageSize = 0; + $this->previous = null; + } +} diff --git a/sdks/php/src/Models/Shared/WalletsPosting.php b/sdks/php/src/Models/Shared/WalletsPosting.php new file mode 100755 index 0000000000..5b1fe862c3 --- /dev/null +++ b/sdks/php/src/Models/Shared/WalletsPosting.php @@ -0,0 +1,37 @@ +amount = 0; + $this->asset = ""; + $this->destination = ""; + $this->source = ""; + } +} diff --git a/sdks/php/src/Payments.php b/sdks/php/src/Payments.php index 0d95808718..26166b8caf 100755 --- a/sdks/php/src/Payments.php +++ b/sdks/php/src/Payments.php @@ -123,6 +123,43 @@ public function connectorsTransfer( return $response; } + /** + * Get account balances + * + * @param \formance\stack\Models\Operations\GetAccountBalancesRequest $request + * @return \formance\stack\Models\Operations\GetAccountBalancesResponse + */ + public function getAccountBalances( + \formance\stack\Models\Operations\GetAccountBalancesRequest $request, + ): \formance\stack\Models\Operations\GetAccountBalancesResponse + { + $baseUrl = $this->_serverUrl; + $url = Utils\Utils::generateUrl($baseUrl, '/api/payments/accounts/{accountID}/balances', \formance\stack\Models\Operations\GetAccountBalancesRequest::class, $request); + + $options = ['http_errors' => false]; + $options = array_merge_recursive($options, Utils\Utils::getQueryParams(\formance\stack\Models\Operations\GetAccountBalancesRequest::class, $request, null)); + $options['headers']['Accept'] = 'application/json'; + $options['headers']['user-agent'] = sprintf('speakeasy-sdk/%s %s %s', $this->_language, $this->_sdkVersion, $this->_genVersion); + + $httpResponse = $this->_securityClient->request('GET', $url, $options); + + $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; + + $response = new \formance\stack\Models\Operations\GetAccountBalancesResponse(); + $response->statusCode = $httpResponse->getStatusCode(); + $response->contentType = $contentType; + $response->rawResponse = $httpResponse; + + if ($httpResponse->getStatusCode() === 200) { + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $serializer = Utils\JSON::createSerializer(); + $response->balancesCursor = $serializer->deserialize((string)$httpResponse->getBody(), 'formance\stack\Models\Shared\BalancesCursor', 'json'); + } + } + + return $response; + } + /** * Read a specific task of the connector * diff --git a/sdks/python/README.md b/sdks/python/README.md index f0851c072c..794200e757 100755 --- a/sdks/python/README.md +++ b/sdks/python/README.md @@ -106,6 +106,7 @@ if res.get_versions_response is not None: * [connectors_stripe_transfer](docs/payments/README.md#connectors_stripe_transfer) - Transfer funds between Stripe accounts * [connectors_transfer](docs/payments/README.md#connectors_transfer) - Transfer funds between Connector accounts +* [get_account_balances](docs/payments/README.md#get_account_balances) - Get account balances * [get_connector_task](docs/payments/README.md#get_connector_task) - Read a specific task of the connector * [get_payment](docs/payments/README.md#get_payment) - Get a payment * [install_connector](docs/payments/README.md#install_connector) - Install a connector diff --git a/sdks/python/docs/payments/README.md b/sdks/python/docs/payments/README.md index feb94af59c..68f2bc69f9 100755 --- a/sdks/python/docs/payments/README.md +++ b/sdks/python/docs/payments/README.md @@ -4,6 +4,7 @@ * [connectors_stripe_transfer](#connectors_stripe_transfer) - Transfer funds between Stripe accounts * [connectors_transfer](#connectors_transfer) - Transfer funds between Connector accounts +* [get_account_balances](#get_account_balances) - Get account balances * [get_connector_task](#get_connector_task) - Read a specific task of the connector * [get_payment](#get_payment) - Get a payment * [install_connector](#install_connector) - Install a connector @@ -84,6 +85,45 @@ if res.transfer_response is not None: # handle response ``` +## get_account_balances + +Get account balances + +### Example Usage + +```python +import sdk +import dateutil.parser +from sdk.models import operations + +s = sdk.SDK( + security=shared.Security( + authorization="Bearer YOUR_ACCESS_TOKEN_HERE", + ), +) + +req = operations.GetAccountBalancesRequest( + account_id='provident', + currency='necessitatibus', + cursor='aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==', + from_=dateutil.parser.isoparse('2021-09-21T14:06:09.271Z'), + limit=223081, + page_size=891555, + sort=[ + 'dolorum', + 'in', + 'in', + 'illum', + ], + to=dateutil.parser.isoparse('2020-11-26T01:41:04.216Z'), +) + +res = s.payments.get_account_balances(req) + +if res.balances_cursor is not None: + # handle response +``` + ## get_connector_task Get a specific task associated to the connector. @@ -101,8 +141,8 @@ s = sdk.SDK( ) req = operations.GetConnectorTaskRequest( - connector=shared.Connector.CURRENCY_CLOUD, - task_id='necessitatibus', + connector=shared.Connector.STRIPE, + task_id='magnam', ) res = s.payments.get_connector_task(req) @@ -128,7 +168,7 @@ s = sdk.SDK( ) req = operations.GetPaymentRequest( - payment_id='sint', + payment_id='cumque', ) res = s.payments.get_payment(req) @@ -154,16 +194,13 @@ s = sdk.SDK( ) req = operations.InstallConnectorRequest( - request_body=shared.BankingCircleConfig( - authorization_endpoint='XXX', + request_body=shared.MangoPayConfig( + api_key='XXX', + client_id='XXX', endpoint='XXX', - password='XXX', polling_period='60s', - user_certificate='XXX', - user_certificate_key='XXX', - username='XXX', ), - connector=shared.Connector.DUMMY_PAY, + connector=shared.Connector.MODULR, ) res = s.payments.install_connector(req) @@ -235,9 +272,9 @@ s = sdk.SDK( ) req = operations.ListConnectorTasksRequest( - connector=shared.Connector.MONEYCORP, + connector=shared.Connector.MODULR, cursor='aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==', - page_size=952749, + page_size=675439, ) res = s.payments.list_connector_tasks(req) @@ -263,7 +300,7 @@ s = sdk.SDK( ) req = operations.ListConnectorsTransfersRequest( - connector=shared.Connector.BANKING_CIRCLE, + connector=shared.Connector.MONEYCORP, ) res = s.payments.list_connectors_transfers(req) @@ -290,10 +327,11 @@ s = sdk.SDK( req = operations.ListPaymentsRequest( cursor='aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==', - page_size=447125, + page_size=249796, sort=[ - 'illum', - 'maiores', + 'enim', + 'accusamus', + 'delectus', ], ) @@ -344,9 +382,11 @@ s = sdk.SDK( req = operations.PaymentslistAccountsRequest( cursor='aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==', - page_size=699479, + page_size=692532, sort=[ - 'magnam', + 'nam', + 'id', + 'blanditiis', ], ) @@ -373,7 +413,7 @@ s = sdk.SDK( ) req = operations.ReadConnectorConfigRequest( - connector=shared.Connector.MANGOPAY, + connector=shared.Connector.CURRENCY_CLOUD, ) res = s.payments.read_connector_config(req) @@ -401,7 +441,7 @@ s = sdk.SDK( ) req = operations.ResetConnectorRequest( - connector=shared.Connector.MANGOPAY, + connector=shared.Connector.MONEYCORP, ) res = s.payments.reset_connector(req) @@ -427,7 +467,7 @@ s = sdk.SDK( ) req = operations.UninstallConnectorRequest( - connector=shared.Connector.MODULR, + connector=shared.Connector.DUMMY_PAY, ) res = s.payments.uninstall_connector(req) @@ -454,9 +494,9 @@ s = sdk.SDK( req = operations.UpdateMetadataRequest( payment_metadata=shared.PaymentMetadata( - key='aliquid', + key='deserunt', ), - payment_id='laborum', + payment_id='nisi', ) res = s.payments.update_metadata(req) diff --git a/sdks/python/docs/search/README.md b/sdks/python/docs/search/README.md index c3c720a48c..2816427c0f 100755 --- a/sdks/python/docs/search/README.md +++ b/sdks/python/docs/search/README.md @@ -25,25 +25,24 @@ req = shared.Query( after=[ 'users:002', 'users:002', - 'users:002', - 'users:002', ], cursor='YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol=', ledgers=[ 'quickstart', + 'quickstart', + 'quickstart', ], - page_size=581273, + page_size=606393, policy='OR', raw={ - "accusamus": 'delectus', - "quidem": 'provident', + "perferendis": 'nihil', + "magnam": 'distinctio', }, sort='txid:asc', - target='nam', + target='id', terms=[ 'destination=central_bank1', 'destination=central_bank1', - 'destination=central_bank1', ], ) diff --git a/sdks/python/docs/wallets/README.md b/sdks/python/docs/wallets/README.md index 022317dbcc..c51451b32a 100755 --- a/sdks/python/docs/wallets/README.md +++ b/sdks/python/docs/wallets/README.md @@ -40,7 +40,7 @@ req = operations.ConfirmHoldRequest( amount=100, final=True, ), - hold_id='blanditiis', + hold_id='labore', ) res = s.wallets.confirm_hold(req) @@ -68,11 +68,11 @@ s = sdk.SDK( req = operations.CreateBalanceRequest( create_balance_request=shared.CreateBalanceRequest( - expires_at=dateutil.parser.isoparse('2021-02-02T01:24:52.629Z'), - name='Sandy Huels', - priority=606393, + expires_at=dateutil.parser.isoparse('2022-05-20T10:11:05.115Z'), + name='Duane Thiel II', + priority=92373, ), - id='7074ba44-69b6-4e21-8195-9890afa563e2', + id='959890af-a563-4e25-96fe-4c8b711e5b7f', ) res = s.wallets.create_balance(req) @@ -99,10 +99,12 @@ s = sdk.SDK( req = shared.CreateWalletRequest( metadata={ - "quasi": 'iure', - "doloribus": 'debitis', + "sed": 'saepe', + "pariatur": 'accusantium', + "consequuntur": 'praesentium', + "natus": 'magni', }, - name='Jasmine Lind', + name='Angelica Stanton', ) res = s.wallets.create_wallet(req) @@ -130,39 +132,28 @@ s = sdk.SDK( req = operations.CreditWalletRequest( credit_wallet_request=shared.CreditWalletRequest( amount=shared.Monetary( - amount=100226, - asset='architecto', + amount=411397, + asset='excepturi', ), - balance='repudiandae', + balance='odit', metadata={ - "expedita": 'nihil', - "repellat": 'quibusdam', + "accusantium": 'ab', + "maiores": 'quidem', }, - reference='sed', + reference='ipsam', sources=[ - shared.WalletSubject( - balance='accusantium', - identifier='consequuntur', - type='praesentium', - ), - shared.WalletSubject( - balance='magni', - identifier='sunt', - type='quo', - ), - shared.WalletSubject( - balance='pariatur', - identifier='maxime', - type='ea', + shared.LedgerAccountSubject( + identifier='nam', + type='eaque', ), shared.WalletSubject( - balance='odit', - identifier='ea', - type='accusantium', + balance='nemo', + identifier='voluptatibus', + type='perferendis', ), ], ), - id='1fb576b0-d5f0-4d30-85fb-b2587053202c', + id='d30c5fbb-2587-4053-a02c-73d5fe9b90c2', ) res = s.wallets.credit_wallet(req) @@ -190,29 +181,24 @@ s = sdk.SDK( req = operations.DebitWalletRequest( debit_wallet_request=shared.DebitWalletRequest( amount=shared.Monetary( - amount=463451, - asset='dolor', + amount=500026, + asset='error', ), balances=[ - 'nostrum', - 'hic', - 'recusandae', - 'omnis', + 'occaecati', ], - description='facilis', - destination=shared.WalletSubject( - balance='voluptatem', - identifier='porro', - type='consequuntur', + description='rerum', + destination=shared.LedgerAccountSubject( + identifier='asperiores', + type='earum', ), metadata={ - "error": 'eaque', - "occaecati": 'rerum', - "adipisci": 'asperiores', + "iste": 'dolorum', + "deleniti": 'pariatur', }, pending=False, ), - id='e49a8d9c-bf48-4633-b23f-9b77f3a41006', + id='9cbf4863-3323-4f9b-b7f3-a4100674ebf6', ) res = s.wallets.debit_wallet(req) @@ -238,8 +224,8 @@ s = sdk.SDK( ) req = operations.GetBalanceRequest( - balance_name='odio', - id='4ebf6928-0d1b-4a77-a89e-bf737ae4203c', + balance_name='natus', + id='280d1ba7-7a89-4ebf-b37a-e4203ce5e6a9', ) res = s.wallets.get_balance(req) @@ -265,7 +251,7 @@ s = sdk.SDK( ) req = operations.GetHoldRequest( - hold_id='accusamus', + hold_id='minima', ) res = s.wallets.get_hold(req) @@ -293,11 +279,13 @@ s = sdk.SDK( req = operations.GetHoldsRequest( cursor='aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==', metadata={ - "saepe": 'suscipit', - "deserunt": 'provident', + "totam": 'similique', + "alias": 'at', + "quaerat": 'tempora', + "vel": 'quod', }, - page_size=324683, - wallet_id='repellendus', + page_size=885338, + wallet_id='qui', ) res = s.wallets.get_holds(req) @@ -322,8 +310,8 @@ s = sdk.SDK( req = operations.GetTransactionsRequest( cursor='aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==', - page_size=519711, - wallet_id='similique', + page_size=679880, + wallet_id='a', ) res = s.wallets.get_transactions(req) @@ -349,7 +337,7 @@ s = sdk.SDK( ) req = operations.GetWalletRequest( - id='0d446ce2-af7a-473c-b3be-453f870b326b', + id='7a73cf3b-e453-4f87-8b32-6b5a73429cdb', ) res = s.wallets.get_wallet(req) @@ -375,7 +363,7 @@ s = sdk.SDK( ) req = operations.GetWalletSummaryRequest( - id='5a73429c-db1a-4842-abb6-79d2322715bf', + id='1a8422bb-679d-4232-a715-bf0cbb1e31b8', ) res = s.wallets.get_wallet_summary(req) @@ -401,7 +389,7 @@ s = sdk.SDK( ) req = operations.ListBalancesRequest( - id='0cbb1e31-b8b9-40f3-843a-1108e0adcf4b', + id='b90f3443-a110-48e0-adcf-4b921879fce9', ) res = s.wallets.list_balances(req) @@ -429,12 +417,11 @@ s = sdk.SDK( req = operations.ListWalletsRequest( cursor='aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==', metadata={ - "qui": 'quae', - "laudantium": 'odio', - "occaecati": 'voluptatibus', + "ipsum": 'delectus', + "voluptate": 'consectetur', }, - name='Ignacio Moen', - page_size=961571, + name='Roman Kulas', + page_size=799203, ) res = s.wallets.list_wallets(req) @@ -462,11 +449,11 @@ s = sdk.SDK( req = operations.UpdateWalletRequest( request_body=operations.UpdateWalletRequestBody( metadata={ - "consectetur": 'vero', - "tenetur": 'dignissimos', + "similique": 'facilis', + "vero": 'ducimus', }, ), - id='fbc7abd7-4dd3-49c0-b5d2-cff7c70a4562', + id='4dd39c0f-5d2c-4ff7-870a-45626d436813', ) res = s.wallets.update_wallet(req) @@ -492,7 +479,7 @@ s = sdk.SDK( ) req = operations.VoidHoldRequest( - hold_id='vel', + hold_id='maiores', ) res = s.wallets.void_hold(req) diff --git a/sdks/python/docs/webhooks/README.md b/sdks/python/docs/webhooks/README.md index b90082ff23..57e37926af 100755 --- a/sdks/python/docs/webhooks/README.md +++ b/sdks/python/docs/webhooks/README.md @@ -177,9 +177,6 @@ req = shared.ConfigUser( endpoint='https://example.com', event_types=[ 'TYPE1', - 'TYPE1', - 'TYPE1', - 'TYPE1', ], secret='V0bivxRWveaoz08afqjU6Ko/jwO0Cb+3', ) diff --git a/sdks/python/files.gen b/sdks/python/files.gen index b33783e385..84a8acf536 100755 --- a/sdks/python/files.gen +++ b/sdks/python/files.gen @@ -62,6 +62,7 @@ src/sdk/models/operations/runworkflow.py src/sdk/models/operations/sendevent.py src/sdk/models/operations/connectorsstripetransfer.py src/sdk/models/operations/connectorstransfer.py +src/sdk/models/operations/getaccountbalances.py src/sdk/models/operations/getconnectortask.py src/sdk/models/operations/getpayment.py src/sdk/models/operations/installconnector.py @@ -214,6 +215,8 @@ src/sdk/models/shared/runworkflowresponse.py src/sdk/models/shared/stripetransferrequest.py src/sdk/models/shared/transferresponse.py src/sdk/models/shared/transferrequest.py +src/sdk/models/shared/balancescursor.py +src/sdk/models/shared/accountbalance.py src/sdk/models/shared/taskresponse.py src/sdk/models/shared/taskstripe.py src/sdk/models/shared/taskwise.py diff --git a/sdks/python/pylintrc b/sdks/python/pylintrc index 1ce47d88d3..b67c3cbbbc 100755 --- a/sdks/python/pylintrc +++ b/sdks/python/pylintrc @@ -180,6 +180,7 @@ good-names=i, ex, Run, _, + to, id # Good variable names regexes, separated by a comma. If names match any regex, diff --git a/sdks/python/src/sdk/models/operations/__init__.py b/sdks/python/src/sdk/models/operations/__init__.py index ce964e4ef4..f13691bc71 100755 --- a/sdks/python/src/sdk/models/operations/__init__.py +++ b/sdks/python/src/sdk/models/operations/__init__.py @@ -30,6 +30,7 @@ from .deletetransientscope import * from .deleteworkflow import * from .getaccount import * +from .getaccountbalances import * from .getbalance import * from .getbalances import * from .getbalancesaggregated import * @@ -90,4 +91,4 @@ from .voidhold import * from .walletsgetserverinfo import * -__all__ = ["ActivateConfigRequest","ActivateConfigResponse","AddMetadataOnTransactionRequest","AddMetadataOnTransactionResponse","AddMetadataToAccountRequest","AddMetadataToAccountResponse","AddScopeToClientRequest","AddScopeToClientResponse","AddTransientScopeRequest","AddTransientScopeResponse","CancelEventRequest","CancelEventResponse","ChangeConfigSecretRequest","ChangeConfigSecretResponse","ConfirmHoldRequest","ConfirmHoldResponse","ConnectorsStripeTransferResponse","ConnectorsTransferRequest","ConnectorsTransferResponse","CountAccountsRequest","CountAccountsResponse","CountTransactionsRequest","CountTransactionsResponse","CreateBalanceRequest","CreateBalanceResponse","CreateClientResponse","CreateScopeResponse","CreateSecretRequest","CreateSecretResponse","CreateTransactionRequest","CreateTransactionResponse","CreateWalletResponse","CreateWorkflowResponse","CreditWalletRequest","CreditWalletResponse","DeactivateConfigRequest","DeactivateConfigResponse","DebitWalletRequest","DebitWalletResponse","DeleteClientRequest","DeleteClientResponse","DeleteConfigRequest","DeleteConfigResponse","DeleteScopeFromClientRequest","DeleteScopeFromClientResponse","DeleteScopeRequest","DeleteScopeResponse","DeleteSecretRequest","DeleteSecretResponse","DeleteTransientScopeRequest","DeleteTransientScopeResponse","DeleteWorkflowRequest","DeleteWorkflowResponse","GetAccountRequest","GetAccountResponse","GetBalanceRequest","GetBalanceResponse","GetBalancesAggregatedRequest","GetBalancesAggregatedResponse","GetBalancesRequest","GetBalancesResponse","GetConnectorTaskRequest","GetConnectorTaskResponse","GetHoldRequest","GetHoldResponse","GetHoldsRequest","GetHoldsResponse","GetInfoResponse","GetInstanceHistoryRequest","GetInstanceHistoryResponse","GetInstanceRequest","GetInstanceResponse","GetInstanceStageHistoryRequest","GetInstanceStageHistoryResponse","GetLedgerInfoRequest","GetLedgerInfoResponse","GetManyConfigsRequest","GetManyConfigsResponse","GetPaymentRequest","GetPaymentResponse","GetServerInfoResponse","GetTransactionRequest","GetTransactionResponse","GetTransactionsRequest","GetTransactionsResponse","GetVersionsResponse","GetWalletRequest","GetWalletResponse","GetWalletSummaryRequest","GetWalletSummaryResponse","GetWorkflowRequest","GetWorkflowResponse","InsertConfigResponse","InstallConnectorRequest","InstallConnectorResponse","ListAccountsRequest","ListAccountsResponse","ListAllConnectorsResponse","ListBalancesRequest","ListBalancesResponse","ListClientsResponse","ListConfigsAvailableConnectorsResponse","ListConnectorTasksRequest","ListConnectorTasksResponse","ListConnectorsTransfersRequest","ListConnectorsTransfersResponse","ListInstancesRequest","ListInstancesResponse","ListLogsRequest","ListLogsResponse","ListPaymentsRequest","ListPaymentsResponse","ListScopesResponse","ListTransactionsRequest","ListTransactionsResponse","ListUsersResponse","ListWalletsRequest","ListWalletsResponse","ListWorkflowsResponse","OrchestrationgetServerInfoResponse","PaymentsgetServerInfoResponse","PaymentslistAccountsRequest","PaymentslistAccountsResponse","ReadClientRequest","ReadClientResponse","ReadConnectorConfigRequest","ReadConnectorConfigResponse","ReadScopeRequest","ReadScopeResponse","ReadStatsRequest","ReadStatsResponse","ReadUserRequest","ReadUserResponse","ResetConnectorRequest","ResetConnectorResponse","RevertTransactionRequest","RevertTransactionResponse","RunWorkflowRequest","RunWorkflowResponse","SearchResponse","SearchgetServerInfoResponse","SendEventRequest","SendEventRequestBody","SendEventResponse","TestConfigRequest","TestConfigResponse","UninstallConnectorRequest","UninstallConnectorResponse","UpdateClientRequest","UpdateClientResponse","UpdateMetadataRequest","UpdateMetadataResponse","UpdateScopeRequest","UpdateScopeResponse","UpdateWalletRequest","UpdateWalletRequestBody","UpdateWalletResponse","VoidHoldRequest","VoidHoldResponse","WalletsgetServerInfoResponse"] +__all__ = ["ActivateConfigRequest","ActivateConfigResponse","AddMetadataOnTransactionRequest","AddMetadataOnTransactionResponse","AddMetadataToAccountRequest","AddMetadataToAccountResponse","AddScopeToClientRequest","AddScopeToClientResponse","AddTransientScopeRequest","AddTransientScopeResponse","CancelEventRequest","CancelEventResponse","ChangeConfigSecretRequest","ChangeConfigSecretResponse","ConfirmHoldRequest","ConfirmHoldResponse","ConnectorsStripeTransferResponse","ConnectorsTransferRequest","ConnectorsTransferResponse","CountAccountsRequest","CountAccountsResponse","CountTransactionsRequest","CountTransactionsResponse","CreateBalanceRequest","CreateBalanceResponse","CreateClientResponse","CreateScopeResponse","CreateSecretRequest","CreateSecretResponse","CreateTransactionRequest","CreateTransactionResponse","CreateWalletResponse","CreateWorkflowResponse","CreditWalletRequest","CreditWalletResponse","DeactivateConfigRequest","DeactivateConfigResponse","DebitWalletRequest","DebitWalletResponse","DeleteClientRequest","DeleteClientResponse","DeleteConfigRequest","DeleteConfigResponse","DeleteScopeFromClientRequest","DeleteScopeFromClientResponse","DeleteScopeRequest","DeleteScopeResponse","DeleteSecretRequest","DeleteSecretResponse","DeleteTransientScopeRequest","DeleteTransientScopeResponse","DeleteWorkflowRequest","DeleteWorkflowResponse","GetAccountBalancesRequest","GetAccountBalancesResponse","GetAccountRequest","GetAccountResponse","GetBalanceRequest","GetBalanceResponse","GetBalancesAggregatedRequest","GetBalancesAggregatedResponse","GetBalancesRequest","GetBalancesResponse","GetConnectorTaskRequest","GetConnectorTaskResponse","GetHoldRequest","GetHoldResponse","GetHoldsRequest","GetHoldsResponse","GetInfoResponse","GetInstanceHistoryRequest","GetInstanceHistoryResponse","GetInstanceRequest","GetInstanceResponse","GetInstanceStageHistoryRequest","GetInstanceStageHistoryResponse","GetLedgerInfoRequest","GetLedgerInfoResponse","GetManyConfigsRequest","GetManyConfigsResponse","GetPaymentRequest","GetPaymentResponse","GetServerInfoResponse","GetTransactionRequest","GetTransactionResponse","GetTransactionsRequest","GetTransactionsResponse","GetVersionsResponse","GetWalletRequest","GetWalletResponse","GetWalletSummaryRequest","GetWalletSummaryResponse","GetWorkflowRequest","GetWorkflowResponse","InsertConfigResponse","InstallConnectorRequest","InstallConnectorResponse","ListAccountsRequest","ListAccountsResponse","ListAllConnectorsResponse","ListBalancesRequest","ListBalancesResponse","ListClientsResponse","ListConfigsAvailableConnectorsResponse","ListConnectorTasksRequest","ListConnectorTasksResponse","ListConnectorsTransfersRequest","ListConnectorsTransfersResponse","ListInstancesRequest","ListInstancesResponse","ListLogsRequest","ListLogsResponse","ListPaymentsRequest","ListPaymentsResponse","ListScopesResponse","ListTransactionsRequest","ListTransactionsResponse","ListUsersResponse","ListWalletsRequest","ListWalletsResponse","ListWorkflowsResponse","OrchestrationgetServerInfoResponse","PaymentsgetServerInfoResponse","PaymentslistAccountsRequest","PaymentslistAccountsResponse","ReadClientRequest","ReadClientResponse","ReadConnectorConfigRequest","ReadConnectorConfigResponse","ReadScopeRequest","ReadScopeResponse","ReadStatsRequest","ReadStatsResponse","ReadUserRequest","ReadUserResponse","ResetConnectorRequest","ResetConnectorResponse","RevertTransactionRequest","RevertTransactionResponse","RunWorkflowRequest","RunWorkflowResponse","SearchResponse","SearchgetServerInfoResponse","SendEventRequest","SendEventRequestBody","SendEventResponse","TestConfigRequest","TestConfigResponse","UninstallConnectorRequest","UninstallConnectorResponse","UpdateClientRequest","UpdateClientResponse","UpdateMetadataRequest","UpdateMetadataResponse","UpdateScopeRequest","UpdateScopeResponse","UpdateWalletRequest","UpdateWalletRequestBody","UpdateWalletResponse","VoidHoldRequest","VoidHoldResponse","WalletsgetServerInfoResponse"] diff --git a/sdks/python/src/sdk/models/operations/getaccountbalances.py b/sdks/python/src/sdk/models/operations/getaccountbalances.py new file mode 100755 index 0000000000..29a0cb1dc9 --- /dev/null +++ b/sdks/python/src/sdk/models/operations/getaccountbalances.py @@ -0,0 +1,50 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +import dataclasses +import requests as requests_http +from ..shared import balancescursor as shared_balancescursor +from datetime import datetime +from typing import Optional + + +@dataclasses.dataclass +class GetAccountBalancesRequest: + + account_id: str = dataclasses.field(metadata={'path_param': { 'field_name': 'accountID', 'style': 'simple', 'explode': False }}) + r"""The account ID.""" + currency: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'currency', 'style': 'form', 'explode': True }}) + r"""Filter balances by currency. + If not specified, all account's balances will be returned. + """ + cursor: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'cursor', 'style': 'form', 'explode': True }}) + r"""Parameter used in pagination requests. Maximum page size is set to 15. + Set to the value of next for the next page of results. + Set to the value of previous for the previous page of results. + No other parameters can be set when this parameter is set. + """ + from_: Optional[datetime] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'from', 'style': 'form', 'explode': True }}) + r"""Filter balances by date. + If not specified, all account's balances will be returned. + """ + limit: Optional[int] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'limit', 'style': 'form', 'explode': True }}) + r"""The maximum number of results to return per page.""" + page_size: Optional[int] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'pageSize', 'style': 'form', 'explode': True }}) + r"""The maximum number of results to return per page.""" + sort: Optional[list[str]] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'sort', 'style': 'form', 'explode': True }}) + r"""Fields used to sort payments (default is date:desc).""" + to: Optional[datetime] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'to', 'style': 'form', 'explode': True }}) + r"""Filter balances by date. + If not specified, default will be set to now. + """ + + +@dataclasses.dataclass +class GetAccountBalancesResponse: + + content_type: str = dataclasses.field() + status_code: int = dataclasses.field() + balances_cursor: Optional[shared_balancescursor.BalancesCursor] = dataclasses.field(default=None) + r"""OK""" + raw_response: Optional[requests_http.Response] = dataclasses.field(default=None) + \ No newline at end of file diff --git a/sdks/python/src/sdk/models/shared/__init__.py b/sdks/python/src/sdk/models/shared/__init__.py index 0ce8c443a6..3ae76c89b5 100755 --- a/sdks/python/src/sdk/models/shared/__init__.py +++ b/sdks/python/src/sdk/models/shared/__init__.py @@ -1,6 +1,7 @@ """Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" from .account import * +from .accountbalance import * from .accountresponse import * from .accountscursor import * from .accountscursorresponse import * @@ -26,6 +27,7 @@ from .attempt import * from .attemptresponse import * from .balance import * +from .balancescursor import * from .balancescursorresponse import * from .balancewithassets import * from .bankingcircleconfig import * @@ -171,4 +173,4 @@ from .workflowinstancehistorystageinput import * from .workflowinstancehistorystageoutput import * -__all__ = ["Account","AccountResponse","AccountWithVolumesAndBalances","AccountsCursor","AccountsCursorCursor","AccountsCursorResponse","AccountsCursorResponseCursor","ActivityConfirmHold","ActivityCreateTransaction","ActivityCreateTransactionOutput","ActivityCreditWallet","ActivityDebitWallet","ActivityDebitWalletOutput","ActivityGetAccount","ActivityGetAccountOutput","ActivityGetPayment","ActivityGetPaymentOutput","ActivityGetWallet","ActivityGetWalletOutput","ActivityRevertTransaction","ActivityRevertTransactionOutput","ActivityStripeTransfer","ActivityVoidHold","AggregateBalancesResponse","AssetHolder","Attempt","AttemptResponse","Balance","BalanceWithAssets","BalancesCursorResponse","BalancesCursorResponseCursor","BankingCircleConfig","Client","ClientSecret","Config","ConfigChangeSecret","ConfigInfo","ConfigInfoResponse","ConfigResponse","ConfigUser","ConfigsResponse","ConfigsResponseCursor","ConfirmHoldRequest","Connector","ConnectorConfigResponse","ConnectorsConfigsResponse","ConnectorsConfigsResponseData","ConnectorsConfigsResponseDataConnector","ConnectorsConfigsResponseDataConnectorKey","ConnectorsResponse","ConnectorsResponseData","CreateBalanceRequest","CreateBalanceResponse","CreateClientRequest","CreateClientResponse","CreateScopeRequest","CreateScopeResponse","CreateSecretRequest","CreateSecretResponse","CreateTransactionResponse","CreateWalletRequest","CreateWalletResponse","CreateWorkflowRequest","CreateWorkflowResponse","CreditWalletRequest","CurrencyCloudConfig","DebitWalletRequest","DebitWalletResponse","DummyPayConfig","Error","ErrorErrorCode","ErrorResponse","ErrorsEnum","ExpandedDebitHold","ExpandedTransaction","GetBalanceResponse","GetHoldResponse","GetHoldsResponse","GetHoldsResponseCursor","GetTransactionResponse","GetTransactionsResponse","GetTransactionsResponseCursor","GetVersionsResponse","GetWalletResponse","GetWalletSummaryResponse","GetWorkflowInstanceHistoryResponse","GetWorkflowInstanceHistoryStageResponse","GetWorkflowInstanceResponse","GetWorkflowResponse","Hold","LedgerAccountSubject","LedgerInfo","LedgerInfoResponse","LedgerInfoStorage","LedgerStorage","ListBalancesResponse","ListBalancesResponseCursor","ListClientsResponse","ListRunsResponse","ListScopesResponse","ListUsersResponse","ListWalletsResponse","ListWalletsResponseCursor","ListWorkflowsResponse","Log","LogType","LogsCursorResponse","LogsCursorResponseCursor","MangoPayConfig","MigrationInfo","MigrationInfoState","ModulrConfig","Monetary","MoneycorpConfig","Payment","PaymentAdjustment","PaymentMetadata","PaymentResponse","PaymentScheme","PaymentStatus","PaymentType","PaymentsAccount","PaymentsCursor","PaymentsCursorCursor","PostTransaction","PostTransactionScript","Posting","Query","ReadClientResponse","ReadScopeResponse","ReadUserResponse","Response","ResponseCursor","ResponseCursorTotal","RevertTransactionResponse","RunWorkflowResponse","Scope","Secret","Security","ServerInfo","StageDelay","StageSend","StageSendDestination","StageSendDestinationAccount","StageSendDestinationPayment","StageSendDestinationWallet","StageSendSource","StageSendSourceAccount","StageSendSourcePayment","StageSendSourceWallet","StageStatus","StageWaitEvent","Stats","StatsResponse","StripeConfig","StripeTransferRequest","TaskBankingCircle","TaskBankingCircleDescriptor","TaskCurrencyCloud","TaskCurrencyCloudDescriptor","TaskDummyPay","TaskDummyPayDescriptor","TaskMangoPay","TaskMangoPayDescriptor","TaskModulr","TaskModulrDescriptor","TaskMoneycorp","TaskMoneycorpDescriptor","TaskResponse","TaskStripe","TaskStripeDescriptor","TaskWise","TaskWiseDescriptor","TasksCursor","TasksCursorCursor","Transaction","TransactionsCursorResponse","TransactionsCursorResponseCursor","TransferRequest","TransferResponse","TransfersResponse","TransfersResponseData","UpdateClientRequest","UpdateClientResponse","UpdateScopeRequest","UpdateScopeResponse","User","Version","Volume","Wallet","WalletSubject","WalletWithBalances","WalletWithBalancesBalances","WalletsErrorResponse","WalletsErrorResponseErrorCode","WalletsTransaction","WalletsVolume","WebhooksConfig","WiseConfig","Workflow","WorkflowConfig","WorkflowInstance","WorkflowInstanceHistory","WorkflowInstanceHistoryStage","WorkflowInstanceHistoryStageInput","WorkflowInstanceHistoryStageOutput"] +__all__ = ["Account","AccountBalance","AccountResponse","AccountWithVolumesAndBalances","AccountsCursor","AccountsCursorCursor","AccountsCursorResponse","AccountsCursorResponseCursor","ActivityConfirmHold","ActivityCreateTransaction","ActivityCreateTransactionOutput","ActivityCreditWallet","ActivityDebitWallet","ActivityDebitWalletOutput","ActivityGetAccount","ActivityGetAccountOutput","ActivityGetPayment","ActivityGetPaymentOutput","ActivityGetWallet","ActivityGetWalletOutput","ActivityRevertTransaction","ActivityRevertTransactionOutput","ActivityStripeTransfer","ActivityVoidHold","AggregateBalancesResponse","AssetHolder","Attempt","AttemptResponse","Balance","BalanceWithAssets","BalancesCursor","BalancesCursorCursor","BalancesCursorResponse","BalancesCursorResponseCursor","BankingCircleConfig","Client","ClientSecret","Config","ConfigChangeSecret","ConfigInfo","ConfigInfoResponse","ConfigResponse","ConfigUser","ConfigsResponse","ConfigsResponseCursor","ConfirmHoldRequest","Connector","ConnectorConfigResponse","ConnectorsConfigsResponse","ConnectorsConfigsResponseData","ConnectorsConfigsResponseDataConnector","ConnectorsConfigsResponseDataConnectorKey","ConnectorsResponse","ConnectorsResponseData","CreateBalanceRequest","CreateBalanceResponse","CreateClientRequest","CreateClientResponse","CreateScopeRequest","CreateScopeResponse","CreateSecretRequest","CreateSecretResponse","CreateTransactionResponse","CreateWalletRequest","CreateWalletResponse","CreateWorkflowRequest","CreateWorkflowResponse","CreditWalletRequest","CurrencyCloudConfig","DebitWalletRequest","DebitWalletResponse","DummyPayConfig","Error","ErrorErrorCode","ErrorResponse","ErrorsEnum","ExpandedDebitHold","ExpandedTransaction","GetBalanceResponse","GetHoldResponse","GetHoldsResponse","GetHoldsResponseCursor","GetTransactionResponse","GetTransactionsResponse","GetTransactionsResponseCursor","GetVersionsResponse","GetWalletResponse","GetWalletSummaryResponse","GetWorkflowInstanceHistoryResponse","GetWorkflowInstanceHistoryStageResponse","GetWorkflowInstanceResponse","GetWorkflowResponse","Hold","LedgerAccountSubject","LedgerInfo","LedgerInfoResponse","LedgerInfoStorage","LedgerStorage","ListBalancesResponse","ListBalancesResponseCursor","ListClientsResponse","ListRunsResponse","ListScopesResponse","ListUsersResponse","ListWalletsResponse","ListWalletsResponseCursor","ListWorkflowsResponse","Log","LogType","LogsCursorResponse","LogsCursorResponseCursor","MangoPayConfig","MigrationInfo","MigrationInfoState","ModulrConfig","Monetary","MoneycorpConfig","Payment","PaymentAdjustment","PaymentMetadata","PaymentResponse","PaymentScheme","PaymentStatus","PaymentType","PaymentsAccount","PaymentsCursor","PaymentsCursorCursor","PostTransaction","PostTransactionScript","Posting","Query","ReadClientResponse","ReadScopeResponse","ReadUserResponse","Response","ResponseCursor","ResponseCursorTotal","RevertTransactionResponse","RunWorkflowResponse","Scope","Secret","Security","ServerInfo","StageDelay","StageSend","StageSendDestination","StageSendDestinationAccount","StageSendDestinationPayment","StageSendDestinationWallet","StageSendSource","StageSendSourceAccount","StageSendSourcePayment","StageSendSourceWallet","StageStatus","StageWaitEvent","Stats","StatsResponse","StripeConfig","StripeTransferRequest","TaskBankingCircle","TaskBankingCircleDescriptor","TaskCurrencyCloud","TaskCurrencyCloudDescriptor","TaskDummyPay","TaskDummyPayDescriptor","TaskMangoPay","TaskMangoPayDescriptor","TaskModulr","TaskModulrDescriptor","TaskMoneycorp","TaskMoneycorpDescriptor","TaskResponse","TaskStripe","TaskStripeDescriptor","TaskWise","TaskWiseDescriptor","TasksCursor","TasksCursorCursor","Transaction","TransactionsCursorResponse","TransactionsCursorResponseCursor","TransferRequest","TransferResponse","TransfersResponse","TransfersResponseData","UpdateClientRequest","UpdateClientResponse","UpdateScopeRequest","UpdateScopeResponse","User","Version","Volume","Wallet","WalletSubject","WalletWithBalances","WalletWithBalancesBalances","WalletsErrorResponse","WalletsErrorResponseErrorCode","WalletsTransaction","WalletsVolume","WebhooksConfig","WiseConfig","Workflow","WorkflowConfig","WorkflowInstance","WorkflowInstanceHistory","WorkflowInstanceHistoryStage","WorkflowInstanceHistoryStageInput","WorkflowInstanceHistoryStageOutput"] diff --git a/sdks/python/src/sdk/models/shared/accountbalance.py b/sdks/python/src/sdk/models/shared/accountbalance.py new file mode 100755 index 0000000000..97108e0652 --- /dev/null +++ b/sdks/python/src/sdk/models/shared/accountbalance.py @@ -0,0 +1,21 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +import dataclasses +import dateutil.parser +from dataclasses_json import Undefined, dataclass_json +from datetime import datetime +from marshmallow import fields +from sdk import utils + + +@dataclass_json(undefined=Undefined.EXCLUDE) +@dataclasses.dataclass +class AccountBalance: + + account_id: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('accountId') }}) + balance: int = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('balance') }}) + created_at: datetime = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('createdAt'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse, 'mm_field': fields.DateTime(format='iso') }}) + currency: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('currency') }}) + last_updated_at: datetime = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('lastUpdatedAt'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse, 'mm_field': fields.DateTime(format='iso') }}) + \ No newline at end of file diff --git a/sdks/python/src/sdk/models/shared/balancescursor.py b/sdks/python/src/sdk/models/shared/balancescursor.py new file mode 100755 index 0000000000..b952a6003e --- /dev/null +++ b/sdks/python/src/sdk/models/shared/balancescursor.py @@ -0,0 +1,28 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +import dataclasses +from ..shared import accountbalance as shared_accountbalance +from dataclasses_json import Undefined, dataclass_json +from sdk import utils +from typing import Optional + + +@dataclass_json(undefined=Undefined.EXCLUDE) +@dataclasses.dataclass +class BalancesCursorCursor: + + data: list[shared_accountbalance.AccountBalance] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('data') }}) + has_more: bool = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('hasMore') }}) + page_size: int = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('pageSize') }}) + next: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('next'), 'exclude': lambda f: f is None }}) + previous: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('previous'), 'exclude': lambda f: f is None }}) + + +@dataclass_json(undefined=Undefined.EXCLUDE) +@dataclasses.dataclass +class BalancesCursor: + r"""OK""" + + cursor: BalancesCursorCursor = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('cursor') }}) + \ No newline at end of file diff --git a/sdks/python/src/sdk/models/shared/walletsposting.py b/sdks/python/src/sdk/models/shared/walletsposting.py new file mode 100755 index 0000000000..7dab8f8177 --- /dev/null +++ b/sdks/python/src/sdk/models/shared/walletsposting.py @@ -0,0 +1,17 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +import dataclasses +from dataclasses_json import Undefined, dataclass_json +from sdk import utils + + +@dataclass_json(undefined=Undefined.EXCLUDE) +@dataclasses.dataclass +class WalletsPosting: + + amount: int = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('amount') }}) + asset: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('asset') }}) + destination: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('destination') }}) + source: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('source') }}) + \ No newline at end of file diff --git a/sdks/python/src/sdk/payments.py b/sdks/python/src/sdk/payments.py index 49d25456c4..91b6425e96 100755 --- a/sdks/python/src/sdk/payments.py +++ b/sdks/python/src/sdk/payments.py @@ -84,6 +84,31 @@ def connectors_transfer(self, request: operations.ConnectorsTransferRequest) -> return res + def get_account_balances(self, request: operations.GetAccountBalancesRequest) -> operations.GetAccountBalancesResponse: + r"""Get account balances""" + base_url = self._server_url + + url = utils.generate_url(operations.GetAccountBalancesRequest, base_url, '/api/payments/accounts/{accountID}/balances', request) + headers = {} + query_params = utils.get_query_params(operations.GetAccountBalancesRequest, request) + headers['Accept'] = 'application/json' + headers['user-agent'] = f'speakeasy-sdk/{self._language} {self._sdk_version} {self._gen_version}' + + client = self._security_client + + http_res = client.request('GET', url, params=query_params, headers=headers) + content_type = http_res.headers.get('Content-Type') + + res = operations.GetAccountBalancesResponse(status_code=http_res.status_code, content_type=content_type, raw_response=http_res) + + if http_res.status_code == 200: + if utils.match_content_type(content_type, 'application/json'): + out = utils.unmarshal_json(http_res.text, Optional[shared.BalancesCursor]) + res.balances_cursor = out + + return res + + def get_connector_task(self, request: operations.GetConnectorTaskRequest) -> operations.GetConnectorTaskResponse: r"""Read a specific task of the connector Get a specific task associated to the connector. diff --git a/sdks/typescript/README.md b/sdks/typescript/README.md index e9c1906305..51dca4bcc0 100755 --- a/sdks/typescript/README.md +++ b/sdks/typescript/README.md @@ -114,6 +114,7 @@ sdk.getVersions().then((res: GetVersionsResponse) => { * [connectorsStripeTransfer](docs/payments/README.md#connectorsstripetransfer) - Transfer funds between Stripe accounts * [connectorsTransfer](docs/payments/README.md#connectorstransfer) - Transfer funds between Connector accounts +* [getAccountBalances](docs/payments/README.md#getaccountbalances) - Get account balances * [getConnectorTask](docs/payments/README.md#getconnectortask) - Read a specific task of the connector * [getPayment](docs/payments/README.md#getpayment) - Get a payment * [installConnector](docs/payments/README.md#installconnector) - Install a connector diff --git a/sdks/typescript/docs/payments/README.md b/sdks/typescript/docs/payments/README.md index 46a28acf8d..5387142100 100755 --- a/sdks/typescript/docs/payments/README.md +++ b/sdks/typescript/docs/payments/README.md @@ -4,6 +4,7 @@ * [connectorsStripeTransfer](#connectorsstripetransfer) - Transfer funds between Stripe accounts * [connectorsTransfer](#connectorstransfer) - Transfer funds between Connector accounts +* [getAccountBalances](#getaccountbalances) - Get account balances * [getConnectorTask](#getconnectortask) - Read a specific task of the connector * [getPayment](#getpayment) - Get a payment * [installConnector](#installconnector) - Install a connector @@ -83,6 +84,43 @@ sdk.payments.connectorsTransfer({ }); ``` +## getAccountBalances + +Get account balances + +### Example Usage + +```typescript +import { SDK } from "@formance/formance-sdk"; +import { GetAccountBalancesResponse } from "@formance/formance-sdk/dist/sdk/models/operations"; + +const sdk = new SDK({ + security: { + authorization: "Bearer YOUR_ACCESS_TOKEN_HERE", + }, +}); + +sdk.payments.getAccountBalances({ + accountID: "provident", + currency: "necessitatibus", + cursor: "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==", + from: new Date("2021-09-21T14:06:09.271Z"), + limit: 223081, + pageSize: 891555, + sort: [ + "dolorum", + "in", + "in", + "illum", + ], + to: new Date("2020-11-26T01:41:04.216Z"), +}).then((res: GetAccountBalancesResponse) => { + if (res.statusCode == 200) { + // handle response + } +}); +``` + ## getConnectorTask Get a specific task associated to the connector. @@ -101,8 +139,8 @@ const sdk = new SDK({ }); sdk.payments.getConnectorTask({ - connector: Connector.CurrencyCloud, - taskId: "necessitatibus", + connector: Connector.Stripe, + taskId: "magnam", }).then((res: GetConnectorTaskResponse) => { if (res.statusCode == 200) { // handle response @@ -128,7 +166,7 @@ const sdk = new SDK({ }); sdk.payments.getPayment({ - paymentId: "sint", + paymentId: "cumque", }).then((res: GetPaymentResponse) => { if (res.statusCode == 200) { // handle response @@ -155,15 +193,12 @@ const sdk = new SDK({ sdk.payments.installConnector({ requestBody: { - authorizationEndpoint: "XXX", + apiKey: "XXX", + clientID: "XXX", endpoint: "XXX", - password: "XXX", pollingPeriod: "60s", - userCertificate: "XXX", - userCertificateKey: "XXX", - username: "XXX", }, - connector: Connector.DummyPay, + connector: Connector.Modulr, }).then((res: InstallConnectorResponse) => { if (res.statusCode == 200) { // handle response @@ -236,9 +271,9 @@ const sdk = new SDK({ }); sdk.payments.listConnectorTasks({ - connector: Connector.Moneycorp, + connector: Connector.Modulr, cursor: "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==", - pageSize: 952749, + pageSize: 675439, }).then((res: ListConnectorTasksResponse) => { if (res.statusCode == 200) { // handle response @@ -264,7 +299,7 @@ const sdk = new SDK({ }); sdk.payments.listConnectorsTransfers({ - connector: Connector.BankingCircle, + connector: Connector.Moneycorp, }).then((res: ListConnectorsTransfersResponse) => { if (res.statusCode == 200) { // handle response @@ -291,10 +326,11 @@ const sdk = new SDK({ sdk.payments.listPayments({ cursor: "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==", - pageSize: 447125, + pageSize: 249796, sort: [ - "illum", - "maiores", + "enim", + "accusamus", + "delectus", ], }).then((res: ListPaymentsResponse) => { if (res.statusCode == 200) { @@ -345,9 +381,11 @@ const sdk = new SDK({ sdk.payments.paymentslistAccounts({ cursor: "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==", - pageSize: 699479, + pageSize: 692532, sort: [ - "magnam", + "nam", + "id", + "blanditiis", ], }).then((res: PaymentslistAccountsResponse) => { if (res.statusCode == 200) { @@ -374,7 +412,7 @@ const sdk = new SDK({ }); sdk.payments.readConnectorConfig({ - connector: Connector.Mangopay, + connector: Connector.CurrencyCloud, }).then((res: ReadConnectorConfigResponse) => { if (res.statusCode == 200) { // handle response @@ -402,7 +440,7 @@ const sdk = new SDK({ }); sdk.payments.resetConnector({ - connector: Connector.Mangopay, + connector: Connector.Moneycorp, }).then((res: ResetConnectorResponse) => { if (res.statusCode == 200) { // handle response @@ -428,7 +466,7 @@ const sdk = new SDK({ }); sdk.payments.uninstallConnector({ - connector: Connector.Modulr, + connector: Connector.DummyPay, }).then((res: UninstallConnectorResponse) => { if (res.statusCode == 200) { // handle response @@ -454,9 +492,9 @@ const sdk = new SDK({ sdk.payments.updateMetadata({ paymentMetadata: { - key: "aliquid", + key: "deserunt", }, - paymentId: "laborum", + paymentId: "nisi", }).then((res: UpdateMetadataResponse) => { if (res.statusCode == 200) { // handle response diff --git a/sdks/typescript/docs/search/README.md b/sdks/typescript/docs/search/README.md index 65eb9be80f..12b015d87a 100755 --- a/sdks/typescript/docs/search/README.md +++ b/sdks/typescript/docs/search/README.md @@ -25,25 +25,24 @@ sdk.search.search({ after: [ "users:002", "users:002", - "users:002", - "users:002", ], cursor: "YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol=", ledgers: [ "quickstart", + "quickstart", + "quickstart", ], - pageSize: 581273, + pageSize: 606393, policy: "OR", raw: { - "accusamus": "delectus", - "quidem": "provident", + "perferendis": "nihil", + "magnam": "distinctio", }, sort: "txid:asc", - target: "nam", + target: "id", terms: [ "destination=central_bank1", "destination=central_bank1", - "destination=central_bank1", ], }).then((res: SearchResponse) => { if (res.statusCode == 200) { diff --git a/sdks/typescript/docs/wallets/README.md b/sdks/typescript/docs/wallets/README.md index ca6991ae0c..ddeb9477ac 100755 --- a/sdks/typescript/docs/wallets/README.md +++ b/sdks/typescript/docs/wallets/README.md @@ -41,7 +41,7 @@ sdk.wallets.confirmHold({ amount: 100, final: true, }, - holdId: "blanditiis", + holdId: "labore", }).then((res: ConfirmHoldResponse) => { if (res.statusCode == 200) { // handle response @@ -68,11 +68,11 @@ const sdk = new SDK({ sdk.wallets.createBalance({ createBalanceRequest: { - expiresAt: new Date("2021-02-02T01:24:52.629Z"), - name: "Sandy Huels", - priority: 606393, + expiresAt: new Date("2022-05-20T10:11:05.115Z"), + name: "Duane Thiel II", + priority: 92373, }, - id: "7074ba44-69b6-4e21-8195-9890afa563e2", + id: "959890af-a563-4e25-96fe-4c8b711e5b7f", }).then((res: CreateBalanceResponse) => { if (res.statusCode == 200) { // handle response @@ -99,10 +99,12 @@ const sdk = new SDK({ sdk.wallets.createWallet({ metadata: { - "quasi": "iure", - "doloribus": "debitis", + "sed": "saepe", + "pariatur": "accusantium", + "consequuntur": "praesentium", + "natus": "magni", }, - name: "Jasmine Lind", + name: "Angelica Stanton", }).then((res: CreateWalletResponse) => { if (res.statusCode == 200) { // handle response @@ -130,39 +132,28 @@ const sdk = new SDK({ sdk.wallets.creditWallet({ creditWalletRequest: { amount: { - amount: 100226, - asset: "architecto", + amount: 411397, + asset: "excepturi", }, - balance: "repudiandae", + balance: "odit", metadata: { - "expedita": "nihil", - "repellat": "quibusdam", + "accusantium": "ab", + "maiores": "quidem", }, - reference: "sed", + reference: "ipsam", sources: [ { - balance: "accusantium", - identifier: "consequuntur", - type: "praesentium", + identifier: "nam", + type: "eaque", }, { - balance: "magni", - identifier: "sunt", - type: "quo", - }, - { - balance: "pariatur", - identifier: "maxime", - type: "ea", - }, - { - balance: "odit", - identifier: "ea", - type: "accusantium", + balance: "nemo", + identifier: "voluptatibus", + type: "perferendis", }, ], }, - id: "1fb576b0-d5f0-4d30-85fb-b2587053202c", + id: "d30c5fbb-2587-4053-a02c-73d5fe9b90c2", }).then((res: CreditWalletResponse) => { if (res.statusCode == 200) { // handle response @@ -190,29 +181,24 @@ const sdk = new SDK({ sdk.wallets.debitWallet({ debitWalletRequest: { amount: { - amount: 463451, - asset: "dolor", + amount: 500026, + asset: "error", }, balances: [ - "nostrum", - "hic", - "recusandae", - "omnis", + "occaecati", ], - description: "facilis", + description: "rerum", destination: { - balance: "voluptatem", - identifier: "porro", - type: "consequuntur", + identifier: "asperiores", + type: "earum", }, metadata: { - "error": "eaque", - "occaecati": "rerum", - "adipisci": "asperiores", + "iste": "dolorum", + "deleniti": "pariatur", }, pending: false, }, - id: "e49a8d9c-bf48-4633-b23f-9b77f3a41006", + id: "9cbf4863-3323-4f9b-b7f3-a4100674ebf6", }).then((res: DebitWalletResponse) => { if (res.statusCode == 200) { // handle response @@ -238,8 +224,8 @@ const sdk = new SDK({ }); sdk.wallets.getBalance({ - balanceName: "odio", - id: "4ebf6928-0d1b-4a77-a89e-bf737ae4203c", + balanceName: "natus", + id: "280d1ba7-7a89-4ebf-b37a-e4203ce5e6a9", }).then((res: GetBalanceResponse) => { if (res.statusCode == 200) { // handle response @@ -265,7 +251,7 @@ const sdk = new SDK({ }); sdk.wallets.getHold({ - holdID: "accusamus", + holdID: "minima", }).then((res: GetHoldResponse) => { if (res.statusCode == 200) { // handle response @@ -293,11 +279,13 @@ const sdk = new SDK({ sdk.wallets.getHolds({ cursor: "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==", metadata: { - "saepe": "suscipit", - "deserunt": "provident", + "totam": "similique", + "alias": "at", + "quaerat": "tempora", + "vel": "quod", }, - pageSize: 324683, - walletID: "repellendus", + pageSize: 885338, + walletID: "qui", }).then((res: GetHoldsResponse) => { if (res.statusCode == 200) { // handle response @@ -322,8 +310,8 @@ const sdk = new SDK({ sdk.wallets.getTransactions({ cursor: "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==", - pageSize: 519711, - walletID: "similique", + pageSize: 679880, + walletID: "a", }).then((res: GetTransactionsResponse) => { if (res.statusCode == 200) { // handle response @@ -349,7 +337,7 @@ const sdk = new SDK({ }); sdk.wallets.getWallet({ - id: "0d446ce2-af7a-473c-b3be-453f870b326b", + id: "7a73cf3b-e453-4f87-8b32-6b5a73429cdb", }).then((res: GetWalletResponse) => { if (res.statusCode == 200) { // handle response @@ -375,7 +363,7 @@ const sdk = new SDK({ }); sdk.wallets.getWalletSummary({ - id: "5a73429c-db1a-4842-abb6-79d2322715bf", + id: "1a8422bb-679d-4232-a715-bf0cbb1e31b8", }).then((res: GetWalletSummaryResponse) => { if (res.statusCode == 200) { // handle response @@ -400,7 +388,7 @@ const sdk = new SDK({ }); sdk.wallets.listBalances({ - id: "0cbb1e31-b8b9-40f3-843a-1108e0adcf4b", + id: "b90f3443-a110-48e0-adcf-4b921879fce9", }).then((res: ListBalancesResponse) => { if (res.statusCode == 200) { // handle response @@ -427,12 +415,11 @@ const sdk = new SDK({ sdk.wallets.listWallets({ cursor: "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==", metadata: { - "qui": "quae", - "laudantium": "odio", - "occaecati": "voluptatibus", + "ipsum": "delectus", + "voluptate": "consectetur", }, - name: "Ignacio Moen", - pageSize: 961571, + name: "Roman Kulas", + pageSize: 799203, }).then((res: ListWalletsResponse) => { if (res.statusCode == 200) { // handle response @@ -460,11 +447,11 @@ const sdk = new SDK({ sdk.wallets.updateWallet({ requestBody: { metadata: { - "consectetur": "vero", - "tenetur": "dignissimos", + "similique": "facilis", + "vero": "ducimus", }, }, - id: "fbc7abd7-4dd3-49c0-b5d2-cff7c70a4562", + id: "4dd39c0f-5d2c-4ff7-870a-45626d436813", }).then((res: UpdateWalletResponse) => { if (res.statusCode == 200) { // handle response @@ -490,7 +477,7 @@ const sdk = new SDK({ }); sdk.wallets.voidHold({ - holdId: "vel", + holdId: "maiores", }).then((res: VoidHoldResponse) => { if (res.statusCode == 200) { // handle response diff --git a/sdks/typescript/docs/webhooks/README.md b/sdks/typescript/docs/webhooks/README.md index 5387adbb57..844d818833 100755 --- a/sdks/typescript/docs/webhooks/README.md +++ b/sdks/typescript/docs/webhooks/README.md @@ -178,9 +178,6 @@ sdk.webhooks.insertConfig({ endpoint: "https://example.com", eventTypes: [ "TYPE1", - "TYPE1", - "TYPE1", - "TYPE1", ], secret: "V0bivxRWveaoz08afqjU6Ko/jwO0Cb+3", }).then((res: InsertConfigResponse) => { diff --git a/sdks/typescript/files.gen b/sdks/typescript/files.gen index 928d9c1be3..92c3761d07 100755 --- a/sdks/typescript/files.gen +++ b/sdks/typescript/files.gen @@ -73,6 +73,7 @@ src/sdk/models/operations/runworkflow.ts src/sdk/models/operations/sendevent.ts src/sdk/models/operations/connectorsstripetransfer.ts src/sdk/models/operations/connectorstransfer.ts +src/sdk/models/operations/getaccountbalances.ts src/sdk/models/operations/getconnectortask.ts src/sdk/models/operations/getpayment.ts src/sdk/models/operations/installconnector.ts @@ -225,6 +226,8 @@ src/sdk/models/shared/runworkflowresponse.ts src/sdk/models/shared/stripetransferrequest.ts src/sdk/models/shared/transferresponse.ts src/sdk/models/shared/transferrequest.ts +src/sdk/models/shared/balancescursor.ts +src/sdk/models/shared/accountbalance.ts src/sdk/models/shared/taskresponse.ts src/sdk/models/shared/taskstripe.ts src/sdk/models/shared/taskwise.ts diff --git a/sdks/typescript/src/sdk/models/operations/getaccountbalances.ts b/sdks/typescript/src/sdk/models/operations/getaccountbalances.ts new file mode 100755 index 0000000000..de0656cfa2 --- /dev/null +++ b/sdks/typescript/src/sdk/models/operations/getaccountbalances.ts @@ -0,0 +1,103 @@ +/* + * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + */ + +import { SpeakeasyBase, SpeakeasyMetadata } from "../../../internal/utils"; +import * as shared from "../shared"; +import { AxiosResponse } from "axios"; + +export class GetAccountBalancesRequest extends SpeakeasyBase { + /** + * The account ID. + */ + @SpeakeasyMetadata({ + data: "pathParam, style=simple;explode=false;name=accountID", + }) + accountID: string; + + /** + * Filter balances by currency. + * + * @remarks + * If not specified, all account's balances will be returned. + * + */ + @SpeakeasyMetadata({ + data: "queryParam, style=form;explode=true;name=currency", + }) + currency?: string; + + /** + * Parameter used in pagination requests. Maximum page size is set to 15. + * + * @remarks + * Set to the value of next for the next page of results. + * Set to the value of previous for the previous page of results. + * No other parameters can be set when this parameter is set. + * + */ + @SpeakeasyMetadata({ + data: "queryParam, style=form;explode=true;name=cursor", + }) + cursor?: string; + + /** + * Filter balances by date. + * + * @remarks + * If not specified, all account's balances will be returned. + * + */ + @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=from" }) + from?: Date; + + /** + * The maximum number of results to return per page. + */ + @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=limit" }) + limit?: number; + + /** + * The maximum number of results to return per page. + * + * @remarks + * + */ + @SpeakeasyMetadata({ + data: "queryParam, style=form;explode=true;name=pageSize", + }) + pageSize?: number; + + /** + * Fields used to sort payments (default is date:desc). + */ + @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=sort" }) + sort?: string[]; + + /** + * Filter balances by date. + * + * @remarks + * If not specified, default will be set to now. + * + */ + @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=to" }) + to?: Date; +} + +export class GetAccountBalancesResponse extends SpeakeasyBase { + /** + * OK + */ + @SpeakeasyMetadata() + balancesCursor?: shared.BalancesCursor; + + @SpeakeasyMetadata() + contentType: string; + + @SpeakeasyMetadata() + statusCode: number; + + @SpeakeasyMetadata() + rawResponse?: AxiosResponse; +} diff --git a/sdks/typescript/src/sdk/models/operations/index.ts b/sdks/typescript/src/sdk/models/operations/index.ts index 33655e11ab..4e350544b4 100755 --- a/sdks/typescript/src/sdk/models/operations/index.ts +++ b/sdks/typescript/src/sdk/models/operations/index.ts @@ -32,6 +32,7 @@ export * from "./deletesecret"; export * from "./deletetransientscope"; export * from "./deleteworkflow"; export * from "./getaccount"; +export * from "./getaccountbalances"; export * from "./getbalance"; export * from "./getbalances"; export * from "./getbalancesaggregated"; diff --git a/sdks/typescript/src/sdk/models/shared/accountbalance.ts b/sdks/typescript/src/sdk/models/shared/accountbalance.ts new file mode 100755 index 0000000000..2e44e7de10 --- /dev/null +++ b/sdks/typescript/src/sdk/models/shared/accountbalance.ts @@ -0,0 +1,30 @@ +/* + * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + */ + +import { SpeakeasyBase, SpeakeasyMetadata } from "../../../internal/utils"; +import { Expose, Transform } from "class-transformer"; + +export class AccountBalance extends SpeakeasyBase { + @SpeakeasyMetadata() + @Expose({ name: "accountId" }) + accountId: string; + + @SpeakeasyMetadata() + @Expose({ name: "balance" }) + balance: number; + + @SpeakeasyMetadata() + @Expose({ name: "createdAt" }) + @Transform(({ value }) => new Date(value), { toClassOnly: true }) + createdAt: Date; + + @SpeakeasyMetadata() + @Expose({ name: "currency" }) + currency: string; + + @SpeakeasyMetadata() + @Expose({ name: "lastUpdatedAt" }) + @Transform(({ value }) => new Date(value), { toClassOnly: true }) + lastUpdatedAt: Date; +} diff --git a/sdks/typescript/src/sdk/models/shared/balancescursor.ts b/sdks/typescript/src/sdk/models/shared/balancescursor.ts new file mode 100755 index 0000000000..b42416d01c --- /dev/null +++ b/sdks/typescript/src/sdk/models/shared/balancescursor.ts @@ -0,0 +1,40 @@ +/* + * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + */ + +import { SpeakeasyBase, SpeakeasyMetadata } from "../../../internal/utils"; +import { AccountBalance } from "./accountbalance"; +import { Expose, Type } from "class-transformer"; + +export class BalancesCursorCursor extends SpeakeasyBase { + @SpeakeasyMetadata({ elemType: AccountBalance }) + @Expose({ name: "data" }) + @Type(() => AccountBalance) + data: AccountBalance[]; + + @SpeakeasyMetadata() + @Expose({ name: "hasMore" }) + hasMore: boolean; + + @SpeakeasyMetadata() + @Expose({ name: "next" }) + next?: string; + + @SpeakeasyMetadata() + @Expose({ name: "pageSize" }) + pageSize: number; + + @SpeakeasyMetadata() + @Expose({ name: "previous" }) + previous?: string; +} + +/** + * OK + */ +export class BalancesCursor extends SpeakeasyBase { + @SpeakeasyMetadata() + @Expose({ name: "cursor" }) + @Type(() => BalancesCursorCursor) + cursor: BalancesCursorCursor; +} diff --git a/sdks/typescript/src/sdk/models/shared/index.ts b/sdks/typescript/src/sdk/models/shared/index.ts index dbc06bb74b..2212ca43cd 100755 --- a/sdks/typescript/src/sdk/models/shared/index.ts +++ b/sdks/typescript/src/sdk/models/shared/index.ts @@ -3,6 +3,7 @@ */ export * from "./account"; +export * from "./accountbalance"; export * from "./accountresponse"; export * from "./accountscursor"; export * from "./accountscursorresponse"; @@ -28,6 +29,7 @@ export * from "./assetholder"; export * from "./attempt"; export * from "./attemptresponse"; export * from "./balance"; +export * from "./balancescursor"; export * from "./balancescursorresponse"; export * from "./balancewithassets"; export * from "./bankingcircleconfig"; diff --git a/sdks/typescript/src/sdk/models/shared/walletsposting.ts b/sdks/typescript/src/sdk/models/shared/walletsposting.ts new file mode 100755 index 0000000000..dd91445ebb --- /dev/null +++ b/sdks/typescript/src/sdk/models/shared/walletsposting.ts @@ -0,0 +1,24 @@ +/* + * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + */ + +import { SpeakeasyBase, SpeakeasyMetadata } from "../../../internal/utils"; +import { Expose } from "class-transformer"; + +export class WalletsPosting extends SpeakeasyBase { + @SpeakeasyMetadata() + @Expose({ name: "amount" }) + amount: number; + + @SpeakeasyMetadata() + @Expose({ name: "asset" }) + asset: string; + + @SpeakeasyMetadata() + @Expose({ name: "destination" }) + destination: string; + + @SpeakeasyMetadata() + @Expose({ name: "source" }) + source: string; +} diff --git a/sdks/typescript/src/sdk/payments.ts b/sdks/typescript/src/sdk/payments.ts index dbd7ca9abd..427095af2b 100755 --- a/sdks/typescript/src/sdk/payments.ts +++ b/sdks/typescript/src/sdk/payments.ts @@ -185,6 +185,67 @@ export class Payments { return res; } + /** + * Get account balances + */ + async getAccountBalances( + req: operations.GetAccountBalancesRequest, + config?: AxiosRequestConfig + ): Promise { + if (!(req instanceof utils.SpeakeasyBase)) { + req = new operations.GetAccountBalancesRequest(req); + } + + const baseURL: string = this._serverURL; + const url: string = utils.generateURL( + baseURL, + "/api/payments/accounts/{accountID}/balances", + req + ); + + const client: AxiosInstance = this._securityClient || this._defaultClient; + + const headers = { ...config?.headers }; + const queryParams: string = utils.serializeQueryParams(req); + headers["Accept"] = "application/json"; + headers[ + "user-agent" + ] = `speakeasy-sdk/${this._language} ${this._sdkVersion} ${this._genVersion}`; + + const httpRes: AxiosResponse = await client.request({ + validateStatus: () => true, + url: url + queryParams, + method: "get", + headers: headers, + ...config, + }); + + const contentType: string = httpRes?.headers?.["content-type"] ?? ""; + + if (httpRes?.status == null) { + throw new Error(`status code not found in response: ${httpRes}`); + } + + const res: operations.GetAccountBalancesResponse = + new operations.GetAccountBalancesResponse({ + statusCode: httpRes.status, + contentType: contentType, + rawResponse: httpRes, + }); + switch (true) { + case httpRes?.status == 200: + if (utils.matchContentType(contentType, `application/json`)) { + res.balancesCursor = utils.objectToClass( + httpRes?.data, + shared.BalancesCursor + ); + } + break; + } + + return res; + } + /** * Read a specific task of the connector *