V2 Payment Features (#4974)

* Added ability to add seats to enterprise
* first logged in date on people page
* Remove Premium config section				
* Cleanup add seat flow					
* Shrink numbers in plan 					
* Make editing text a server feature in the highlights
* default to dollar pricing				
* clear checkout logic when crash				
* Recongnise location and find pricing			
* Payment successful page

---------

Co-authored-by: Connor Yoh <[email protected]>
This commit is contained in:
ConnorYoh
2025-11-24 16:38:07 +00:00
committed by GitHub
co-authored by Connor Yoh
parent 050408639b
commit 5d18184e46
37 changed files with 2321 additions and 685 deletions
@@ -43,6 +43,7 @@ export interface CheckoutSessionRequest {
current_license_key?: string; // Current license key for upgrades
requires_seats?: boolean; // Whether to add adjustable seat pricing
seat_count?: number; // Initial number of seats for enterprise plans (user can adjust in Stripe UI)
email?: string; // Customer email for checkout pre-fill
successUrl?: string;
cancelUrl?: string;
}
@@ -109,7 +110,7 @@ const licenseService = {
/**
* Get available plans with pricing for the specified currency
*/
async getPlans(currency: string = 'gbp'): Promise<PlansResponse> {
async getPlans(currency: string = 'usd'): Promise<PlansResponse> {
try {
// Check if Supabase is configured
if (!isSupabaseConfigured || !supabase) {
@@ -320,6 +321,7 @@ const licenseService = {
current_license_key: request.current_license_key,
requires_seats: request.requires_seats,
seat_count: request.seat_count || 1,
email: request.email,
callback_base_url: baseUrl,
ui_mode: checkoutMode,
// For hosted checkout, provide success/cancel URLs
@@ -443,6 +445,42 @@ const licenseService = {
throw error;
}
},
/**
* Update enterprise seat count
* Creates a Stripe billing portal session for confirming seat changes
* @param newSeatCount - New number of seats
* @param licenseKey - Current license key for authentication
* @returns Billing portal URL for confirming the change
*/
async updateEnterpriseSeats(newSeatCount: number, licenseKey: string): Promise<string> {
// Check if Supabase is configured
if (!isSupabaseConfigured || !supabase) {
throw new Error('Supabase is not configured. Seat updates are not available.');
}
const baseUrl = window.location.origin;
const returnUrl = `${baseUrl}/settings/adminPlan?seats_updated=true`;
const { data, error } = await supabase.functions.invoke('manage-billing', {
body: {
return_url: returnUrl,
license_key: licenseKey,
self_hosted: true,
new_seat_count: newSeatCount,
},
});
if (error) {
throw new Error(`Failed to update seat count: ${error.message}`);
}
if (!data || !data.url) {
throw new Error('No billing portal URL returned');
}
return data.url;
},
};
/**