Phase 3 & Phase 4 - Completed

This commit is contained in:
IGNY8 VPS (Salman)
2026-01-07 00:57:26 +00:00
parent 4b6a03a898
commit 909ed1cb17
25 changed files with 5549 additions and 215 deletions

View File

@@ -1126,3 +1126,289 @@ export async function getDashboardStats(params?: { site_id?: number; days?: numb
const query = searchParams.toString();
return fetchAPI(`/v1/account/dashboard/stats/${query ? `?${query}` : ''}`);
}
// ============================================================================
// STRIPE INTEGRATION
// ============================================================================
export interface StripeConfig {
publishable_key: string;
is_sandbox: boolean;
}
export interface StripeCheckoutSession {
checkout_url: string;
session_id: string;
}
export interface StripeBillingPortalSession {
portal_url: string;
}
/**
* Get Stripe publishable key for frontend initialization
*/
export async function getStripeConfig(): Promise<StripeConfig> {
return fetchAPI('/v1/billing/stripe/config/');
}
/**
* Create Stripe Checkout session for plan subscription
* Redirects user to Stripe's hosted checkout page
*/
export async function createStripeCheckout(planId: string, options?: {
success_url?: string;
cancel_url?: string;
}): Promise<StripeCheckoutSession> {
return fetchAPI('/v1/billing/stripe/checkout/', {
method: 'POST',
body: JSON.stringify({
plan_id: planId,
...options,
}),
});
}
/**
* Create Stripe Checkout session for credit package purchase
* Redirects user to Stripe's hosted checkout page
*/
export async function createStripeCreditCheckout(packageId: string, options?: {
success_url?: string;
cancel_url?: string;
}): Promise<StripeCheckoutSession> {
return fetchAPI('/v1/billing/stripe/credit-checkout/', {
method: 'POST',
body: JSON.stringify({
package_id: packageId,
...options,
}),
});
}
/**
* Create Stripe Billing Portal session for subscription management
* Allows customers to manage payment methods, view invoices, cancel subscription
*/
export async function openStripeBillingPortal(options?: {
return_url?: string;
}): Promise<StripeBillingPortalSession> {
return fetchAPI('/v1/billing/stripe/billing-portal/', {
method: 'POST',
body: JSON.stringify(options || {}),
});
}
// ============================================================================
// PAYPAL INTEGRATION
// ============================================================================
export interface PayPalConfig {
client_id: string;
is_sandbox: boolean;
currency: string;
}
export interface PayPalOrder {
order_id: string;
status: string;
approval_url: string;
links?: Array<{ rel: string; href: string }>;
credit_package_id?: string;
credit_amount?: number;
plan_id?: string;
plan_name?: string;
}
export interface PayPalCaptureResult {
order_id: string;
status: string;
capture_id: string;
amount: string;
currency: string;
credits_added?: number;
new_balance?: number;
subscription_id?: string;
plan_name?: string;
payment_id?: number;
}
export interface PayPalSubscription {
subscription_id: string;
status: string;
approval_url: string;
links?: Array<{ rel: string; href: string }>;
}
/**
* Get PayPal client ID for frontend initialization
*/
export async function getPayPalConfig(): Promise<PayPalConfig> {
return fetchAPI('/v1/billing/paypal/config/');
}
/**
* Create PayPal order for credit package purchase
* Returns approval URL for PayPal redirect
*/
export async function createPayPalCreditOrder(packageId: string, options?: {
return_url?: string;
cancel_url?: string;
}): Promise<PayPalOrder> {
return fetchAPI('/v1/billing/paypal/create-order/', {
method: 'POST',
body: JSON.stringify({
package_id: packageId,
...options,
}),
});
}
/**
* Create PayPal order for plan subscription (one-time payment model)
* Returns approval URL for PayPal redirect
*/
export async function createPayPalSubscriptionOrder(planId: string, options?: {
return_url?: string;
cancel_url?: string;
}): Promise<PayPalOrder> {
return fetchAPI('/v1/billing/paypal/create-subscription-order/', {
method: 'POST',
body: JSON.stringify({
plan_id: planId,
...options,
}),
});
}
/**
* Capture PayPal order after user approval
* Call this when user returns from PayPal with approved order
*/
export async function capturePayPalOrder(orderId: string, options?: {
package_id?: string;
plan_id?: string;
}): Promise<PayPalCaptureResult> {
return fetchAPI('/v1/billing/paypal/capture-order/', {
method: 'POST',
body: JSON.stringify({
order_id: orderId,
...options,
}),
});
}
/**
* Create PayPal recurring subscription
* Requires plan to have paypal_plan_id configured
*/
export async function createPayPalSubscription(planId: string, options?: {
return_url?: string;
cancel_url?: string;
}): Promise<PayPalSubscription> {
return fetchAPI('/v1/billing/paypal/create-subscription/', {
method: 'POST',
body: JSON.stringify({
plan_id: planId,
...options,
}),
});
}
// ============================================================================
// PAYMENT GATEWAY HELPERS
// ============================================================================
export type PaymentGateway = 'stripe' | 'paypal' | 'manual';
/**
* Helper to check if Stripe is configured
*/
export async function isStripeConfigured(): Promise<boolean> {
try {
const config = await getStripeConfig();
return !!config.publishable_key;
} catch {
return false;
}
}
/**
* Helper to check if PayPal is configured
*/
export async function isPayPalConfigured(): Promise<boolean> {
try {
const config = await getPayPalConfig();
return !!config.client_id;
} catch {
return false;
}
}
/**
* Get available payment gateways
*/
export async function getAvailablePaymentGateways(): Promise<{
stripe: boolean;
paypal: boolean;
manual: boolean;
}> {
const [stripeAvailable, paypalAvailable] = await Promise.all([
isStripeConfigured(),
isPayPalConfigured(),
]);
return {
stripe: stripeAvailable,
paypal: paypalAvailable,
manual: true, // Manual payment is always available
};
}
/**
* Subscribe to plan using preferred payment gateway
*/
export async function subscribeToPlan(
planId: string,
gateway: PaymentGateway,
options?: { return_url?: string; cancel_url?: string }
): Promise<{ redirect_url: string }> {
switch (gateway) {
case 'stripe': {
const session = await createStripeCheckout(planId, options);
return { redirect_url: session.checkout_url };
}
case 'paypal': {
const order = await createPayPalSubscriptionOrder(planId, options);
return { redirect_url: order.approval_url };
}
case 'manual':
throw new Error('Manual payment requires different flow - use submitManualPayment()');
default:
throw new Error(`Unsupported payment gateway: ${gateway}`);
}
}
/**
* Purchase credit package using preferred payment gateway
*/
export async function purchaseCredits(
packageId: string,
gateway: PaymentGateway,
options?: { return_url?: string; cancel_url?: string }
): Promise<{ redirect_url: string }> {
switch (gateway) {
case 'stripe': {
const session = await createStripeCreditCheckout(packageId, options);
return { redirect_url: session.checkout_url };
}
case 'paypal': {
const order = await createPayPalCreditOrder(packageId, options);
return { redirect_url: order.approval_url };
}
case 'manual':
throw new Error('Manual payment requires different flow - use submitManualPayment()');
default:
throw new Error(`Unsupported payment gateway: ${gateway}`);
}
}