182 lines
4.3 KiB
TypeScript
182 lines
4.3 KiB
TypeScript
'use server';
|
|
|
|
import Stripe from 'stripe';
|
|
import { stripe } from '@/utils/stripe/config';
|
|
import { createClient } from '@/utils/supabase/server';
|
|
import { createOrRetrieveCustomer } from '@/utils/supabase/admin';
|
|
import {
|
|
getURL,
|
|
getErrorRedirect,
|
|
calculateTrialEndUnixTimestamp
|
|
} from '@/utils/helpers';
|
|
import { Tables } from '@/types/types_db';
|
|
|
|
type Price = Tables<'prices'>;
|
|
|
|
type CheckoutResponse = {
|
|
errorRedirect?: string;
|
|
sessionId?: string;
|
|
};
|
|
|
|
export async function checkoutWithStripe(
|
|
price: Price,
|
|
redirectPath: string = '/account'
|
|
): Promise<CheckoutResponse> {
|
|
try {
|
|
// Get the user from Supabase auth
|
|
const supabase = createClient();
|
|
const {
|
|
error,
|
|
data: { user }
|
|
} = await supabase.auth.getUser();
|
|
|
|
if (error || !user) {
|
|
console.error(error);
|
|
throw new Error('Could not get user session.');
|
|
}
|
|
|
|
// Retrieve or create the customer in Stripe
|
|
let customer: string;
|
|
try {
|
|
customer = await createOrRetrieveCustomer({
|
|
uuid: user?.id || '',
|
|
email: user?.email || ''
|
|
});
|
|
} catch (err) {
|
|
console.error(err);
|
|
throw new Error('Unable to access customer record.');
|
|
}
|
|
|
|
let params: Stripe.Checkout.SessionCreateParams = {
|
|
allow_promotion_codes: true,
|
|
billing_address_collection: 'required',
|
|
customer,
|
|
customer_update: {
|
|
address: 'auto'
|
|
},
|
|
line_items: [
|
|
{
|
|
price: price.id,
|
|
quantity: 1
|
|
}
|
|
],
|
|
cancel_url: getURL(),
|
|
success_url: getURL(redirectPath)
|
|
};
|
|
|
|
console.log(
|
|
'Trial end:',
|
|
calculateTrialEndUnixTimestamp(price.trial_period_days)
|
|
);
|
|
if (price.type === 'recurring') {
|
|
params = {
|
|
...params,
|
|
mode: 'subscription',
|
|
subscription_data: {
|
|
trial_end: calculateTrialEndUnixTimestamp(price.trial_period_days)
|
|
}
|
|
};
|
|
} else if (price.type === 'one_time') {
|
|
params = {
|
|
...params,
|
|
mode: 'payment'
|
|
};
|
|
}
|
|
|
|
// Create a checkout session in Stripe
|
|
let session;
|
|
try {
|
|
session = await stripe.checkout.sessions.create(params);
|
|
} catch (err) {
|
|
console.error(err);
|
|
throw new Error('Unable to create checkout session.');
|
|
}
|
|
|
|
// Instead of returning a Response, just return the data or error.
|
|
if (session) {
|
|
return { sessionId: session.id };
|
|
} else {
|
|
throw new Error('Unable to create checkout session.');
|
|
}
|
|
} catch (error) {
|
|
if (error instanceof Error) {
|
|
return {
|
|
errorRedirect: getErrorRedirect(
|
|
redirectPath,
|
|
error.message,
|
|
'Please try again later or contact a system administrator.'
|
|
)
|
|
};
|
|
} else {
|
|
return {
|
|
errorRedirect: getErrorRedirect(
|
|
redirectPath,
|
|
'An unknown error occurred.',
|
|
'Please try again later or contact a system administrator.'
|
|
)
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
export async function createStripePortal(currentPath: string) {
|
|
try {
|
|
const supabase = createClient();
|
|
const {
|
|
error,
|
|
data: { user }
|
|
} = await supabase.auth.getUser();
|
|
|
|
if (!user) {
|
|
if (error) {
|
|
console.error(error);
|
|
}
|
|
throw new Error('Could not get user session.');
|
|
}
|
|
|
|
let customer;
|
|
try {
|
|
customer = await createOrRetrieveCustomer({
|
|
uuid: user.id || '',
|
|
email: user.email || ''
|
|
});
|
|
} catch (err) {
|
|
console.error(err);
|
|
throw new Error('Unable to access customer record.');
|
|
}
|
|
|
|
if (!customer) {
|
|
throw new Error('Could not get customer.');
|
|
}
|
|
|
|
try {
|
|
const { url } = await stripe.billingPortal.sessions.create({
|
|
customer,
|
|
return_url: getURL('/account')
|
|
});
|
|
if (!url) {
|
|
throw new Error('Could not create billing portal');
|
|
}
|
|
return url;
|
|
} catch (err) {
|
|
console.error(err);
|
|
throw new Error('Could not create billing portal');
|
|
}
|
|
} catch (error) {
|
|
if (error instanceof Error) {
|
|
console.error(error);
|
|
return getErrorRedirect(
|
|
currentPath,
|
|
error.message,
|
|
'Please try again later or contact a system administrator.'
|
|
);
|
|
} else {
|
|
return getErrorRedirect(
|
|
currentPath,
|
|
'An unknown error occurred.',
|
|
'Please try again later or contact a system administrator.'
|
|
);
|
|
}
|
|
}
|
|
}
|