defmodule Plaid.Institutions do @moduledoc """ [Plaid Institutions API](https://plaid.com/docs/api/institutions/) calls and schema. """ defmodule GetResponse do @moduledoc """ [Plaid API /institutions/get response schema.](https://plaid.com/docs/api/institutions/#institutionsget) """ @behaviour Plaid.Castable alias Plaid.Castable alias Plaid.Institution @type t :: %__MODULE__{ institutions: [Institution.t()], total: integer(), request_id: String.t() } defstruct [ :institutions, :total, :request_id ] @impl true def cast(generic_map) do %__MODULE__{ institutions: Castable.cast_list(Institution, generic_map["institutions"]), total: generic_map["total"], request_id: generic_map["request_id"] } end end @doc """ Get information about Plaid institutions. Does a `POST /institutions/get` call to list the supported Plaid institutions with their details. ## Params * `:count` - The total number of Institutions to return. * `:offset` - The number of Institutions to skip. * `:country_codes` - Array of country codes the institution supports. ## Options * `:products` - Filter based on which products they support. * `:routing_numbers` - Filter based on routing numbers. * `:oauth` - Filter institutions with or without OAuth login flows. * `:include_optional_metadata` - When true, return the institution's homepage URL, logo and primary brand color. ## Examples Institutions.get(%{count: 25, offset: 0, country_codes: ["CA", "GB]}, client_id: "123", secret: "abc") {:ok, %Institutions.GetResponse{}} """ @spec get(params, options, Plaid.config()) :: {:ok, GetResponse.t()} | {:error, Plaid.Error.t()} when params: %{ required(:count) => integer(), required(:offset) => integer(), required(:country_codes) => [String.t()] }, options: %{ optional(:products) => [String.t()], optional(:routing_numbers) => [String.t()], optional(:oauth) => boolean(), optional(:include_optional_metadata) => boolean() } def get(params, options \\ %{}, config) do options_payload = Map.take(options, [:products, :routing_numbers, :oauth, :include_optional_metadata]) payload = params |> Map.take([:count, :offset, :country_codes]) |> Map.merge(%{options: options_payload}) Plaid.Client.call( "/institutions/get", payload, GetResponse, config ) end defmodule GetByIdResponse do @moduledoc """ [Plaid API /institutions/get_by_id response schema.](https://plaid.com/docs/api/institutions/#institutionsget_by_id) """ @behaviour Plaid.Castable alias Plaid.Castable alias Plaid.Institution @type t :: %__MODULE__{ institution: Institution.t(), request_id: String.t() } defstruct [ :institution, :request_id ] @impl true def cast(generic_map) do %__MODULE__{ institution: Castable.cast(Institution, generic_map["institution"]), request_id: generic_map["request_id"] } end end @doc """ Get information about a Plaid institution. Does a `POST /institutions/get_by_id` call to retrieve a Plaid institution by it's ID. ## Params * `institution_id` - The ID of the institution to get details about. * `country_codes` - Array of country codes the institution supports. ## Options * `:include_optional_metadata` - When true, return the institution's homepage URL, logo and primary brand color. * `:include_status` - When true, the response will include status information about the institution. ## Examples Institutions.get_by_id("ins_1", ["CA", "GB], client_id: "123", secret: "abc") {:ok, %Institutions.GetByIdResponse{}} """ @spec get_by_id(String.t(), [String.t()], options, Plaid.config()) :: {:ok, GetByIdResponse.t()} | {:error, Plaid.Error.t()} when options: %{ optional(:products) => [String.t()], optional(:routing_numbers) => [String.t()], optional(:oauth) => boolean(), optional(:include_optional_metadata) => boolean() } def get_by_id(institution_id, country_codes, options \\ %{}, config) do options_payload = Map.take(options, [:include_optional_metadata, :include_status]) payload = %{} |> Map.put(:institution_id, institution_id) |> Map.put(:country_codes, country_codes) |> Map.merge(%{options: options_payload}) Plaid.Client.call( "/institutions/get_by_id", payload, GetByIdResponse, config ) end defmodule SearchResponse do @moduledoc """ [Plaid API /institutions/search response schema.](https://plaid.com/docs/api/institutions/#institutionssearch) """ @behaviour Plaid.Castable alias Plaid.Castable alias Plaid.Institution @type t :: %__MODULE__{ institutions: [Institution.t()], request_id: String.t() } defstruct [ :institutions, :request_id ] @impl true def cast(generic_map) do %__MODULE__{ institutions: Castable.cast_list(Institution, generic_map["institutions"]), request_id: generic_map["request_id"] } end end @doc """ Get information about all Plaid institutions matching the search params. Does a `POST /institutions/search` call to list the supported Plaid institutions with their details based on your search query. ## Params * `:query` - The search query. Institutions with names matching the query are returned * `:products` - Filter the Institutions based on whether they support listed products. * `:country_codes` - Array of country codes the institution supports. ## Options * `:include_optional_metadata` - When true, return the institution's homepage URL, logo and primary brand color. * `:oauth` - Filter institutions with or without OAuth login flows. * `:account_filter` - Object allowing account type -> sub-type filtering. > See [Account Type Schema](https://plaid.com/docs/api/accounts/#account-type-schema) for more details on the `account_filter` option. ## Examples Institutions.search(%{query: "Ally", products: ["auth"], country_codes: ["US"]}, client_id: "123", secret: "abc") {:ok, %Institutions.SearchResponse{}} """ @spec search(params, options, Plaid.config()) :: {:ok, SearchResponse.t()} | {:error, Plaid.Error.t()} when params: %{ required(:query) => String.t(), required(:products) => [String.t()], required(:country_codes) => [String.t()] }, options: %{ optional(:include_optional_metadata) => boolean(), optional(:oauth) => boolean(), optional(:account_filter) => map() } def search(params, options \\ %{}, config) do options_payload = Map.take(options, [:oauth, :include_optional_metadata, :account_filter]) payload = params |> Map.take([:query, :products, :country_codes]) |> Map.merge(%{options: options_payload}) Plaid.Client.call( "/institutions/search", payload, SearchResponse, config ) end end