defmodule Dwolla.Transfer do
@moduledoc """
Functions for `transfers` endpoint.
"""
alias Dwolla.Utils
defstruct id: nil, created: nil, status: nil, amount: nil, metadata: nil,
source_resource: nil, source_resource_id: nil,
source_funding_source_id: nil, dest_resource: nil,
dest_resource_id: nil, can_cancel: false
@type t :: %__MODULE__{id: String.t,
created: String.t,
status: String.t, # "pending" | "processed" | "cancelled" | "failed" | "reclaimed"
amount: Dwolla.Transfer.Amount.t,
metadata: Dwolla.Transfer.Metadata.t,
source_resource: String.t,
source_resource_id: String.t,
source_funding_source_id: String.t,
dest_resource: String.t,
dest_resource_id: String.t,
can_cancel: boolean
}
@type token :: String.t
@type id :: String.t
@type params :: %{required(atom) => any}
@type error :: HTTPoison.Error.t | Dwolla.Errors.t | tuple
@type location :: %{id: String.t}
@endpoint "transfers"
defmodule Amount do
@moduledoc """
Dwolla Transfer Amount data structure.
"""
defstruct value: nil, currency: nil
@type t :: %__MODULE__{value: String.t, currency: String.t}
end
defmodule Metadata do
@moduledoc """
Dwolla Transfer Metatdata data structure.
"""
defstruct vendor: nil, origin_trans_id: nil, title: nil, note: nil
@type t :: %__MODULE__{vendor: String.t,
origin_trans_id: String.t,
title: String.t,
note: String.t
}
end
defmodule Failure do
@moduledoc """
Dwolla Transfer Failure data structure.
"""
defstruct code: nil, description: nil
@type t :: %__MODULE__{code: String.t, description: String.t}
end
@doc """
Initiates a transfer.
The parameters are verbose because of the many options available to the user
for setting the source and destination of the funds in the `href` field.
Parameters
```
%{
_links: %{
source: %{
href: "https://api-sandbox.dwolla.com/funding-sources/..."
},
destination: %{
href: "https://api-sandbox.dwolla.com/funding-sources/..."
}
},
amount: %{
value: 100.00,
currency: "USD"
},
metadata: %{
vendor: "Acme Inc.",
note: "Invoice #12314"
}
}
```
"""
@spec initiate(token, params, any | nil) :: {:ok, location} | {:error, error}
def initiate(token, params, idempotency_key \\ nil) do
headers = Utils.idempotency_header(idempotency_key || params)
Dwolla.make_request_with_token(:post, @endpoint, token, params, headers)
|> Utils.handle_resp(:transfer)
end
@doc """
Gets a transfer by id.
"""
@spec get(token, id) :: {:ok, Dwolla.Transfer.t} | {:error, error}
def get(token, id) do
endpoint = @endpoint <> "/#{id}"
Dwolla.make_request_with_token(:get, endpoint, token)
|> Utils.handle_resp(:transfer)
end
@doc """
Gets reason for a transfer's failure.
"""
@spec get_transfer_failure_reason(token, id) :: {:ok, Dwolla.Transfer.Failure} | {:error, error}
def get_transfer_failure_reason(token, id) do
endpoint = @endpoint <> "/#{id}/failure"
Dwolla.make_request_with_token(:get, endpoint, token)
|> Utils.handle_resp(:failure)
end
@doc """
Cancels a transfer.
"""
@spec cancel(token, id) :: {:ok, Dwolla.Transfer.t} | {:error, error}
def cancel(token, id) do
endpoint = @endpoint <> "/#{id}"
params = %{status: "cancelled"}
headers = Utils.idempotency_header(params)
Dwolla.make_request_with_token(:post, endpoint, token, params, headers)
|> Utils.handle_resp(:transfer)
end
end