Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package client
import (
"context"

"github.com/formancehq/payments/internal/connectors/metrics"
pluginsdkmetrics "github.com/formancehq/payments/pkg/pluginsdk/metrics"
"github.com/stripe/stripe-go/v79"
)

Expand All @@ -17,7 +17,7 @@ func (c *client) GetAccounts(
if !timeline.IsCaughtUp() {
var oldest interface{}
oldest, timeline, hasMore, err = scanForOldest(timeline, pageSize, func(params stripe.ListParams) (stripe.ListContainer, error) {
params.Context = metrics.OperationContext(ctx, "list_accounts_scan")
params.Context = pluginsdkmetrics.OperationContext(ctx, "list_accounts_scan")
itr := c.accountClient.List(&stripe.AccountListParams{ListParams: params})
return itr.AccountList(), wrapSDKErr(itr.Err())
})
Expand All @@ -32,7 +32,7 @@ func (c *client) GetAccounts(
}

filters := stripe.ListParams{
Context: metrics.OperationContext(ctx, "list_accounts"),
Context: pluginsdkmetrics.OperationContext(ctx, "list_accounts"),
Limit: limit(pageSize, len(results)),
EndingBefore: &timeline.LatestID,
Single: true, // turn off autopagination
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import (
"context"
"fmt"

"github.com/formancehq/payments/internal/connectors/metrics"
pluginsdkmetrics "github.com/formancehq/payments/pkg/pluginsdk/metrics"
"github.com/stripe/stripe-go/v79"
)

func (c *client) GetAccountBalances(ctx context.Context, accountID string) (*stripe.Balance, error) {
filters := stripe.Params{Context: metrics.OperationContext(ctx, "list_balances")}
filters := stripe.Params{Context: pluginsdkmetrics.OperationContext(ctx, "list_balances")}
if accountID != "" {
filters.StripeAccount = &accountID
}
Expand Down
12 changes: 6 additions & 6 deletions internal/connectors/plugins/public/stripe/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import (
"time"

"github.com/formancehq/go-libs/v3/logging"
"github.com/formancehq/payments/internal/connectors/httpwrapper"
"github.com/formancehq/payments/internal/connectors/metrics"
errorsutils "github.com/formancehq/payments/internal/utils/errors"
pluginsdkhttp "github.com/formancehq/payments/pkg/pluginsdk/http"
pluginsdkmetrics "github.com/formancehq/payments/pkg/pluginsdk/metrics"
errorsutils "github.com/formancehq/payments/pkg/pluginsdk/errors"
"github.com/stripe/stripe-go/v79"
"github.com/stripe/stripe-go/v79/account"
"github.com/stripe/stripe-go/v79/balance"
Expand Down Expand Up @@ -46,7 +46,7 @@ type client struct {

func New(name string, logger logging.Logger, backend stripe.Backend, apiKey string) Client {
if backend == nil {
backends := stripe.NewBackends(metrics.NewHTTPClient(name, StripeDefaultTimeout))
backends := stripe.NewBackends(pluginsdkmetrics.NewHTTPClient(name, StripeDefaultTimeout))
backend = backends.API
}

Expand Down Expand Up @@ -81,15 +81,15 @@ func wrapSDKErr(err error) error {
if stripeErr.Code == stripe.ErrorCodeRateLimit {
return errorsutils.NewWrappedError(
err,
httpwrapper.ErrStatusCodeTooManyRequests,
pluginsdkhttp.ErrStatusCodeTooManyRequests,
)
}
Comment on lines 81 to 86
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Critical: pluginsdk errors.NewWrappedError likely breaks classification (uses two %w).

pluginsdk/errors.NewWrappedError (see pkg/pluginsdk/errors/errors.go) uses fmt.Errorf("%w: %w", ...), which is invalid (only one %w is honored). Result: only the first error is wrapped; the classification error (e.g., ErrStatusCodeTooManyRequests / ErrStatusCodeClientError) is not discoverable via errors.Is, breaking non‑retryable vs retryable decisioning.

Fix in pluginsdk/errors to wrap the classification error and keep the cause in the message:

--- a/pkg/pluginsdk/errors/errors.go
+++ b/pkg/pluginsdk/errors/errors.go
@@
-func NewWrappedError(cause error, newError error) error {
-    return &wrappedError{err: fmt.Errorf("%w: %w", cause, newError)}
-}
+func NewWrappedError(cause error, classify error) error {
+    // Wrap classification for errors.Is(err, classify) while retaining the cause in the message.
+    return &wrappedError{err: fmt.Errorf("%w: %v", classify, cause)}
+}

Alternatively, if you want both errors to be discoverable via errors.Is, consider using errors.Join(classify, cause) inside wrappedError.

Also applies to: 88-94

🤖 Prompt for AI Agents
In internal/connectors/plugins/public/stripe/client/client.go around lines 81-86
(also apply same fix to 88-94), the use of pluginsdk/errors.NewWrappedError to
combine a classification sentinel and the stripe error results in only the first
%w being wrapped (the classification sentinel), breaking errors.Is checks for
the classification; update the call so the classification error is wrapped as
the primary error and the stripe cause is preserved in a way discoverable by
errors.Is (either by changing NewWrappedError to wrap the classification
sentinel and include the cause in the message, or replace this call-site with
errors.Join(classifyErr, causeErr) so both are discoverable), ensuring
non-retryable vs retryable classification remains detectable.


switch stripeErr.Type {
case stripe.ErrorTypeInvalidRequest, stripe.ErrorTypeIdempotency:
return errorsutils.NewWrappedError(
err,
httpwrapper.ErrStatusCodeClientError,
pluginsdkhttp.ErrStatusCodeClientError,
)
}
return err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package client
import (
"context"

"github.com/formancehq/payments/internal/connectors/metrics"
pluginsdkmetrics "github.com/formancehq/payments/pkg/pluginsdk/metrics"
"github.com/stripe/stripe-go/v79"
)

Expand All @@ -23,7 +23,7 @@ func (c *client) GetExternalAccounts(
if !timeline.IsCaughtUp() {
var oldest interface{}
oldest, timeline, hasMore, err = scanForOldest(timeline, pageSize, func(params stripe.ListParams) (stripe.ListContainer, error) {
params.Context = metrics.OperationContext(ctx, "list_bank_accounts_scan")
params.Context = pluginsdkmetrics.OperationContext(ctx, "list_bank_accounts_scan")
itr := c.bankAccountClient.List(&stripe.BankAccountListParams{
Account: &accountID,
ListParams: params,
Expand All @@ -43,7 +43,7 @@ func (c *client) GetExternalAccounts(
itr := c.bankAccountClient.List(&stripe.BankAccountListParams{
Account: &accountID,
ListParams: stripe.ListParams{
Context: metrics.OperationContext(ctx, "list_bank_accounts"),
Context: pluginsdkmetrics.OperationContext(ctx, "list_bank_accounts"),
Limit: &pageSize,
EndingBefore: &timeline.LatestID,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package client
import (
"context"

"github.com/formancehq/payments/internal/connectors/metrics"
pluginsdkmetrics "github.com/formancehq/payments/pkg/pluginsdk/metrics"
"github.com/stripe/stripe-go/v79"
)

Expand Down Expand Up @@ -32,7 +32,7 @@ func (c *client) GetPayments(
if accountID != "" {
params.StripeAccount = &accountID
}
params.Context = metrics.OperationContext(ctx, "list_transactions_scan")
params.Context = pluginsdkmetrics.OperationContext(ctx, "list_transactions_scan")
transactionParams := &stripe.BalanceTransactionListParams{ListParams: params}
expandBalanceTransactionParams(transactionParams)
itr := c.balanceTransactionClient.List(transactionParams)
Expand All @@ -49,7 +49,7 @@ func (c *client) GetPayments(
}

filters := stripe.ListParams{
Context: metrics.OperationContext(ctx, "list_transactions"),
Context: pluginsdkmetrics.OperationContext(ctx, "list_transactions"),
Limit: limit(pageSize, len(results)),
EndingBefore: &timeline.LatestID,
Single: true, // turn off autopagination
Expand Down
4 changes: 2 additions & 2 deletions internal/connectors/plugins/public/stripe/client/payouts.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package client
import (
"context"

"github.com/formancehq/payments/internal/connectors/metrics"
pluginsdkmetrics "github.com/formancehq/payments/pkg/pluginsdk/metrics"
"github.com/stripe/stripe-go/v79"
)

Expand All @@ -20,7 +20,7 @@ type CreatePayoutRequest struct {
func (c *client) CreatePayout(ctx context.Context, createPayoutRequest *CreatePayoutRequest) (*stripe.Payout, error) {
params := &stripe.PayoutParams{
Params: stripe.Params{
Context: metrics.OperationContext(ctx, "initiate_payout"),
Context: pluginsdkmetrics.OperationContext(ctx, "initiate_payout"),
StripeAccount: createPayoutRequest.Source,
},
Amount: stripe.Int64(createPayoutRequest.Amount),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package client
import (
"context"

"github.com/formancehq/payments/internal/connectors/metrics"
pluginsdkmetrics "github.com/formancehq/payments/pkg/pluginsdk/metrics"
"github.com/stripe/stripe-go/v79"
)

Expand All @@ -19,7 +19,7 @@ type ReverseTransferRequest struct {
func (c *client) ReverseTransfer(ctx context.Context, reverseTransferRequest ReverseTransferRequest) (*stripe.TransferReversal, error) {
params := &stripe.TransferReversalParams{
Params: stripe.Params{
Context: metrics.OperationContext(ctx, "reverse_transfer"),
Context: pluginsdkmetrics.OperationContext(ctx, "reverse_transfer"),
StripeAccount: reverseTransferRequest.Account,
},
ID: stripe.String(reverseTransferRequest.StripeTransferID),
Expand Down
10 changes: 5 additions & 5 deletions internal/connectors/plugins/public/stripe/client/transfers.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package client

import (
"context"
"context"

"github.com/formancehq/payments/internal/connectors/metrics"
"github.com/stripe/stripe-go/v79"
pluginsdkmetrics "github.com/formancehq/payments/pkg/pluginsdk/metrics"
"github.com/stripe/stripe-go/v79"
)

type CreateTransferRequest struct {
Expand All @@ -19,8 +19,8 @@ type CreateTransferRequest struct {

func (c *client) CreateTransfer(ctx context.Context, createTransferRequest *CreateTransferRequest) (*stripe.Transfer, error) {
params := &stripe.TransferParams{
Params: stripe.Params{
Context: metrics.OperationContext(ctx, "initiate_transfer"),
Params: stripe.Params{
Context: pluginsdkmetrics.OperationContext(ctx, "initiate_transfer"),
StripeAccount: createTransferRequest.Source,
},
Amount: stripe.Int64(createTransferRequest.Amount),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/formancehq/go-libs/v3/currency"
"github.com/formancehq/payments/internal/connectors/plugins/public/stripe/client"
"github.com/formancehq/payments/internal/models"
errorsutils "github.com/formancehq/payments/internal/utils/errors"
errorsutils "github.com/formancehq/payments/pkg/pluginsdk/errors"
"github.com/stripe/stripe-go/v79"
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/formancehq/go-libs/v3/currency"
"github.com/formancehq/payments/internal/connectors/plugins/public/stripe/client"
"github.com/formancehq/payments/internal/models"
errorsutils "github.com/formancehq/payments/internal/utils/errors"
errorsutils "github.com/formancehq/payments/pkg/pluginsdk/errors"
"github.com/stripe/stripe-go/v79"
)

Expand Down
23 changes: 12 additions & 11 deletions internal/connectors/plugins/public/stripe/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ import (
"encoding/json"

"github.com/formancehq/go-libs/v3/logging"
"github.com/formancehq/payments/internal/connectors/plugins"
pluginsdk "github.com/formancehq/payments/pkg/pluginsdk/plugins"
"github.com/formancehq/payments/internal/connectors/plugins/public/stripe/client"
"github.com/formancehq/payments/internal/connectors/plugins/registry"
sdkregistry "github.com/formancehq/payments/pkg/pluginsdk/registry"
"github.com/formancehq/payments/internal/models"
)

const ProviderName = "stripe"


func init() {
registry.RegisterPlugin(ProviderName, models.PluginTypePSP, func(_ models.ConnectorID, name string, logger logging.Logger, rm json.RawMessage) (models.Plugin, error) {
sdkregistry.RegisterPlugin(ProviderName, models.PluginTypePSP, func(_ models.ConnectorID, name string, logger logging.Logger, rm json.RawMessage) (models.Plugin, error) {
return New(name, logger, rm)
}, capabilities, Config{})
}
Expand All @@ -37,7 +38,7 @@ func New(name string, logger logging.Logger, rawConfig json.RawMessage) (*Plugin
client := client.New(ProviderName, logger, nil, config.APIKey)

return &Plugin{
Plugin: plugins.NewBasePlugin(),
Plugin: pluginsdk.NewBasePlugin(),

name: name,
logger: logger,
Expand Down Expand Up @@ -66,35 +67,35 @@ func (p *Plugin) Uninstall(ctx context.Context, req models.UninstallRequest) (mo

func (p *Plugin) FetchNextAccounts(ctx context.Context, req models.FetchNextAccountsRequest) (models.FetchNextAccountsResponse, error) {
if p.client == nil {
return models.FetchNextAccountsResponse{}, plugins.ErrNotYetInstalled
return models.FetchNextAccountsResponse{}, pluginsdk.ErrNotYetInstalled
}
return p.fetchNextAccounts(ctx, req)
}

func (p *Plugin) FetchNextBalances(ctx context.Context, req models.FetchNextBalancesRequest) (models.FetchNextBalancesResponse, error) {
if p.client == nil {
return models.FetchNextBalancesResponse{}, plugins.ErrNotYetInstalled
return models.FetchNextBalancesResponse{}, pluginsdk.ErrNotYetInstalled
}
return p.fetchNextBalances(ctx, req)
}

func (p *Plugin) FetchNextExternalAccounts(ctx context.Context, req models.FetchNextExternalAccountsRequest) (models.FetchNextExternalAccountsResponse, error) {
if p.client == nil {
return models.FetchNextExternalAccountsResponse{}, plugins.ErrNotYetInstalled
return models.FetchNextExternalAccountsResponse{}, pluginsdk.ErrNotYetInstalled
}
return p.fetchNextExternalAccounts(ctx, req)
}

func (p *Plugin) FetchNextPayments(ctx context.Context, req models.FetchNextPaymentsRequest) (models.FetchNextPaymentsResponse, error) {
if p.client == nil {
return models.FetchNextPaymentsResponse{}, plugins.ErrNotYetInstalled
return models.FetchNextPaymentsResponse{}, pluginsdk.ErrNotYetInstalled
}
return p.fetchNextPayments(ctx, req)
}

func (p *Plugin) CreateTransfer(ctx context.Context, req models.CreateTransferRequest) (models.CreateTransferResponse, error) {
if p.client == nil {
return models.CreateTransferResponse{}, plugins.ErrNotYetInstalled
return models.CreateTransferResponse{}, pluginsdk.ErrNotYetInstalled
}

payment, err := p.createTransfer(ctx, req.PaymentInitiation)
Expand All @@ -109,7 +110,7 @@ func (p *Plugin) CreateTransfer(ctx context.Context, req models.CreateTransferRe

func (p *Plugin) ReverseTransfer(ctx context.Context, req models.ReverseTransferRequest) (models.ReverseTransferResponse, error) {
if p.client == nil {
return models.ReverseTransferResponse{}, plugins.ErrNotYetInstalled
return models.ReverseTransferResponse{}, pluginsdk.ErrNotYetInstalled
}

payment, err := p.reverseTransfer(ctx, req.PaymentInitiationReversal)
Expand All @@ -124,7 +125,7 @@ func (p *Plugin) ReverseTransfer(ctx context.Context, req models.ReverseTransfer

func (p *Plugin) CreatePayout(ctx context.Context, req models.CreatePayoutRequest) (models.CreatePayoutResponse, error) {
if p.client == nil {
return models.CreatePayoutResponse{}, plugins.ErrNotYetInstalled
return models.CreatePayoutResponse{}, pluginsdk.ErrNotYetInstalled
}

payment, err := p.createPayout(ctx, req.PaymentInitiation)
Expand Down
22 changes: 11 additions & 11 deletions internal/connectors/plugins/public/stripe/reverse_transfers.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package stripe

import (
"context"
"encoding/json"
"fmt"
"math/big"
"strings"
"time"
"context"
"encoding/json"
"fmt"
"math/big"
"strings"
"time"

"github.com/formancehq/go-libs/v3/currency"
"github.com/formancehq/payments/internal/connectors/plugins/public/stripe/client"
"github.com/formancehq/payments/internal/models"
errorsutils "github.com/formancehq/payments/internal/utils/errors"
"github.com/stripe/stripe-go/v79"
"github.com/formancehq/go-libs/v3/currency"
"github.com/formancehq/payments/internal/connectors/plugins/public/stripe/client"
"github.com/formancehq/payments/internal/models"
errorsutils "github.com/formancehq/payments/pkg/pluginsdk/errors"
"github.com/stripe/stripe-go/v79"
)

const (
Expand Down
6 changes: 3 additions & 3 deletions internal/connectors/plugins/public/stripe/utils.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package stripe

import (
"fmt"
"fmt"

"github.com/formancehq/payments/internal/models"
errorsutils "github.com/formancehq/payments/internal/utils/errors"
"github.com/formancehq/payments/internal/models"
errorsutils "github.com/formancehq/payments/pkg/pluginsdk/errors"
)

func (p *Plugin) validatePayoutTransferRequest(pi models.PSPPaymentInitiation) error {
Expand Down
Loading
Loading