A complete, production-grade Go SDK for the SaltEdge API v6 , covering all three product areas:
AIS — Account Information Service
PIS — Payment Initiation Service
Data Enrichment Platform — Categorisation, Merchant ID & Financial Insights
Category
What's included
Full API v6 coverage
AIS, PIS, Data Enrichment — every endpoint from the official docs
Entry point
Single salt_edge.go with saltedge.New() and three service groups: AIS, PIS, Enrichment
Authentication
App-id + Secret auto-injected; optional HMAC-SHA256 request signing
Resilience
Exponential-backoff retries (configurable), 429/5xx handled, context cancellation
Generics
ListResponse[T], SingleResponse[T], Paginator[T], pagination.All, pagination.ForEach
Typed errors
APIError with errors.Is/errors.As, sentinel vars, IsNotFound, IsRetryable, IsClass
Webhooks
webhook.Handler — HMAC validation, event routing by type, typed On() / OnAny()
Middleware
Logging, User-Agent injection, debug mode via log/slog
Functional options
WithTimeout, WithMaxRetries, WithPrivateKey, WithLogger, WithHTTPClient, WithDebug
Tests
57 unit tests (race-detector clean), integration test suite
go get github.com/iamkanishka/saltedge-client-go@latest
Requires Go 1.25+ .
import (
saltedge "github.com/iamkanishka/saltedge-client-go"
"github.com/iamkanishka/saltedge-client-go/pkg/models/ais"
"github.com/iamkanishka/saltedge-client-go/pkg/pagination"
)
client := saltedge .New ("YOUR_APP_ID" , "YOUR_SECRET" ,
saltedge .WithTimeout (20 * time .Second ),
saltedge .WithMaxRetries (3 ),
saltedge .WithDebug (true ),
)
// ── AIS ──────────────────────────────────────────────────────────────────────
customer , err := client .AIS .Customers .Create (ctx , ais.CreateCustomerParams {
Identifier : "alice@example.com" ,
})
session , err := client .AIS .Connections .Connect (ctx , ais.ConnectParams {
CustomerID : customer .ID ,
Consent : ais.ConsentObject {Scopes : []string {"accounts" , "transactions" }},
Attempt : & ais.AttemptObject {ReturnTo : "https://yourapp.com/callback" },
})
fmt .Println ("Connect URL:" , session .ConnectURL )
// Paginate all accounts
accounts , err := pagination .All (ctx , func (ctx context.Context , fromID string ) ([]ais.Account , string , error ) {
return client .AIS .Accounts .List (ctx , ais.ListAccountsParams {
ConnectionID : "conn-id" ,
FromID : fromID ,
})
})
// ── PIS ──────────────────────────────────────────────────────────────────────
payment , err := client .PIS .Payments .Create (ctx , pis.CreatePaymentParams {
CustomerID : customer .ID ,
ProviderCode : "fake_client_xf" ,
TemplateCode : "sepa_credit_transfer" ,
PaymentAttributes : map [string ]any {
"amount" : "100.00" ,
"currency_code" : "EUR" ,
"creditor_name" : "Acme Corp" ,
"creditor_iban" : "DE89370400440532013000" ,
},
})
// ── Data Enrichment ───────────────────────────────────────────────────────────
bucket , err := client .Enrichment .Buckets .Create (ctx , enrichment.CreateBucketParams {
CustomerID : customer .ID ,
})
AIS (Account Information Service)
Resource
Operations
Countries
List
Providers
List, Show
Customers
Create, Show, List, Remove
Connections
Show, List, Connect, Reconnect, Refresh, BackgroundRefresh, Update, Remove
Consents
List, Show, Revoke
Accounts
List
Transactions
List, Update
Exchange Rates
List
PIS (Payment Initiation Service)
Resource
Operations
Customers
Create, Show, List, Remove
Providers
List, Show
Payments
Create, Show, List, Refresh
Payment Templates
Show, List
Bulk Payments
Create, Show, List, Refresh
Resource
Operations
Buckets
Create, Show, Remove
Accounts
Import, List, Remove
Transactions
Import, StartCategorization, ListCategorized
Merchants
Show
Categories
List, ListByType, Learn
Customer Rules
List, Show, Remove
Financial Insights
Create, Show, List, Remove
import saltErr "github.com/iamkanishka/saltedge-client-go/pkg/errors"
_ , err := client .AIS .Customers .Show (ctx , "missing-id" )
// Helper functions
if saltErr .IsNotFound (err ) { /* 404 */ }
if saltErr .IsRateLimit (err ) { /* 429 */ }
if saltErr .IsServerError (err ){ /* 5xx */ }
if saltErr .IsRetryable (err ) { /* auto-retried but still failed */ }
if saltErr .IsClass (err , "InvalidCredentials" ) { /* specific class */ }
// Sentinel matching with errors.Is
if errors .Is (err , saltErr .ErrNotFound ) { ... }
if errors .Is (err , saltErr .ErrCustomerNotFound ) { ... }
// Full details via errors.As
var apiErr * saltErr.APIError
if errors .As (err , & apiErr ) {
fmt .Printf ("status=%d class=%s message=%s\n " ,
apiErr .StatusCode , apiErr .Class , apiErr .Message )
}
Pagination
// Option A: collect everything
all , err := pagination .All (ctx , func (ctx context.Context , fromID string ) ([]ais.Transaction , string , error ) {
return client .AIS .Transactions .List (ctx , ais.ListTransactionsParams {
ConnectionID : "conn-id" ,
FromID : fromID ,
})
})
// Option B: streaming with ForEach (memory-efficient)
err = pagination .ForEach (ctx , fetchFn , func (tx ais.Transaction ) error {
fmt .Println (tx .Description , tx .Amount )
return nil
})
// Option C: manual iteration
pager := pagination .New (fetchFn )
for pager .Next (ctx ) {
for _ , item := range pager .Page ().Items {
process (item )
}
}
if err := pager .Err (); err != nil { ... }
import (
"github.com/iamkanishka/saltedge-client-go/internal/signer"
"github.com/iamkanishka/saltedge-client-go/pkg/webhook"
)
s := signer .New ("YOUR_WEBHOOK_SECRET" )
handler := webhook .New (s )
handler .On (webhook .AISSuccess , func (ev * webhook.Event ) error {
var cb ais.SuccessCallback
json .Unmarshal (ev .Data , & cb .Data )
fmt .Println ("Connection synced:" , cb .Data .ConnectionID , "stage:" , cb .Data .Stage )
return nil
})
handler .On (webhook .AISFailure , handleFail )
handler .On (webhook .AISNotify , handleNotify )
handler .On (webhook .AISDestroy , handleDestroy )
handler .On (webhook .PISPaymentSuccess , handlePaymentSuccess )
handler .OnAny (logUnhandled ) // fallback
http .Handle ("/webhook/saltedge" , handler )
client := saltedge .New (appID , secret ,
saltedge .WithBaseURL ("https://custom-proxy.example.com/api/v6" ),
saltedge .WithTimeout (15 * time .Second ),
saltedge .WithMaxRetries (5 ),
saltedge .WithRetry (httpclient.RetryConfig {
MaxAttempts : 4 ,
BaseDelay : 200 * time .Millisecond ,
MaxDelay : 30 * time .Second ,
}),
saltedge .WithPrivateKey (hmacPrivateKey ), // enables request signing
saltedge .WithLogger (logger .DefaultSlog ()),
saltedge .WithHTTPClient (myCustomHTTPClient ), // for tests or proxying
saltedge .WithDebug (true ),
)
saltedge-client-go/
├── salt_edge.go # ← Entry point: saltedge.New(), Client, service groups
├── client.go # Core HTTP executor, Config, functional options
│
├── pkg/
│ ├── errors/ # APIError, sentinels, IsNotFound, IsRetryable, …
│ ├── logger/ # Logger interface, Noop, Slog adapters
│ ├── models/
│ │ ├── ais/ # AIS models: Country, Provider, Customer, Connection,
│ │ │ # Consent, Account, Transaction, ExchangeRate, Callbacks
│ │ ├── pis/ # PIS models: Customer, Provider, Payment, BulkPayment,
│ │ │ # PaymentTemplate, Callbacks
│ │ └── enrichment/ # Enrichment models: Bucket, Account, Transaction,
│ │ # Merchant, Category, CustomerRule, FinancialInsight
│ ├── pagination/ # Paginator[T], All(), ForEach()
│ └── webhook/ # Handler, EventType constants, Event struct
│
├── services/
│ ├── requester.go # Requester interface (Get/Post/Put/Delete)
│ ├── ais/ # CountriesService, ProvidersService, CustomersService,
│ │ # ConnectionsService, ConsentsService, AccountsService,
│ │ # TransactionsService, RatesService
│ ├── pis/ # CustomersService, ProvidersService, PaymentsService,
│ │ # TemplatesService, BulkPaymentsService
│ └── enrichment/ # BucketsService, AccountsService, TransactionsService,
│ # MerchantsService, CategoriesService,
│ # CustomerRulesService, FinancialInsightsService
│
├── internal/
│ ├── httpclient/ # Doer interface, retry engine, connection pool
│ └── signer/ # HMAC-SHA256 request/webhook signing
│
├── examples/
│ ├── ais_quickstart/ # Customer → connect session → paginate accounts + txns
│ ├── pis_payment/ # SEPA payment + bulk payment
│ ├── webhook_server/ # Full HTTP webhook server
│ └── data_enrichment/ # Bucket → import → categorize → insights
│
├── tests/
│ ├── unit/ # 57 tests, race-detector clean, httptest-based mocks
│ └── integration/ # Build-tagged real-API tests (needs credentials)
│
└── .github/workflows/ # CI (lint → test → build) + release automation
# Unit tests (no credentials needed)
go test -v -race ./tests/unit/...
# With coverage
go test -race -coverpkg=./... -coverprofile=coverage.out ./tests/unit/...
go tool cover -html=coverage.out
# Integration tests (requires real credentials)
SALTEDGE_APP_ID=xxx SALTEDGE_SECRET=yyy \
go test -tags=integration -v ./tests/integration/...
This module follows Semantic Versioning .
Breaking changes are introduced only in major version bumps (v2, v3, …).
The current version is v2.0.0.
MIT