billing accoutn with all the mess here
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Billing API Service
|
||||
* Handles all billing-related API calls
|
||||
* Uses STANDARD existing billing endpoints from /v1/billing/, /v1/system/, and /v1/admin/
|
||||
*/
|
||||
|
||||
import { fetchAPI } from './api';
|
||||
@@ -9,6 +9,127 @@ import { fetchAPI } from './api';
|
||||
// TYPES
|
||||
// ============================================================================
|
||||
|
||||
export interface CreditBalance {
|
||||
credits: number; // Current balance
|
||||
plan_credits_per_month: number; // Monthly allocation from plan
|
||||
credits_used_this_month: number; // Used this billing period
|
||||
credits_remaining: number; // Remaining credits
|
||||
}
|
||||
|
||||
export interface CreditTransaction {
|
||||
id: number;
|
||||
amount: number;
|
||||
transaction_type: 'purchase' | 'subscription' | 'refund' | 'deduction' | 'adjustment' | 'grant';
|
||||
description: string;
|
||||
created_at: string;
|
||||
reference_id?: string;
|
||||
metadata?: Record<string, any>;
|
||||
balance_after?: number;
|
||||
}
|
||||
|
||||
export interface CreditUsageLog {
|
||||
id: number;
|
||||
operation_type: string;
|
||||
credits_used: number;
|
||||
cost_usd: string;
|
||||
model_used?: string;
|
||||
tokens_input?: number;
|
||||
tokens_output?: number;
|
||||
created_at: string;
|
||||
metadata?: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface AdminBillingStats {
|
||||
total_accounts: number;
|
||||
active_subscriptions: number;
|
||||
total_revenue: string;
|
||||
revenue_this_month?: string;
|
||||
new_accounts_this_month?: number;
|
||||
active_accounts?: number;
|
||||
credits_issued_30d?: number;
|
||||
credits_used_30d?: number;
|
||||
pending_approvals?: number;
|
||||
invoices_pending?: number;
|
||||
invoices_overdue?: number;
|
||||
system_health?: {
|
||||
status: string;
|
||||
last_check: string;
|
||||
};
|
||||
recent_activity?: Array<{
|
||||
id: number;
|
||||
type: string;
|
||||
account_name: string;
|
||||
amount: string;
|
||||
currency: string;
|
||||
timestamp: string;
|
||||
description: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface CreditCostConfig {
|
||||
id: number;
|
||||
operation_type: string;
|
||||
credits_cost: number;
|
||||
unit: string;
|
||||
display_name: string;
|
||||
description: string;
|
||||
is_active: boolean;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface AdminUser {
|
||||
id: number;
|
||||
email: string;
|
||||
account_name: string;
|
||||
account_id: number;
|
||||
role: string;
|
||||
is_active: boolean;
|
||||
credit_balance: number;
|
||||
plan_name?: string;
|
||||
created_at: string;
|
||||
last_login?: string;
|
||||
}
|
||||
|
||||
export interface Invoice {
|
||||
id: number;
|
||||
invoice_number: string;
|
||||
status: 'draft' | 'pending' | 'paid' | 'void' | 'uncollectible';
|
||||
total_amount: string;
|
||||
subtotal: string;
|
||||
tax_amount: string;
|
||||
currency: string;
|
||||
created_at: string;
|
||||
paid_at?: string;
|
||||
due_date?: string;
|
||||
line_items: Array<{
|
||||
description: string;
|
||||
amount: string;
|
||||
quantity?: number;
|
||||
}>;
|
||||
billing_email?: string;
|
||||
notes?: string;
|
||||
stripe_invoice_id?: string;
|
||||
billing_period_start?: string;
|
||||
billing_period_end?: string;
|
||||
}
|
||||
|
||||
export interface Payment {
|
||||
id: number;
|
||||
invoice_id: number;
|
||||
amount: string;
|
||||
currency: string;
|
||||
status: 'pending' | 'processing' | 'succeeded' | 'failed' | 'refunded' | 'cancelled' | 'pending_approval';
|
||||
payment_method: 'stripe' | 'paypal' | 'bank_transfer' | 'local_wallet' | 'manual';
|
||||
created_at: string;
|
||||
processed_at?: string;
|
||||
failed_at?: string;
|
||||
refunded_at?: string;
|
||||
failure_reason?: string;
|
||||
manual_reference?: string;
|
||||
manual_notes?: string;
|
||||
transaction_reference?: string;
|
||||
}
|
||||
|
||||
export interface CreditPackage {
|
||||
id: number;
|
||||
name: string;
|
||||
@@ -21,106 +142,182 @@ export interface CreditPackage {
|
||||
display_order: number;
|
||||
}
|
||||
|
||||
export interface Invoice {
|
||||
export interface TeamMember {
|
||||
id: number;
|
||||
invoice_number: string;
|
||||
status: 'draft' | 'pending' | 'paid' | 'void';
|
||||
total_amount: string;
|
||||
subtotal: string;
|
||||
tax_amount: string;
|
||||
currency: string;
|
||||
email: string;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
role: string;
|
||||
is_active: boolean;
|
||||
is_staff?: boolean;
|
||||
created_at: string;
|
||||
paid_at: string | null;
|
||||
due_date: string | null;
|
||||
line_items: Array<{
|
||||
description: string;
|
||||
amount: string;
|
||||
quantity: number;
|
||||
}>;
|
||||
billing_period_start: string | null;
|
||||
billing_period_end: string | null;
|
||||
}
|
||||
|
||||
export interface Payment {
|
||||
id: number;
|
||||
amount: string;
|
||||
currency: string;
|
||||
payment_method: 'stripe' | 'paypal' | 'bank_transfer' | 'local_wallet' | 'manual';
|
||||
status: 'pending' | 'completed' | 'failed' | 'pending_approval';
|
||||
created_at: string;
|
||||
processed_at: string | null;
|
||||
invoice_id: number;
|
||||
invoice_number: string | null;
|
||||
transaction_reference: string;
|
||||
failure_reason: string | null;
|
||||
date_joined?: string;
|
||||
last_login?: string;
|
||||
}
|
||||
|
||||
export interface PaymentMethod {
|
||||
type: string;
|
||||
name: string;
|
||||
instructions: string;
|
||||
id: string;
|
||||
type: 'stripe' | 'paypal' | 'bank_transfer' | 'local_wallet';
|
||||
display_name: string;
|
||||
name?: string;
|
||||
is_enabled: boolean;
|
||||
instructions?: string;
|
||||
bank_details?: {
|
||||
bank_name: string;
|
||||
account_number: string;
|
||||
routing_number: string;
|
||||
swift_code: string;
|
||||
bank_name?: string;
|
||||
account_number?: string;
|
||||
routing_number?: string;
|
||||
swift_code?: string;
|
||||
};
|
||||
wallet_details?: {
|
||||
wallet_type: string;
|
||||
wallet_id: string;
|
||||
wallet_type?: string;
|
||||
wallet_id?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface CreditTransaction {
|
||||
id: number;
|
||||
amount: number;
|
||||
transaction_type: string;
|
||||
description: string;
|
||||
created_at: string;
|
||||
reference_id: string;
|
||||
metadata: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface CreditBalance {
|
||||
balance: number;
|
||||
subscription_plan: string;
|
||||
monthly_credits: number;
|
||||
subscription_status: string | null;
|
||||
}
|
||||
|
||||
export interface PendingPayment {
|
||||
id: number;
|
||||
export interface PendingPayment extends Payment {
|
||||
account_name: string;
|
||||
amount: string;
|
||||
currency: string;
|
||||
payment_method: string;
|
||||
transaction_reference: string;
|
||||
created_at: string;
|
||||
invoice_number: string | null;
|
||||
admin_notes: string;
|
||||
user_email: string;
|
||||
invoice_number?: string;
|
||||
admin_notes?: string;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// CREDIT PACKAGES
|
||||
// CREDIT BALANCE & TRANSACTIONS
|
||||
// ============================================================================
|
||||
|
||||
export async function getCreditPackages(): Promise<{ results: CreditPackage[]; count: number }> {
|
||||
return fetchAPI('/billing/v2/credit-packages/');
|
||||
export async function getCreditBalance(): Promise<CreditBalance> {
|
||||
return fetchAPI('/v1/billing/credits/balance/balance/');
|
||||
}
|
||||
|
||||
export async function purchaseCreditPackage(
|
||||
packageId: number,
|
||||
paymentMethod: string
|
||||
): Promise<{
|
||||
invoice_id: number;
|
||||
invoice_number: string;
|
||||
total_amount: string;
|
||||
message: string;
|
||||
next_action: string;
|
||||
export async function getCreditTransactions(): Promise<{
|
||||
results: CreditTransaction[];
|
||||
count: number;
|
||||
current_balance?: number;
|
||||
}> {
|
||||
return fetchAPI(`/billing/v2/credit-packages/${packageId}/purchase/`, {
|
||||
return fetchAPI('/v1/billing/transactions/');
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// CREDIT USAGE LOGS
|
||||
// ============================================================================
|
||||
|
||||
export async function getCreditUsage(params?: {
|
||||
operation_type?: string;
|
||||
start_date?: string;
|
||||
end_date?: string;
|
||||
}): Promise<{
|
||||
results: CreditUsageLog[];
|
||||
count: number;
|
||||
}> {
|
||||
const queryParams = new URLSearchParams();
|
||||
if (params?.operation_type) queryParams.append('operation_type', params.operation_type);
|
||||
if (params?.start_date) queryParams.append('start_date', params.start_date);
|
||||
if (params?.end_date) queryParams.append('end_date', params.end_date);
|
||||
|
||||
const url = `/v1/billing/credits/usage/${queryParams.toString() ? '?' + queryParams.toString() : ''}`;
|
||||
return fetchAPI(url);
|
||||
}
|
||||
|
||||
export async function getCreditUsageSummary(params?: {
|
||||
start_date?: string;
|
||||
end_date?: string;
|
||||
}): Promise<{
|
||||
total_credits_used: number;
|
||||
total_cost_usd: string;
|
||||
by_operation: Record<string, {
|
||||
credits: number;
|
||||
cost: number;
|
||||
count: number;
|
||||
}>;
|
||||
by_model: Record<string, {
|
||||
credits: number;
|
||||
cost: number;
|
||||
count: number;
|
||||
}>;
|
||||
}> {
|
||||
const queryParams = new URLSearchParams();
|
||||
if (params?.start_date) queryParams.append('start_date', params.start_date);
|
||||
if (params?.end_date) queryParams.append('end_date', params.end_date);
|
||||
|
||||
const url = `/v1/billing/credits/usage/summary/${queryParams.toString() ? '?' + queryParams.toString() : ''}`;
|
||||
return fetchAPI(url);
|
||||
}
|
||||
|
||||
export async function getCreditUsageLimits(): Promise<{
|
||||
plan_name: string;
|
||||
plan_credits_per_month: number;
|
||||
credits_used_this_month: number;
|
||||
credits_remaining: number;
|
||||
percentage_used: number;
|
||||
approaching_limit: boolean;
|
||||
}> {
|
||||
return fetchAPI('/v1/billing/credits/usage/limits/');
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ADMIN - BILLING STATS & MANAGEMENT
|
||||
// ============================================================================
|
||||
|
||||
export async function getAdminBillingStats(): Promise<AdminBillingStats> {
|
||||
return fetchAPI('/v1/admin/billing/stats/');
|
||||
}
|
||||
|
||||
export async function getAdminUsers(params?: {
|
||||
search?: string;
|
||||
role?: string;
|
||||
is_active?: boolean;
|
||||
}): Promise<{
|
||||
results: AdminUser[];
|
||||
count: number;
|
||||
}> {
|
||||
const queryParams = new URLSearchParams();
|
||||
if (params?.search) queryParams.append('search', params.search);
|
||||
if (params?.role) queryParams.append('role', params.role);
|
||||
if (params?.is_active !== undefined) queryParams.append('is_active', String(params.is_active));
|
||||
|
||||
const url = `/v1/admin/users/${queryParams.toString() ? '?' + queryParams.toString() : ''}`;
|
||||
return fetchAPI(url);
|
||||
}
|
||||
|
||||
export async function adjustUserCredits(
|
||||
userId: number,
|
||||
data: {
|
||||
amount: number;
|
||||
reason: string;
|
||||
}
|
||||
): Promise<{
|
||||
message: string;
|
||||
new_balance: number;
|
||||
}> {
|
||||
return fetchAPI(`/v1/admin/users/${userId}/adjust-credits/`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ payment_method: paymentMethod }),
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ADMIN - CREDIT COSTS CONFIGURATION
|
||||
// ============================================================================
|
||||
|
||||
export async function getCreditCosts(): Promise<{
|
||||
results: CreditCostConfig[];
|
||||
count: number;
|
||||
}> {
|
||||
return fetchAPI('/v1/admin/credit-costs/');
|
||||
}
|
||||
|
||||
export async function updateCreditCosts(
|
||||
costs: Array<{
|
||||
operation_type: string;
|
||||
credits_cost: number;
|
||||
}>
|
||||
): Promise<{
|
||||
message: string;
|
||||
updated_count: number;
|
||||
}> {
|
||||
return fetchAPI('/v1/admin/credit-costs/', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ costs }),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -128,24 +325,32 @@ export async function purchaseCreditPackage(
|
||||
// INVOICES
|
||||
// ============================================================================
|
||||
|
||||
export async function getInvoices(status?: string): Promise<{ results: Invoice[]; count: number }> {
|
||||
const params = status ? `?status=${status}` : '';
|
||||
return fetchAPI(`/billing/v2/invoices/${params}`);
|
||||
export async function getInvoices(params?: {
|
||||
status?: string;
|
||||
}): Promise<{
|
||||
results: Invoice[];
|
||||
count: number;
|
||||
}> {
|
||||
const queryParams = new URLSearchParams();
|
||||
if (params?.status) queryParams.append('status', params.status);
|
||||
|
||||
const url = `/v1/billing/invoices/${queryParams.toString() ? '?' + queryParams.toString() : ''}`;
|
||||
return fetchAPI(url);
|
||||
}
|
||||
|
||||
export async function getInvoice(invoiceId: number): Promise<Invoice> {
|
||||
return fetchAPI(`/billing/v2/invoices/${invoiceId}/`);
|
||||
export async function getInvoiceDetail(invoiceId: number): Promise<Invoice> {
|
||||
return fetchAPI(`/v1/billing/invoices/${invoiceId}/`);
|
||||
}
|
||||
|
||||
export async function downloadInvoicePDF(invoiceId: number): Promise<Blob> {
|
||||
const response = await fetch(`/api/v1/billing/v2/invoices/${invoiceId}/download_pdf/`, {
|
||||
const response = await fetch(`/api/v1/billing/invoices/${invoiceId}/download_pdf/`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('access_token')}`,
|
||||
'Authorization': `Bearer ${localStorage.getItem('access_token')}`,
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to download invoice');
|
||||
throw new Error('Failed to download invoice PDF');
|
||||
}
|
||||
|
||||
return response.blob();
|
||||
@@ -155,51 +360,126 @@ export async function downloadInvoicePDF(invoiceId: number): Promise<Blob> {
|
||||
// PAYMENTS
|
||||
// ============================================================================
|
||||
|
||||
export async function getPayments(status?: string): Promise<{ results: Payment[]; count: number }> {
|
||||
const params = status ? `?status=${status}` : '';
|
||||
return fetchAPI(`/billing/v2/payments/${params}`);
|
||||
}
|
||||
|
||||
export async function getAvailablePaymentMethods(): Promise<{
|
||||
methods: PaymentMethod[];
|
||||
stripe: boolean;
|
||||
paypal: boolean;
|
||||
bank_transfer: boolean;
|
||||
local_wallet: boolean;
|
||||
export async function getPayments(params?: {
|
||||
status?: string;
|
||||
invoice_id?: number;
|
||||
}): Promise<{
|
||||
results: Payment[];
|
||||
count: number;
|
||||
}> {
|
||||
return fetchAPI('/billing/v2/payments/available_methods/');
|
||||
const queryParams = new URLSearchParams();
|
||||
if (params?.status) queryParams.append('status', params.status);
|
||||
if (params?.invoice_id) queryParams.append('invoice_id', String(params.invoice_id));
|
||||
|
||||
const url = `/v1/billing/payments/${queryParams.toString() ? '?' + queryParams.toString() : ''}`;
|
||||
return fetchAPI(url);
|
||||
}
|
||||
|
||||
export async function submitManualPayment(data: {
|
||||
invoice_id: number;
|
||||
payment_method: 'bank_transfer' | 'local_wallet';
|
||||
transaction_reference: string;
|
||||
payment_method: 'bank_transfer' | 'local_wallet' | 'manual';
|
||||
amount: string;
|
||||
currency?: string;
|
||||
reference?: string;
|
||||
notes?: string;
|
||||
proof_file?: File;
|
||||
}): Promise<{
|
||||
id: number;
|
||||
status: string;
|
||||
message: string;
|
||||
}> {
|
||||
return fetchAPI('/billing/v2/payments/create_manual_payment/', {
|
||||
return fetchAPI('/v1/billing/payments/manual/', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// CREDIT TRANSACTIONS
|
||||
// CREDIT PACKAGES
|
||||
// ============================================================================
|
||||
|
||||
export async function getCreditTransactions(): Promise<{
|
||||
results: CreditTransaction[];
|
||||
export async function getCreditPackages(): Promise<{
|
||||
results: CreditPackage[];
|
||||
count: number;
|
||||
current_balance: number;
|
||||
}> {
|
||||
return fetchAPI('/billing/v2/transactions/');
|
||||
return fetchAPI('/v1/billing/credit-packages/');
|
||||
}
|
||||
|
||||
export async function getCreditBalance(): Promise<CreditBalance> {
|
||||
return fetchAPI('/billing/v2/transactions/balance/');
|
||||
export async function purchaseCreditPackage(data: {
|
||||
package_id: number;
|
||||
payment_method: 'stripe' | 'paypal' | 'bank_transfer' | 'local_wallet';
|
||||
}): Promise<{
|
||||
id: number;
|
||||
status: string;
|
||||
message?: string;
|
||||
stripe_client_secret?: string;
|
||||
paypal_order_id?: string;
|
||||
}> {
|
||||
return fetchAPI(`/v1/billing/credit-packages/${data.package_id}/purchase/`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ payment_method: data.payment_method }),
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// TEAM MANAGEMENT
|
||||
// ============================================================================
|
||||
|
||||
export async function getTeamMembers(): Promise<{
|
||||
results: TeamMember[];
|
||||
count: number;
|
||||
}> {
|
||||
return fetchAPI('/v1/account/team/');
|
||||
}
|
||||
|
||||
export async function inviteTeamMember(data: {
|
||||
email: string;
|
||||
first_name?: string;
|
||||
last_name?: string;
|
||||
role?: string;
|
||||
}): Promise<{
|
||||
message: string;
|
||||
member?: TeamMember;
|
||||
}> {
|
||||
return fetchAPI('/v1/account/team/invite/', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
}
|
||||
|
||||
export async function removeTeamMember(memberId: number): Promise<{
|
||||
message: string;
|
||||
}> {
|
||||
return fetchAPI(`/v1/account/team/${memberId}/`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// PAYMENT METHODS
|
||||
// ============================================================================
|
||||
|
||||
export async function getAvailablePaymentMethods(): Promise<{
|
||||
results: PaymentMethod[];
|
||||
count: number;
|
||||
}> {
|
||||
return fetchAPI('/v1/billing/payment-methods/');
|
||||
}
|
||||
|
||||
export async function createManualPayment(data: {
|
||||
amount: string;
|
||||
payment_method: string;
|
||||
reference: string;
|
||||
notes?: string;
|
||||
}): Promise<{
|
||||
id: number;
|
||||
status: string;
|
||||
message: string;
|
||||
}> {
|
||||
return fetchAPI('/v1/billing/payments/manual/', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
@@ -210,44 +490,94 @@ export async function getPendingPayments(): Promise<{
|
||||
results: PendingPayment[];
|
||||
count: number;
|
||||
}> {
|
||||
return fetchAPI('/billing/v2/admin/pending_payments/');
|
||||
return fetchAPI('/v1/admin/payments/pending/');
|
||||
}
|
||||
|
||||
export async function approvePayment(
|
||||
paymentId: number,
|
||||
notes?: string
|
||||
): Promise<{
|
||||
id: number;
|
||||
status: string;
|
||||
export async function approvePayment(paymentId: number, data?: {
|
||||
notes?: string;
|
||||
}): Promise<{
|
||||
message: string;
|
||||
payment: Payment;
|
||||
}> {
|
||||
return fetchAPI(`/billing/v2/admin/${paymentId}/approve_payment/`, {
|
||||
return fetchAPI(`/v1/admin/payments/${paymentId}/approve/`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ notes }),
|
||||
body: JSON.stringify(data || {}),
|
||||
});
|
||||
}
|
||||
|
||||
export async function rejectPayment(
|
||||
paymentId: number,
|
||||
reason: string
|
||||
): Promise<{
|
||||
id: number;
|
||||
status: string;
|
||||
export async function rejectPayment(paymentId: number, data: {
|
||||
reason: string;
|
||||
notes?: string;
|
||||
}): Promise<{
|
||||
message: string;
|
||||
payment: Payment;
|
||||
}> {
|
||||
return fetchAPI(`/billing/v2/admin/${paymentId}/reject_payment/`, {
|
||||
return fetchAPI(`/v1/admin/payments/${paymentId}/reject/`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ reason }),
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
}
|
||||
|
||||
export async function getAdminBillingStats(): Promise<{
|
||||
total_accounts: number;
|
||||
active_subscriptions: number;
|
||||
total_revenue: string;
|
||||
pending_approvals: number;
|
||||
invoices_pending: number;
|
||||
invoices_paid: number;
|
||||
}> {
|
||||
return fetchAPI('/billing/v2/admin/stats/');
|
||||
// ============================================================================
|
||||
// ACCOUNT MANAGEMENT
|
||||
// ============================================================================
|
||||
|
||||
export interface AccountSettings {
|
||||
id: number;
|
||||
name: string;
|
||||
slug: string;
|
||||
billing_address_line1?: string;
|
||||
billing_address_line2?: string;
|
||||
billing_city?: string;
|
||||
billing_state?: string;
|
||||
billing_postal_code?: string;
|
||||
billing_country?: string;
|
||||
tax_id?: string;
|
||||
billing_email?: string;
|
||||
credit_balance: number;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export async function getAccountSettings(): Promise<AccountSettings> {
|
||||
return fetchAPI('/v1/account/settings/');
|
||||
}
|
||||
|
||||
export async function updateAccountSettings(data: Partial<AccountSettings>): Promise<{
|
||||
message: string;
|
||||
account: AccountSettings;
|
||||
}> {
|
||||
return fetchAPI('/v1/account/settings/', {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
}
|
||||
|
||||
export interface UsageAnalytics {
|
||||
period_days: number;
|
||||
start_date: string;
|
||||
end_date: string;
|
||||
current_balance: number;
|
||||
usage_by_type: Array<{
|
||||
transaction_type: string;
|
||||
total: number;
|
||||
count: number;
|
||||
}>;
|
||||
purchases_by_type: Array<{
|
||||
transaction_type: string;
|
||||
total: number;
|
||||
count: number;
|
||||
}>;
|
||||
daily_usage: Array<{
|
||||
date: string;
|
||||
usage: number;
|
||||
purchases: number;
|
||||
net: number;
|
||||
}>;
|
||||
total_usage: number;
|
||||
total_purchases: number;
|
||||
}
|
||||
|
||||
export async function getUsageAnalytics(days: number = 30): Promise<UsageAnalytics> {
|
||||
return fetchAPI(`/v1/account/usage/analytics/?days=${days}`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user