From fcf6f1fcb79ba859a8ad6ffd890bf1d2ec9b5ae8 Mon Sep 17 00:00:00 2001 From: Josh Creek <8179928+jcreek@users.noreply.github.com> Date: Tue, 30 Apr 2024 21:41:05 +0100 Subject: [PATCH] feat(*): Add stripe checkout support --- package-lock.json | 55 +++++++++++----------- package.json | 3 +- src/routes/api/checkout/+server.ts | 29 ++++++++++++ src/routes/checkout/+page.svelte | 14 ++++++ src/routes/checkout/cancelled/+page.svelte | 3 ++ src/routes/checkout/success/+page.svelte | 6 +++ 6 files changed, 82 insertions(+), 28 deletions(-) create mode 100644 src/routes/api/checkout/+server.ts create mode 100644 src/routes/checkout/+page.svelte create mode 100644 src/routes/checkout/cancelled/+page.svelte create mode 100644 src/routes/checkout/success/+page.svelte diff --git a/package-lock.json b/package-lock.json index 2a5b9a2..2432aa8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,8 @@ "version": "0.0.1", "dependencies": { "@supabase/ssr": "^0.1.0", - "@supabase/supabase-js": "^2.42.0" + "@supabase/supabase-js": "^2.42.0", + "stripe": "^15.4.0" }, "devDependencies": { "@sveltejs/adapter-auto": "^3.0.0", @@ -4060,8 +4061,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, - "peer": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -4538,8 +4537,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "peer": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -4753,8 +4750,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "peer": true, "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -4766,8 +4761,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "peer": true, "engines": { "node": ">= 0.4" } @@ -5365,7 +5358,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5413,8 +5405,6 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "peer": true, "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -5570,8 +5560,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "peer": true, "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -5614,8 +5602,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "peer": true, "dependencies": { "es-define-property": "^1.0.0" }, @@ -5627,8 +5613,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -5640,8 +5624,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -5669,7 +5651,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -6689,8 +6670,6 @@ "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "dev": true, - "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7227,6 +7206,20 @@ "node": ">=6" } }, + "node_modules/qs": { + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", + "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -7759,8 +7752,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "peer": true, "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -7848,8 +7839,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -8294,6 +8283,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/stripe": { + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/stripe/-/stripe-15.4.0.tgz", + "integrity": "sha512-o3STlHYUmJh1ogAem434As7hCMEGG43R1fFkX0NuxabnmZoOQ9Ytxuu+e5Tq5NSE3LPUIV64jbjQebHoZvLTKw==", + "dependencies": { + "@types/node": ">=8.1.0", + "qs": "^6.11.0" + }, + "engines": { + "node": ">=12.*" + } + }, "node_modules/sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", diff --git a/package.json b/package.json index a83ee0e..fb9a97d 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,8 @@ "type": "module", "dependencies": { "@supabase/ssr": "^0.1.0", - "@supabase/supabase-js": "^2.42.0" + "@supabase/supabase-js": "^2.42.0", + "stripe": "^15.4.0" }, "engines": { "node": ">=18.13.0" diff --git a/src/routes/api/checkout/+server.ts b/src/routes/api/checkout/+server.ts new file mode 100644 index 0000000..e618d5b --- /dev/null +++ b/src/routes/api/checkout/+server.ts @@ -0,0 +1,29 @@ +import { type RequestHandler, redirect } from '@sveltejs/kit'; + +// This is a public sample test API key. +// Don’t submit any personally identifiable information in requests made with this key. +// Sign in to see your own test API key embedded in code samples. +// eslint-disable-next-line @typescript-eslint/no-var-requires +import stripe from 'stripe'; +const stripeSecretKey = + 'sk_test_51PBMpZLiKlsU6INBHEsWwU2ekDfmotWTZghSl0XRLhtWp6mU7cBIfyBs6eBnG5kgC6MUhnvH5lUm2AbSWxgGfnKm00qTpaUnAP'; +const stripeClient = new stripe(stripeSecretKey); + +// Create a checkout session +export const POST: RequestHandler = async ({ request }) => { + // const { priceId } = await request.json(); // Assuming you'll send the price ID from the client + const session = await stripeClient.checkout.sessions.create({ + line_items: [ + { + // Provide the exact Price ID (for example, pr_1234) of the product you want to sell + price: 'price_1PBNHRLiKlsU6INBjXMcRxxS', //priceId, + quantity: 1 + } + ], + mode: 'payment', + success_url: `${request.headers.get('origin')}/checkout/success`, + cancel_url: `${request.headers.get('origin')}/checkout/cancel` + }); + + return redirect(303, session.url as string); +}; diff --git a/src/routes/checkout/+page.svelte b/src/routes/checkout/+page.svelte new file mode 100644 index 0000000..72c2b88 --- /dev/null +++ b/src/routes/checkout/+page.svelte @@ -0,0 +1,14 @@ + + +
+
+ The cover of Stubborn Attachments +
+

Stubborn Attachments

+
$20.00
+
+
+
+ +
+
diff --git a/src/routes/checkout/cancelled/+page.svelte b/src/routes/checkout/cancelled/+page.svelte new file mode 100644 index 0000000..2a0f39a --- /dev/null +++ b/src/routes/checkout/cancelled/+page.svelte @@ -0,0 +1,3 @@ +
+

Forgot to add something to your cart? Shop around then come back to pay!

+
diff --git a/src/routes/checkout/success/+page.svelte b/src/routes/checkout/success/+page.svelte new file mode 100644 index 0000000..412d1ba --- /dev/null +++ b/src/routes/checkout/success/+page.svelte @@ -0,0 +1,6 @@ +
+

+ We appreciate your business! If you have any questions, please email + orders@example.com. +

+