defmodule Plaid.Item do
@moduledoc """
Functions for Plaid `item` endpoint.
"""
alias Plaid.Client.Request
alias Plaid.Client
@derive Jason.Encoder
defstruct available_products: [],
billed_products: [],
error: nil,
institution_id: nil,
item_id: nil,
webhook: nil,
consent_expiration_time: nil,
request_id: nil,
status: nil
@type t :: %__MODULE__{
available_products: [String.t()],
billed_products: [String.t()],
error: String.t() | nil,
institution_id: String.t(),
item_id: String.t(),
webhook: String.t(),
consent_expiration_time: String.t(),
request_id: String.t(),
status: Plaid.Item.Status.t()
}
@type params :: %{required(atom) => term}
@type config :: %{required(atom) => String.t() | keyword}
@type error :: {:error, Plaid.Error.t() | any()} | no_return
defmodule Status do
@moduledoc """
Plaid Item Status data structure.
"""
@derive Jason.Encoder
defstruct investments: nil,
transactions: nil,
last_webhook: nil
@type t :: %__MODULE__{
investments: Plaid.Item.Status.Investments.t(),
transactions: Plaid.Item.Status.Transactions.t(),
last_webhook: Plaid.Item.Status.LastWebhook.t()
}
defmodule Investments do
@moduledoc """
Plaid Item Status Investments data structure.
"""
@derive Jason.Encoder
defstruct last_successful_update: nil, last_failed_update: nil
@type t :: %__MODULE__{last_successful_update: String.t(), last_failed_update: String.t()}
end
defmodule Transactions do
@moduledoc """
Plaid Item Status Transactions data structure.
"""
@derive Jason.Encoder
defstruct last_successful_update: nil, last_failed_update: nil
@type t :: %__MODULE__{last_successful_update: String.t(), last_failed_update: String.t()}
end
defmodule LastWebhook do
@moduledoc """
Plaid Item Status LastWebhook data structure.
"""
@derive Jason.Encoder
defstruct sent_at: nil, code_sent: nil
@type t :: %__MODULE__{sent_at: String.t(), code_sent: String.t()}
end
end
@doc """
Gets an Item.
Parameters
```
%{access_token: "access-env-identifier"}
```
"""
@spec get(params, config) :: {:ok, Plaid.Item.t()} | error
def get(params, config \\ %{}) do
mapper = fn %{"item" => item, "request_id" => r, "status" => s} ->
map_item(Map.merge(item, %{"request_id" => r, "status" => s}))
end
request_operation("item/get", params, config, mapper)
end
defp request_operation(endpoint, params, config, mapper) do
c = config[:client] || Plaid
Request
|> struct(method: :post, endpoint: endpoint, body: params)
|> Request.add_metadata(config)
|> c.send_request(Client.new(config))
|> c.handle_response(mapper)
end
defp map_item(body) do
Poison.Decode.transform(
body,
%{
as: %Plaid.Item{
status: %Plaid.Item.Status{
investments: %Plaid.Item.Status.Investments{},
transactions: %Plaid.Item.Status.Transactions{},
last_webhook: %Plaid.Item.Status.LastWebhook{}
}
}
}
)
end
@doc """
Exchanges a public token for an access token and item id.
Parameters
```
%{public_token: "public-env-identifier"}
```
Response
```
{:ok, %{access_token: "access-env-identifier", item_id: "some-id", request_id: "f24wfg"}}
```
"""
@spec exchange_public_token(params, config) :: {:ok, map} | error
def exchange_public_token(params, config \\ %{}) do
mapper = fn %{"access_token" => t, "item_id" => i, "request_id" => r} ->
%{access_token: t, item_id: i, request_id: r}
end
request_operation("item/public_token/exchange", params, config, mapper)
end
@doc """
Creates a public token. To be used to put Plaid Link into update mode.
Parameters
```
%{access_token: "access-env-identifier"}
```
Response
```
{:ok, %{public_token: "access-env-identifier", expiration: 3600, request_id: "kg414f"}}
```
"""
@spec create_public_token(params, config) :: {:ok, map} | error
def create_public_token(params, config \\ %{}) do
mapper = fn %{"public_token" => t, "expiration" => e, "request_id" => r} ->
%{public_token: t, expiration: e, request_id: r}
end
request_operation("item/public_token/create", params, config, mapper)
end
@doc """
Updates an Item's webhook.
Parameters
```
%{access_token: "access-env-identifier", webhook: "http://mywebsite/api"}
```
"""
@spec update_webhook(params, config) :: {:ok, Plaid.Item.t()} | error
def update_webhook(params, config \\ %{}) do
mapper = fn %{"item" => item, "request_id" => r} ->
map_item(Map.merge(item, %{"request_id" => r}))
end
request_operation("item/webhook/update", params, config, mapper)
end
@doc """
Invalidates access token and returns a new one.
Parameters
```
%{access_token: "access-env-identifier"}
```
Response
```
{:ok, %{new_access_token: "access-env-identifier", request_id: "gag8fs"}}
```
"""
@spec rotate_access_token(params, config) :: {:ok, map} | error
def rotate_access_token(params, config \\ %{}) do
mapper = fn %{"new_access_token" => t, "request_id" => r} ->
%{new_access_token: t, request_id: r}
end
request_operation("item/access_token/invalidate", params, config, mapper)
end
@doc """
Updates a V1 access token to V2.
Parameters
```
%{access_token_v1: "test_wells"}
```
Response
```
{:ok, %{access_token: "access-env-identifier", item_id: "some-id", request_id: "f24wfg"}}
```
"""
@spec update_version_access_token(params, config) :: {:ok, map} | error
def update_version_access_token(params, config \\ %{}) do
mapper = fn %{"access_token" => t, "request_id" => r} ->
%{access_token: t, request_id: r}
end
request_operation("item/access_token/update_version", params, config, mapper)
end
@doc """
Removes an Item.
Parameters
```
%{access_token: "access-env-identifier"}
```
Response
```
{:ok, %{request_id: "[Unique request ID]"}}
```
"""
@spec remove(params, config) :: {:ok, map} | error
def remove(params, config \\ %{}) do
mapper = fn %{"request_id" => r} ->
%{request_id: r}
end
request_operation("item/remove", params, config, mapper)
end
@doc """
[Creates a processor token](https://plaid.com/docs/api/processors)
used to integrate with services external to Plaid.
Parameters
```
%{
access_token: "access-env-identifier",
account_id: "plaid-account-id",
processor: "dwolla"
}
```
Response
```
{:ok, %{processor_token: "some-token", request_id: "k522f2"}}
```
"""
@spec create_processor_token(params, config) :: {:ok, map} | error
def create_processor_token(params, config) do
mapper = fn %{"processor_token" => t, "request_id" => r} ->
%{processor_token: t, request_id: r}
end
request_operation("processor/token/create", params, config, mapper)
end
@doc """
[Creates a stripe bank account token](https://stripe.com/docs/ach)
used to create an authenticated funding source with Stripe.
Parameters
```
%{access_token: "access-env-identifier", account_id: "plaid-account-id"}
```
Response
```
{:ok, %{stripe_bank_account_token: "btok_Kb62HbBqrrvdf8pBsAdt", request_id: "[Unique request ID]"}}
```
"""
@spec create_stripe_bank_account_token(params, config) :: {:ok, map} | error
def create_stripe_bank_account_token(params, config \\ %{}) do
mapper = fn %{"stripe_bank_account_token" => t, "request_id" => r} ->
%{stripe_bank_account_token: t, request_id: r}
end
request_operation("processor/stripe/bank_account_token/create", params, config, mapper)
end
end