Files
myeasycms-v2/apps/web/app/(dashboard)/home/(user)/billing/server-actions.ts
giancarlo 95793c42b4 Remove admin functionality related code
The admin functionality related code has been removed which includes various user and organization functionalities like delete, update, ban etc. This includes action logic, UI components and supportive utility functions. Notable deletions include the server action files, dialog components for actions like banning and deleting, and related utility functions. This massive cleanup is aimed at simplifying the codebase and the commit reflects adherence to project restructuring.
2024-03-25 15:40:43 +08:00

127 lines
3.4 KiB
TypeScript

'use server';
import { headers } from 'next/headers';
import { redirect } from 'next/navigation';
import { z } from 'zod';
import { getProductPlanPairFromId } from '@kit/billing';
import { getBillingGatewayProvider } from '@kit/billing-gateway';
import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client';
import billingConfig from '~/config/billing.config';
import pathsConfig from '~/config/paths.config';
/**
* Creates a checkout session for a personal account.
*
* @param {object} params - The parameters for creating the checkout session.
* @param {string} params.planId - The ID of the plan to be associated with the account.
*/
export async function createPersonalAccountCheckoutSession(params: {
planId: string;
}) {
const client = getSupabaseServerActionClient();
const { data, error } = await client.auth.getUser();
if (error ?? !data.user) {
throw new Error('Authentication required');
}
const planId = z.string().min(1).parse(params.planId);
const service = await getBillingGatewayProvider(client);
const productPlanPairFromId = getProductPlanPairFromId(billingConfig, planId);
if (!productPlanPairFromId) {
throw new Error('Product not found');
}
// in the case of personal accounts
// the account ID is the same as the user ID
const accountId = data.user.id;
// the return URL for the checkout session
const returnUrl = getCheckoutSessionReturnUrl();
// find the customer ID for the account if it exists
// (eg. if the account has been billed before)
const customerId = await getCustomerIdFromAccountId(accountId);
// retrieve the product and plan from the billing configuration
const { product, plan } = productPlanPairFromId;
// call the payment gateway to create the checkout session
const { checkoutToken } = await service.createCheckoutSession({
paymentType: product.paymentType,
returnUrl,
accountId,
planId,
trialPeriodDays: plan.trialPeriodDays,
customerEmail: data.user.email,
customerId,
});
// return the checkout token to the client
// so we can call the payment gateway to complete the checkout
return {
checkoutToken,
};
}
export async function createBillingPortalSession() {
const client = getSupabaseServerActionClient();
const { data, error } = await client.auth.getUser();
if (error ?? !data.user) {
throw new Error('Authentication required');
}
const service = await getBillingGatewayProvider(client);
const accountId = data.user.id;
const customerId = await getCustomerIdFromAccountId(accountId);
const returnUrl = getBillingPortalReturnUrl();
if (!customerId) {
throw new Error('Customer not found');
}
const { url } = await service.createBillingPortalSession({
customerId,
returnUrl,
});
return redirect(url);
}
function getCheckoutSessionReturnUrl() {
const origin = headers().get('origin')!;
return new URL(
pathsConfig.app.personalAccountBillingReturn,
origin,
).toString();
}
function getBillingPortalReturnUrl() {
const origin = headers().get('origin')!;
return new URL(pathsConfig.app.accountBilling, origin).toString();
}
async function getCustomerIdFromAccountId(accountId: string) {
const client = getSupabaseServerActionClient();
const { data, error } = await client
.from('billing_customers')
.select('customer_id')
.eq('account_id', accountId)
.maybeSingle();
if (error) {
throw error;
}
return data?.customer_id;
}