Updated dependencies, Added Hosted mode for Stripe checkout

* chore: bump version to 3.1.0 and update dependencies in package.json, pnpm-lock.yaml, and pnpm-workspace.yaml; enhance billing services with support for hosted checkout page in Stripe integration

* Enhance error handling in billing services to log error messages instead of objects; update documentation for Stripe integration to clarify publishable key requirements based on UI mode.
This commit is contained in:
Giancarlo Buomprisco
2026-03-31 12:44:30 +08:00
committed by GitHub
parent 9d7c7f8030
commit 6268d1bab0
15 changed files with 1018 additions and 566 deletions

View File

@@ -18,6 +18,7 @@ EMAIL_PASSWORD=password
# STRIPE
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_51K9cWKI1i3VnbZTq2HGstY2S8wt3peF1MOqPXFO4LR8ln2QgS7GxL8XyKaKLvn7iFHeqAnvdDw0o48qN7rrwwcHU00jOtKhjsf
STRIPE_UI_MODE=embedded_page # TESTS ONLY SUPPORT THIS MODE, KEEP AS IS
CONTACT_EMAIL=test@makerkit.dev

View File

@@ -1,4 +1,6 @@
import 'server-only';
import { redirect } from 'next/navigation';
import { SupabaseClient } from '@supabase/supabase-js';
import * as z from 'zod';
@@ -81,9 +83,12 @@ class UserBillingService {
`User requested a personal account checkout session. Contacting provider...`,
);
let checkoutToken: string | null | undefined;
let url: string | null | undefined;
try {
// call the payment gateway to create the checkout session
const { checkoutToken } = await service.createCheckoutSession({
const checkout = await service.createCheckoutSession({
returnUrl,
accountId,
customerEmail: user.email,
@@ -93,32 +98,55 @@ class UserBillingService {
enableDiscountField: product.enableDiscountField,
});
logger.info(
{
userId: user.id,
},
`Checkout session created. Returning checkout token to client...`,
);
// return the checkout token to the client
// so we can call the payment gateway to complete the checkout
return {
checkoutToken,
};
checkoutToken = checkout.checkoutToken;
url = checkout.url;
} catch (error) {
const message = Error.isError(error) ? error.message : error;
logger.error(
{
name: `billing.personal-account`,
planId,
customerId,
accountId,
error,
error: message
},
`Checkout session not created due to an error`,
);
throw new Error(`Failed to create a checkout session`, { cause: error });
}
if (!url && !checkoutToken) {
throw new Error(
'Checkout session returned neither a URL nor a checkout token',
);
}
// if URL provided, we redirect to the provider's hosted page
if (url) {
logger.info(
{
userId: user.id,
},
`Checkout session created. Redirecting to hosted page...`,
);
redirect(url);
}
// return the checkout token to the client
// so we can call the payment gateway to complete the checkout
logger.info(
{
userId: user.id,
},
`Checkout session created. Returning checkout token to client...`,
);
return {
checkoutToken,
};
}
/**

View File

@@ -1,4 +1,6 @@
import 'server-only';
import { redirect } from 'next/navigation';
import { SupabaseClient } from '@supabase/supabase-js';
import * as z from 'zod';
@@ -106,9 +108,12 @@ class TeamBillingService {
`Creating checkout session...`,
);
let checkoutToken: string | null = null;
let url: string | null | undefined;
try {
// call the payment gateway to create the checkout session
const { checkoutToken } = await service.createCheckoutSession({
const checkout = await service.createCheckoutSession({
accountId,
plan,
returnUrl,
@@ -118,22 +123,37 @@ class TeamBillingService {
enableDiscountField: product.enableDiscountField,
});
// return the checkout token to the client
// so we can call the payment gateway to complete the checkout
return {
checkoutToken,
};
checkoutToken = checkout.checkoutToken;
url = checkout.url;
} catch (error) {
const message = Error.isError(error) ? error.message : error;
logger.error(
{
...ctx,
error,
error: message
},
`Error creating the checkout session`,
);
throw new Error(`Checkout not created`, { cause: error });
}
// if URL provided, we redirect to the provider's hosted page
if (url) {
logger.info(
ctx,
`Checkout session created. Redirecting to hosted page...`,
);
redirect(url);
}
// return the checkout token to the client
// so we can call the payment gateway to complete the checkout
return {
checkoutToken,
};
}
/**