Skip to content

Instantly share code, notes, and snippets.

@egze
Forked from devonestes/with_example.ex
Created February 15, 2020 17:46
Show Gist options
  • Save egze/88afa5ef0e5e1e8dd338f5abdec9bde6 to your computer and use it in GitHub Desktop.
Save egze/88afa5ef0e5e1e8dd338f5abdec9bde6 to your computer and use it in GitHub Desktop.
Further refactoring of a with statement
# Step 1
def create_subscription(email, plan_id, payment_method_id) do
with %User{customer_id: nil, name: name} = user <-
Repo.get_by(User, email: email),
{:ok, %Stripe.Customer{id: customer_id}} <-
Stripe.Customer.create(%{
name: name,
email: email,
payment_method: payment_method_id,
invoice_settings: %{
default_payment_method: payment_method_id
}
}),
{:ok, %Stripe.Subscription{id: subscription_id}} <-
Stripe.Subscription.create(%{customer: customer_id, items: [%{plan: plan_id}]}),
{:ok, %User{}} <-
User.update(user, %{customer_id: customer_id, subscription_id: subscription_id}) do
{:ok, :subscription_created}
else
err ->
{:error, err}
end
end
# Step 2
def create_subscription(email, plan_id, payment_method_id) do
with {:user_lookup, %User{customer_id: nil, name: name} = user} <-
{:user_lookup, Repo.get_by(User, email: email)},
{:customer_creation, {:ok, %Stripe.Customer{id: customer_id}}} <-
{:customer_creation,
Stripe.Customer.create(%{
name: name,
email: email,
payment_method: payment_method_id,
invoice_settings: %{
default_payment_method: payment_method_id
}
})},
{:subscription_creation, {:ok, %Stripe.Subscription{id: subscription_id}}} <-
{:subscription_creation,
Stripe.Subscription.create(%{customer: customer_id, items: [%{plan: plan_id}]})},
{:user_update, {:ok, %User{}}} <-
{:user_update,
User.update(user, %{customer_id: customer_id, subscription_id: subscription_id})} do
{:ok, :subscription_created}
else
{:user_lookup, _} ->
{:error, :user_lookup_error}
{:customer_creation, _} ->
{:error, :customer_creation_error}
{:subscription_creation, _} ->
{:error, :subscription_creation_error}
{:user_update, _} ->
{:error, :user_update_error}
err ->
{:error, err}
end
end
# Step 3
def create_subscription(email, plan_id, payment_method_id) do
with {:ok, user} <- lookup_user(email),
{:ok, customer} <- create_customer(user.name, email, payment_method_id),
{:ok, subscription} <- create_subscription(customer.id, plan_id),
:ok <- update_user(user, customer.id, subscription.id) do
{:ok, :subscription_created}
end
end
defp lookup_user(email) do
case Repo.get_by(User, email: email) do
%{customer_id: nil} = user -> {:ok, user}
_ -> {:error, :user_lookup_error}
end
end
defp create_customer(name, email, payment_method_id) do
params = %{
name: name,
email: email,
payment_method: payment_method_id,
invoice_settings: %{
default_payment_method: payment_method_id
}
}
case Stripe.Customer.create(params) do
{:ok, _} = response -> response
_ -> {:error, :customer_creation_error}
end
end
defp create_subscription(customer_id, plan_id) do
case Stripe.Subscription.create(%{customer: customer_id, items: [%{plan: plan_id}]}) do
{:ok, _} = response -> response
_ -> {:error, :subscription_creation_error}
end
end
defp update_user(user, customer_id, subscription_id) do
case User.update(user, %{customer_id: customer_id, subscription_id: subscription_id}) do
{:ok, _} -> :ok
_ -> {:error, :user_update_error}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment