From ec684f9074f79b3b4e2c87e678cd712909d2012c Mon Sep 17 00:00:00 2001 From: OllyNicholass Date: Tue, 15 Oct 2024 23:05:19 +0100 Subject: [PATCH 1/3] feat(#31): populate stripe checkout session email --- src/routes/api/checkout/+server.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/routes/api/checkout/+server.ts b/src/routes/api/checkout/+server.ts index 29661e3..3753ec7 100644 --- a/src/routes/api/checkout/+server.ts +++ b/src/routes/api/checkout/+server.ts @@ -11,6 +11,7 @@ export const POST: RequestHandler = async ({ request, cookies, locals: { safeGet } const userId = session.user.id; + const userEmail = session.user.email; const formData = new URLSearchParams(await request.text()); const items: { priceId: string; quantity: number }[] = []; @@ -26,6 +27,7 @@ export const POST: RequestHandler = async ({ request, cookies, locals: { safeGet })); const checkoutSession = await stripeClient.checkout.sessions.create({ + customer_email: userEmail, line_items: lineItems, mode: 'payment', success_url: `${request.headers.get('origin')}/checkout/success`, From 43bd4e8026190d1036a3272df2d723a82599ddce Mon Sep 17 00:00:00 2001 From: OllyNicholass Date: Tue, 15 Oct 2024 23:36:24 +0100 Subject: [PATCH 2/3] refactor: product page data fetching --- src/lib/types/Products/ProductInfo.ts | 7 +++++++ src/routes/products/[productId]/+page.server.ts | 15 ++++++--------- src/routes/products/[productId]/+server.ts | 15 +++++++++++---- 3 files changed, 24 insertions(+), 13 deletions(-) create mode 100644 src/lib/types/Products/ProductInfo.ts diff --git a/src/lib/types/Products/ProductInfo.ts b/src/lib/types/Products/ProductInfo.ts new file mode 100644 index 0000000..900eab4 --- /dev/null +++ b/src/lib/types/Products/ProductInfo.ts @@ -0,0 +1,7 @@ +import Stripe from 'stripe'; + +export type ProductInfo = { + product: Stripe.Product; + price: Stripe.Price; + isSubscription: boolean; +}; \ No newline at end of file diff --git a/src/routes/products/[productId]/+page.server.ts b/src/routes/products/[productId]/+page.server.ts index 6a3fba3..2a43b4e 100644 --- a/src/routes/products/[productId]/+page.server.ts +++ b/src/routes/products/[productId]/+page.server.ts @@ -1,5 +1,6 @@ import { redirect } from '@sveltejs/kit'; import { hasProductAccess } from '$lib/utils/supabase/admin'; +import type { ProductInfo } from '$lib/types/Products/ProductInfo'; export const load = async ({ params, locals: { safeGetSession }, fetch }) => { const { session } = await safeGetSession(); @@ -8,7 +9,7 @@ export const load = async ({ params, locals: { safeGetSession }, fetch }) => { } const productResponse = await fetch(`/products/${params.productId}`); - const product = await productResponse.json(); + const { product, isSubscription, price }: ProductInfo = await productResponse.json(); // Create the item object const item = { @@ -17,17 +18,13 @@ export const load = async ({ params, locals: { safeGetSession }, fetch }) => { categoryDescription: product.description, imgAlt: product.description, imgSrc: product.images[0], - price: 0, priceId: product.default_price, quantity: 1, - isSubscription: product.isSubscription + isSubscription: isSubscription, + price: (price.unit_amount ? price.unit_amount / 100 : NaN), + interval: price.recurring ? price.recurring.interval : null, } - - // Fetch the price of the product - const priceResponse = await fetch(`/products/prices/${product.default_price}`); - const price = await priceResponse.json(); - // Set the price of the product - item.price = price.unit_amount / 100; + // Check if the user has access to the 'EXAMPLE PRODUCT' product const hasPurchasedProduct = await hasProductAccess(session.user.id, params.productId); diff --git a/src/routes/products/[productId]/+server.ts b/src/routes/products/[productId]/+server.ts index c1b83c8..528dcce 100644 --- a/src/routes/products/[productId]/+server.ts +++ b/src/routes/products/[productId]/+server.ts @@ -1,14 +1,21 @@ import { json } from '@sveltejs/kit'; import { stripe as stripeClient } from '$lib/utils/stripe'; import Stripe from 'stripe'; +import { type ProductInfo } from '$lib/types/Products/ProductInfo'; export const GET = async ({ params }) => { const { productId } = params; const product = await stripeClient.products.retrieve(productId); - const price = await stripeClient.prices.retrieve(product.default_price); + const price = await stripeClient.prices.retrieve(product.default_price as string); - const isSubscription = price.type === ('recurring' as Stripe.Price.type); - product.isSubscription = isSubscription; - return json(product); + const isSubscription = price.type === ('recurring' as Stripe.Price.Type); + + const productInfo: ProductInfo = { + product, + price, + isSubscription + } + + return json(productInfo); }; From b61983368c2098346989fe7c056d2bb48eae7657 Mon Sep 17 00:00:00 2001 From: OllyNicholass Date: Tue, 15 Oct 2024 23:47:34 +0100 Subject: [PATCH 3/3] feat: display interval for subscriptions --- src/lib/components/products/ProductsListItem.svelte | 5 ++++- src/routes/products/[productId]/+page.svelte | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/lib/components/products/ProductsListItem.svelte b/src/lib/components/products/ProductsListItem.svelte index 40574a5..927738b 100644 --- a/src/lib/components/products/ProductsListItem.svelte +++ b/src/lib/components/products/ProductsListItem.svelte @@ -1,5 +1,8 @@ @@ -13,7 +16,7 @@
{product.name}
-
£{product.actualPrice}
+
£{product.actualPrice} {isSubscription ? `/ ${defaultPrice.interval}` : ''}