A production-grade Elixir hex package for the ClearBank UK API.
Features
- ✅ Complete API coverage — GBP Accounts, GBP Payments, Multi-currency & FX, Embedded Banking
- ✅ RSA-SHA256 digital signatures — PKCS#1 v1.5, HSM-compatible
- ✅ Webhook verification & dispatch — signature verification, idiomatic
Handlerbehaviour - ✅ Multi-tenant — per-call client structs for multiple credential sets
- ✅ NimbleOptions config validation — fail-fast with clear error messages
- ✅ Telemetry — all requests emit structured events
- ✅ Client-side rate limiter — token-bucket GenServer
- ✅ Typed errors —
%ClearBank.Error{}withretryable?/1 - ✅ Full test suite — ExUnit + Bypass HTTP mocking
- ✅ CI matrix — Elixir 1.14–1.16, OTP 25–26
- ✅ Dialyzer + Credo — strict type checking and linting
- ✅ ExDoc with grouped module navigation and guides
Supported APIs
| Area | Modules |
|---|---|
| GBP Accounts | Accounts, Accounts.Transactions, Accounts.BacsPaymentData, Accounts.Reporting |
| GBP Payments | Payments.FasterPayments, Payments.Chaps, Payments.Bacs, Payments.BacsDirectDebit, Payments.Cheques, Payments.CrossBorder, Payments.ConfirmationOfPayee |
| Multi-currency & FX | MultiCurrency.Accounts, MultiCurrency.Payments, MultiCurrency.FxTrade, MultiCurrency.FxTradeRfq, MultiCurrency.SepaCreditTransfer |
| Embedded Banking | EmbeddedBanking.Customers, EmbeddedBanking.Accounts, EmbeddedBanking.Isa, EmbeddedBanking.Interest, EmbeddedBanking.Kyc |
| Webhooks | Webhook, Webhook.Verifier, Webhook.Handler |
Installation
# mix.exs
def deps do
[
{:clearbank, "~> 1.0"}
]
endQuick Start
1. Configure
# config/runtime.exs
config :clearbank,
api_token: System.fetch_env!("CLEARBANK_API_TOKEN"),
private_key_path: System.fetch_env!("CLEARBANK_PRIVATE_KEY_PATH"),
environment: :simulation # :simulation | :production2. Use
client = ClearBank.default_client()
# List GBP accounts
{:ok, %{"accounts" => accounts}} = ClearBank.Accounts.list(client)
# Send a Faster Payment
{:ok, _} = ClearBank.Payments.FasterPayments.send(client, %{
account_id: "your-account-uuid",
amount: "100.00",
currency: "GBP",
destination_sort_code: "040004",
destination_account_number: "12345678",
destination_account_name: "Jane Smith",
reference: "Invoice 001"
})
# Execute an FX spot trade
{:ok, trade} = ClearBank.MultiCurrency.FxTrade.execute(client, %{
sell_account_id: "eur-account-uuid",
buy_account_id: "gbp-account-uuid",
sell_currency: "EUR",
buy_currency: "GBP",
sell_amount: "10000.00"
})
# Create an embedded retail customer
{:ok, customer} = ClearBank.EmbeddedBanking.Customers.create_retail(client, %{
first_name: "Alice",
last_name: "Smith",
date_of_birth: "1990-05-15",
email: "alice@example.com"
})3. Handle Webhooks
defmodule MyApp.WebhookHandler do
use ClearBank.Webhook.Handler
@impl true
def handle(%ClearBank.Webhook{type: "TransactionSettled", payload: payload}) do
MyApp.Ledger.record(payload)
:ok
end
def handle(_webhook), do: :ok
end4. Error Handling
case ClearBank.Payments.FasterPayments.send(client, payment) do
{:ok, _} -> :ok
{:error, %ClearBank.Error{status: 409}} -> :duplicate_ignored
{:error, %ClearBank.Error{status: 429}} -> retry_later()
{:error, err} when ClearBank.Error.retryable?(err) -> retry_with_same_id()
{:error, err} -> Logger.error(inspect(err))
endDevelopment
mix deps.get
mix test
mix test --cover
mix credo --strict
mix dialyzer
mix docs
Security
- Never commit your
private_key.pem— add it to.gitignore - In production, load private keys from an HSM, not the filesystem
- Rotate API tokens before their 1-year expiry
- Verify all inbound webhook signatures before processing
- Store
X-Correlation-Idfrom error responses — required for ClearBank support
License
MIT — see LICENSE.
Contributing
Pull requests welcome. Please ensure mix test, mix credo --strict,
and mix dialyzer all pass before submitting.