feat: add Printify order submission and fulfilment tracking
Submit paid orders to Printify via provider API with idempotent guards, Stripe address mapping, and error handling. Track fulfilment status through submitted → processing → shipped → delivered via webhook-driven updates (primary) and Oban Cron polling fallback. - 9 fulfilment fields on orders (status, provider IDs, tracking, timestamps) - OrderSubmissionWorker with retry logic, auto-enqueued after Stripe payment - FulfilmentStatusWorker polls every 30 mins for missed webhook events - Printify order webhook handlers (sent-to-production, shipment, delivered) - Admin UI: fulfilment column in table, fulfilment card with tracking info, submit/retry and refresh buttons on order detail - Mox provider mocking for test isolation (Provider.for_type configurable) - 33 new tests (555 total), verified against real Printify API Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ defmodule SimpleshopThemeWeb.StripeWebhookController do
|
||||
use SimpleshopThemeWeb, :controller
|
||||
|
||||
alias SimpleshopTheme.Orders
|
||||
alias SimpleshopTheme.Orders.OrderSubmissionWorker
|
||||
|
||||
require Logger
|
||||
|
||||
@@ -36,14 +37,24 @@ defmodule SimpleshopThemeWeb.StripeWebhookController do
|
||||
{:ok, order} = Orders.mark_paid(order, payment_intent_id)
|
||||
|
||||
# Update shipping address if collected by Stripe
|
||||
if session.shipping_details do
|
||||
update_shipping(order, session.shipping_details)
|
||||
end
|
||||
order =
|
||||
if session.shipping_details do
|
||||
{:ok, updated} = update_shipping(order, session.shipping_details)
|
||||
updated
|
||||
else
|
||||
order
|
||||
end
|
||||
|
||||
# Update customer email from Stripe session
|
||||
if session.customer_details && session.customer_details.email do
|
||||
Orders.update_order(order, %{customer_email: session.customer_details.email})
|
||||
end
|
||||
order =
|
||||
if session.customer_details && session.customer_details.email do
|
||||
{:ok, updated} =
|
||||
Orders.update_order(order, %{customer_email: session.customer_details.email})
|
||||
|
||||
updated
|
||||
else
|
||||
order
|
||||
end
|
||||
|
||||
# Broadcast to success page via PubSub
|
||||
Phoenix.PubSub.broadcast(
|
||||
@@ -52,6 +63,15 @@ defmodule SimpleshopThemeWeb.StripeWebhookController do
|
||||
{:order_paid, order}
|
||||
)
|
||||
|
||||
# Submit to fulfilment provider
|
||||
if order.shipping_address && order.shipping_address != %{} do
|
||||
OrderSubmissionWorker.enqueue(order.id)
|
||||
else
|
||||
Logger.warning(
|
||||
"Order #{order.order_number} paid but no shipping address — manual submit needed"
|
||||
)
|
||||
end
|
||||
|
||||
Logger.info("Order #{order.order_number} marked as paid")
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user