Files
zeekay 7d727874d5 chore: rebrand Formance Payments -> Hanzo Payments (hanzo-fi)
- go.mod module path + all self-imports: github.com/formancehq/payments -> github.com/hanzo-fi/payments
  (1590 .go files / 3152 refs; 20 modules: root, pkg/client, pkg/domain, 18 ce/plugins).
  External dep kept: formancehq/go-libs.
- plugins: each ce/plugins/* consumed a *published* pkg/domain; added local
  'replace .../pkg/domain => ../../../pkg/domain' (consistent with root) so every
  standalone plugin module builds in-monorepo. compile-plugin.sh MOD var rebranded too.
- branding: README, LICENSE (dual MIT+EE; upstream copyright retained + Hanzo added),
  goreleaser (release images -> registry.hanzo.ai/hanzo-fi, OCI labels, homepage),
  proto go_package, renovate, speakeasy gen.yaml, connector-template *.gotpl.
- CI: removed Numary/Formance workflows + composite action; added canonical hanzo.yml +
  cicd.yml (hanzoai/ci, gated HANZO_CI_ENABLED) + secretless ci.yml (go build/vet).
- kept as data/compat keys: wire capability enums ALLOW_FORMANCE_*, generated SDK type
  client.Formance, domain field FormanceRedirectURL, OTEL_SERVICE_NAME, upstream base image.
- verified: go build ./... (default + -tags ee) + all 20 nested modules green.
2026-07-05 13:08:55 -07:00

78 lines
3.1 KiB
Go

package client
import (
"context"
"net/url"
"os"
"github.com/hanzo-fi/payments/pkg/domain/httpwrapper"
"github.com/hanzo-fi/payments/pkg/domain/metrics"
"github.com/hanzo-fi/payments/pkg/domain/models"
lru "github.com/hashicorp/golang-lru/v2"
"github.com/plaid/plaid-go/v34/plaid"
)
//go:generate mockgen -source client.go -destination client_generated.go -package client . Client
type Client interface {
CreateUser(ctx context.Context, userID string) (string, error)
CreateLinkToken(ctx context.Context, req CreateLinkTokenRequest) (CreateLinkTokenResponse, error)
UpdateLinkToken(ctx context.Context, req UpdateLinkTokenRequest) (UpdateLinkTokenResponse, error)
ExchangePublicToken(ctx context.Context, req ExchangePublicTokenRequest) (ExchangePublicTokenResponse, error)
GetWebhookVerificationKey(ctx context.Context, kid string) (*plaid.JWKPublicKey, error)
BaseWebhookTranslation(body []byte) (BaseWebhooks, error)
DeleteItem(ctx context.Context, req DeleteItemRequest) error
DeleteUser(ctx context.Context, userToken string) error
FormanceOpenBankingRedirect(ctx context.Context, req FormanceOpenBankingRedirectRequest) error
ListAccounts(ctx context.Context, accessToken string) (plaid.AccountsGetResponse, error)
ListTransactions(ctx context.Context, accessToken string, cursor string, pageSize int) (plaid.TransactionsSyncResponse, error)
TranslateItemAddResultWebhook(body []byte) (plaid.ItemAddResultWebhook, error)
TranslateSessionFinishedWebhook(body []byte) (plaid.LinkSessionFinishedWebhook, error)
TranslateUserPendingDisconnectWebhook(body []byte) (plaid.PendingDisconnectWebhook, error)
TranslateUserPendingExpirationWebhook(body []byte) (plaid.PendingExpirationWebhook, error)
TranslateItemErrorWebhook(body []byte) (plaid.ItemErrorWebhook, error)
}
type client struct {
client *plaid.APIClient
connectorID models.ConnectorID
formanceHTTPClient httpwrapper.Client
formanceStackEndpoint string
webhookKeysCache *lru.Cache[string, *plaid.JWKPublicKey]
}
// TODO(polo): enable compression ? We have to activate compression directly in the http client
func New(name, clientID, clientSecret string, connectorID models.ConnectorID, isSandbox bool) (Client, error) {
formanceStackEndpoint, err := url.JoinPath(os.Getenv("STACK_PUBLIC_URL"), "api", "payments", "v3")
if err != nil {
return nil, err
}
configuration := plaid.NewConfiguration()
configuration.AddDefaultHeader("PLAID-CLIENT-ID", clientID)
configuration.AddDefaultHeader("PLAID-SECRET", clientSecret)
env := plaid.Production
if isSandbox {
env = plaid.Sandbox
}
configuration.UseEnvironment(env)
webhookKeysCache, _ := lru.New[string, *plaid.JWKPublicKey](2048)
configuration.HTTPClient = metrics.NewHTTPClient(name, models.DefaultConnectorClientTimeout)
formanceHTTPClient := httpwrapper.NewClient(&httpwrapper.Config{
Transport: metrics.NewTransport(name, metrics.TransportOpts{}),
})
return &client{
client: plaid.NewAPIClient(configuration),
connectorID: connectorID,
formanceStackEndpoint: formanceStackEndpoint,
formanceHTTPClient: formanceHTTPClient,
webhookKeysCache: webhookKeysCache,
}, nil
}