defmodule SimpleshopThemeWeb.Admin.Settings do
use SimpleshopThemeWeb, :live_view
alias SimpleshopTheme.Settings
alias SimpleshopTheme.Stripe.Setup, as: StripeSetup
@impl true
def mount(_params, _session, socket) do
{:ok,
socket
|> assign(:page_title, "Settings")
|> assign(:site_live, Settings.site_live?())
|> assign_stripe_state()}
end
defp assign_stripe_state(socket) do
has_key = Settings.has_secret?("stripe_api_key")
has_signing = Settings.has_secret?("stripe_signing_secret")
status =
cond do
!has_key -> :not_configured
has_key && StripeSetup.localhost?() -> :connected_localhost
true -> :connected
end
socket
|> assign(:stripe_status, status)
|> assign(:stripe_api_key_hint, Settings.secret_hint("stripe_api_key"))
|> assign(:stripe_signing_secret_hint, Settings.secret_hint("stripe_signing_secret"))
|> assign(:stripe_webhook_url, StripeSetup.webhook_url())
|> assign(:stripe_has_signing_secret, has_signing)
|> assign(:connect_form, to_form(%{"api_key" => ""}, as: :stripe))
|> assign(:secret_form, to_form(%{"signing_secret" => ""}, as: :webhook))
|> assign(:advanced_open, false)
|> assign(:connecting, false)
end
@impl true
def handle_event("connect_stripe", %{"stripe" => %{"api_key" => api_key}}, socket) do
if api_key == "" do
{:noreply, put_flash(socket, :error, "Please enter your Stripe secret key")}
else
socket = assign(socket, :connecting, true)
case StripeSetup.connect(api_key) do
{:ok, :webhook_created} ->
socket =
socket
|> assign_stripe_state()
|> put_flash(:info, "Stripe connected and webhook endpoint created")
{:noreply, socket}
{:ok, :localhost} ->
socket =
socket
|> assign_stripe_state()
|> put_flash(
:info,
"API key saved. Enter a webhook signing secret below for local testing."
)
{:noreply, socket}
{:error, message} ->
socket =
socket
|> assign(:connecting, false)
|> put_flash(:error, "Stripe connection failed: #{message}")
{:noreply, socket}
end
end
end
def handle_event("disconnect_stripe", _params, socket) do
StripeSetup.disconnect()
socket =
socket
|> assign_stripe_state()
|> put_flash(:info, "Stripe disconnected")
{:noreply, socket}
end
def handle_event("save_signing_secret", %{"webhook" => %{"signing_secret" => secret}}, socket) do
if secret == "" do
{:noreply, put_flash(socket, :error, "Please enter a signing secret")}
else
StripeSetup.save_signing_secret(secret)
socket =
socket
|> assign_stripe_state()
|> put_flash(:info, "Webhook signing secret saved")
{:noreply, socket}
end
end
def handle_event("toggle_site_live", _params, socket) do
new_value = !socket.assigns.site_live
{:ok, _} = Settings.set_site_live(new_value)
message = if new_value, do: "Shop is now live", else: "Shop taken offline"
{:noreply,
socket
|> assign(:site_live, new_value)
|> put_flash(:info, message)}
end
def handle_event("toggle_advanced", _params, socket) do
{:noreply, assign(socket, :advanced_open, !socket.assigns.advanced_open)}
end
@impl true
def render(assigns) do
~H"""
<%= if @site_live do %>
Your shop is visible to the public.
<% else %>
Your shop is offline. Visitors see a "coming soon" page.
<% end %>
Shop status
<%= if @site_live do %>
<.icon name="hero-check-circle-mini" class="size-3" /> Live
<% else %>
Offline
<% end %>
Stripe
<%= case @stripe_status do %>
<% :connected -> %>
<.icon name="hero-check-circle-mini" class="size-3" /> Connected
<% :connected_localhost -> %>
<.icon name="hero-exclamation-triangle-mini" class="size-3" /> Dev mode
<% :not_configured -> %>
Not connected
<% end %>
To accept payments, connect your Stripe account by entering your secret key. You can find it in your Stripe dashboard under Developers → API keys.
<.form for={@connect_form} phx-submit="connect_stripe" class="mt-6"> <.input field={@connect_form[:api_key]} type="password" label="Secret key" autocomplete="off" placeholder="sk_test_... or sk_live_..." />
Starts with sk_test_ (test mode) or sk_live_ (live mode).
This key is encrypted at rest in the database.
{@stripe_api_key_hint}{@stripe_webhook_url}{@stripe_signing_secret_hint}
<% else %>
Not set
<% end %>
Stripe can't reach localhost for webhooks. For local testing, run the Stripe CLI:
stripe listen --forward-to localhost:4000/webhooks/stripe
The CLI will output a signing secret starting with whsec_. Enter it below.
Override the webhook signing secret if you need to use a custom endpoint or the Stripe CLI.
<.form for={@secret_form} phx-submit="save_signing_secret"> <.input field={@secret_form[:signing_secret]} type="password" label="Webhook signing secret" autocomplete="off" placeholder="whsec_..." />