rename project from SimpleshopTheme to Berrypod
All modules, configs, paths, and references updated. 836 tests pass, zero warnings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
129
lib/berrypod_web/controllers/checkout_controller.ex
Normal file
129
lib/berrypod_web/controllers/checkout_controller.ex
Normal file
@@ -0,0 +1,129 @@
|
||||
defmodule BerrypodWeb.CheckoutController do
|
||||
use BerrypodWeb, :controller
|
||||
|
||||
alias Berrypod.Cart
|
||||
alias Berrypod.Orders
|
||||
alias Berrypod.Shipping
|
||||
|
||||
require Logger
|
||||
|
||||
def create(conn, _params) do
|
||||
cart_items = Cart.get_from_session(get_session(conn))
|
||||
hydrated = Cart.hydrate(cart_items)
|
||||
|
||||
if hydrated == [] do
|
||||
conn
|
||||
|> put_flash(:error, "Your basket is empty")
|
||||
|> redirect(to: ~p"/cart")
|
||||
else
|
||||
create_checkout(conn, hydrated)
|
||||
end
|
||||
end
|
||||
|
||||
defp create_checkout(conn, hydrated_items) do
|
||||
# Create a pending order with price snapshots
|
||||
case Orders.create_order(%{items: hydrated_items}) do
|
||||
{:ok, order} ->
|
||||
create_stripe_session(conn, order, hydrated_items)
|
||||
|
||||
{:error, _changeset} ->
|
||||
Logger.error("Failed to create order")
|
||||
|
||||
conn
|
||||
|> put_flash(:error, "Something went wrong. Please try again.")
|
||||
|> redirect(to: ~p"/cart")
|
||||
end
|
||||
end
|
||||
|
||||
defp create_stripe_session(conn, order, hydrated_items) do
|
||||
line_items =
|
||||
Enum.map(hydrated_items, fn item ->
|
||||
product_name =
|
||||
if item.variant,
|
||||
do: "#{item.name} — #{item.variant}",
|
||||
else: item.name
|
||||
|
||||
%{
|
||||
price_data: %{
|
||||
currency: "gbp",
|
||||
unit_amount: item.price,
|
||||
product_data: %{name: product_name}
|
||||
},
|
||||
quantity: item.quantity
|
||||
}
|
||||
end)
|
||||
|
||||
base_url = BerrypodWeb.Endpoint.url()
|
||||
|
||||
params =
|
||||
%{
|
||||
mode: "payment",
|
||||
line_items: line_items,
|
||||
success_url: "#{base_url}/checkout/success?session_id={CHECKOUT_SESSION_ID}",
|
||||
cancel_url: "#{base_url}/cart",
|
||||
metadata: %{"order_id" => order.id},
|
||||
shipping_address_collection: %{
|
||||
allowed_countries: ["GB", "US", "CA", "AU", "DE", "FR", "NL", "IE", "AT", "BE"]
|
||||
}
|
||||
}
|
||||
|> maybe_add_shipping_options(hydrated_items)
|
||||
|
||||
case Stripe.Checkout.Session.create(params) do
|
||||
{:ok, session} ->
|
||||
{:ok, _order} = Orders.set_stripe_session(order, session.id)
|
||||
|
||||
conn
|
||||
|> redirect(external: session.url)
|
||||
|
||||
{:error, %Stripe.Error{message: message}} ->
|
||||
Logger.error("Stripe session creation failed: #{message}")
|
||||
Orders.mark_failed(order)
|
||||
|
||||
conn
|
||||
|> put_flash(:error, "Payment setup failed. Please try again.")
|
||||
|> redirect(to: ~p"/cart")
|
||||
|
||||
{:error, reason} ->
|
||||
Logger.error("Stripe session creation failed: #{inspect(reason)}")
|
||||
Orders.mark_failed(order)
|
||||
|
||||
conn
|
||||
|> put_flash(:error, "Payment setup failed. Please try again.")
|
||||
|> redirect(to: ~p"/cart")
|
||||
end
|
||||
end
|
||||
|
||||
defp maybe_add_shipping_options(params, hydrated_items) do
|
||||
gb_result = Shipping.calculate_for_cart(hydrated_items, "GB")
|
||||
us_result = Shipping.calculate_for_cart(hydrated_items, "US")
|
||||
|
||||
options =
|
||||
[]
|
||||
|> maybe_add_option(gb_result, "UK delivery", 5, 10)
|
||||
|> maybe_add_option(us_result, "International delivery", 10, 20)
|
||||
|
||||
if options == [] do
|
||||
params
|
||||
else
|
||||
Map.put(params, :shipping_options, options)
|
||||
end
|
||||
end
|
||||
|
||||
defp maybe_add_option(options, {:ok, cost}, name, min_days, max_days) when cost > 0 do
|
||||
option = %{
|
||||
shipping_rate_data: %{
|
||||
type: "fixed_amount",
|
||||
display_name: name,
|
||||
fixed_amount: %{amount: cost, currency: "gbp"},
|
||||
delivery_estimate: %{
|
||||
minimum: %{unit: "business_day", value: min_days},
|
||||
maximum: %{unit: "business_day", value: max_days}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
options ++ [option]
|
||||
end
|
||||
|
||||
defp maybe_add_option(options, _result, _name, _min, _max), do: options
|
||||
end
|
||||
Reference in New Issue
Block a user