a tool for shared writing and social publishing
at main 64 lines 2.0 kB view raw
1"use server"; 2 3import { getIdentityData } from "./getIdentityData"; 4import { getStripe } from "stripe/client"; 5import { supabaseServerClient } from "supabase/serverClient"; 6import { getPriceId } from "stripe/products"; 7import { Ok, Err, type Result } from "src/result"; 8 9export async function createCheckoutSession( 10 cadence: "month" | "year", 11 returnUrl?: string, 12): Promise<Result<{ url: string }, string>> { 13 const identity = await getIdentityData(); 14 if (!identity) { 15 return Err("Not authenticated"); 16 } 17 18 const priceId = await getPriceId(cadence); 19 if (!priceId) { 20 return Err("No Stripe price found. Run the sync script first."); 21 } 22 23 // Check for existing Stripe customer 24 let customerId: string | undefined; 25 const { data: existingSub } = await supabaseServerClient 26 .from("user_subscriptions") 27 .select("stripe_customer_id") 28 .eq("identity_id", identity.id) 29 .single(); 30 31 if (existingSub?.stripe_customer_id) { 32 customerId = existingSub.stripe_customer_id; 33 } 34 35 const successUrl = new URL( 36 "/api/checkout/success", 37 process.env.NEXT_PUBLIC_APP_URL || "https://leaflet.pub", 38 ); 39 successUrl.searchParams.set("session_id", "{CHECKOUT_SESSION_ID}"); 40 if (returnUrl) { 41 successUrl.searchParams.set("return", returnUrl); 42 } 43 44 const cancelUrl = returnUrl || process.env.NEXT_PUBLIC_APP_URL || "https://leaflet.pub"; 45 46 const session = await getStripe().checkout.sessions.create({ 47 mode: "subscription", 48 line_items: [{ price: priceId, quantity: 1 }], 49 client_reference_id: identity.id, 50 ...(customerId 51 ? { customer: customerId } 52 : { customer_email: identity.email || undefined }), 53 subscription_data: { metadata: { identity_id: identity.id } }, 54 allow_promotion_codes: true, 55 success_url: successUrl.toString(), 56 cancel_url: cancelUrl, 57 }); 58 59 if (!session.url) { 60 return Err("Failed to create checkout session"); 61 } 62 63 return Ok({ url: session.url }); 64}