@@ -4,7 +4,12 @@ import { randomUUID } from "node:crypto";
44import { and , eq } from "drizzle-orm" ;
55import type Stripe from "stripe" ;
66import { db } from "@/lib/db" ;
7- import { commissionOverride , purchase , purchaseEvent , user } from "@/lib/db/schema" ;
7+ import {
8+ commissionOverride ,
9+ purchase ,
10+ purchaseEvent ,
11+ user ,
12+ } from "@/lib/db/schema" ;
813import { templatePath } from "@/lib/routes" ;
914import { getStripeClient } from "@/lib/stripe" ;
1015import {
@@ -16,6 +21,7 @@ import { requireTemplateRecordBySlug } from "@/lib/templates/repository";
1621import { PurchaseServiceError } from "./errors" ;
1722import type { CreatePurchaseCheckoutInput } from "./schemas" ;
1823import type { CreatePurchaseCheckoutResponse } from "./types" ;
24+ import { cookies } from "next/headers" ;
1925
2026type PurchaseStatus = "pending" | "completed" | "failed" ;
2127type PurchaseEventType =
@@ -115,10 +121,7 @@ function getResourceId(value: unknown): string | null {
115121 return null ;
116122}
117123
118- function resolveSaleType ( input : {
119- sellerUsername : string ;
120- ref ?: string ;
121- } ) : {
124+ function resolveSaleType ( input : { sellerUsername : string ; ref ?: string } ) : {
122125 saleType : TemplateSaleType ;
123126 referralCode : string | null ;
124127} {
@@ -163,7 +166,9 @@ async function findPurchaseByBuyerTemplate(
163166 stripeCheckoutSessionId : purchase . stripeCheckoutSessionId ,
164167 } )
165168 . from ( purchase )
166- . where ( and ( eq ( purchase . buyerId , buyerId ) , eq ( purchase . templateId , templateId ) ) )
169+ . where (
170+ and ( eq ( purchase . buyerId , buyerId ) , eq ( purchase . templateId , templateId ) ) ,
171+ )
167172 . limit ( 1 ) ;
168173
169174 return record ?? null ;
@@ -593,7 +598,10 @@ export async function createTemplatePurchaseCheckout(options: {
593598 input : CreatePurchaseCheckoutInput ;
594599 baseUrl : string ;
595600} ) : Promise < CreatePurchaseCheckoutResponse > {
596- const templateRow = await requireTemplateRecordBySlug ( options . input . templateSlug ) ;
601+ const templateRow = await requireTemplateRecordBySlug (
602+ options . input . templateSlug ,
603+ ) ;
604+ const cookieStore = await cookies ( ) ;
597605
598606 if (
599607 templateRow . status !== "published" ||
@@ -655,7 +663,10 @@ export async function createTemplatePurchaseCheckout(options: {
655663 } ) ;
656664 }
657665
658- const commissionRate = await resolveCommissionRate ( templateRow . sellerId , sale . saleType ) ;
666+ const commissionRate = await resolveCommissionRate (
667+ templateRow . sellerId ,
668+ sale . saleType ,
669+ ) ;
659670 const split = calculateSplitFromRate ( templateRow . priceCents , commissionRate ) ;
660671 const pending = await upsertPendingPurchase ( {
661672 buyerId : options . buyerId ,
@@ -683,43 +694,53 @@ export async function createTemplatePurchaseCheckout(options: {
683694
684695 let session : Stripe . Checkout . Session ;
685696 try {
686- session = await stripe . checkout . sessions . create ( {
687- mode : "payment" ,
688- customer_email : stripeUser . email ,
689- line_items : [
690- {
691- quantity : 1 ,
692- price_data : {
693- currency : toStripeCurrencyCode ( templateRow . currency ) ,
694- unit_amount : templateRow . priceCents ,
695- product_data : {
696- name : templateRow . title ,
697- description : deriveTemplateExcerptFromMarkdown ( templateRow . description , 180 ) ,
697+ session = await stripe . checkout . sessions . create (
698+ {
699+ mode : "payment" ,
700+ customer_email : stripeUser . email ,
701+ line_items : [
702+ {
703+ quantity : 1 ,
704+ price_data : {
705+ currency : toStripeCurrencyCode ( templateRow . currency ) ,
706+ unit_amount : templateRow . priceCents ,
707+ product_data : {
708+ name : templateRow . title ,
709+ description : deriveTemplateExcerptFromMarkdown (
710+ templateRow . description ,
711+ 180 ,
712+ ) ,
713+ } ,
698714 } ,
699715 } ,
700- } ,
701- ] ,
702- success_url : `${ baseUrl } ${ templatePath ( templateRow . slug ) } ?checkout=success&session_id={CHECKOUT_SESSION_ID}` ,
703- cancel_url : `${ baseUrl } ${ templatePath ( templateRow . slug ) } ?checkout=cancel` ,
704- metadata : {
705- kind : "template_purchase" ,
706- purchaseId : pending . purchaseId ,
707- buyerId : options . buyerId ,
708- templateId : templateRow . id ,
709- } ,
710- payment_intent_data : {
711- application_fee_amount : split . platformFeeCents ,
716+ ] ,
717+ success_url : `${ baseUrl } ${ templatePath ( templateRow . slug ) } ?checkout=success&session_id={CHECKOUT_SESSION_ID}` ,
718+ cancel_url : `${ baseUrl } ${ templatePath ( templateRow . slug ) } ?checkout=cancel` ,
712719 metadata : {
713720 kind : "template_purchase" ,
714721 purchaseId : pending . purchaseId ,
715722 buyerId : options . buyerId ,
716723 templateId : templateRow . id ,
717724 } ,
725+ payment_intent_data : {
726+ application_fee_amount : split . platformFeeCents ,
727+ metadata : {
728+ kind : "template_purchase" ,
729+ purchaseId : pending . purchaseId ,
730+ buyerId : options . buyerId ,
731+ templateId : templateRow . id ,
732+ datafast_visitor_id :
733+ cookieStore . get ( "datafast_visitor_id" ) ?. value || null ,
734+ datafast_session_id :
735+ cookieStore . get ( "datafast_session_id" ) ?. value || null ,
736+ } ,
737+ } ,
738+ client_reference_id : pending . purchaseId ,
718739 } ,
719- client_reference_id : pending . purchaseId ,
720- } , {
721- stripeAccount : sellerRow . stripeAccountId ,
722- } ) ;
740+ {
741+ stripeAccount : sellerRow . stripeAccountId ,
742+ } ,
743+ ) ;
723744 } catch ( error ) {
724745 await db
725746 . update ( purchase )
0 commit comments