Skip to content

Commit

Permalink
Add Stripe.Account
Browse files Browse the repository at this point in the history
Fix usage of lists for hackney opts

Add retrieving your own account
  • Loading branch information
joshsmith committed Nov 11, 2016
1 parent f2ccdf8 commit cabec08
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 88 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Expand Up @@ -2,5 +2,5 @@
/deps
erl_crash.dump
*.ez
config
config/config.secret.exs
/doc
5 changes: 5 additions & 0 deletions config/config.exs
@@ -0,0 +1,5 @@
use Mix.Config

if File.exists?("config/config.secret.exs") do
import_config "config.secret.exs"
end
19 changes: 10 additions & 9 deletions lib/stripe.ex
Expand Up @@ -5,7 +5,7 @@ defmodule Stripe do
## Configuration
### API Key
You need to set your API key in your application configuration. Typically
this is done in `config/config.exs` or a similar file. For example:
Expand All @@ -18,7 +18,7 @@ defmodule Stripe do
config :stripity_stripe, api_key: System.get_env("STRIPE_API_KEY")
### HTTP Connection Pool
Stripity Stripe is set up to use an HTTP connection pool by default. This
means that it will reuse already opened HTTP connections in order to
minimize the overhead of establishing connections. Two configuration
Expand Down Expand Up @@ -203,15 +203,15 @@ defmodule Stripe do
Map.put(existing_headers, "Stripe-Account", account_id)
end

@spec add_default_options(Keyword.t) :: Keyword.t
@spec add_default_options(list) :: list
defp add_default_options(opts) do
Keyword.merge(opts, [with_body: opts])
[ :with_body | opts ]
end

@spec add_pool_option(Keyword.t) :: Keyword.t
@spec add_pool_option(list) :: list
defp add_pool_option(opts) do
if use_pool?() do
Keyword.put(opts, :pool, @pool_name)
[ {:pool, @pool_name} | opts ]
else
opts
end
Expand All @@ -229,11 +229,12 @@ defmodule Stripe do
request(:get, "/customers", %{}, %{}, connect_account: "acc_134151")
"""
@spec request(method, String.t, map, headers, Keyword.t) :: {:ok, map} | {:error, Exception.t}
@spec request(method, String.t, map, headers, list) :: {:ok, map} | {:error, Exception.t}
def request(method, endpoint, body, headers, opts) do
{connect_account_id, opts} = Keyword.pop(opts, :connection_account)
{connect_account_id, opts} = Keyword.pop(opts, :connect_account)

req_url = get_base_url() <> endpoint
base_url = get_base_url()
req_url = base_url <> endpoint
req_body = Stripe.URI.encode_query(body)
req_headers =
headers
Expand Down
78 changes: 78 additions & 0 deletions lib/stripe/account.ex
@@ -0,0 +1,78 @@
defmodule Stripe.Account do
@moduledoc """
Work with Stripe account objects.
You can:
- Retrieve your own account
- Retrieve an account with a specified `id`
This module does not yet support managed accounts.
Stripe API reference: https://stripe.com/docs/api#account
"""

alias Stripe.Util

@type t :: %__MODULE__{}

defstruct [
:id, :business_name, :business_primary_color, :business_url,
:charges_enabled, :country, :default_currency, :details_submitted,
:display_name, :email, :managed, :metadata, :statement_descriptor,
:support_email, :support_phone, :support_url, :timezone,
:transfers_enabled
]

@singular_endpoint "account"
@plural_endpoint "accounts"

@doc """
Retrieve your own account without options.
"""
@spec retrieve :: {:ok, t} | {:error, Exception.t}
def retrieve, do: retrieve([])

@doc """
Retrieve your own account with options.
"""
@spec retrieve(Keyword.t) :: {:ok, t} | {:error, Exception.t}
def retrieve(opts), do: do_retrieve(@singular_endpoint, opts)

@doc """
Retrieve an account with a specified `id`.
"""
@spec retrieve(binary, Keyword.t) :: {:ok, t} | {:error, Exception.t}
def retrieve(id, opts \\ []), do: do_retrieve(@plural_endpoint <> "/" <> id, opts)

@spec do_retrieve(String.t, Keyword.t) :: {:ok, t} | {:error, Exception.t}
defp do_retrieve(endpoint, opts) do
case Stripe.request(:get, endpoint, %{}, %{}, opts) do
{:ok, result} -> {:ok, to_struct(result)}
{:error, error} -> {:error, error}
end
end

defp to_struct(response) do
%__MODULE__{
id: Map.get(response, "id"),
business_name: Map.get(response, "business_name"),
business_primary_color: Map.get(response, "business_primary_color"),
business_url: Map.get(response, "business_url"),
charges_enabled: Map.get(response, "charges_enabled"),
country: Map.get(response, "country"),
default_currency: Map.get(response, "default_currency"),
details_submitted: Map.get(response, "details_submitted"),
display_name: Map.get(response, "display_name"),
email: Map.get(response, "email"),
managed: Map.get(response, "managed"),
metadata: Map.get(response, "metadata"),
statement_descriptor: Map.get(response, "statement_descriptor"),
support_email: Map.get(response, "support_email"),
support_phone: Map.get(response, "support_phone"),
support_url: Map.get(response, "support_url"),
timezone: Map.get(response, "timezone"),
transfers_enabled: Map.get(response, "transfers_enabled")
}
end
end
1 change: 0 additions & 1 deletion lib/stripe/connect.ex
Expand Up @@ -19,7 +19,6 @@ defmodule Stripe.Connect do
crsf token to be sent to stripe, which they send you back at the end of the workflow to further secure the interaction. Make sure you verify this token yourself on reception of the workflow callback.
"""
def generate_button_url(csrf_token) do
client_id = Stripe.config_or_env_platform_client_id
url = base_url() <> "oauth/authorize?response_type=code"
url = url <> "&scope=read_write"
url = url <> "&client_id=#{Stripe.config_or_env_platform_client_id}"
Expand Down
66 changes: 9 additions & 57 deletions lib/stripe/util.ex
@@ -1,4 +1,13 @@
defmodule Stripe.Util do

@spec get_date(map, atom | String.t) :: DateTime.t | nil
def get_date(m, k) do
case Map.get(m, k) do
nil -> nil
ts -> DateTime.from_unix!(ts)
end
end

def datetime_from_timestamp(ts) when is_binary ts do
ts = case Integer.parse ts do
:error -> 0
Expand All @@ -23,61 +32,4 @@ defmodule Stripe.Util do
def string_map_to_atoms(string_key_map) do
for {key, val} <- string_key_map, into: %{}, do: {String.to_atom(key), val}
end

def handle_stripe_response(res) do
cond do
res["error"] -> {:error, res}
res["data"] -> {:ok, Enum.map(res["data"], &Stripe.Util.string_map_to_atoms &1)}
true -> {:ok, Stripe.Util.string_map_to_atoms res}
end
end

# returns the full response in {:ok, response}
# this is useful to access top-level properties
def handle_stripe_full_response(res) do
cond do
res["error"] -> {:error, res}
true -> {:ok, Stripe.Util.string_map_to_atoms res}
end
end

def list_raw( endpoint, limit \\ 10, starting_after \\ "") do
list_raw endpoint, Stripe.config_or_env_key, limit, starting_after
end

def list_raw( endpoint, key, limit, starting_after) do
q = "#{endpoint}?limit=#{limit}"

q =
if String.length(starting_after) > 0 do
q <> "&starting_after=#{starting_after}"
else
q
end

Stripe.make_request_with_key(:get, q, key )
|> Stripe.Util.handle_stripe_full_response
end

def list( endpoint, key, starting_after, limit) do
list_raw endpoint, key, limit, starting_after
end

def list( endpoint, starting_after \\ "", limit \\ 10) do
list endpoint, Stripe.config_or_env_key, starting_after, limit
end

# most stripe listing endpoints allow the total count to be included without any results
def count(endpoint) do
count endpoint, Stripe.config_or_env_key
end

def count(endpoint, key) do
case Stripe.make_request_with_key(:get, "#{endpoint}?include[]=total_count&limit=0", key)
|> Stripe.Util.handle_stripe_full_response do
{:ok, res} ->
{:ok, res[:total_count]}
{:error, err} -> raise err
end
end
end
37 changes: 17 additions & 20 deletions mix.exs
Expand Up @@ -4,47 +4,44 @@ defmodule Stripe.Mixfile do
def project do
[
app: :stripity_stripe,
version: "2.0.0",
deps: deps,
description: description(),
package: package(),
elixir: "~> 1.1",
test_coverage: [tool: ExCoveralls],
package: package(),
preferred_cli_env: [
"coveralls": :test,
"coveralls.detail": :test,
"coveralls.post": :test,
"coveralls.html": :test
],
deps: deps
test_coverage: [tool: ExCoveralls],
version: "2.0.0"
]
end

# Configuration for the OTP application
def application do
[
mod: {Stripe, []},
applications: apps(Mix.env),
env: env(),
applications: apps(Mix.env)
mod: {Stripe, []}
]
end

defp env() do
[
stripity_stripe: [
api_base_url: "https://api.stripe.com/v1/",
use_connection_pool: true,
pool_options: [
timeout: 5_000,
max_connections: 10
]
]
api_base_url: "https://api.stripe.com/v1/",
pool_options: [
timeout: 5_000,
max_connections: 10
],
use_connection_pool: true
]
end

defp apps(:test), do: [:bypass | apps()]
defp apps(_), do: apps()

defp apps(), do: [:hackney, :poison, :logger]
defp apps(), do: [:hackney, :logger, :poison]

defp deps do
[
Expand All @@ -60,18 +57,18 @@ defmodule Stripe.Mixfile do

defp description do
"""
A Stripe Library for Elixir.
A Stripe client for Elixir.
"""
end

defp package do
[
files: ["lib", "mix.exs", "README*", "LICENSE*"],
maintainers: ["Dan Matthews", "Josh Smith"],
files: ["lib", "LICENSE*", "mix.exs", "README*"],
licenses: ["New BSD"],
links: %{
"GitHub" => "https://github.com/code-corps/stripity-stripe"
}
},
maintainers: ["Dan Matthews", "Josh Smith"]
]
end
end

0 comments on commit cabec08

Please sign in to comment.