defmodule Unit do @moduledoc """ `Unit` — Production-grade Elixir client for the [Unit embedded banking API](https://www.unit.co/docs/api/). ## Overview Full Unit API coverage across all 24 resource domains: | Domain | Module | |-------------------------|-------------------------------------| | Applications (KYC/KYB) | `Unit.API.Applications` | | Customers | `Unit.API.Customers` | | Accounts | `Unit.API.Accounts` | | Cards | `Unit.API.Cards` | | Authorizations | `Unit.API.Authorizations` | | Payments | `Unit.API.Payments` | | Recurring Payments | `Unit.API.RecurringPayments` | | Transactions | `Unit.API.Transactions` | | Counterparties | `Unit.API.Counterparties` | | Repayments | `Unit.API.Repayments` | | Recurring Repayments | `Unit.API.RecurringRepayments` | | Check Deposits | `Unit.API.CheckDeposits` | | Check Payments | `Unit.API.CheckPayments` | | Stop Payments | `Unit.API.StopPayments` | | Chargebacks | `Unit.API.Chargebacks` | | Disputes | `Unit.API.Disputes` | | Rewards | `Unit.API.Rewards` | | Fees | `Unit.API.Fees` | | Statements | `Unit.API.Statements` | | Tax Forms | `Unit.API.TaxForms` | | Webhooks | `Unit.API.Webhooks` | | Events | `Unit.API.Events` | | Tokens | `Unit.API.Tokens` | | Institutions | `Unit.API.Institutions` | | ATM Locations | `Unit.API.AtmLocations` | | Account End-of-Day | `Unit.API.AccountEndOfDay` | | Account Limit Overrides | `Unit.API.AccountLimitOverrides` | | Sandbox | `Unit.API.Sandbox` | ## Configuration # config/runtime.exs config :unit, api_token: System.get_env("UNIT_API_TOKEN"), environment: :sandbox # :sandbox | :production ## Quick start # 1. Onboard an individual customer {:ok, app} = Unit.API.Applications.create_individual(%{ full_name: %{first: "Jane", last: "Doe"}, ssn: "000000002", date_of_birth: ~D[1990-01-15], address: %{street: "123 Main St", city: "SF", state: "CA", postal_code: "94105", country: "US"}, email: "jane@example.com", phone: %{country_code: "1", number: "5555550100"}, ip: "127.0.0.1" }) # 2. Open accounts {:ok, account} = Unit.API.Accounts.create_deposit(app.customer_id, "checking") {:ok, credit} = Unit.API.Accounts.create_credit(app.customer_id, "basic-credit") # 3. Issue a virtual debit card {:ok, card} = Unit.API.Cards.create_individual_virtual_debit(%{ customer_id: app.customer_id, account_id: account.id }) # 4. Send money {:ok, payment} = Unit.API.Payments.create_ach(%{ account_id: account.id, amount: 10_000, direction: "Credit", description: "Payroll", counterparty: %{routing_number: "812345678", account_number: "1000000002", account_type: "Checking", name: "Jane Doe"} }) # 5. Set up recurring payments {:ok, _} = Unit.API.RecurringPayments.create_credit_ach(%{ account_id: account.id, amount: 5_000, description: "Monthly savings transfer", counterparty_id: counterparty.id, schedule: %{interval: "Monthly", day_of_month: 1, start_time: ~D[2024-02-01]} }) # 6. Reward the customer {:ok, _} = Unit.API.Rewards.create(%{ amount: 500, description: "Sign-up bonus", receiving_account_id: account.id, funding_account_id: revenue_account_id }) ## Error handling All functions return `{:ok, result}` or `{:error, %Unit.Error{}}`: case Unit.API.Payments.create_ach(params) do {:ok, payment} -> Logger.info("Payment created: \#{payment.id}") {:error, %Unit.Error{type: :validation_error, errors: errors}} -> Logger.warning("Validation: \#{inspect(errors)}") {:error, %Unit.Error{type: :auth_error}} -> Logger.error("Invalid token") {:error, %Unit.Error{type: :network_error}} -> Logger.error("Network failure — will retry automatically") end ## Per-request overrides # Use a customer-scoped token Unit.API.Accounts.list(api_token: customer_token) # Point to a custom base URL Unit.API.Sandbox.receive_ach(params, base_url: "http://localhost:8080") ## Telemetry :telemetry.attach("unit-log", [:unit, :request, :stop], fn _evt, %{duration: d}, %{resource: r, action: a, status: s}, _ -> Logger.info("[Unit] \#{r}.\#{a} → \#{s} (\#{div(d, 1_000_000)}ms)") end, nil) """ # --------------------------------------------------------------------------- # Applications # --------------------------------------------------------------------------- defdelegate create_individual_application(params, opts \\ []), to: Unit.API.Applications, as: :create_individual defdelegate create_business_application(params, opts \\ []), to: Unit.API.Applications, as: :create_business defdelegate get_application(id, opts \\ []), to: Unit.API.Applications, as: :get defdelegate list_applications(opts \\ []), to: Unit.API.Applications, as: :list # --------------------------------------------------------------------------- # Customers # --------------------------------------------------------------------------- defdelegate get_customer(id, opts \\ []), to: Unit.API.Customers, as: :get defdelegate list_customers(opts \\ []), to: Unit.API.Customers, as: :list defdelegate update_customer(id, params, opts \\ []), to: Unit.API.Customers, as: :update # --------------------------------------------------------------------------- # Accounts # --------------------------------------------------------------------------- defdelegate create_deposit_account(customer_id, deposit_product, params \\ [], opts \\ []), to: Unit.API.Accounts, as: :create_deposit defdelegate create_credit_account(customer_id, credit_terms, params \\ [], opts \\ []), to: Unit.API.Accounts, as: :create_credit defdelegate get_account(id, opts \\ []), to: Unit.API.Accounts, as: :get defdelegate list_accounts(opts \\ []), to: Unit.API.Accounts, as: :list defdelegate close_account(id, params, opts \\ []), to: Unit.API.Accounts, as: :close defdelegate freeze_account(id, params \\ [], opts \\ []), to: Unit.API.Accounts, as: :freeze defdelegate unfreeze_account(id, opts \\ []), to: Unit.API.Accounts, as: :unfreeze # --------------------------------------------------------------------------- # Cards # --------------------------------------------------------------------------- defdelegate create_virtual_debit_card(params, opts \\ []), to: Unit.API.Cards, as: :create_individual_virtual_debit defdelegate get_card(id, opts \\ []), to: Unit.API.Cards, as: :get defdelegate list_cards(opts \\ []), to: Unit.API.Cards, as: :list defdelegate freeze_card(id, opts \\ []), to: Unit.API.Cards, as: :freeze defdelegate unfreeze_card(id, opts \\ []), to: Unit.API.Cards, as: :unfreeze defdelegate replace_card(id, params \\ %{}, opts \\ []), to: Unit.API.Cards, as: :replace # --------------------------------------------------------------------------- # Authorizations # --------------------------------------------------------------------------- defdelegate get_authorization(id, opts \\ []), to: Unit.API.Authorizations, as: :get defdelegate list_authorizations(opts \\ []), to: Unit.API.Authorizations, as: :list # --------------------------------------------------------------------------- # Payments # --------------------------------------------------------------------------- defdelegate create_ach_payment(params, opts \\ []), to: Unit.API.Payments, as: :create_ach defdelegate create_wire_payment(params, opts \\ []), to: Unit.API.Payments, as: :create_wire defdelegate create_book_payment(params, opts \\ []), to: Unit.API.Payments, as: :create_book defdelegate create_push_to_card_payment(params, opts \\ []), to: Unit.API.Payments, as: :create_push_to_card defdelegate get_payment(id, opts \\ []), to: Unit.API.Payments, as: :get defdelegate list_payments(opts \\ []), to: Unit.API.Payments, as: :list defdelegate cancel_payment(id, opts \\ []), to: Unit.API.Payments, as: :cancel # --------------------------------------------------------------------------- # Recurring Payments # --------------------------------------------------------------------------- defdelegate create_recurring_ach(params, opts \\ []), to: Unit.API.RecurringPayments, as: :create_credit_ach defdelegate list_recurring_payments(opts \\ []), to: Unit.API.RecurringPayments, as: :list # --------------------------------------------------------------------------- # Transactions # --------------------------------------------------------------------------- defdelegate list_transactions(opts \\ []), to: Unit.API.Transactions, as: :list defdelegate get_transaction(account_id, transaction_id, opts \\ []), to: Unit.API.Transactions, as: :get # --------------------------------------------------------------------------- # Rewards # --------------------------------------------------------------------------- defdelegate create_reward(params, opts \\ []), to: Unit.API.Rewards, as: :create defdelegate list_rewards(opts \\ []), to: Unit.API.Rewards, as: :list # --------------------------------------------------------------------------- # Counterparties # --------------------------------------------------------------------------- defdelegate create_counterparty(params, opts \\ []), to: Unit.API.Counterparties, as: :create defdelegate list_counterparties(opts \\ []), to: Unit.API.Counterparties, as: :list # --------------------------------------------------------------------------- # Institutions # --------------------------------------------------------------------------- defdelegate get_institution(routing_number, opts \\ []), to: Unit.API.Institutions, as: :get end