Pending and shipment fulfillment

This commit is contained in:
Dominic Ferrando
2025-10-17 09:49:13 -04:00
parent 0e57e60f3f
commit 533a957996
3 changed files with 55 additions and 15 deletions
+10 -10
View File
@@ -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;
}
}
+28 -5
View File
@@ -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<Event.ProductUpdated, {
sync_product: {
id: number;
@@ -137,7 +137,6 @@ export namespace Printful {
};
}> { }
// product deleted
export interface ProductDeleted extends MetaData<Event.ProductDeleted, {
sync_product: {
id: number;
@@ -146,7 +145,31 @@ export namespace Printful {
};
}> { }
export type EventPayload = ProductUpdated | ProductDeleted
export interface PackageShipped extends MetaData<Event.PackageShipped, {
shipment: {
id: number
status: string
store_id: number
tracking_number: string
tracking_url: string
created_at: string
ship_date: string
shipped_at: string
delivered_at: string
reshipment: boolean
}
order: {
id: number
external_id: string
status: string
store_id: number
dashboard_url: string
created_at: string
updated_at: string
}
}> { }
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
+17
View File
@@ -124,6 +124,23 @@ export default class WebflowService {
}
}
static Orders = class {
static async update(webflowOrderId: string, webflowOrder: DeepPartial<Webflow.Orders.Order>) {
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 {