/** * Subscription API Module * * HTTP client methods for subscription, billing, and usage operations. * Uses endpoint constants and Zod-inferred types from @archer/api-interface. * * @layer Infrastructure - API Client */ import { apiClient } from '../../ApiClient'; import { SUBSCRIPTION_GET, SUBSCRIPTION_PLANS_LIST, SUBSCRIPTION_CHECKOUT, SUBSCRIPTION_CREATE_PAYMENT_INTENT, SUBSCRIPTION_CONFIRM_PAYMENT, SUBSCRIPTION_SUBSCRIBE, SUBSCRIPTION_CONFIRM, SUBSCRIPTION_CHANGE_PLAN, SUBSCRIPTION_CANCEL, SUBSCRIPTION_RESUME, SUBSCRIPTION_USAGE, SUBSCRIPTION_INVOICES_LIST, SUBSCRIPTION_INVOICE_PDF, SUBSCRIPTION_COMMAND_STATS, SUBSCRIPTION_PURCHASE_COMMANDS, SUBSCRIPTION_CONFIGURE, SUBSCRIPTION_CONFIGURABLE_CAPS, SUBSCRIPTION_CONFIRM_COMMAND_PURCHASE, SUBSCRIPTION_SET_AUTO_BUY, SUBSCRIPTION_REDEEM_CODE, SUBSCRIPTION_VALIDATE_CODE, PAYMENT_COMPLETE, } from '@archer/api-interface/endpoints/customer-api'; import type { SubscriptionResponse, AvailablePlanResponse, CheckoutResponse, CreatePaymentIntentResponse, ConfirmPaymentResponse, SubscribeResponse, ConfirmSubscriptionResponse, ChangePlanResponse, CancelSubscriptionResponse, ResumeSubscriptionResponse, UsageResponse, InvoiceResponse, CommandStatsResponse, PurchaseCommandsResponse, ConfirmCommandPurchaseResponse, SetAutoBuyResponse, RedeemCodeResponse, ValidateCodeResponse, ConfigurableCapsResponse, } from '@archer/api-interface/schemas/customer-api/response'; import type { PaginatedResponse } from '@archer/api-interface/schemas/shared/paginated.response'; export const subscriptionApi = { async getSubscription(): Promise { return apiClient.get(SUBSCRIPTION_GET.path); }, async listPlans(channel?: string): Promise { const params = channel ? `?channel=${channel}` : ''; return apiClient.get(`${SUBSCRIPTION_PLANS_LIST.path}${params}`); }, /** Reserved for single purchase flow — no backend route yet */ async checkout(paymentProvider: string, planId?: string): Promise { return apiClient.post(SUBSCRIPTION_CHECKOUT.path, { paymentProvider, ...(planId && { planId }), }); }, async createPaymentIntent(planId: string): Promise { return apiClient.post(SUBSCRIPTION_CREATE_PAYMENT_INTENT.path, { planId }); }, async confirmPayment(paymentIntentId: string): Promise { return apiClient.post(SUBSCRIPTION_CONFIRM_PAYMENT.path, { paymentIntentId }); }, async subscribe(planId: string): Promise { return apiClient.post(SUBSCRIPTION_SUBSCRIBE.path, { planId }); }, async confirmSubscription(subscriptionId: string): Promise { return apiClient.post(SUBSCRIPTION_CONFIRM.path, { subscriptionId }); }, async changePlan(planId: string): Promise { return apiClient.post(SUBSCRIPTION_CHANGE_PLAN.path, { planId }); }, async cancel(): Promise { return apiClient.post(SUBSCRIPTION_CANCEL.path); }, async resume(): Promise { return apiClient.post(SUBSCRIPTION_RESUME.path); }, async getUsage(): Promise { return apiClient.get(SUBSCRIPTION_USAGE.path); }, async getInvoices(page: number = 1, limit: number = 20): Promise> { return apiClient.get>(`${SUBSCRIPTION_INVOICES_LIST.path}?page=${page}&limit=${limit}`); }, async downloadInvoicePdf(transactionId: string): Promise { return apiClient.get( SUBSCRIPTION_INVOICE_PDF.path.replace(':id', transactionId), { responseType: 'blob' }, ); }, async getCommandStats(): Promise { return apiClient.get(SUBSCRIPTION_COMMAND_STATS.path); }, async purchaseCommands(packageSize: 100 | 1000, quantity = 1): Promise { return apiClient.post(SUBSCRIPTION_PURCHASE_COMMANDS.path, { packageSize, quantity }); }, async confirmCommandPurchase(paymentIntentId: string): Promise { return apiClient.post(SUBSCRIPTION_CONFIRM_COMMAND_PURCHASE.path, { paymentIntentId }); }, async setAutoBuy(enabled: boolean): Promise { return apiClient.post(SUBSCRIPTION_SET_AUTO_BUY.path, { enabled }); }, async completePayment(transactionId: string): Promise<{ clientSecret: string; paymentIntentId: string; transactionId: string; amount: number; currency: string }> { return apiClient.post(PAYMENT_COMPLETE.path.replace(':transactionId', transactionId), {}); }, async redeemCode(code: string, paymentOnly?: boolean): Promise { const res = await apiClient.post<{ data: RedeemCodeResponse }>(SUBSCRIPTION_REDEEM_CODE.path, { code, paymentOnly }); return res.data; }, async validateCode(code: string, planId: string): Promise { return apiClient.post(SUBSCRIPTION_VALIDATE_CODE.path, { code, planId }); }, async getConfigurableCaps(): Promise { return apiClient.get(SUBSCRIPTION_CONFIGURABLE_CAPS.path); }, async configure(items: Array<{ capabilityKey: string; quantity: number }>): Promise { return apiClient.post(SUBSCRIPTION_CONFIGURE.path, { items }); }, };