Skip to content

fintech-sdk/increase-go

Repository files navigation

increase-go

A production-grade, independent Go client for the Increase API — banking-as-a-service for accounts, ACH/wire/check/RTP/FedNow transfers, cards, entities, and more.

This is a from-scratch implementation with a hexagonal/DDD architecture, built to match the standards of Increase's public API surface (all ~90 resource groups, ~240 operations). It has zero external dependencies — only the Go standard library.

Usage

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/iamkanishka/increase-go"
	"github.com/iamkanishka/increase-go/domain"
)

func main() {
	client := increase.New(
		increase.WithAPIKey(os.Getenv("INCREASE_API_KEY")),
		increase.WithEnvironment(increase.SandboxEnvironment),
	)

	ctx := context.Background()

	account, err := client.Accounts.Create(ctx, domain.AccountCreateParams{
		Name: "My First Account",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("created", account.ID)

	// Lazy, cursor-based pagination — pages are fetched on demand as
	// the iterator is consumed, not all up front.
	iter := client.Accounts.ListAutoPaging(ctx, domain.AccountListParams{})
	for iter.Next(ctx) {
		fmt.Println(iter.Current().ID, iter.Current().Name)
	}
	if err := iter.Err(); err != nil {
		log.Fatal(err)
	}

	// Sandbox-only simulations let you drive objects through their
	// lifecycle without waiting on real banking rails.
	transfer, err := client.ACHTransfers.Create(ctx, domain.ACHTransferCreateParams{
		AccountID:           account.ID,
		Amount:              1000,
		StatementDescriptor: "Test payment",
	})
	if err != nil {
		log.Fatal(err)
	}
	if _, err := client.Simulations.ACHTransfers.Submit(ctx, transfer.ID); err != nil {
		log.Fatal(err)
	}
}

Error handling

_, err := client.Accounts.Get(ctx, "account_does_not_exist")
if increase.IsNotFound(err) {
	// ...
}

var apiErr *increase.Error
if errors.As(err, &apiErr) {
	fmt.Println(apiErr.Type, apiErr.Title, apiErr.Status, apiErr.Detail)
}

Webhooks

body, _ := io.ReadAll(r.Body)
if err := webhook.Verify(body, r.Header, signingSecret, webhook.Options{}); err != nil {
	http.Error(w, "invalid signature", http.StatusBadRequest)
	return
}
var event map[string]any
json.Unmarshal(body, &event)

Retries and idempotency

WithMaxRetries (default 2) retries rate-limited (429) and server-error (5xx/408/409) responses with exponential backoff and jitter, honoring Retry-After when present. Because retrying a POST/PATCH naively could double-create something, the transport generates an Idempotency-Key once before the first attempt and reuses it across every retry of that request — Increase guarantees replaying the same key returns the original result.

Logging

client := increase.New(
	increase.WithAPIKey(apiKey),
	increase.WithLogger(slog.Default()),
)

Emits structured events for request start, completion (status, duration, attempt count), retries, and terminal failures.

Design notes

  • Nullability: response fields Increase documents as nullable are Go pointers (*string, *time.Time, ...); everything else is a plain value. Optional request parameters are pointers with omitempty; required parameters are plain values.
  • Enums: modeled as named string types with an IsKnown() method, since Increase may add new enum values over time — check IsKnown() before treating an unrecognized value as an error.
  • Pagination: every List method returns a *pagination.Page[T], and every resource also has a ListAutoPaging method returning a lazy *pagination.Iterator[T] that only fetches the next page when the current one is exhausted.
  • File uploads: client.Files.Create is the one method that sends multipart/form-data instead of JSON, since it uploads raw bytes.

Provenance

Domain models and endpoint definitions were derived from Increase's published API surface (cross-referenced against Increase's official Go SDK for field-level accuracy) and reimplemented from scratch in this hexagonal architecture — this is an independent client, not a fork.

Testing

go test ./...          # all packages
go test ./... -race     # with the race detector

Covers: webhook signature verification (valid/invalid/tampered/stale/multi-signature), lazy pagination (page-boundary laziness, error propagation), the HTTP transport (retry/backoff, non-retryable errors, idempotency key stability across retries, caller-supplied idempotency keys, nested query encoding, context cancellation), and end-to-end resource behavior against httptest servers (create/get/update, 404 → IsNotFound, multi-page auto-pagination, simulations wiring, and nullable/optional field JSON semantics across multiple resources).

About

A production-grade, independent Go client for the Increase API — banking-as-a-service for accounts, ACH/wire/check/RTP/FedNow transfers, cards, entities, and more.

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages