Packages

A complete, production-grade Elixir client for the Mercury Banking API (accounts, transactions, recipients, invoices, payments, treasury, webhooks, and more), with typed errors, retry with backoff, and lazy auto-paginating streams.

Current section

Files

Jump to
mercury_client lib mercury treasury.ex
Raw

lib/mercury/treasury.ex

defmodule Mercury.TreasuryAccount do
@moduledoc "A Mercury Treasury investment account."
@type t :: %__MODULE__{
id: String.t(),
name: String.t(),
balance: float(),
currency: String.t(),
status: String.t(),
created_at: DateTime.t() | nil
}
defstruct [:id, :name, :balance, :currency, :status, :created_at]
@doc false
def from_json(map) when is_map(map) do
%__MODULE__{
id: map["id"],
name: map["name"],
balance: map["balance"],
currency: map["currency"],
status: map["status"],
created_at: Mercury.Types.datetime(map["createdAt"])
}
end
end
defmodule Mercury.TreasuryTransaction do
@moduledoc "A transaction on a Treasury account."
@type t :: %__MODULE__{
id: String.t(),
amount: float(),
status: String.t(),
created_at: DateTime.t() | nil,
kind: String.t(),
description: String.t() | nil
}
defstruct [:id, :amount, :status, :created_at, :kind, :description]
@doc false
def from_json(map) when is_map(map) do
%__MODULE__{
id: map["id"],
amount: map["amount"],
status: map["status"],
created_at: Mercury.Types.datetime(map["createdAt"]),
kind: map["kind"],
description: map["description"]
}
end
end
defmodule Mercury.TreasuryStatement do
@moduledoc "A statement for a Treasury account."
@type t :: %__MODULE__{
id: String.t(),
period: String.t(),
document_type: String.t(),
url: String.t() | nil,
created_at: DateTime.t() | nil
}
defstruct [:id, :period, :document_type, :url, :created_at]
@doc false
def from_json(map) when is_map(map) do
%__MODULE__{
id: map["id"],
period: map["period"],
document_type: map["documentType"],
url: map["url"],
created_at: Mercury.Types.datetime(map["createdAt"])
}
end
end
defmodule Mercury.Treasury do
@moduledoc "The Mercury Treasury API — investment accounts, transactions, and statements."
alias Mercury.{
Client,
HTTP,
Page,
Pagination,
Support,
TreasuryAccount,
TreasuryStatement,
TreasuryTransaction
}
@doc "Returns one page of treasury accounts. `GET /treasury`"
@spec list(client :: Client.t(), opts :: keyword()) ::
{:ok, Page.t(TreasuryAccount.t())} | {:error, Exception.t()}
def list(%Client{} = client, opts \\ []) do
with {:ok, body} <- HTTP.get(client, "treasury", opts) do
{:ok, Page.from_json(body, "accounts", &TreasuryAccount.from_json/1)}
end
end
@spec list!(client :: Client.t(), opts :: keyword()) :: Page.t(TreasuryAccount.t())
def list!(client, opts \\ []), do: Support.bang!(list(client, opts))
@doc "A lazy, auto-paginating stream of every treasury account."
@spec stream(client :: Client.t(), opts :: keyword()) :: Enumerable.t()
def stream(%Client{} = client, opts \\ []) do
opts = Keyword.new(opts)
Pagination.stream(fn cursor -> list(client, Keyword.put(opts, :start_after, cursor)) end)
end
@doc "Returns one page of transactions for a treasury account. `GET /treasury/{id}/transactions`"
@spec list_transactions(client :: Client.t(), account_id :: String.t(), opts :: keyword()) ::
{:ok, Page.t(TreasuryTransaction.t())} | {:error, Exception.t()}
def list_transactions(%Client{} = client, account_id, opts \\ []) do
with {:ok, body} <- HTTP.get(client, "treasury/#{account_id}/transactions", opts) do
{:ok, Page.from_json(body, "transactions", &TreasuryTransaction.from_json/1)}
end
end
@spec list_transactions!(client :: Client.t(), account_id :: String.t(), opts :: keyword()) ::
Page.t(TreasuryTransaction.t())
def list_transactions!(client, account_id, opts \\ []),
do: Support.bang!(list_transactions(client, account_id, opts))
@doc "A lazy, auto-paginating stream of every transaction for a treasury account."
@spec stream_transactions(client :: Client.t(), account_id :: String.t(), opts :: keyword()) ::
Enumerable.t()
def stream_transactions(%Client{} = client, account_id, opts \\ []) do
opts = Keyword.new(opts)
Pagination.stream(fn cursor ->
list_transactions(client, account_id, Keyword.put(opts, :start_after, cursor))
end)
end
@doc """
Returns one page of statements for a treasury account.
`GET /treasury/{id}/statements`
Accepts a `:document_type` filter in addition to the common list options.
"""
@spec list_statements(client :: Client.t(), account_id :: String.t(), opts :: keyword()) ::
{:ok, Page.t(TreasuryStatement.t())} | {:error, Exception.t()}
def list_statements(%Client{} = client, account_id, opts \\ []) do
with {:ok, body} <- HTTP.get(client, "treasury/#{account_id}/statements", opts) do
{:ok, Page.from_json(body, "statements", &TreasuryStatement.from_json/1)}
end
end
@spec list_statements!(client :: Client.t(), account_id :: String.t(), opts :: keyword()) ::
Page.t(TreasuryStatement.t())
def list_statements!(client, account_id, opts \\ []),
do: Support.bang!(list_statements(client, account_id, opts))
@doc "A lazy, auto-paginating stream of every statement for a treasury account."
@spec stream_statements(client :: Client.t(), account_id :: String.t(), opts :: keyword()) ::
Enumerable.t()
def stream_statements(%Client{} = client, account_id, opts \\ []) do
opts = Keyword.new(opts)
Pagination.stream(fn cursor ->
list_statements(client, account_id, Keyword.put(opts, :start_after, cursor))
end)
end
end