Add logging and error-handling to billing service
Enhanced the TeamBillingService class by including several logging statements and added error-handling surrounding the creation of a checkout session and a billing portal session. The logging statements provide more context about the processes such as the associated user and account, adding a layer of transparency and traceability.
This commit is contained in:
@@ -16,6 +16,8 @@ import billingConfig from '~/config/billing.config';
|
|||||||
import pathsConfig from '~/config/paths.config';
|
import pathsConfig from '~/config/paths.config';
|
||||||
|
|
||||||
export class TeamBillingService {
|
export class TeamBillingService {
|
||||||
|
private readonly namespace = 'billing.team-account';
|
||||||
|
|
||||||
constructor(private readonly client: SupabaseClient<Database>) {}
|
constructor(private readonly client: SupabaseClient<Database>) {}
|
||||||
|
|
||||||
async createCheckout(params: z.infer<typeof TeamCheckoutSchema>) {
|
async createCheckout(params: z.infer<typeof TeamCheckoutSchema>) {
|
||||||
@@ -29,6 +31,15 @@ export class TeamBillingService {
|
|||||||
const userId = user.id;
|
const userId = user.id;
|
||||||
const accountId = params.accountId;
|
const accountId = params.accountId;
|
||||||
|
|
||||||
|
Logger.info(
|
||||||
|
{
|
||||||
|
userId,
|
||||||
|
accountId,
|
||||||
|
name: this.namespace,
|
||||||
|
},
|
||||||
|
`Requested checkout session. Processing...`,
|
||||||
|
);
|
||||||
|
|
||||||
// verify permissions to manage billing
|
// verify permissions to manage billing
|
||||||
const hasPermission = await getBillingPermissionsForAccountId(
|
const hasPermission = await getBillingPermissionsForAccountId(
|
||||||
userId,
|
userId,
|
||||||
@@ -38,6 +49,15 @@ export class TeamBillingService {
|
|||||||
// if the user does not have permission to manage billing for the account
|
// if the user does not have permission to manage billing for the account
|
||||||
// then we should not proceed
|
// then we should not proceed
|
||||||
if (!hasPermission) {
|
if (!hasPermission) {
|
||||||
|
Logger.warn(
|
||||||
|
{
|
||||||
|
userId,
|
||||||
|
accountId,
|
||||||
|
name: this.namespace,
|
||||||
|
},
|
||||||
|
`User without permissions attempted to create checkout.`,
|
||||||
|
);
|
||||||
|
|
||||||
throw new Error('Permission denied');
|
throw new Error('Permission denied');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,6 +85,17 @@ export class TeamBillingService {
|
|||||||
accountId,
|
accountId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Logger.info(
|
||||||
|
{
|
||||||
|
userId,
|
||||||
|
accountId,
|
||||||
|
planId: plan.id,
|
||||||
|
namespace: this.namespace,
|
||||||
|
},
|
||||||
|
`Creating checkout session...`,
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
// call the payment gateway to create the checkout session
|
// call the payment gateway to create the checkout session
|
||||||
const { checkoutToken } = await service.createCheckoutSession({
|
const { checkoutToken } = await service.createCheckoutSession({
|
||||||
accountId,
|
accountId,
|
||||||
@@ -80,6 +111,19 @@ export class TeamBillingService {
|
|||||||
return {
|
return {
|
||||||
checkoutToken,
|
checkoutToken,
|
||||||
};
|
};
|
||||||
|
} catch (error) {
|
||||||
|
Logger.error(
|
||||||
|
{
|
||||||
|
name: this.namespace,
|
||||||
|
error,
|
||||||
|
accountId,
|
||||||
|
planId: plan.id,
|
||||||
|
},
|
||||||
|
`Error creating the checkout session`,
|
||||||
|
);
|
||||||
|
|
||||||
|
throw new Error(`Checkout not created`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async createBillingPortalSession({
|
async createBillingPortalSession({
|
||||||
@@ -91,6 +135,14 @@ export class TeamBillingService {
|
|||||||
}) {
|
}) {
|
||||||
const client = getSupabaseServerActionClient();
|
const client = getSupabaseServerActionClient();
|
||||||
|
|
||||||
|
Logger.info(
|
||||||
|
{
|
||||||
|
accountId,
|
||||||
|
name: this.namespace,
|
||||||
|
},
|
||||||
|
`Billing portal session requested. Processing...`,
|
||||||
|
);
|
||||||
|
|
||||||
const { data: user, error } = await requireUser(client);
|
const { data: user, error } = await requireUser(client);
|
||||||
|
|
||||||
if (error ?? !user) {
|
if (error ?? !user) {
|
||||||
@@ -108,17 +160,38 @@ export class TeamBillingService {
|
|||||||
// if the user does not have permission to manage billing for the account
|
// if the user does not have permission to manage billing for the account
|
||||||
// then we should not proceed
|
// then we should not proceed
|
||||||
if (!hasPermission) {
|
if (!hasPermission) {
|
||||||
|
Logger.warn(
|
||||||
|
{
|
||||||
|
userId,
|
||||||
|
accountId,
|
||||||
|
name: this.namespace,
|
||||||
|
},
|
||||||
|
`User without permissions attempted to create billing portal session.`,
|
||||||
|
);
|
||||||
|
|
||||||
throw new Error('Permission denied');
|
throw new Error('Permission denied');
|
||||||
}
|
}
|
||||||
|
|
||||||
const service = await getBillingGatewayProvider(client);
|
const service = await getBillingGatewayProvider(client);
|
||||||
const customerId = await getCustomerIdFromAccountId(client, accountId);
|
const customerId = await getCustomerIdFromAccountId(client, accountId);
|
||||||
const returnUrl = getBillingPortalReturnUrl(slug);
|
|
||||||
|
|
||||||
if (!customerId) {
|
if (!customerId) {
|
||||||
throw new Error('Customer not found');
|
throw new Error('Customer not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger.info(
|
||||||
|
{
|
||||||
|
userId,
|
||||||
|
customerId,
|
||||||
|
accountId,
|
||||||
|
name: this.namespace,
|
||||||
|
},
|
||||||
|
`Creating billing portal session...`,
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const returnUrl = getBillingPortalReturnUrl(slug);
|
||||||
|
|
||||||
const { url } = await service.createBillingPortalSession({
|
const { url } = await service.createBillingPortalSession({
|
||||||
customerId,
|
customerId,
|
||||||
returnUrl,
|
returnUrl,
|
||||||
@@ -126,6 +199,19 @@ export class TeamBillingService {
|
|||||||
|
|
||||||
// redirect the user to the billing portal
|
// redirect the user to the billing portal
|
||||||
return url;
|
return url;
|
||||||
|
} catch (error) {
|
||||||
|
Logger.error(
|
||||||
|
{
|
||||||
|
userId,
|
||||||
|
customerId,
|
||||||
|
accountId,
|
||||||
|
name: this.namespace,
|
||||||
|
},
|
||||||
|
`Billing Portal session was not created`,
|
||||||
|
);
|
||||||
|
|
||||||
|
throw new Error(`Error creating Billing Portal`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user