Packages

Cashier is an Elixir library that aims to be an easy to use payment gateway, whilst offering the fault tolerance and scalability benefits of being built on top of Erlang/OTP

Current section

Files

Jump to
cashier lib cashier.ex
Raw

lib/cashier.ex

defmodule Cashier do
use Application
alias Cashier.Pipeline.GatewayProducer
def start(_type, _args),
do: Cashier.Pipeline.PipelineSupervisor.start_link
def authorize(amount, card),
do: authorize(amount, card, default_opts())
def authorize(amount, card, opts),
do: send_event(opts, {:authorize, amount, card})
def capture(id, amount),
do: capture(id, amount, default_opts())
def capture(id, amount, opts),
do: send_event(opts, {:capture, id, amount})
def purchase(amount, card),
do: purchase(amount, card, default_opts())
def purchase(amount, card, opts),
do: send_event(opts, {:purchase, amount, card})
def refund(id),
do: refund(id, default_opts())
def refund(id, opts),
do: send_event(opts, {:refund, id})
def store(card),
do: store(card, default_opts())
def store(card, opts),
do: send_event(opts, {:store, card})
def unstore(id),
do: unstore(id, default_opts())
def unstore(id, opts),
do: send_event(opts, {:unstore, id})
def void(id),
do: void(id, default_opts())
def void(id, opts),
do: send_event(opts, {:void, id})
defp send_event(opts, event) do
opts =
opts
|> merge_default_opts
|> merge_gateway_timeout
GatewayProducer.send_demand({self(), event, opts})
receive do
{:ok, data} ->
data
_ -> # todo: add some proper error handling when there are process issues
IO.puts "something went wrong"
{:error, :need_a_reason}
after
# todo: not sure this is the best approach as it leaves the
# worker process running
opts[:timeout] ->
{:error, :timeout}
end
end
defp merge_default_opts(opts),
do: Keyword.merge(default_opts(), opts)
defp default_opts do
[
gateway: get_default(:gateway),
currency: get_default(:currency)
]
end
defp get_default(key) do
case Application.get_env(:cashier, :cashier)[:defaults] do
nil -> nil
defaults -> defaults[key]
end
end
defp merge_gateway_timeout(opts),
do: Keyword.put(opts, :timeout, gateway_timeout(opts[:gateway]))
defp gateway_timeout(gateway),
do: Application.get_env(:cashier, gateway)[:timeout] || default_timeout()
defp default_timeout,
do: get_default(:timeout) || 5000
end