add shipping costs with live exchange rates and country detection

Shipping rates fetched from Printify during product sync, converted to
GBP at sync time using frankfurter.app ECB exchange rates with 5%
buffer. Cached in shipping_rates table per blueprint/provider/country.

Cart page shows shipping estimate with country selector (detected from
Accept-Language header, persisted in cookie). Stripe Checkout includes
shipping_options for UK domestic and international delivery. Order
shipping_cost extracted from Stripe on payment.

ScheduledSyncWorker runs every 6 hours via Oban cron to keep rates
and exchange rates fresh. REST_OF_THE_WORLD fallback covers unlisted
countries. 780 tests, 0 failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jamey
2026-02-14 10:48:00 +00:00
parent 44933acebb
commit 5c2f70ce44
26 changed files with 1707 additions and 38 deletions

View File

@@ -18,6 +18,7 @@ defmodule SimpleshopTheme.Orders.Order do
field :customer_email, :string
field :shipping_address, :map, default: %{}
field :subtotal, :integer
field :shipping_cost, :integer
field :total, :integer
field :currency, :string, default: "gbp"
field :metadata, :map, default: %{}
@@ -48,6 +49,7 @@ defmodule SimpleshopTheme.Orders.Order do
:customer_email,
:shipping_address,
:subtotal,
:shipping_cost,
:total,
:currency,
:metadata