Skip to content

Commit

Permalink
Cleanup formatting & error handling in various stripe services
Browse files Browse the repository at this point in the history
  • Loading branch information
begedin committed Jan 12, 2017
1 parent 6d29b42 commit dff0b26
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 70 deletions.
4 changes: 3 additions & 1 deletion lib/code_corps/stripe_service/stripe_connect_account.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ defmodule CodeCorps.StripeService.StripeConnectAccountService do
{:ok, params} <- StripeConnectAccountAdapter.to_params(account, attributes)
do
%StripeConnectAccount{} |> StripeConnectAccount.create_changeset(params) |> Repo.insert
else
failure -> failure
end
end

Expand All @@ -40,8 +42,8 @@ defmodule CodeCorps.StripeService.StripeConnectAccountService do
do
local_account |> StripeConnectAccount.webhook_update_changeset(params) |> Repo.update
else
# Not found locally
nil -> {:error, :not_found}
failure -> failure
end
end
end
9 changes: 3 additions & 6 deletions lib/code_corps/stripe_service/stripe_connect_card.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ defmodule CodeCorps.StripeService.StripeConnectCardService do

def find_or_create(%StripePlatformCard{} = platform_card, %StripeConnectCustomer{} = connect_customer, %StripePlatformCustomer{} = platform_customer, %StripeConnectAccount{} = connect_account) do
case get_from_db(connect_account.id, platform_card.id) do
%StripeConnectCard{} = existing_card ->
{:ok, existing_card}
nil ->
create(platform_card, connect_customer, platform_customer, connect_account)
%StripeConnectCard{} = existing_card -> {:ok, existing_card}
nil -> create(platform_card, connect_customer, platform_customer, connect_account)
end
end

Expand All @@ -22,8 +20,7 @@ defmodule CodeCorps.StripeService.StripeConnectCardService do
do
{:ok, updated_stripe_card}
else
{:error, %Stripe.APIErrorResponse{} = error} -> {:error, error}
_ -> {:error, :unhandled}
failure -> failure
end
end

Expand Down
2 changes: 2 additions & 0 deletions lib/code_corps/stripe_service/stripe_connect_customer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ defmodule CodeCorps.StripeService.StripeConnectCustomerService do
%StripeConnectCustomer{}
|> StripeConnectCustomer.create_changeset(params)
|> Repo.insert
else
failure -> failure
end
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ defmodule CodeCorps.StripeService.StripeConnectExternalAccountService do
%StripeExternalAccount{}
|> StripeExternalAccount.changeset(params)
|> Repo.insert
else
failure -> failure
end
end

Expand Down
23 changes: 17 additions & 6 deletions lib/code_corps/stripe_service/stripe_connect_plan.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,31 @@ defmodule CodeCorps.StripeService.StripeConnectPlanService do

@api Application.get_env(:code_corps, :stripe)

@doc """
Creates a new `Stripe.Plan` record on Stripe API, as well as an associated local
`StripeConnectPlan` record
# Possible return values
- `{:ok, %StripeConnectPlan{}}` - the created record.
- `{:error, %Ecto.Changeset{}}` - the record was not created due to validation issues.
- `{:error, :project_not_ready}` - the associated project does not meed the prerequisites for creating a plan.
- `{:error, %Stripe.APIErrorResponse{}}` - there was a problem with the stripe request
- `{:error, :not_found}` - one of the associated records was not found
"""
def create(%{"project_id" => project_id} = attributes) do
with {:ok, %Project{} = project} <- get_project(project_id) |> ProjectCanEnableDonations.validate,
%{} = create_attributes <- get_create_attributes(project_id),
connect_account_id <- project.organization.stripe_connect_account.id_from_stripe,
{:ok, plan} <- @api.Plan.create(create_attributes, connect_account: connect_account_id),
{:ok, params} <- StripeConnectPlanAdapter.to_params(plan, attributes)
%{} = create_attributes <- get_create_attributes(project_id),
connect_account_id <- project.organization.stripe_connect_account.id_from_stripe,
{:ok, plan} <- @api.Plan.create(create_attributes, connect_account: connect_account_id),
{:ok, params} <- StripeConnectPlanAdapter.to_params(plan, attributes)
do
%StripeConnectPlan{}
|> StripeConnectPlan.create_changeset(params)
|> Repo.insert
else
{:error, :project_not_ready} -> {:error, :project_not_ready}
{:error, error} -> {:error, error}
nil -> {:error, :not_found}
failure -> failure
end
end

Expand Down
44 changes: 30 additions & 14 deletions lib/code_corps/stripe_service/stripe_connect_subscription.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,24 @@ defmodule CodeCorps.StripeService.StripeConnectSubscriptionService do

@api Application.get_env(:code_corps, :stripe)

@doc """
Finds or creates a new `Stripe.Subscription` record on Stripe API, as well as an associated local
`StripeConnectSubscription` record
# Possible return values
- `{:ok, %StripeConnectSubscription{}}` - the created record.
- `{:error, %Ecto.Changeset{}}` - the record was not created due to validation issues.
- `{:error, :project_not_ready}` - the associated project does not meed the prerequisites for receiving donations.
- `{:error, :user_not_ready}` - the associated user does not meet the prerequisits to donate.
- `{:error, %Stripe.APIErrorResponse{}}` - there was a problem with the stripe request
- `{:error, :not_found}` - one of the associated records was not found
# Side effects
- If the subscription is created or found, associated project totals will get updated
- If the subscription is created or found, associated donation goal states will be updated
"""
def find_or_create(%{"project_id" => project_id, "quantity" => _, "user_id" => user_id} = attributes) do
with {:ok, %Project{} = project} <- get_project(project_id) |> ProjectSubscribable.validate,
{:ok, %User{} = user} <- get_user(user_id) |> UserCanSubscribe.validate
Expand All @@ -23,18 +41,21 @@ defmodule CodeCorps.StripeService.StripeConnectSubscriptionService do

{:ok, subscription}
else
# possible errors
# {:error, :project_not_ready} - `CodeCorps.ProjectSubscribable.validate/1` failed
# {:error, :user_not_ready} - `CodeCorps.UserCanSubscribe.validate/1` failed
# {:error, %Ecto.Changeset{}} - Record creation failed due to validation errors
# {:error, %Stripe.APIErrorResponse{}} - Stripe request failed
# {:error, :not_found} - One of the associated records was not found
{:error, error} -> {:error, error}
nil -> {:error, :not_found}
_ -> {:error, :unexpected}
failure -> failure
end
end

@doc """
Updates an existing `StripeConnectSubscription` record by retrieving a `Stripe.Subscription` record and
using that data as update parameters
# Possible return values
- `{:ok, %StripeConnectSubscription{}}` - the updated record.
- `{:error, %Stripe.APIErrorResponse{}}` - there was a problem with the stripe request
- `{:error, :not_found}` - one of the associated records was not found
"""
def update_from_stripe(stripe_id, connect_customer_id) do
with {:ok, %StripeConnectAccount{} = connect_account} <- retrieve_connect_account(connect_customer_id),
{:ok, %Stripe.Subscription{} = stripe_subscription} <- @api.Subscription.retrieve(stripe_id, connect_account: connect_account.id),
Expand All @@ -49,13 +70,8 @@ defmodule CodeCorps.StripeService.StripeConnectSubscriptionService do

{:ok, subscription}
else
# possible errors
# {:error, %Ecto.Changeset{}} - Record creation failed due to validation errors
# {:error, %Stripe.APIErrorResponse{}} - Stripe request failed
# {:error, :not_found} - One of the associated records was not found
{:error, error} -> {:error, error}
nil -> {:error, :not_found}
_ -> {:error, :unexpected}
failure -> failure
end
end

Expand Down
2 changes: 2 additions & 0 deletions lib/code_corps/stripe_service/stripe_invoice_service.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ defmodule CodeCorps.StripeService.StripeInvoiceService do
|> StripeInvoice.create_changeset(params)
|> Repo.insert
|> CodeCorps.Analytics.Segment.track(:payment_succeeded, nil)
else
failure -> failure
end
end

Expand Down
40 changes: 11 additions & 29 deletions lib/code_corps/stripe_service/stripe_platform_card.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,47 +9,29 @@ defmodule CodeCorps.StripeService.StripePlatformCardService do
@api Application.get_env(:code_corps, :stripe)

def create(%{"stripe_token" => stripe_token, "user_id" => user_id} = attributes) do
with %StripePlatformCustomer{} = customer <- get_customer(user_id),
{:ok, card} <- @api.Card.create(:customer, customer.id_from_stripe, stripe_token),
{:ok, params} <- StripePlatformCardAdapter.to_params(card, attributes)
with %StripePlatformCustomer{} = customer <- StripePlatformCustomer |> CodeCorps.Repo.get_by(user_id: user_id),
{:ok, %Stripe.Card{} = card} <- @api.Card.create(:customer, customer.id_from_stripe, stripe_token),
{:ok, params} <- StripePlatformCardAdapter.to_params(card, attributes)
do
%StripePlatformCard{}
|> StripePlatformCard.create_changeset(params)
|> Repo.insert
%StripePlatformCard{} |> StripePlatformCard.create_changeset(params) |> Repo.insert
else
nil -> {:error, :not_found}
{:error, %Stripe.APIErrorResponse{} = error} -> {:error, error}
{:error, %Ecto.Changeset{} = changeset} -> {:error, changeset}
failure -> failure
end
end

def update_from_stripe(card_id) do
with {:ok, %StripePlatformCard{} = record} <- get_card(card_id),
{:ok, %Stripe.Card{} = stripe_card} <- get_card_from_stripe(record),
{:ok, params} <- StripePlatformCardAdapter.to_params(stripe_card, %{})
with %StripePlatformCard{} = record <- Repo.get_by(StripePlatformCard, id_from_stripe: card_id),
{:ok, %Stripe.Card{} = stripe_card} <- @api.Card.retrieve(:customer, record.customer_id_from_stripe, card_id),
{:ok, params} <- StripePlatformCardAdapter.to_params(stripe_card, %{})
do
perform_update(record, params)
else
nil -> {:error, :not_found}
{:error, %Stripe.APIErrorResponse{} = error} -> {:error, error}
{:error, %Ecto.Changeset{} = changeset} -> {:error, changeset}
failure -> failure
end
end

defp get_customer(user_id) do
StripePlatformCustomer
|> CodeCorps.Repo.get_by(user_id: user_id)
end

defp get_card(card_id_from_stripe) do
record = Repo.get_by(StripePlatformCard, id_from_stripe: card_id_from_stripe)
{:ok, record}
end

defp get_card_from_stripe(%StripePlatformCard{id_from_stripe: stripe_id, customer_id_from_stripe: owner_id}) do
@api.Card.retrieve(:customer, owner_id, stripe_id)
end

defp perform_update(record, params) do
changeset = record |> StripePlatformCard.update_changeset(params)

Expand All @@ -63,8 +45,8 @@ defmodule CodeCorps.StripeService.StripePlatformCardService do
{:ok, platform_card_update, connect_card_updates}
{:error, :update_platform_card, %Ecto.Changeset{} = changeset, %{}} ->
{:error, changeset}
{:error, _failed_operation, _failed_value, _changes_so_far} ->
{:error, :unhandled}
{:error, failed_operation, failed_value, _changes_so_far} ->
{:error, failed_operation, failed_value}
end
end

Expand Down
24 changes: 10 additions & 14 deletions lib/code_corps/stripe_service/stripe_platform_customer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ defmodule CodeCorps.StripeService.StripePlatformCustomerService do
%StripePlatformCustomer{}
|> StripePlatformCustomer.create_changeset(params)
|> Repo.insert
else
failure -> failure
end
end

Expand All @@ -37,9 +39,7 @@ defmodule CodeCorps.StripeService.StripePlatformCustomerService do
do
{:ok, updated_customer, stripe_customer}
else
{:error, %Ecto.Changeset{} = changeset} -> {:error, changeset}
{:error, %Stripe.APIErrorResponse{} = error} -> {:error, error}
_ -> {:error, :unhandled}
failure -> failure
end
end

Expand All @@ -56,17 +56,14 @@ defmodule CodeCorps.StripeService.StripePlatformCustomerService do
- `{:error, :unhandled}` -if something unexpected went wrong
"""
def update_from_stripe(id_from_stripe) do
with %StripePlatformCustomer{} = customer <- Repo.get_by(StripePlatformCustomer, id_from_stripe: id_from_stripe),
{:ok, %Stripe.Customer{} = stripe_customer} <- @api.Customer.retrieve(id_from_stripe),
{:ok, params} <- StripePlatformCustomerAdapter.to_params(stripe_customer, %{}),
{:ok, %StripePlatformCustomer{} = platform_customer, connect_customer_updates} <- perform_update(customer, params)
with %StripePlatformCustomer{} = customer <- Repo.get_by(StripePlatformCustomer, id_from_stripe: id_from_stripe),
{:ok, %Stripe.Customer{} = stripe_customer} <- @api.Customer.retrieve(id_from_stripe),
{:ok, params} <- StripePlatformCustomerAdapter.to_params(stripe_customer, %{})
do
{:ok, platform_customer, connect_customer_updates}
perform_update(customer, params)
else
nil -> {:error, :not_found}
{:error, %Ecto.Changeset{} = changeset} -> {:error, changeset}
{:error, %Stripe.APIErrorResponse{} = error} -> {:error, error}
_ -> {:error, :unhandled}
failure -> failure
end
end

Expand All @@ -91,8 +88,8 @@ defmodule CodeCorps.StripeService.StripePlatformCustomerService do
{:ok, platform_customer, update_connect_customers_results}
{:error, :update_platform_customer, %Ecto.Changeset{} = changeset, %{}} ->
{:error, changeset}
{:error, _failed_operation, _failed_value, _changes_so_far} ->
{:error, :unhandled}
{:error, failed_operation, failed_value, _changes_so_far} ->
{:error, failed_operation, failed_value}
end
end

Expand All @@ -101,7 +98,6 @@ defmodule CodeCorps.StripeService.StripePlatformCustomerService do
{:ok, platform_customer, nil}
else
{:error, changeset} -> {:error, changeset}
_ -> {:error, :unhandled}
end
end

Expand Down

0 comments on commit dff0b26

Please sign in to comment.