/** * SaaS Billing Slice * * Plans, subscription, and payment actions. */ import { saasClient } from '../../lib/saas-client'; import { createLogger } from '../../lib/logger'; import type { SaaSStore } from './types'; const log = createLogger('SaaSStore:Billing'); type SetFn = (partial: Partial | ((state: SaaSStore) => Partial)) => void; type GetFn = () => SaaSStore; export function createBillingSlice(set: SetFn, _get: GetFn) { return { plans: [], subscription: null, billingLoading: false, billingError: null, fetchPlans: async () => { try { const plans = await saasClient.listPlans(); set({ plans }); } catch (err: unknown) { log.warn('Failed to fetch plans:', err); } }, fetchSubscription: async () => { try { const sub = await saasClient.getSubscription(); set({ subscription: sub }); } catch (err: unknown) { log.warn('Failed to fetch subscription:', err); set({ subscription: null }); } }, fetchBillingOverview: async () => { set({ billingLoading: true, billingError: null }); try { const [plans, sub] = await Promise.all([ saasClient.listPlans(), saasClient.getSubscription(), ]); set({ plans, subscription: sub, billingLoading: false }); } catch (err: unknown) { const msg = err instanceof Error ? err.message : String(err); set({ billingLoading: false, billingError: msg }); } }, createPayment: async (planId: string, method: 'alipay' | 'wechat') => { set({ billingLoading: true, billingError: null }); try { const result = await saasClient.createPayment({ plan_id: planId, payment_method: method }); set({ billingLoading: false }); return result; } catch (err: unknown) { const msg = err instanceof Error ? err.message : String(err); set({ billingLoading: false, billingError: msg }); return null; } }, pollPaymentStatus: async (paymentId: string) => { try { const status = await saasClient.getPaymentStatus(paymentId); if (status.status === 'succeeded') { await _get().fetchSubscription(); } return status; } catch (err: unknown) { log.warn('Failed to poll payment status:', err); return null; } }, clearBillingError: () => set({ billingError: null }), }; }