Current section

Files

Jump to
plaid_elixir lib plaid.ex
Raw

lib/plaid.ex

defmodule Plaid do
@moduledoc """
An HTTP Client for Plaid.
## Configuring
All calls to Plaid require a `ROOT_URI` (production or development), a `CLIENT_ID`
and `SECRET`. These values are configured in the `config.exs` file of your
application.
The environment variables for `PLAID_CLIENT_ID` and `PLAID_SECRET` will be used
if no variables are configured.
```
config :plaid, client_id: "YOUR_CLIENT_ID"
config :plaid, secret: "YOUR_SECRET"
config :plaid, root_uri: "DEV_OR_PROD_URI"
```
"""
alias Plaid.Utilities
use HTTPoison.Base
defmodule MissingSecretError do
defexception message: """
The secret is required for all calls to Plaid. Please configure secret
in your config.exs and environment specific config files.
config :plaid, secret: YOUR_SECRET
If you haven't registered with Plaid for a secret, you can still test
the API with the following test credentials:
config: :plaid, secret: "plaid_good"
"""
end
defmodule MissingClientIdError do
defexception message: """
The client_id is required for all call to Plaid. Please configure client_id
in your config.exs and environment specific config files.
config :plaid, client_id: YOUR_CLIENT_ID
If you haven't registered with Plaid for a client_id, you can still test
the API with the following test credentials:
config: :plaid, client_id: "plaid_test"
"""
end
defmodule MissingRootUriError do
defexception message: """
The root_uri is required to specify the Plaid environment to which you are
making calls, i.e. development or production. Please configure root_uri in
your config.exs file.
config :plaid, root_uri: "https://tartan.plaid.com/" (development)
config :plaid, root_uri: "https://api.plaid.com/" (production)
"""
end
@doc """
Fetches credentials from `config.exs`.
Returns a map or raises if not found.
"""
@spec config_or_env_cred() :: map
def config_or_env_cred() do
require_plaid_credentials()
end
@doc """
Fetches url using the root_uri specified in `config.exs` (dev or prod).
Returns binary.
"""
@spec process_url(binary) :: binary
def process_url(endpoint) do
require_root_uri <> endpoint
end
@doc """
Sets request headers.
"""
def request_headers() do
Map.new
|> Map.put("Content-Type", "application/x-www-form-urlencoded")
end
@doc """
Boiler plate code to make calls to the Plaid API.
Calls `Plaid.make_request_with_cred/6` and passes an empty map as credentials.
For endpoints not requiring authentication.
Arguments
* `method` - request method - `atom` - required
* `endpoint` - request endpoint - `string` - required
* `body` - request body - `map` - optional
* `headers` - request headers - `map` - optional
* `options` - HTTPoison options - `list` - optional
"""
@spec make_request(atom, binary, map, map, list) :: tuple
def make_request(method, endpoint, body \\ %{}, headers \\ %{}, options \\ []) do
make_request_with_cred(method, endpoint, %{}, body, headers, options)
end
@doc """
Boiler plate code to make calls to the Plaid API for endpoints requiring
authentication.
Arguments
* `method` - request method - `atom` - required
* `endpoint` - request endpoint - `string` - required
* `cred` - Plaid credentials - `map` - required
* `body` - request body - `map` - optional
* `headers` - request headers - `map` - optional
* `options` - HTTPoison options - `list` - optional
"""
@spec make_request_with_cred(atom, binary, map, map, map, list) :: tuple
def make_request_with_cred(method, endpoint, cred, body \\ %{}, headers \\ %{}, options \\ []) do
rb = Utilities.encode_params(body, cred)
rh = request_headers() |> Map.merge(headers) |> Map.to_list
options = httpoison_request_options() ++ options
case request(method, endpoint, rb, rh, options) do
{:ok, response} ->
response
{:error, httpoison_error} ->
{:error, httpoison_error}
end
end
defp require_plaid_credentials() do
client_id = Application.get_env(:plaid, :client_id, System.get_env("PLAID_CLIENT_ID")) || :not_found
secret = Application.get_env(:plaid, :secret, System.get_env("PLAID_SECRET")) || :not_found
case {client_id, secret} do
{:not_found, _} ->
raise MissingClientIdError
{_, :not_found} ->
raise MissingSecretError
{client_id, secret} ->
%{client_id: client_id, secret: secret}
end
end
defp require_root_uri() do
case Application.get_env(:plaid, :root_uri) || :not_found do
:not_found ->
raise MissingRootUriError
value ->
value
end
end
defp httpoison_request_options() do
Application.get_env(:plaid, :httpoison_options, [])
end
end