Skip to content

Commit 7d509a9

Browse files
authored
Merge pull request #2607 from dubinc/fix-shopify-errors
Handle null customer from Shopify webhooks
2 parents 2536f83 + 3b80be5 commit 7d509a9

File tree

4 files changed

+47
-34
lines changed

4 files changed

+47
-34
lines changed

apps/web/app/(ee)/api/shopify/integration/webhook/orders-paid.ts

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,31 @@ export async function ordersPaid({
1212
event: any;
1313
workspaceId: string;
1414
}) {
15-
const {
16-
customer: { id: externalId },
17-
checkout_token: checkoutToken,
18-
} = orderSchema.parse(event);
15+
const { customer: orderCustomer, checkout_token: checkoutToken } =
16+
orderSchema.parse(event);
1917

20-
const customer = await prisma.customer.findUnique({
21-
where: {
22-
projectId_externalId: {
23-
projectId: workspaceId,
24-
externalId: externalId.toString(),
25-
},
26-
},
27-
});
18+
if (orderCustomer) {
19+
const { id: externalId } = orderCustomer;
2820

29-
// customer is found, process the order right away
30-
if (customer) {
31-
await processOrder({
32-
event,
33-
workspaceId,
34-
customerId: customer.id,
21+
const customer = await prisma.customer.findUnique({
22+
where: {
23+
projectId_externalId: {
24+
projectId: workspaceId,
25+
externalId: externalId.toString(),
26+
},
27+
},
3528
});
3629

37-
return "[Shopify] Order event processed successfully.";
30+
// customer is found, process the order right away
31+
if (customer) {
32+
await processOrder({
33+
event,
34+
workspaceId,
35+
customerId: customer.id,
36+
});
37+
38+
return "[Shopify] Order event processed successfully.";
39+
}
3840
}
3941

4042
// Check the cache to see the pixel event for this checkout token exist before publishing the event to the queue

apps/web/lib/integrations/shopify/create-lead.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,19 @@ export async function createShopifyLead({
1919
workspaceId: string;
2020
event: any;
2121
}) {
22-
const {
23-
customer: { id: externalId, email, first_name, last_name },
24-
} = orderSchema.parse(event);
22+
const { customer: orderCustomer } = orderSchema.parse(event);
23+
24+
const customerId = createId({ prefix: "cus_" });
25+
/*
26+
if orderCustomer is undefined (guest checkout):
27+
- use the customerId as the externalId
28+
- generate random name + email
29+
*/
30+
const externalId = orderCustomer?.id?.toString() || customerId; // need to convert to string because Shopify customer ID is a number
31+
const name = orderCustomer
32+
? `${orderCustomer.first_name} ${orderCustomer.last_name}`.trim()
33+
: generateRandomName();
34+
const email = orderCustomer?.email;
2535

2636
// find click
2737
const clickEvent = await getClickEvent({ clickId });
@@ -32,11 +42,10 @@ export async function createShopifyLead({
3242
// create customer
3343
const customer = await prisma.customer.create({
3444
data: {
35-
id: createId({ prefix: "cus_" }),
36-
// need to convert to string because Shopify customer ID is a number
37-
externalId: externalId.toString(),
38-
name: `${first_name} ${last_name}`.trim() || generateRandomName(),
39-
email: email || null,
45+
id: customerId,
46+
externalId,
47+
name,
48+
email,
4049
projectId: workspaceId,
4150
clickedAt: new Date(timestamp + "Z"),
4251
clickId,

apps/web/lib/integrations/shopify/create-sale.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export async function createShopifySale({
3131
current_subtotal_price_set: { shop_money: shopMoney },
3232
} = order;
3333

34-
const amount = Number(shopMoney.amount) * 100;
34+
const amount = Math.round(Number(shopMoney.amount) * 100); // round to nearest cent
3535
const { link_id: linkId } = leadData;
3636
const currency = shopMoney.currency_code.toLowerCase();
3737

apps/web/lib/integrations/shopify/schema.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ import { z } from "zod";
33
export const orderSchema = z.object({
44
confirmation_number: z.string(),
55
checkout_token: z.string(),
6-
customer: z.object({
7-
id: z.number(),
8-
email: z.string().nullish(),
9-
first_name: z.string().nullish(),
10-
last_name: z.string().nullish(),
11-
}),
6+
customer: z
7+
.object({
8+
id: z.number(),
9+
email: z.string().nullish(),
10+
first_name: z.string().nullish(),
11+
last_name: z.string().nullish(),
12+
})
13+
.nullish(),
1214
current_subtotal_price_set: z.object({
1315
shop_money: z
1416
.object({

0 commit comments

Comments
 (0)