From 533a95799669ca8d5d074e541f9d10a8c2fff683 Mon Sep 17 00:00:00 2001 From: Dominic Ferrando Date: Fri, 17 Oct 2025 09:49:13 -0400 Subject: [PATCH] Pending and shipment fulfillment --- src/lib/server/app.ts | 20 +++++++-------- src/lib/services/commerce/util/types.ts | 33 +++++++++++++++++++++---- src/lib/services/commerce/webflow.ts | 17 +++++++++++++ 3 files changed, 55 insertions(+), 15 deletions(-) diff --git a/src/lib/server/app.ts b/src/lib/server/app.ts index 3c59fc1..744a9d6 100644 --- a/src/lib/server/app.ts +++ b/src/lib/server/app.ts @@ -67,6 +67,9 @@ export const app = new Elysia({ prefix: "/api" }) // WEBHOOKS .post("/webhook/printful", async ({ body }) => { const payload = body as Printful.Webhook.EventPayload; + + console.log("Hit webhook", payload.type); + switch (payload.type) { case Printful.Webhook.Event.ProductUpdated: { const printfulProduct = payload.data.sync_product; @@ -77,6 +80,11 @@ export const app = new Elysia({ prefix: "/api" }) await WebflowService.Products.remove(payload.data.sync_product.external_id); break; } + case Printful.Webhook.Event.PackageShipped: { + const webflowOrderId = payload.data.order.external_id; + await WebflowService.Orders.update(webflowOrderId, { status: "fulfilled" }); + break; + } } }) .post("/webhook/webflow", async ({ request, body, set }) => { @@ -87,12 +95,10 @@ export const app = new Elysia({ prefix: "/api" }) const payload = body as Webflow.Webhook.EventPayload; - console.log(payload.triggerType); switch (payload.triggerType) { case Webflow.Webhook.Event.OrderCreated: { const webflowOrder = payload.payload; - console.log("Creating printful order..."); await PrintfulService.Orders.create({ external_id: webflowOrder.orderId, // TODO: derive from webflow @@ -113,17 +119,11 @@ export const app = new Elysia({ prefix: "/api" }) }); // set webflow order to pending + webflowOrder.status = "pending"; + await WebflowService.Orders.update(webflowOrder.orderId, webflowOrder); console.log("Complete"); - break; - } - case Webflow.Webhook.Event.OrderUpdated: { - - // read printful order status - - // set webflow order to fulfulled (if indeed printful order got confirmed) - break; } } diff --git a/src/lib/services/commerce/util/types.ts b/src/lib/services/commerce/util/types.ts index 9ed9722..c9adcd1 100644 --- a/src/lib/services/commerce/util/types.ts +++ b/src/lib/services/commerce/util/types.ts @@ -121,10 +121,10 @@ export namespace Printful { export enum Event { ProductUpdated = "product_updated", - ProductDeleted = "product_deleted" + ProductDeleted = "product_deleted", + PackageShipped = "package_shipped" } - // product updated export interface ProductUpdated extends MetaData { } - // product deleted export interface ProductDeleted extends MetaData { } - export type EventPayload = ProductUpdated | ProductDeleted + export interface PackageShipped extends MetaData { } + + export type EventPayload = ProductUpdated | ProductDeleted | PackageShipped } } @@ -210,7 +233,7 @@ export namespace Webflow { export namespace Orders { export type Order = { orderId: string - status: string + status: "pending" | "unfulfilled" | "fulfilled" | "disputed" | "dispute-lost" | "refunded" comment: string orderComment: string acceptedOn: string diff --git a/src/lib/services/commerce/webflow.ts b/src/lib/services/commerce/webflow.ts index 845a9bc..f03e5c4 100644 --- a/src/lib/services/commerce/webflow.ts +++ b/src/lib/services/commerce/webflow.ts @@ -124,6 +124,23 @@ export default class WebflowService { } } + static Orders = class { + static async update(webflowOrderId: string, webflowOrder: DeepPartial) { + const res = await fetch(`${env().API_SITES_URL}/orders/${webflowOrderId}`, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + ...env().AUTH_HEADER + }, + body: JSON.stringify(webflowOrder) + }); + + if (!res.ok) { + throw new FetchError("Failed to update Webflow order", res); + } + } + } + static Util = class { static verifyWebflowSignature(request: Request, body: unknown) { try {