diff --git a/apps/web/app/api/stripe/connect/webhook/checkout-session-completed.ts b/apps/web/app/api/stripe/connect/webhook/checkout-session-completed.ts index 4695671f03..1831386de7 100644 --- a/apps/web/app/api/stripe/connect/webhook/checkout-session-completed.ts +++ b/apps/web/app/api/stripe/connect/webhook/checkout-session-completed.ts @@ -51,16 +51,28 @@ export async function checkoutSessionCompleted(event: Stripe.Event) { } } - // Record sale - await recordSale({ - ...leadEvent.data[0], - event_id: nanoid(16), - payment_processor: "stripe", - amount: charge.amount_total!, - currency: charge.currency!, - invoice_id: invoiceId || "", - metadata: JSON.stringify({ - charge, + await Promise.all([ + recordSale({ + ...leadEvent.data[0], + event_id: nanoid(16), + payment_processor: "stripe", + amount: charge.amount_total!, + currency: charge.currency!, + invoice_id: invoiceId || "", + metadata: JSON.stringify({ + charge, + }), }), - }); + // update link sales count + prisma.link.update({ + where: { + id: leadEvent.data[0].link_id, + }, + data: { + sales: { + increment: 1, + }, + }, + }), + ]); } diff --git a/apps/web/app/api/stripe/connect/webhook/customer-created.ts b/apps/web/app/api/stripe/connect/webhook/customer-created.ts index 85be9135af..897d52d9e7 100644 --- a/apps/web/app/api/stripe/connect/webhook/customer-created.ts +++ b/apps/web/app/api/stripe/connect/webhook/customer-created.ts @@ -78,5 +78,17 @@ export async function customerCreated(event: Stripe.Event) { event_name: "Customer created", customer_id: customer.id, }), + + // update link leads count + prisma.link.update({ + where: { + id: clickData.link_id, + }, + data: { + leads: { + increment: 1, + }, + }, + }), ]); } diff --git a/apps/web/app/api/stripe/connect/webhook/invoice-paid.ts b/apps/web/app/api/stripe/connect/webhook/invoice-paid.ts index 0ca2ecb928..4afd8bd892 100644 --- a/apps/web/app/api/stripe/connect/webhook/invoice-paid.ts +++ b/apps/web/app/api/stripe/connect/webhook/invoice-paid.ts @@ -43,16 +43,28 @@ export async function invoicePaid(event: Stripe.Event) { return; } - // Record sale - await recordSale({ - ...leadEvent.data[0], - event_id: nanoid(16), - payment_processor: "stripe", - amount: invoice.amount_paid, - currency: invoice.currency, - invoice_id: invoiceId, - metadata: JSON.stringify({ - invoice, + await Promise.all([ + recordSale({ + ...leadEvent.data[0], + event_id: nanoid(16), + payment_processor: "stripe", + amount: invoice.amount_paid, + currency: invoice.currency, + invoice_id: invoiceId, + metadata: JSON.stringify({ + invoice, + }), }), - }); + // update link sales count + prisma.link.update({ + where: { + id: leadEvent.data[0].link_id, + }, + data: { + sales: { + increment: 1, + }, + }, + }), + ]); } diff --git a/apps/web/app/api/track/lead/route.ts b/apps/web/app/api/track/lead/route.ts index eba1918ac9..d7d26540b0 100644 --- a/apps/web/app/api/track/lead/route.ts +++ b/apps/web/app/api/track/lead/route.ts @@ -87,6 +87,18 @@ export const POST = withWorkspaceEdge( customer_id: customer.id, metadata: metadata ? JSON.stringify(metadata) : "", }), + + // update link leads count + prismaEdge.link.update({ + where: { + id: clickData.link_id, + }, + data: { + leads: { + increment: 1, + }, + }, + }), ]); const response = trackLeadResponseSchema.parse({ diff --git a/apps/web/app/api/track/sale/route.ts b/apps/web/app/api/track/sale/route.ts index cb2c1df4a6..16f866c67d 100644 --- a/apps/web/app/api/track/sale/route.ts +++ b/apps/web/app/api/track/sale/route.ts @@ -56,16 +56,29 @@ export const POST = withWorkspaceEdge( .omit({ timestamp: true }) .parse(leadEvent.data[0]); - await recordSale({ - ...clickData, - event_id: nanoid(16), - customer_id: customer.id, - payment_processor: paymentProcessor, - amount, - currency, - invoice_id: invoiceId || "", - metadata: metadata ? JSON.stringify(metadata) : "", - }); + await Promise.all([ + recordSale({ + ...clickData, + event_id: nanoid(16), + customer_id: customer.id, + payment_processor: paymentProcessor, + amount, + currency, + invoice_id: invoiceId || "", + metadata: metadata ? JSON.stringify(metadata) : "", + }), + // update link sales count + prismaEdge.link.update({ + where: { + id: leadEvent.data[0].link_id, + }, + data: { + sales: { + increment: 1, + }, + }, + }), + ]); const response = trackSaleResponseSchema.parse({ customerId: externalId, diff --git a/apps/web/lib/zod/schemas/links.ts b/apps/web/lib/zod/schemas/links.ts index a79b164f88..2edd524a53 100644 --- a/apps/web/lib/zod/schemas/links.ts +++ b/apps/web/lib/zod/schemas/links.ts @@ -395,6 +395,14 @@ export const LinkSchema = z .string() .nullable() .describe("The date and time when the short link was last clicked."), + leads: z + .number() + .default(0) + .describe("[BETA]: The number of leads the short links has generated."), + sales: z + .number() + .default(0) + .describe("[BETA]: The number of sales the short links has generated."), createdAt: z .string() .describe("The date and time when the short link was created."), diff --git a/apps/web/prisma/schema.prisma b/apps/web/prisma/schema.prisma index 9c312e5668..898eec9386 100644 --- a/apps/web/prisma/schema.prisma +++ b/apps/web/prisma/schema.prisma @@ -252,6 +252,8 @@ model Link { publicStats Boolean @default(false) // whether to show public stats or not clicks Int @default(0) // number of clicks lastClicked DateTime? // when the link was last clicked + leads Int @default(0) + sales Int @default(0) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt diff --git a/apps/web/tests/utils/schema.ts b/apps/web/tests/utils/schema.ts index 9f2b4264c9..ce040c12ad 100644 --- a/apps/web/tests/utils/schema.ts +++ b/apps/web/tests/utils/schema.ts @@ -25,6 +25,8 @@ export const expectedLink: Partial & { tagId: string | null } = { publicStats: false, clicks: 0, lastClicked: null, + leads: 0, + sales: 0, tagId: null, // backwards compatibility comments: null, createdAt: expect.any(String),