Skip to content

Commit 01141cd

Browse files
committed
fix(dashboard): allow stripe onboarded users to login to the stripe dashboard
1 parent d2211ea commit 01141cd

File tree

7 files changed

+137
-186
lines changed

7 files changed

+137
-186
lines changed

src/lib/server/stripe.server.ts

Lines changed: 78 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,26 @@ import Stripe from "stripe"
77

88
export const stripe = new Stripe(STRIPE_KEY, { apiVersion: "2025-05-28.basil", typescript: true })
99

10+
export async function createCustomer(id: string, email: string, discord: string, username: string) {
11+
let customer: Stripe.Customer
12+
13+
try {
14+
customer = await stripe.customers.create({
15+
email: email,
16+
name: username,
17+
metadata: {
18+
wsid: id,
19+
discord: discord,
20+
username: username
21+
}
22+
})
23+
} catch (error) {
24+
console.error(error)
25+
return null
26+
}
27+
return customer.id
28+
}
29+
1030
export async function createCustomerPortal(customer: string, origin: string) {
1131
let portal: Stripe.BillingPortal.Session
1232

@@ -74,78 +94,7 @@ export async function createCheckoutSession(
7494
return session.url
7595
}
7696

77-
export async function getStripeConnectAccount(scripter: Scripter) {
78-
if (scripter.id == scripter.stripe) return null
79-
let stripeAccount: Stripe.Account | null = null
80-
81-
try {
82-
stripeAccount = await stripe.accounts.retrieve(scripter.stripe)
83-
} catch (error) {
84-
console.error("An error occurred when calling the Stripe API to create an account session", error)
85-
}
86-
87-
return stripeAccount
88-
}
89-
90-
export async function getStripeConnectAccountBalance(scripter: Scripter) {
91-
if (scripter.id == scripter.stripe) return null
92-
let stripeBalance: Stripe.Balance | null = null
93-
try {
94-
stripeBalance = await stripe.balance.retrieve({ stripeAccount: scripter.stripe })
95-
} catch (error) {
96-
console.error("An error occurred when calling the Stripe API to create an account session", error)
97-
}
98-
99-
return stripeBalance
100-
}
101-
102-
export async function getStripeSession(scripter: Scripter) {
103-
if (scripter.id == scripter.stripe) return null
104-
let session: Stripe.Response<Stripe.AccountSession> | null = null
105-
106-
try {
107-
session = await stripe.accountSessions.create({
108-
account: scripter.stripe,
109-
components: {
110-
payments: {
111-
enabled: true,
112-
features: { refund_management: true, dispute_management: true, capture_payments: true }
113-
},
114-
payouts: { enabled: true },
115-
payment_details: {
116-
enabled: true,
117-
features: { refund_management: true, capture_payments: true, dispute_management: true }
118-
}
119-
}
120-
})
121-
} catch (error) {
122-
console.error("An error occurred when calling the Stripe API to create an account session", error)
123-
}
124-
125-
return session?.client_secret ?? null
126-
}
127-
128-
export async function createStripeCustomer(id: string, email: string, discord: string, username: string) {
129-
let customer: Stripe.Customer
130-
131-
try {
132-
customer = await stripe.customers.create({
133-
email: email,
134-
name: username,
135-
metadata: {
136-
wsid: id,
137-
discord: discord,
138-
username: username
139-
}
140-
})
141-
} catch (error) {
142-
console.error(error)
143-
return null
144-
}
145-
return customer.id
146-
}
147-
148-
export async function createStripeConnectAccount(
97+
export async function createAccount(
14998
supabase: SupabaseClient,
15099
baseURL: string,
151100
scripter: Scripter,
@@ -219,16 +168,27 @@ export async function createStripeConnectAccount(
219168
return accountLink.url
220169
}
221170

222-
export async function finishStripeConnectAccountSetup(baseURL: string, account: string) {
171+
export async function getOnboardingLink(baseURL: string, scripter: Scripter) {
172+
const account = await getAccount(scripter)
173+
223174
let accountLink: Stripe.Response<Stripe.AccountLink>
224175

225176
try {
226-
accountLink = await stripe.accountLinks.create({
227-
account: account,
228-
refresh_url: baseURL + "/api/stripe/connect/reauth",
229-
return_url: baseURL + "/api/stripe/connect/return",
230-
type: "account_update"
231-
})
177+
if (!account!.tos_acceptance || !account!.tos_acceptance.date) {
178+
accountLink = await stripe.accountLinks.create({
179+
account: account!.id,
180+
refresh_url: baseURL + "/api/stripe/connect/reauth",
181+
return_url: baseURL + "/api/stripe/connect/return",
182+
type: "account_onboarding"
183+
})
184+
} else {
185+
accountLink = await stripe.accountLinks.create({
186+
account: account!.id,
187+
refresh_url: baseURL + "/api/stripe/connect/reauth",
188+
return_url: baseURL + "/api/stripe/connect/return",
189+
type: "account_update"
190+
})
191+
}
232192
} catch (err) {
233193
console.error(err)
234194
return
@@ -237,7 +197,37 @@ export async function finishStripeConnectAccountSetup(baseURL: string, account:
237197
return accountLink.url
238198
}
239199

240-
export async function updateStripeConnectAccount(id: string, dba: string) {
200+
export async function getAccount(scripter: Scripter) {
201+
if (scripter.id == scripter.stripe) return null
202+
let account: Stripe.Account | null = null
203+
204+
try {
205+
account = await stripe.accounts.retrieve(scripter.stripe)
206+
} catch (error) {
207+
console.error("An error occurred when calling the Stripe API to create an account session", error)
208+
}
209+
210+
return account
211+
}
212+
213+
export async function getLoginLink(scripter: Scripter) {
214+
const account = await getAccount(scripter)
215+
if (!account) return null
216+
217+
if (account.requirements?.currently_due && account.requirements.currently_due.length > 0) return null
218+
219+
let link: Stripe.Response<Stripe.LoginLink> | null = null
220+
221+
try {
222+
link = await stripe.accounts.createLoginLink(account.id)
223+
} catch (error) {
224+
console.error("An error occurred when calling the Stripe API to create an account login link", error)
225+
}
226+
227+
return link?.url ?? null
228+
}
229+
230+
export async function updateAccountDBA(id: string, dba: string) {
241231
try {
242232
await stripe.accounts.update(id, { business_profile: { name: dba } })
243233
} catch (error) {
@@ -248,7 +238,7 @@ export async function updateStripeConnectAccount(id: string, dba: string) {
248238
return true
249239
}
250240

251-
export async function updateStripeProduct(id: string, name: string) {
241+
export async function updateProduct(id: string, name: string) {
252242
try {
253243
await stripe.products
254244
.update(id, {
@@ -260,7 +250,7 @@ export async function updateStripeProduct(id: string, name: string) {
260250
}
261251
}
262252

263-
async function createStripePriceEx(product: string, amount: number, interval: Interval) {
253+
async function createPriceEx(product: string, amount: number, interval: Interval) {
264254
if (amount === 0) return
265255
await stripe.prices
266256
.create({
@@ -273,7 +263,7 @@ async function createStripePriceEx(product: string, amount: number, interval: In
273263
.catch((err: unknown) => console.error(err))
274264
}
275265

276-
export async function createStripePrice(price: PriceSchema, product: string) {
266+
export async function createPrice(price: PriceSchema, product: string) {
277267
if (price.amount === 0) return
278268
await stripe.prices
279269
.create({
@@ -286,7 +276,7 @@ export async function createStripePrice(price: PriceSchema, product: string) {
286276
.catch((err: unknown) => console.error(err))
287277
}
288278

289-
export async function updateStripePrice(price: Price) {
279+
export async function updatePrice(price: Price) {
290280
const promises = []
291281
if (price.amount > 0)
292282
promises.push(
@@ -305,7 +295,7 @@ export async function updateStripePrice(price: Price) {
305295
await Promise.all(promises)
306296
}
307297

308-
export async function createStripeBundleProduct(supabase: SupabaseClient<Database>, bundle: BundleSchema) {
298+
export async function createBundleProduct(supabase: SupabaseClient<Database>, bundle: BundleSchema) {
309299
const scripts = bundle.bundledScripts.reduce((acc: string[], script) => {
310300
if (script.active) acc.push(script.id)
311301
return acc
@@ -341,14 +331,14 @@ export async function createStripeBundleProduct(supabase: SupabaseClient<Databas
341331

342332
bundle.prices.forEach((price) => {
343333
if (price.amount) {
344-
stripePromises.push(createStripePriceEx(product.id, price.amount, price.interval as Interval))
334+
stripePromises.push(createPriceEx(product.id, price.amount, price.interval as Interval))
345335
}
346336
})
347337

348338
await Promise.all(stripePromises)
349339
}
350340

351-
export async function createStripeScriptProduct(script: NewScriptSchema, name: string, user_id: string) {
341+
export async function createScriptProduct(script: NewScriptSchema, name: string, user_id: string) {
352342
script.prices = script.prices.filter((price) => price.amount > 0)
353343
if (script.prices.length === 0) return
354344

@@ -366,7 +356,7 @@ export async function createStripeScriptProduct(script: NewScriptSchema, name: s
366356

367357
script.prices.forEach((price) => {
368358
if (price.amount) {
369-
stripePromises.push(createStripePriceEx(product.id, price.amount, price.interval as Interval))
359+
stripePromises.push(createPriceEx(product.id, price.amount, price.interval as Interval))
370360
}
371361
})
372362

src/routes/auth/callback/+server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { error, redirect } from "@sveltejs/kit"
22
import { formatError } from "$lib/utils"
3-
import { createStripeCustomer } from "$lib/server/stripe.server"
3+
import { createCustomer } from "$lib/server/stripe.server"
44

55
export const GET = async ({ url: { searchParams }, locals: { supabaseServer } }) => {
66
console.log("💻 Logging in")
@@ -40,7 +40,7 @@ export const GET = async ({ url: { searchParams }, locals: { supabaseServer } })
4040

4141
if (user.email && user.app_metadata.provider == "discord") {
4242
const discord = user.user_metadata["provider_id"]
43-
const stripe = await createStripeCustomer(
43+
const stripe = await createCustomer(
4444
user.id,
4545
user.email,
4646
discord,

src/routes/auth/launcher/+server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { error, json } from "@sveltejs/kit"
22
import { formatError } from "$lib/utils"
3-
import { createStripeCustomer } from "$lib/server/stripe.server"
3+
import { createCustomer } from "$lib/server/stripe.server"
44
import { supabaseAdmin } from "$lib/server/supabase.server"
55

66
export const POST = async ({ request }) => {
@@ -32,7 +32,7 @@ export const POST = async ({ request }) => {
3232

3333
if (user.email && user.app_metadata.provider == "discord") {
3434
const discord = user.user_metadata["provider_id"]
35-
const stripe = await createStripeCustomer(
35+
const stripe = await createCustomer(
3636
user.id,
3737
user.email,
3838
discord,

src/routes/dashboard/[slug]/bundles/+page.server.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { bundleArraySchema, newBundleSchema } from "$lib/client/schemas"
22
import { getScripter } from "$lib/client/supabase"
33
import {
4-
createStripeBundleProduct,
5-
createStripePrice,
4+
createBundleProduct,
5+
createPrice,
66
stripe,
7-
updateStripePrice,
8-
updateStripeProduct
7+
updatePrice,
8+
updateProduct
99
} from "$lib/server/stripe.server"
1010
import { addFreeAccess, cancelFreeAccess, doLogin } from "$lib/server/supabase.server"
1111
import { formatError, UUID_V4_REGEX } from "$lib/utils"
@@ -171,7 +171,7 @@ export const actions = {
171171
if (errProducts) return setError(form, "", formatError(errProducts))
172172
if (!productsData.bundle) return setError(form, "", "That product is missing a bundle ID!")
173173

174-
if (product.name !== productsData.name) await updateStripeProduct(product.id, product.name)
174+
if (product.name !== productsData.name) await updateProduct(product.id, product.name)
175175

176176
const { data: pricesData, error: errPrices } = await supabaseServer
177177
.schema("stripe")
@@ -191,7 +191,7 @@ export const actions = {
191191
const updatePricesPromises = []
192192
if (Math.round(newPrice.amount * 100) !== currentPrice.amount)
193193
updatePricesPromises.push(
194-
updateStripePrice({
194+
updatePrice({
195195
active: true,
196196
amount: newPrice.amount,
197197
currency: newPrice.currency as "eur" | "usd" | "cad" | "aud",
@@ -213,7 +213,7 @@ export const actions = {
213213
pricesData.splice(j, 1)
214214
continue
215215
}
216-
createPricePromises.push(createStripePrice(currentPrice, product.id))
216+
createPricePromises.push(createPrice(currentPrice, product.id))
217217
}
218218

219219
await Promise.all(createPricePromises)
@@ -257,7 +257,7 @@ export const actions = {
257257
if (scripter.stripe == scripter.id) return setError(form, "", "Stripe account is not setup!")
258258
if (!["administrator", "moderator"].includes(profile.role)) form.data.user_id = user.id
259259

260-
const err = await createStripeBundleProduct(supabaseServer, form.data)
260+
const err = await createBundleProduct(supabaseServer, form.data)
261261

262262
if (err) return setError(form, "", err.message)
263263

src/routes/dashboard/[slug]/scripts/+page.server.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { newScriptSchema, scriptArraySchema } from "$lib/client/schemas"
22
import { getScripter } from "$lib/client/supabase"
33
import {
4-
createStripePrice,
5-
createStripeScriptProduct,
4+
createPrice,
5+
createScriptProduct,
66
stripe,
7-
updateStripePrice,
8-
updateStripeProduct
7+
updatePrice,
8+
updateProduct
99
} from "$lib/server/stripe.server"
1010
import { addFreeAccess, cancelFreeAccess, doLogin } from "$lib/server/supabase.server"
1111
import { formatError, UUID_V4_REGEX } from "$lib/utils"
@@ -146,7 +146,7 @@ export const actions = {
146146

147147
if (errProducts) return setError(form, "", errProducts.message)
148148

149-
if (product.name !== productsData.name) await updateStripeProduct(product.id, product.name)
149+
if (product.name !== productsData.name) await updateProduct(product.id, product.name)
150150

151151
const { data: pricesData, error: errPrices } = await supabaseServer
152152
.schema("stripe")
@@ -166,7 +166,7 @@ export const actions = {
166166
const updatePricesPromises = []
167167
if (Math.round(newPrice.amount * 100) !== currentPrice.amount)
168168
updatePricesPromises.push(
169-
updateStripePrice({
169+
updatePrice({
170170
active: true,
171171
amount: newPrice.amount,
172172
currency: newPrice.currency as "eur" | "usd" | "cad" | "aud",
@@ -188,7 +188,7 @@ export const actions = {
188188
pricesData.splice(j, 1)
189189
continue
190190
}
191-
createPricePromises.push(createStripePrice(currentPrice, product.id))
191+
createPricePromises.push(createPrice(currentPrice, product.id))
192192
}
193193

194194
await Promise.all(createPricePromises)
@@ -248,7 +248,7 @@ export const actions = {
248248

249249
if (errProtected) return setError(form, "", formatError(errProtected))
250250

251-
await createStripeScriptProduct(form.data, data.scripts.title, data.author)
251+
await createScriptProduct(form.data, data.scripts.title, data.author)
252252

253253
redirect(303, pathname)
254254
},

0 commit comments

Comments
 (0)