UNPKG

a0-purchases

Version:

Lightweight subscription management for AI apps with auto-detecting providers

144 lines 5.73 kB
import { Platform, Linking } from 'react-native'; import { BasePlatformAdapter } from '../../core/adapters'; import { PURCHASES_ERROR_CODE } from '../../types'; import { backendClient } from '../../api/backendClient'; // Try to import Stripe if available let stripeModule; try { stripeModule = require('../../stripe'); } catch (e) { // Stripe module not available, that's okay } export class WebAdapter extends BasePlatformAdapter { constructor() { super(...arguments); this.name = 'web'; this.isStripeInitialized = false; } logEvent(event, data) { if (this.config.debug) { console.log(`[WebAdapter] ${event}`, data ? JSON.stringify(data, null, 2) : ''); } } createError(message, code = PURCHASES_ERROR_CODE.UNKNOWN_ERROR, originalError) { const error = new Error(message); error.code = code; error.message = message; error.userCancelled = false; if (originalError) { error.underlyingError = originalError; } return error; } isSupported() { // Web adapter is always supported as fallback return true; } async init(config) { // Store configuration if (config) { this.config = Object.assign(Object.assign({}, this.config), config); } try { this.logEvent('Initializing web adapter...'); // Try to initialize Stripe if we're on a platform that supports it if (Platform.OS !== 'ios' && Platform.OS !== 'android') { // We're on web, try to initialize Stripe for payment sheets try { await this.initializeStripe(); } catch (error) { this.logEvent('Stripe initialization failed, will use checkout URLs', error); // Don't fail - we can still use checkout URLs } } else { // On mobile but using web adapter (fallback), just use checkout URLs this.logEvent('Mobile platform using web adapter, will use checkout URLs'); } this.logEvent('Web adapter initialized'); } catch (error) { this.logEvent('Web adapter initialization failed', error); throw this.createError('Web adapter initialization failed', PURCHASES_ERROR_CODE.INITIALIZATION_ERROR, error); } } async initializeStripe() { try { const stripeInfo = await backendClient.getStripeInformation(); if (!(stripeInfo === null || stripeInfo === void 0 ? void 0 : stripeInfo.publishableKey)) { throw new Error('Missing Stripe publishable key'); } // Try to use Stripe module if available if (stripeModule && stripeModule.initStripe) { await stripeModule.initStripe({ publishableKey: stripeInfo.publishableKey, stripeAccountId: stripeInfo.stripeAccountId, }); this.isStripeInitialized = true; this.logEvent('Stripe initialized successfully'); } else { // Stripe module not available this.logEvent('Stripe module not available'); } } catch (error) { this.logEvent('Failed to initialize Stripe', error); throw error; } } async purchase(pkg, userId) { this.logEvent('Starting web purchase', { packageId: pkg.identifier, productId: pkg.product.identifier, userId }); if (!userId) { throw this.createError('User ID is required for web purchases', PURCHASES_ERROR_CODE.INVALID_APP_USER_ID_ERROR); } try { // Create checkout session const session = await backendClient.createCheckoutSession(userId, pkg); if (!(session === null || session === void 0 ? void 0 : session.url)) { throw this.createError('Invalid checkout session URL', PURCHASES_ERROR_CODE.BACKEND_VALIDATION_ERROR); } this.logEvent('Opening checkout URL', { url: session.url }); // Open the checkout URL if (Platform.OS === 'web' || typeof window !== 'undefined') { // On web, open in new tab window.open(session.url, '_blank'); } else { // On mobile, use Linking await Linking.openURL(session.url); } // For web purchases, we return a minimal purchase object // The actual validation happens via webhooks on the backend const result = { id: pkg.product.identifier, transactionId: `web_${Date.now()}`, // Generate a pseudo transaction ID }; this.logEvent('Web purchase initiated', result); return result; } catch (error) { this.logEvent('Web purchase failed', error); if (error.code) { throw error; // Re-throw library errors } throw this.createError(error.message || 'Web purchase failed', PURCHASES_ERROR_CODE.PURCHASE_INVALID_ERROR, error); } } async restore(_userId) { // For web, restore is essentially a no-op // Customer info refresh is handled by the service this.logEvent('Web restore completed (no-op)'); } dispose() { this.logEvent('Disposing web adapter'); this.isStripeInitialized = false; } } //# sourceMappingURL=WebAdapter.js.map