UNPKG

breezi-js

Version:

Vanilla JavaScript SDK for Breezi PayPal integration

223 lines (218 loc) 9.98 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.BreeziWidget = {})); })(this, (function (exports) { 'use strict'; /** * Vanilla JavaScript Breezi Widget */ class BreeziWidget { constructor(config) { this.sdkLoaded = false; this.config = config; this.logger = { debug: (message, data) => { if (this.config.debug && typeof console !== 'undefined' && console.debug) { console.debug(`[Breezi Debug] ${message}`, data || ''); } }, error: (message, error) => { if (typeof console !== 'undefined' && console.error) { console.error(`[Breezi Error] ${message}`, error || ''); } }, }; this.validateConfig(); } validateConfig() { if (!this.config.environment) { throw this.createError('Environment is required', 'CONFIG_ERROR', 'MISSING_ENVIRONMENT'); } if (!['sandbox', 'production'].includes(this.config.environment)) { throw this.createError('Environment must be "sandbox" or "production"', 'CONFIG_ERROR', 'INVALID_ENVIRONMENT'); } if (!this.config.providers?.paypal?.clientId) { throw this.createError('PayPal client ID is required in providers.paypal.clientId', 'CONFIG_ERROR', 'MISSING_PAYPAL_CLIENT_ID'); } } createError(message, type, code) { const error = new Error(message); error.type = type; error.code = code; error.retryable = type === 'NETWORK_ERROR'; return error; } /** * Load PayPal SDK */ async loadPayPalSDK(currency) { return new Promise((resolve, reject) => { if (window.paypal) { this.sdkLoaded = true; resolve(); return; } const script = document.createElement('script'); script.src = `https://www.paypal.com/sdk/js?client-id=${this.config.providers.paypal.clientId}&currency=${currency}&components=buttons`; script.onload = () => { this.sdkLoaded = true; this.logger.debug('PayPal SDK loaded successfully'); resolve(); }; script.onerror = () => { const error = this.createError('Failed to load PayPal SDK', 'NETWORK_ERROR', 'SDK_LOAD_FAILED'); this.logger.error('PayPal SDK loading failed', error); reject(error); }; document.body.appendChild(script); }); } /** * Render PayPal button in the specified container */ async renderPayPalButton(containerId, options) { try { // Validate inputs if (!containerId) { throw this.createError('Container ID is required', 'VALIDATION_ERROR', 'MISSING_CONTAINER_ID'); } if (!options.amount || options.amount <= 0) { throw this.createError('Amount must be greater than 0', 'VALIDATION_ERROR', 'INVALID_AMOUNT'); } if (!options.currency || options.currency.length !== 3) { throw this.createError('Currency must be a valid 3-letter ISO code', 'VALIDATION_ERROR', 'INVALID_CURRENCY'); } const container = document.getElementById(containerId); if (!container) { throw this.createError(`Container with ID "${containerId}" not found`, 'VALIDATION_ERROR', 'CONTAINER_NOT_FOUND'); } // Load PayPal SDK if not already loaded if (!this.sdkLoaded) { await this.loadPayPalSDK(options.currency); } // Clear container container.innerHTML = ''; this.logger.debug('Rendering PayPal button', { containerId, options }); // Render PayPal button window.paypal.Buttons({ createOrder: (data, actions) => { this.logger.debug('Creating PayPal order'); return actions.order.create({ purchase_units: [{ amount: { value: options.amount.toString(), currency_code: options.currency }, description: options.description || `Payment of ${options.currency} ${options.amount}` }] }); }, onApprove: async (data, actions) => { try { this.logger.debug('Payment approved, capturing...'); const orderData = await actions.order.capture(); this.logger.debug('Payment captured successfully:', orderData); const result = { id: orderData.id, status: 'completed', amount: options.amount, currency: options.currency, provider: 'paypal', createdAt: new Date().toISOString(), details: orderData }; options.onSuccess?.(result); } catch (error) { this.logger.error('Payment capture failed:', error); const breeziError = this.createError('Payment capture failed', 'PROVIDER_ERROR', 'CAPTURE_FAILED'); options.onError?.(breeziError); } }, onCancel: () => { this.logger.debug('Payment cancelled by user'); options.onCancel?.(); }, onError: (err) => { this.logger.error('PayPal SDK error:', err); const breeziError = this.createError('PayPal error occurred', 'PROVIDER_ERROR', 'PAYPAL_ERROR'); options.onError?.(breeziError); }, style: { color: 'blue', shape: 'rect', label: 'paypal', height: 40, }, }).render(container); } catch (error) { this.logger.error('Failed to render PayPal button:', error); throw error; } } /** * Create a simple payment button with custom styling */ createPaymentButton(containerId, options) { const container = document.getElementById(containerId); if (!container) { throw this.createError(`Container with ID "${containerId}" not found`, 'VALIDATION_ERROR', 'CONTAINER_NOT_FOUND'); } const button = document.createElement('button'); button.textContent = options.buttonText || `Pay ${options.currency} ${options.amount}`; // Default styling Object.assign(button.style, { padding: '12px 24px', backgroundColor: '#0070f3', color: 'white', border: 'none', borderRadius: '6px', cursor: 'pointer', fontSize: '16px', fontWeight: '500', transition: 'all 0.2s ease', ...options.buttonStyle }); button.addEventListener('click', () => { // For now, show message that custom buttons need server implementation const error = this.createError('Custom payment buttons require server-side implementation. Use renderPayPalButton() for direct PayPal integration.', 'CONFIG_ERROR', 'CUSTOM_BUTTON_NOT_IMPLEMENTED'); options.onError?.(error); }); container.innerHTML = ''; container.appendChild(button); } /** * Get current configuration */ getConfig() { return { ...this.config }; } /** * Update configuration */ updateConfig(newConfig) { this.config = { ...this.config, ...newConfig }; this.validateConfig(); } } // Global factory function for easy usage function createBreeziWidget(config) { return new BreeziWidget(config); } // Expose globally when loaded as UMD if (typeof window !== 'undefined') { window.BreeziWidget = BreeziWidget; window.createBreeziWidget = createBreeziWidget; // Auto-initialize if config is available if (window.BreeziConfig) { const widget = new BreeziWidget(window.BreeziConfig); window.breezi = widget; } } exports.BreeziWidget = BreeziWidget; exports.createBreeziWidget = createBreeziWidget; exports.default = BreeziWidget; Object.defineProperty(exports, '__esModule', { value: true }); })); //# sourceMappingURL=widget.js.map