mirror of
https://github.com/hanzo-fi/payments.git
synced 2026-10-30 20:31:20 +00:00
93 lines
3.3 KiB
Go
93 lines
3.3 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/formancehq/payments/internal/connectors/httpwrapper"
|
|
"github.com/formancehq/payments/internal/connectors/metrics"
|
|
errorsutils "github.com/formancehq/payments/internal/utils/errors"
|
|
"github.com/stripe/stripe-go/v79"
|
|
"github.com/stripe/stripe-go/v79/account"
|
|
"github.com/stripe/stripe-go/v79/balance"
|
|
"github.com/stripe/stripe-go/v79/balancetransaction"
|
|
"github.com/stripe/stripe-go/v79/bankaccount"
|
|
"github.com/stripe/stripe-go/v79/payout"
|
|
"github.com/stripe/stripe-go/v79/transfer"
|
|
"github.com/stripe/stripe-go/v79/transferreversal"
|
|
)
|
|
|
|
// https://github.com/stripe/stripe-go/blob/master/stripe.go#L1478
|
|
const StripeDefaultTimeout = 80 * time.Second
|
|
|
|
//go:generate mockgen -source client.go -destination client_generated.go -package client . Client
|
|
type Client interface {
|
|
GetAccounts(ctx context.Context, timeline Timeline, pageSize int64) ([]*stripe.Account, Timeline, bool, error)
|
|
GetAccountBalances(ctx context.Context, accountID string) (*stripe.Balance, error)
|
|
GetExternalAccounts(ctx context.Context, accountID string, timeline Timeline, pageSize int64) ([]*stripe.BankAccount, Timeline, bool, error)
|
|
GetPayments(ctx context.Context, accountID string, timeline Timeline, pageSize int64) ([]*stripe.BalanceTransaction, Timeline, bool, error)
|
|
CreatePayout(ctx context.Context, createPayoutRequest *CreatePayoutRequest) (*stripe.Payout, error)
|
|
CreateTransfer(ctx context.Context, createTransferRequest *CreateTransferRequest) (*stripe.Transfer, error)
|
|
ReverseTransfer(ctx context.Context, reverseTransferRequest ReverseTransferRequest) (*stripe.TransferReversal, error)
|
|
}
|
|
|
|
type client struct {
|
|
accountClient account.Client
|
|
balanceClient balance.Client
|
|
transferClient transfer.Client
|
|
transferReversalClient transferreversal.Client
|
|
payoutClient payout.Client
|
|
bankAccountClient bankaccount.Client
|
|
balanceTransactionClient balancetransaction.Client
|
|
}
|
|
|
|
func New(name string, backend stripe.Backend, apiKey string) Client {
|
|
if backend == nil {
|
|
backends := stripe.NewBackends(metrics.NewHTTPClient(name, StripeDefaultTimeout))
|
|
backend = backends.API
|
|
}
|
|
|
|
return &client{
|
|
accountClient: account.Client{B: backend, Key: apiKey},
|
|
balanceClient: balance.Client{B: backend, Key: apiKey},
|
|
transferClient: transfer.Client{B: backend, Key: apiKey},
|
|
payoutClient: payout.Client{B: backend, Key: apiKey},
|
|
bankAccountClient: bankaccount.Client{B: backend, Key: apiKey},
|
|
balanceTransactionClient: balancetransaction.Client{B: backend, Key: apiKey},
|
|
}
|
|
}
|
|
|
|
func limit(wanted int64, have int) *int64 {
|
|
needed := wanted - int64(have)
|
|
return &needed
|
|
}
|
|
|
|
// wrap a public error for cases that we don't want to retry
|
|
// so that activities can classify this error for temporal
|
|
func wrapSDKErr(err error) error {
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
|
|
stripeErr, ok := err.(*stripe.Error)
|
|
if !ok {
|
|
return err
|
|
}
|
|
|
|
if stripeErr.Code == stripe.ErrorCodeRateLimit {
|
|
return errorsutils.NewWrappedError(
|
|
err,
|
|
httpwrapper.ErrStatusCodeTooManyRequests,
|
|
)
|
|
}
|
|
|
|
switch stripeErr.Type {
|
|
case stripe.ErrorTypeInvalidRequest, stripe.ErrorTypeIdempotency:
|
|
return errorsutils.NewWrappedError(
|
|
err,
|
|
httpwrapper.ErrStatusCodeClientError,
|
|
)
|
|
}
|
|
return err
|
|
}
|