@digilogiclabs/saas-factory-payments 1.2.9 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,1182 +1,1235 @@
1
- # @digilogiclabs/saas-factory-payments
2
-
3
- A comprehensive multi-provider payments package for SaaS Factory that works seamlessly in both Next.js and React Native environments. Built with TypeScript and supporting Stripe, PayPal, and Apple Pay with advanced subscription analytics.
4
-
5
- ## Features
6
-
7
- - 🌐 **Hybrid Support**: Works in both Next.js web applications and React Native mobile apps
8
- - 🔒 **Type-Safe**: Built with TypeScript for better developer experience
9
- - 💳 **Multi-Provider**: Support for Stripe, PayPal, and Apple Pay payments
10
- - 📊 **Subscription Analytics**: Advanced analytics hooks for revenue, churn, and growth metrics
11
- - 🎨 **UI Components**: Pre-built components for subscription plans, billing management, and payment methods
12
- - 🪝 **React Hooks**: Powerful hooks for payments, subscriptions, and analytics
13
- - 🔧 **Server Utilities**: Complete server-side API and webhook handling
14
- - 📱 **Mobile-First**: Native mobile payment flows with provider-specific implementations
15
- - 🎯 **Provider-Agnostic**: Extensible architecture supporting multiple payment providers
16
- - 🚀 **CLI Integration**: Works seamlessly with create-saas-app
17
- - 💰 **Complete SaaS Solution**: Everything needed for subscription-based applications
18
- - 🔄 **Auto-Detection**: Automatic provider detection based on environment variables
19
-
20
- ## Installation
21
-
22
- ```bash
23
- npm install @digilogiclabs/saas-factory-payments
24
- # or
25
- yarn add @digilogiclabs/saas-factory-payments
26
- # or
27
- pnpm add @digilogiclabs/saas-factory-payments
28
- ```
29
-
30
- ### Peer Dependencies
31
-
32
- The package requires different peer dependencies based on your platform and payment providers:
33
-
34
- **For Web (Next.js):**
35
- ```bash
36
- # Required for all payment providers
37
- npm install react react-dom
38
-
39
- # Stripe (optional)
40
- npm install @stripe/stripe-js @stripe/react-stripe-js stripe
41
-
42
- # PayPal SDK is loaded dynamically - no additional installation required
43
-
44
- # Apple Pay is native to Safari - no additional installation required
45
- ```
46
-
47
- **For React Native:**
48
- ```bash
49
- # Required for all payment providers
50
- npm install react react-native
51
-
52
- # Stripe (optional)
53
- npm install @stripe/stripe-react-native stripe
54
-
55
- # PayPal React Native (optional)
56
- npm install react-native-paypal
57
-
58
- # Apple Pay React Native (optional)
59
- npm install @react-native-apple-pay/apple-pay
60
- ```
61
-
62
- **For Server-side:**
63
- ```bash
64
- # Stripe (optional)
65
- npm install stripe
66
-
67
- # PayPal SDK (optional)
68
- npm install @paypal/checkout-server-sdk
69
-
70
- # Apple Pay server validation requires custom implementation
71
- ```
72
-
73
- ## Quick Start
74
-
75
- ### 1. Setup Providers
76
-
77
- First, wrap your app with the PaymentsProvider and platform-specific StripeProvider:
78
-
79
- **Web (Next.js) - `pages/_app.tsx`:**
80
- ```tsx
81
- import { PaymentsProvider } from '@digilogiclabs/saas-factory-payments';
82
- import { StripeProvider } from '@digilogiclabs/saas-factory-payments/web';
83
-
84
- export default function App({ Component, pageProps }) {
85
- return (
86
- <PaymentsProvider
87
- config={{
88
- provider: 'stripe',
89
- publishableKey: process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!,
90
- environment: process.env.NODE_ENV as 'development' | 'production',
91
- }}
92
- >
93
- <StripeProvider>
94
- <Component {...pageProps} />
95
- </StripeProvider>
96
- </PaymentsProvider>
97
- );
98
- }
99
- ```
100
-
101
- **React Native - `App.tsx`:**
102
- ```tsx
103
- import { PaymentsProvider } from '@digilogiclabs/saas-factory-payments';
104
- import { StripeProvider } from '@digilogiclabs/saas-factory-payments/native';
105
-
106
- export default function App() {
107
- return (
108
- <PaymentsProvider
109
- config={{
110
- provider: 'stripe',
111
- publishableKey: process.env.EXPO_PUBLIC_STRIPE_PUBLISHABLE_KEY!,
112
- environment: __DEV__ ? 'development' : 'production',
113
- }}
114
- >
115
- <StripeProvider>
116
- <MainApp />
117
- </StripeProvider>
118
- </PaymentsProvider>
119
- );
120
- }
121
- ```
122
-
123
- ### 2. Use UI Components (v0.3.0)
124
-
125
- **Subscription Plans Component:**
126
- ```tsx
127
- import { SubscriptionPlans } from '@digilogiclabs/saas-factory-payments/web';
128
-
129
- const plans = [
130
- {
131
- id: 'basic',
132
- name: 'Basic Plan',
133
- price: 999, // $9.99 in cents
134
- interval: 'month',
135
- features: ['10 projects', 'Basic support', '1GB storage'],
136
- stripePriceId: 'price_basic_monthly',
137
- },
138
- {
139
- id: 'pro',
140
- name: 'Pro Plan',
141
- price: 1999, // $19.99 in cents
142
- interval: 'month',
143
- features: ['Unlimited projects', 'Priority support', '10GB storage'],
144
- popular: true,
145
- stripePriceId: 'price_pro_monthly',
146
- },
147
- ];
148
-
149
- export default function PricingPage() {
150
- return (
151
- <SubscriptionPlans
152
- plans={plans}
153
- onPlanSelect={(planId) => {
154
- console.log('Selected plan:', planId);
155
- // Handle plan selection
156
- }}
157
- currentPlan="basic" // Optional: highlight current plan
158
- />
159
- );
160
- }
161
- ```
162
-
163
- **Subscription Manager Component:**
164
- ```tsx
165
- import { SubscriptionManager } from '@digilogiclabs/saas-factory-payments/web';
166
-
167
- const subscription = {
168
- id: 'sub_123',
169
- planId: 'pro',
170
- planName: 'Pro Plan',
171
- status: 'active',
172
- currentPeriodStart: new Date('2024-01-01'),
173
- currentPeriodEnd: new Date('2024-02-01'),
174
- cancelAtPeriodEnd: false,
175
- amount: 1999,
176
- currency: 'usd',
177
- interval: 'month',
178
- };
179
-
180
- export default function BillingPage() {
181
- return (
182
- <SubscriptionManager
183
- subscription={subscription}
184
- onSubscriptionChange={(action) => {
185
- console.log('Subscription action:', action);
186
- // Handle upgrade, downgrade, pause, resume
187
- }}
188
- onCancel={() => {
189
- console.log('Cancel subscription');
190
- // Handle cancellation
191
- }}
192
- />
193
- );
194
- }
195
- ```
196
-
197
- **Billing History Component:**
198
- ```tsx
199
- import { BillingHistory } from '@digilogiclabs/saas-factory-payments/web';
200
-
201
- const invoices = [
202
- {
203
- id: 'inv_123',
204
- amount: 1999,
205
- currency: 'usd',
206
- status: 'paid',
207
- date: new Date('2024-01-01'),
208
- description: 'Pro Plan - Monthly',
209
- downloadUrl: 'https://example.com/invoice.pdf',
210
- invoiceNumber: 'INV-001',
211
- },
212
- ];
213
-
214
- export default function BillingHistoryPage() {
215
- return (
216
- <BillingHistory
217
- invoices={invoices}
218
- onInvoiceDownload={(invoiceId) => {
219
- console.log('Download invoice:', invoiceId);
220
- // Handle invoice download
221
- }}
222
- />
223
- );
224
- }
225
- ```
226
-
227
- **Payment Methods Component:**
228
- ```tsx
229
- import { PaymentMethods } from '@digilogiclabs/saas-factory-payments/web';
230
-
231
- const paymentMethods = [
232
- {
233
- id: 'pm_123',
234
- type: 'card',
235
- last4: '4242',
236
- brand: 'visa',
237
- expiryMonth: 12,
238
- expiryYear: 2025,
239
- isDefault: true,
240
- },
241
- ];
242
-
243
- export default function PaymentMethodsPage() {
244
- return (
245
- <PaymentMethods
246
- paymentMethods={paymentMethods}
247
- onAdd={() => console.log('Add payment method')}
248
- onEdit={(methodId) => console.log('Edit method:', methodId)}
249
- onDelete={(methodId) => console.log('Delete method:', methodId)}
250
- onSetDefault={(methodId) => console.log('Set default:', methodId)}
251
- />
252
- );
253
- }
254
- ```
255
-
256
- ### 3. Use Utilities and Hooks
257
-
258
- **Formatting Utilities:**
259
- ```tsx
260
- import { formatCurrency, formatDate } from '@digilogiclabs/saas-factory-payments';
261
-
262
- // Format currency amounts
263
- const price = formatCurrency(1999, 'USD'); // "$19.99"
264
-
265
- // Format dates
266
- const date = formatDate(new Date()); // "January 1, 2024"
267
- ```
268
-
269
- **Payment Hooks:**
270
- ```tsx
271
- import { usePayments } from '@digilogiclabs/saas-factory-payments';
272
-
273
- function SubscriptionStatus({ customerId }) {
274
- const { customer, subscriptions, loading } = usePayments({ customerId });
275
-
276
- if (loading) return <div>Loading...</div>;
277
-
278
- return (
279
- <div>
280
- <h3>Customer: {customer?.name}</h3>
281
- <p>Active Subscriptions: {subscriptions?.length || 0}</p>
282
- </div>
283
- );
284
- }
285
- ```
286
-
287
- ### 4. Multi-Provider Support (v1.1.0)
288
-
289
- The package now supports multiple payment providers with automatic detection and unified components.
290
-
291
- **Environment Variables for Auto-Detection:**
292
- ```bash
293
- # Stripe (optional)
294
- NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
295
- STRIPE_SECRET_KEY=sk_test_...
296
-
297
- # PayPal (optional)
298
- NEXT_PUBLIC_PAYPAL_CLIENT_ID=your_paypal_client_id
299
- PAYPAL_CLIENT_SECRET=your_paypal_client_secret
300
- PAYPAL_CURRENCY=USD
301
-
302
- # Apple Pay (optional)
303
- NEXT_PUBLIC_APPLE_PAY_MERCHANT_ID=merchant.yourapp.com
304
- NEXT_PUBLIC_APPLE_PAY_MERCHANT_NAME=Your Store
305
- NEXT_PUBLIC_APPLE_PAY_COUNTRY_CODE=US
306
- NEXT_PUBLIC_APPLE_PAY_CURRENCY_CODE=USD
307
- ```
308
-
309
- **Multi-Provider Payment Component:**
310
- ```tsx
311
- import { MultiProviderPayment } from '@digilogiclabs/saas-factory-payments/web';
312
- import { PaymentProviderFactory } from '@digilogiclabs/saas-factory-payments';
313
-
314
- function CheckoutPage() {
315
- const providers = {
316
- stripe: {
317
- provider: 'stripe' as const,
318
- publishableKey: process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!,
319
- environment: 'development' as const,
320
- stripeConfig: {
321
- publishableKey: process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!,
322
- },
323
- },
324
- paypal: {
325
- provider: 'paypal' as const,
326
- environment: 'development' as const,
327
- paypalConfig: {
328
- clientId: process.env.NEXT_PUBLIC_PAYPAL_CLIENT_ID!,
329
- environment: 'sandbox',
330
- currency: 'USD',
331
- },
332
- },
333
- applepay: {
334
- provider: 'applepay' as const,
335
- environment: 'development' as const,
336
- applePayConfig: {
337
- merchantId: process.env.NEXT_PUBLIC_APPLE_PAY_MERCHANT_ID!,
338
- merchantName: 'Your Store',
339
- countryCode: 'US',
340
- currencyCode: 'USD',
341
- environment: 'sandbox',
342
- },
343
- },
344
- };
345
-
346
- return (
347
- <MultiProviderPayment
348
- amount={1999} // $19.99 for one-time payments
349
- currency="USD"
350
- label="Complete Purchase"
351
- description="Pro Plan - Monthly Subscription"
352
- providers={providers}
353
- preferredProvider="stripe"
354
- allowProviderSelection={true}
355
- layout="vertical"
356
- showProviderLogos={true}
357
- merchantValidationEndpoint="/api/apple-pay/validate" // Required for Apple Pay
358
- onPaymentSuccess={(provider, details) => {
359
- console.log(`Payment successful with ${provider}:`, details);
360
- }}
361
- onPaymentError={(provider, error) => {
362
- console.error(`Payment failed with ${provider}:`, error);
363
- }}
364
- />
365
- );
366
- }
367
- ```
368
-
369
- **Provider-Specific Components:**
370
- ```tsx
371
- import {
372
- PayPalButton,
373
- PayPalSubscriptionButton,
374
- ApplePayButton,
375
- ApplePaySubscriptionButton
376
- } from '@digilogiclabs/saas-factory-payments/web';
377
-
378
- // PayPal one-time payment
379
- <PayPalButton
380
- amount={1999}
381
- currency="USD"
382
- config={paypalConfig}
383
- onSuccess={(details) => console.log('PayPal payment:', details)}
384
- onError={(error) => console.error('PayPal error:', error)}
385
- />
386
-
387
- // PayPal subscription
388
- <PayPalSubscriptionButton
389
- planId="P-5ML4271244454362WXNWU5NQ"
390
- config={paypalConfig}
391
- onSubscriptionSuccess={(subscriptionId, details) => {
392
- console.log('PayPal subscription:', subscriptionId, details);
393
- }}
394
- />
395
-
396
- // Apple Pay one-time payment
397
- <ApplePayButton
398
- amount={1999}
399
- currency="USD"
400
- label="Buy Pro Plan"
401
- config={applePayConfig}
402
- merchantValidationEndpoint="/api/apple-pay/validate"
403
- onPaymentSuccess={(payment) => console.log('Apple Pay:', payment)}
404
- />
405
-
406
- // Apple Pay subscription
407
- <ApplePaySubscriptionButton
408
- subscriptionDescription="Pro Plan Monthly"
409
- regularBilling={{ label: "Pro Plan", amount: 1999 }}
410
- managementURL="https://yourapp.com/billing"
411
- config={applePayConfig}
412
- merchantValidationEndpoint="/api/apple-pay/validate"
413
- onPaymentSuccess={(payment) => console.log('Apple Pay subscription:', payment)}
414
- />
415
- ```
416
-
417
- ### 5. Subscription Analytics (v1.1.0)
418
-
419
- Get insights into your subscription business with built-in analytics hooks.
420
-
421
- **Subscription Analytics Hook:**
422
- ```tsx
423
- import { useSubscriptionAnalytics } from '@digilogiclabs/saas-factory-payments';
424
-
425
- function DashboardPage({ subscriptions }) {
426
- const analytics = useSubscriptionAnalytics(subscriptions, {
427
- period: 'month',
428
- realTime: true,
429
- refreshInterval: 60000, // 1 minute
430
- });
431
-
432
- if (analytics.loading) return <div>Loading analytics...</div>;
433
-
434
- return (
435
- <div>
436
- <h2>Subscription Analytics</h2>
437
-
438
- {/* Key Metrics */}
439
- <div className="metrics-grid">
440
- <div>
441
- <h3>Monthly Recurring Revenue</h3>
442
- <p>${analytics.metrics?.monthlyRecurringRevenue.toFixed(2)}</p>
443
- </div>
444
- <div>
445
- <h3>Active Subscribers</h3>
446
- <p>{analytics.metrics?.activeSubscribers}</p>
447
- </div>
448
- <div>
449
- <h3>Churn Rate</h3>
450
- <p>{analytics.metrics?.monthlyChurnRate.toFixed(1)}%</p>
451
- </div>
452
- <div>
453
- <h3>Growth Rate</h3>
454
- <p>{analytics.metrics?.growthRate.toFixed(1)}%</p>
455
- </div>
456
- </div>
457
-
458
- {/* Health Status */}
459
- <div className={`status ${analytics.isHealthy ? 'healthy' : 'warning'}`}>
460
- Status: {analytics.isHealthy ? 'Healthy' : 'Needs Attention'}
461
- </div>
462
-
463
- {/* Insights */}
464
- <div className="insights">
465
- <h3>Insights</h3>
466
- {analytics.insights.map((insight, index) => (
467
- <p key={index}>{insight}</p>
468
- ))}
469
- </div>
470
-
471
- {/* Alerts */}
472
- {analytics.alerts.length > 0 && (
473
- <div className="alerts">
474
- <h3>Alerts</h3>
475
- {analytics.alerts.map((alert, index) => (
476
- <div key={index} className={`alert alert-${alert.type}`}>
477
- <strong>{alert.title}</strong>: {alert.message}
478
- </div>
479
- ))}
480
- </div>
481
- )}
482
- </div>
483
- );
484
- }
485
- ```
486
-
487
- **Revenue Analytics Hook:**
488
- ```tsx
489
- import { useRevenueAnalytics } from '@digilogiclabs/saas-factory-payments';
490
-
491
- function RevenuePage({ subscriptions }) {
492
- const revenue = useRevenueAnalytics(subscriptions, {
493
- period: 'month',
494
- includeBreakdown: true,
495
- includeForecasting: true,
496
- currency: 'USD',
497
- });
498
-
499
- return (
500
- <div>
501
- <h2>Revenue Analytics</h2>
502
-
503
- <div className="revenue-overview">
504
- <div>
505
- <h3>Total Revenue</h3>
506
- <p>${revenue.totalRevenue.toFixed(2)}</p>
507
- </div>
508
- <div>
509
- <h3>Recurring Revenue</h3>
510
- <p>${revenue.recurringRevenue.toFixed(2)}</p>
511
- </div>
512
- <div>
513
- <h3>Growth Rate</h3>
514
- <p>{revenue.revenueGrowth.toFixed(1)}%</p>
515
- </div>
516
- <div>
517
- <h3>Revenue Quality</h3>
518
- <p>{revenue.revenueQuality}</p>
519
- </div>
520
- <div>
521
- <h3>Predictability Score</h3>
522
- <p>{revenue.predictability}/100</p>
523
- </div>
524
- </div>
525
-
526
- {revenue.revenueBreakdown && (
527
- <div className="revenue-breakdown">
528
- <h3>Revenue Breakdown</h3>
529
- <div>New Revenue: ${revenue.revenueBreakdown.newRevenue.toFixed(2)}</div>
530
- <div>Expansion: ${revenue.revenueBreakdown.expansionRevenue.toFixed(2)}</div>
531
- <div>Contraction: -${revenue.revenueBreakdown.contractionRevenue.toFixed(2)}</div>
532
- <div>Churned: -${revenue.revenueBreakdown.churned.toFixed(2)}</div>
533
- <div><strong>Net New: ${revenue.revenueBreakdown.netNewRevenue.toFixed(2)}</strong></div>
534
- </div>
535
- )}
536
-
537
- {revenue.forecast && (
538
- <div className="revenue-forecast">
539
- <h3>6-Month Forecast</h3>
540
- {revenue.forecast.map((forecast, index) => (
541
- <div key={index}>
542
- {forecast.period}: ${forecast.predictedRevenue.toFixed(2)}
543
- (±${(forecast.confidenceInterval.high - forecast.confidenceInterval.low).toFixed(2)})
544
- </div>
545
- ))}
546
- </div>
547
- )}
548
- </div>
549
- );
550
- }
551
- ```
552
-
553
- ### 6. Server-Side Integration
554
-
555
- **Create Checkout Session:**
556
- ```tsx
557
- import { createStripeCheckoutSession } from '@digilogiclabs/saas-factory-payments/server';
558
- import Stripe from 'stripe';
559
-
560
- const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
561
-
562
- export default async function handler(req, res) {
563
- try {
564
- const session = await createStripeCheckoutSession(stripe, {
565
- priceId: 'price_pro_monthly',
566
- successUrl: 'https://yourapp.com/success',
567
- cancelUrl: 'https://yourapp.com/cancel',
568
- customerId: 'cus_123', // optional
569
- });
570
-
571
- res.json({ sessionId: session.id });
572
- } catch (error) {
573
- res.status(500).json({ error: error.message });
574
- }
575
- }
576
- ```
577
-
578
- **Process Payment:**
579
- ```tsx
580
- import { processPayment } from '@digilogiclabs/saas-factory-payments/server';
581
- import Stripe from 'stripe';
582
-
583
- const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
584
-
585
- export default async function handler(req, res) {
586
- try {
587
- const paymentIntent = await processPayment(stripe, {
588
- amount: 1999, // $19.99 in cents
589
- currency: 'usd',
590
- paymentMethodId: 'pm_123',
591
- customerId: 'cus_123',
592
- description: 'Pro Plan Subscription',
593
- });
594
-
595
- res.json({ paymentIntent });
596
- } catch (error) {
597
- res.status(500).json({ error: error.message });
598
- }
599
- }
600
- ```
601
-
602
- **Manage Subscriptions:**
603
- ```tsx
604
- import {
605
- createSubscription,
606
- updateSubscription,
607
- cancelSubscription
608
- } from '@digilogiclabs/saas-factory-payments/server';
609
- import Stripe from 'stripe';
610
-
611
- const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
612
-
613
- // Create subscription
614
- const subscription = await createSubscription(stripe, {
615
- customerId: 'cus_123',
616
- priceId: 'price_pro_monthly',
617
- paymentMethodId: 'pm_123',
618
- });
619
-
620
- // Update subscription
621
- const updatedSubscription = await updateSubscription(stripe, {
622
- subscriptionId: 'sub_123',
623
- priceId: 'price_enterprise_monthly',
624
- });
625
-
626
- // Cancel subscription
627
- const canceledSubscription = await cancelSubscription(stripe, 'sub_123', true);
628
- ```
629
-
630
- **Webhook Handling:**
631
- ```tsx
632
- import {
633
- validateStripeSignature,
634
- handleStripeWebhook
635
- } from '@digilogiclabs/saas-factory-payments/server';
636
-
637
- export default async function handler(req, res) {
638
- const signature = req.headers['stripe-signature'];
639
-
640
- try {
641
- const event = validateStripeSignature(
642
- req.body,
643
- signature,
644
- process.env.STRIPE_WEBHOOK_SECRET!
645
- );
646
-
647
- await handleStripeWebhook(event, {
648
- onPaymentSucceeded: async (paymentIntent) => {
649
- console.log('Payment succeeded:', paymentIntent.id);
650
- // Update your database
651
- },
652
- onSubscriptionCreated: async (subscription) => {
653
- console.log('Subscription created:', subscription.id);
654
- // Update your database
655
- },
656
- onInvoicePaid: async (invoice) => {
657
- console.log('Invoice paid:', invoice.id);
658
- // Send confirmation email
659
- },
660
- });
661
-
662
- res.json({ received: true });
663
- } catch (error) {
664
- res.status(400).json({ error: error.message });
665
- }
666
- }
667
- ```
668
-
669
- ## API Reference
670
-
671
- ### UI Components (v0.3.0)
672
-
673
- #### SubscriptionPlans
674
-
675
- Display pricing plans with selection functionality.
676
-
677
- **Props:**
678
- - `plans` (PricingPlan[]): Array of pricing plans
679
- - `onPlanSelect` (function): Callback when plan is selected
680
- - `currentPlan?` (string): Currently active plan ID
681
- - `loading?` (boolean): Loading state
682
- - `className?` (string): Additional CSS classes
683
-
684
- #### SubscriptionManager
685
-
686
- Manage subscription status and actions.
687
-
688
- **Props:**
689
- - `subscription` (Subscription): Current subscription object
690
- - `onSubscriptionChange` (function): Handle subscription actions
691
- - `onCancel` (function): Handle subscription cancellation
692
- - `className?` (string): Additional CSS classes
693
-
694
- #### BillingHistory
695
-
696
- Display invoice history with download functionality.
697
-
698
- **Props:**
699
- - `invoices` (Invoice[]): Array of invoice objects
700
- - `loading?` (boolean): Loading state
701
- - `onInvoiceDownload?` (function): Handle invoice downloads
702
- - `className?` (string): Additional CSS classes
703
-
704
- #### PaymentMethods
705
-
706
- Manage payment methods with CRUD operations.
707
-
708
- **Props:**
709
- - `paymentMethods` (PaymentMethod[]): Array of payment methods
710
- - `onAdd` (function): Add new payment method
711
- - `onEdit` (function): Edit existing payment method
712
- - `onDelete` (function): Delete payment method
713
- - `onSetDefault` (function): Set default payment method
714
- - `loading?` (boolean): Loading state
715
- - `className?` (string): Additional CSS classes
716
-
717
- ### Legacy Components
718
-
719
- #### CheckoutButton
720
-
721
- A button component that handles subscription or one-time payment checkout.
722
-
723
- **Props:**
724
- - `priceId` (string): Stripe price ID
725
- - `customerId?` (string): Existing customer ID
726
- - `customerEmail?` (string): Customer email for new customers
727
- - `successUrl?` (string): Redirect URL after successful payment
728
- - `cancelUrl?` (string): Redirect URL after cancelled payment
729
- - `onSuccess?` (function): Callback for successful payment
730
- - `onError?` (function): Callback for payment errors
731
- - `children` (ReactNode): Button content
732
-
733
- #### PricingTable
734
-
735
- A responsive pricing table component with multiple plans.
736
-
737
- **Props:**
738
- - `plans` (PricingPlan[]): Array of pricing plans
739
- - `customerId?` (string): Customer ID for checkout
740
- - `showFeatures?` (boolean): Whether to show plan features
741
- - `layout?` ('grid' | 'list' | 'carousel'): Layout style
742
- - `onPlanSelect?` (function): Callback when plan is selected
743
-
744
- #### PaymentForm
745
-
746
- An inline payment form for direct payment processing.
747
-
748
- **Props:**
749
- - `clientSecret?` (string): Payment intent client secret
750
- - `amount?` (number): Payment amount in cents
751
- - `currency?` (string): Payment currency
752
- - `onSuccess?` (function): Success callback
753
- - `onError?` (function): Error callback
754
-
755
- #### BillingPortal (Web only)
756
-
757
- A button that opens the Stripe Customer Portal for subscription management.
758
-
759
- **Props:**
760
- - `customerId` (string): Customer ID
761
- - `returnUrl?` (string): Return URL after portal session
762
- - `onSuccess?` (function): Success callback
763
- - `onError?` (function): Error callback
764
-
765
- ### Hooks
766
-
767
- #### usePayments
768
-
769
- High-level hook that combines customer and subscription management.
770
-
771
- ```tsx
772
- const {
773
- customer,
774
- subscriptions,
775
- activeSubscription,
776
- loading,
777
- createCustomer,
778
- subscribe,
779
- cancelSubscription,
780
- hasActiveSubscription,
781
- isSubscribedToPlan,
782
- } = usePayments({ customerId });
783
- ```
784
-
785
- #### useSubscription
786
-
787
- Hook for managing customer subscriptions.
788
-
789
- ```tsx
790
- const {
791
- subscription,
792
- subscriptions,
793
- loading,
794
- error,
795
- refetch,
796
- cancel,
797
- reactivate,
798
- updatePaymentMethod,
799
- } = useSubscription({ customerId });
800
- ```
801
-
802
- #### useCheckout
803
-
804
- Hook for handling checkout processes.
805
-
806
- ```tsx
807
- const {
808
- loading,
809
- error,
810
- createCheckoutSession,
811
- redirectToCheckout,
812
- createPaymentIntent,
813
- } = useCheckout({
814
- onSuccess: (sessionId) => console.log('Success:', sessionId),
815
- onError: (error) => console.error('Error:', error),
816
- });
817
- ```
818
-
819
- #### useCustomer
820
-
821
- Hook for customer management.
822
-
823
- ```tsx
824
- const {
825
- customer,
826
- paymentMethods,
827
- loading,
828
- error,
829
- createCustomer,
830
- updateCustomer,
831
- fetchPaymentMethods,
832
- } = useCustomer({ customerId });
833
- ```
834
-
835
- ### Utilities
836
-
837
- #### Formatting Functions
838
-
839
- ```tsx
840
- import { formatCurrency, formatDate } from '@digilogiclabs/saas-factory-payments';
841
-
842
- // Format currency with proper symbols and decimals
843
- const price = formatCurrency(1999, 'USD'); // "$19.99"
844
- const euroPrice = formatCurrency(2499, 'EUR'); // "€24.99"
845
-
846
- // Format dates in user-friendly format
847
- const date = formatDate(new Date()); // "January 1, 2024"
848
- const shortDate = formatDate(new Date(), { short: true }); // "Jan 1, 2024"
849
- ```
850
-
851
- #### Validation Functions
852
-
853
- ```tsx
854
- import { validateAmount, validateEmail, validatePricingPlan } from '@digilogiclabs/saas-factory-payments';
855
-
856
- // Validate payment amounts
857
- const isValidAmount = validateAmount(1999); // true
858
- const isInvalidAmount = validateAmount(-100); // false
859
-
860
- // Validate email addresses
861
- const isValidEmail = validateEmail('user@example.com'); // true
862
-
863
- // Validate pricing plan structure
864
- const isValidPlan = validatePricingPlan({
865
- id: 'basic',
866
- name: 'Basic Plan',
867
- price: 999,
868
- interval: 'month',
869
- features: ['Feature 1'],
870
- stripePriceId: 'price_123',
871
- }); // true
872
- ```
873
-
874
- #### Constants
875
-
876
- ```tsx
877
- import {
878
- BILLING_INTERVALS,
879
- CURRENCY_SYMBOLS,
880
- SUBSCRIPTION_STATUS
881
- } from '@digilogiclabs/saas-factory-payments';
882
-
883
- // Available billing intervals
884
- console.log(BILLING_INTERVALS); // ['day', 'week', 'month', 'year']
885
-
886
- // Currency symbols
887
- console.log(CURRENCY_SYMBOLS.USD); // '$'
888
- console.log(CURRENCY_SYMBOLS.EUR); // '€'
889
-
890
- // Subscription statuses
891
- console.log(SUBSCRIPTION_STATUS.ACTIVE); // 'active'
892
- console.log(SUBSCRIPTION_STATUS.CANCELED); // 'canceled'
893
- ```
894
-
895
- ### Server-Side Utilities
896
-
897
- #### Stripe Integration Helpers
898
-
899
- ```tsx
900
- import {
901
- createStripeCheckoutSession,
902
- processPayment,
903
- createSubscription,
904
- updateSubscription,
905
- cancelSubscription,
906
- validateStripeSignature,
907
- handleStripeWebhook,
908
- } from '@digilogiclabs/saas-factory-payments/server';
909
- ```
910
-
911
- All server utilities require a Stripe instance as the first parameter:
912
-
913
- ```tsx
914
- import Stripe from 'stripe';
915
- const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
916
- ```
917
-
918
- ## Configuration
919
-
920
- ### Environment Variables
921
-
922
- Create a `.env.local` file (Next.js) or configure your environment:
923
-
924
- ```bash
925
- # Stripe Configuration
926
- NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
927
- STRIPE_SECRET_KEY=sk_test_...
928
- STRIPE_WEBHOOK_SECRET=whsec_...
929
-
930
- # For React Native (Expo)
931
- EXPO_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
932
- ```
933
-
934
- ### PaymentsProvider Configuration
935
-
936
- ```tsx
937
- interface PaymentsConfig {
938
- provider: 'stripe'; // More providers coming soon
939
- publishableKey: string;
940
- secretKey?: string; // Server-side only
941
- webhookSecret?: string; // Server-side only
942
- environment: 'development' | 'production';
943
- }
944
- ```
945
-
946
- ### Type Definitions
947
-
948
- ```tsx
949
- interface PricingPlan {
950
- id: string;
951
- name: string;
952
- description?: string;
953
- price: number; // In cents
954
- currency?: string;
955
- interval: 'day' | 'week' | 'month' | 'year';
956
- stripePriceId?: string;
957
- features: string[];
958
- popular?: boolean;
959
- trialPeriodDays?: number;
960
- }
961
-
962
- interface Subscription {
963
- id: string;
964
- planId: string;
965
- planName: string;
966
- status: 'active' | 'canceled' | 'past_due' | 'unpaid' | 'incomplete';
967
- currentPeriodStart: Date;
968
- currentPeriodEnd: Date;
969
- cancelAtPeriodEnd: boolean;
970
- amount: number;
971
- currency: string;
972
- interval: 'month' | 'year';
973
- }
974
-
975
- interface Invoice {
976
- id: string;
977
- amount: number;
978
- currency: string;
979
- status: 'paid' | 'pending' | 'failed' | 'draft' | 'open';
980
- date: Date;
981
- description: string;
982
- downloadUrl?: string;
983
- invoiceNumber?: string;
984
- }
985
-
986
- interface PaymentMethod {
987
- id: string;
988
- type: 'card' | 'bank_account';
989
- last4: string;
990
- brand?: string;
991
- expiryMonth?: number;
992
- expiryYear?: number;
993
- isDefault: boolean;
994
- bankName?: string;
995
- accountType?: 'checking' | 'savings';
996
- }
997
- ```
998
-
999
- ## CLI Integration
1000
-
1001
- This package is designed to work seamlessly with `create-saas-app`:
1002
-
1003
- ```bash
1004
- npx @digilogiclabs/create-saas-app create web ui-auth-payments my-saas-app
1005
- ```
1006
-
1007
- The CLI will generate a complete SaaS application with:
1008
-
1009
- - **Home page** with success confirmation
1010
- - ✅ **Checkout page** with 3-tier pricing (Basic $9.99, Pro $19.99, Enterprise $49.99)
1011
- - ✅ **Billing page** with subscription management and payment methods
1012
- - ✅ **Responsive design** that works on all devices
1013
- - ✅ **TypeScript support** with full type safety
1014
- - ✅ **Working payment flows** using v0.3.0 utilities
1015
-
1016
- ### Generated Features
1017
-
1018
- When using the `ui-auth-payments` template, you get:
1019
-
1020
- 1. **Complete Pricing Page**: Three-tier subscription plans with "Most Popular" highlighting
1021
- 2. **Subscription Management**: Current plan display with upgrade/downgrade options
1022
- 3. **Payment Methods**: Multiple payment method support with default selection
1023
- 4. **Billing History**: Invoice history with download functionality
1024
- 5. **Responsive Design**: Mobile-first design that works on all screen sizes
1025
- 6. **Error Handling**: Proper loading states and error management
1026
- 7. **TypeScript Integration**: Full type safety throughout the application
1027
-
1028
- ## Examples
1029
-
1030
- ### Complete SaaS Application Structure
1031
-
1032
- ```
1033
- my-saas-app/
1034
- ├── pages/
1035
- │ ├── index.tsx # Home page with feature overview
1036
- │ ├── checkout.tsx # Pricing plans and subscription
1037
- │ ├── billing.tsx # Subscription management
1038
- │ └── api/
1039
- │ ├── checkout.ts # Create checkout sessions
1040
- │ └── webhooks/
1041
- │ └── stripe.ts # Handle Stripe webhooks
1042
- ├── components/
1043
- │ ├── SubscriptionPlans.tsx
1044
- │ ├── BillingHistory.tsx
1045
- │ └── PaymentMethods.tsx
1046
- └── lib/
1047
- └── stripe.ts # Stripe configuration
1048
- ```
1049
-
1050
- ### Real-World Implementation
1051
-
1052
- Based on successful implementation in `create-saas-app`:
1053
-
1054
- ```tsx
1055
- // pages/checkout.tsx
1056
- import { SubscriptionPlans } from '@digilogiclabs/saas-factory-payments/web';
1057
- import { formatCurrency } from '@digilogiclabs/saas-factory-payments';
1058
-
1059
- const plans = [
1060
- {
1061
- id: 'basic',
1062
- name: 'Basic Plan',
1063
- price: 999,
1064
- interval: 'month',
1065
- features: [
1066
- 'Up to 10 projects',
1067
- 'Basic support',
1068
- '1GB storage',
1069
- 'Standard templates',
1070
- ],
1071
- stripePriceId: 'price_basic_monthly',
1072
- },
1073
- {
1074
- id: 'pro',
1075
- name: 'Pro Plan',
1076
- price: 1999,
1077
- interval: 'month',
1078
- features: [
1079
- 'Unlimited projects',
1080
- 'Priority support',
1081
- '10GB storage',
1082
- 'Premium templates',
1083
- 'Advanced analytics',
1084
- ],
1085
- popular: true,
1086
- stripePriceId: 'price_pro_monthly',
1087
- },
1088
- {
1089
- id: 'enterprise',
1090
- name: 'Enterprise Plan',
1091
- price: 4999,
1092
- interval: 'month',
1093
- features: [
1094
- 'Everything in Pro',
1095
- 'Custom integrations',
1096
- '100GB storage',
1097
- 'Dedicated support',
1098
- 'White-label options',
1099
- ],
1100
- stripePriceId: 'price_enterprise_monthly',
1101
- },
1102
- ];
1103
-
1104
- export default function CheckoutPage() {
1105
- return (
1106
- <div className="min-h-screen bg-gray-50 py-12">
1107
- <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
1108
- <div className="text-center">
1109
- <h1 className="text-3xl font-extrabold text-gray-900 sm:text-4xl">
1110
- Choose Your Plan
1111
- </h1>
1112
- <p className="mt-4 text-xl text-gray-600">
1113
- Start building your SaaS application today
1114
- </p>
1115
- </div>
1116
-
1117
- <div className="mt-12">
1118
- <SubscriptionPlans
1119
- plans={plans}
1120
- onPlanSelect={(planId) => {
1121
- // Handle plan selection
1122
- window.location.href = `/api/checkout?priceId=${plans.find(p => p.id === planId)?.stripePriceId}`;
1123
- }}
1124
- className="max-w-5xl mx-auto"
1125
- />
1126
- </div>
1127
- </div>
1128
- </div>
1129
- );
1130
- }
1131
- ```
1132
-
1133
- ## TypeScript Support
1134
-
1135
- This package is built with TypeScript and provides full type safety:
1136
-
1137
- ```tsx
1138
- import type {
1139
- PricingPlan,
1140
- Subscription,
1141
- Customer,
1142
- PaymentsConfig,
1143
- Invoice,
1144
- PaymentMethod,
1145
- SubscriptionStatus,
1146
- SubscriptionAction,
1147
- } from '@digilogiclabs/saas-factory-payments';
1148
-
1149
- // All components and hooks are fully typed
1150
- const subscription: Subscription = {
1151
- id: 'sub_123',
1152
- planId: 'pro',
1153
- planName: 'Pro Plan',
1154
- status: 'active',
1155
- currentPeriodStart: new Date(),
1156
- currentPeriodEnd: new Date(),
1157
- cancelAtPeriodEnd: false,
1158
- amount: 1999,
1159
- currency: 'usd',
1160
- interval: 'month',
1161
- };
1162
- ```
1163
-
1164
- ## Contributing
1165
-
1166
- We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
1167
-
1168
- ## License
1169
-
1170
- MIT License - see [LICENSE](LICENSE) file for details.
1171
-
1172
- ## Support
1173
-
1174
- - 📧 Email: support@digilogiclabs.com
1175
- - 💬 Discord: [Join our community](https://discord.gg/digilogiclabs)
1176
- - 📖 Documentation: [docs.digilogiclabs.com](https://docs.digilogiclabs.com)
1177
- - 🐛 Issues: [GitHub Issues](https://github.com/DigiLogicLabs/saas-factory-payments/issues)
1178
-
1179
- ---
1180
-
1181
- Built with ❤️ by [DigiLogicLabs](https://digilogiclabs.com)
1182
-
1
+ # @digilogiclabs/saas-factory-payments
2
+
3
+ A comprehensive multi-provider payments package for SaaS Factory that works seamlessly in both Next.js and React Native environments. Built with TypeScript and supporting Stripe, PayPal, and Apple Pay with advanced subscription analytics.
4
+
5
+ ## Features
6
+
7
+ - 🌐 **Hybrid Support**: Works in both Next.js web applications and React Native mobile apps
8
+ - 🔒 **Type-Safe**: Built with TypeScript for better developer experience
9
+ - 💳 **Multi-Provider**: Support for Stripe, PayPal, and Apple Pay payments
10
+ - 📊 **Subscription Analytics**: Advanced analytics hooks for revenue, churn, and growth metrics
11
+ - 🎨 **UI Components**: Pre-built components for subscription plans, billing management, and payment methods
12
+ - 🪝 **React Hooks**: Powerful hooks for payments, subscriptions, and analytics
13
+ - 🔧 **Server Utilities**: Complete server-side API and webhook handling
14
+ - 📱 **Mobile-First**: Native mobile payment flows with provider-specific implementations
15
+ - 🎯 **Provider-Agnostic**: Extensible architecture supporting multiple payment providers
16
+ - 🚀 **CLI Integration**: Works seamlessly with create-saas-app
17
+ - 💰 **Complete SaaS Solution**: Everything needed for subscription-based applications
18
+ - 🔄 **Auto-Detection**: Automatic provider detection based on environment variables
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ npm install @digilogiclabs/saas-factory-payments
24
+ # or
25
+ yarn add @digilogiclabs/saas-factory-payments
26
+ # or
27
+ pnpm add @digilogiclabs/saas-factory-payments
28
+ ```
29
+
30
+ ### Peer Dependencies
31
+
32
+ The package requires different peer dependencies based on your platform and payment providers:
33
+
34
+ **For Web (Next.js):**
35
+
36
+ ```bash
37
+ # Required for all payment providers
38
+ npm install react react-dom
39
+
40
+ # Stripe (optional)
41
+ npm install @stripe/stripe-js @stripe/react-stripe-js stripe
42
+
43
+ # PayPal SDK is loaded dynamically - no additional installation required
44
+
45
+ # Apple Pay is native to Safari - no additional installation required
46
+ ```
47
+
48
+ **For React Native:**
49
+
50
+ ```bash
51
+ # Required for all payment providers
52
+ npm install react react-native
53
+
54
+ # Stripe (optional)
55
+ npm install @stripe/stripe-react-native stripe
56
+
57
+ # PayPal React Native (optional)
58
+ npm install react-native-paypal
59
+
60
+ # Apple Pay React Native (optional)
61
+ npm install @react-native-apple-pay/apple-pay
62
+ ```
63
+
64
+ **For Server-side:**
65
+
66
+ ```bash
67
+ # Stripe (optional)
68
+ npm install stripe
69
+
70
+ # PayPal SDK (optional)
71
+ npm install @paypal/checkout-server-sdk
72
+
73
+ # Apple Pay server validation requires custom implementation
74
+ ```
75
+
76
+ ## Quick Start
77
+
78
+ ### 1. Setup Providers
79
+
80
+ First, wrap your app with the PaymentsProvider and platform-specific StripeProvider:
81
+
82
+ **Web (Next.js) - `pages/_app.tsx`:**
83
+
84
+ ```tsx
85
+ import { PaymentsProvider } from '@digilogiclabs/saas-factory-payments';
86
+ import { StripeProvider } from '@digilogiclabs/saas-factory-payments/web';
87
+
88
+ export default function App({ Component, pageProps }) {
89
+ return (
90
+ <PaymentsProvider
91
+ config={{
92
+ provider: 'stripe',
93
+ publishableKey: process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!,
94
+ environment: process.env.NODE_ENV as 'development' | 'production',
95
+ }}
96
+ >
97
+ <StripeProvider>
98
+ <Component {...pageProps} />
99
+ </StripeProvider>
100
+ </PaymentsProvider>
101
+ );
102
+ }
103
+ ```
104
+
105
+ **React Native - `App.tsx`:**
106
+
107
+ ```tsx
108
+ import { PaymentsProvider } from '@digilogiclabs/saas-factory-payments';
109
+ import { StripeProvider } from '@digilogiclabs/saas-factory-payments/native';
110
+
111
+ export default function App() {
112
+ return (
113
+ <PaymentsProvider
114
+ config={{
115
+ provider: 'stripe',
116
+ publishableKey: process.env.EXPO_PUBLIC_STRIPE_PUBLISHABLE_KEY!,
117
+ environment: __DEV__ ? 'development' : 'production',
118
+ }}
119
+ >
120
+ <StripeProvider>
121
+ <MainApp />
122
+ </StripeProvider>
123
+ </PaymentsProvider>
124
+ );
125
+ }
126
+ ```
127
+
128
+ ### 2. Use UI Components (v0.3.0)
129
+
130
+ **Subscription Plans Component:**
131
+
132
+ ```tsx
133
+ import { SubscriptionPlans } from '@digilogiclabs/saas-factory-payments/web';
134
+
135
+ const plans = [
136
+ {
137
+ id: 'basic',
138
+ name: 'Basic Plan',
139
+ price: 999, // $9.99 in cents
140
+ interval: 'month',
141
+ features: ['10 projects', 'Basic support', '1GB storage'],
142
+ stripePriceId: 'price_basic_monthly',
143
+ },
144
+ {
145
+ id: 'pro',
146
+ name: 'Pro Plan',
147
+ price: 1999, // $19.99 in cents
148
+ interval: 'month',
149
+ features: ['Unlimited projects', 'Priority support', '10GB storage'],
150
+ popular: true,
151
+ stripePriceId: 'price_pro_monthly',
152
+ },
153
+ ];
154
+
155
+ export default function PricingPage() {
156
+ return (
157
+ <SubscriptionPlans
158
+ plans={plans}
159
+ onPlanSelect={planId => {
160
+ console.log('Selected plan:', planId);
161
+ // Handle plan selection
162
+ }}
163
+ currentPlan="basic" // Optional: highlight current plan
164
+ />
165
+ );
166
+ }
167
+ ```
168
+
169
+ **Subscription Manager Component:**
170
+
171
+ ```tsx
172
+ import { SubscriptionManager } from '@digilogiclabs/saas-factory-payments/web';
173
+
174
+ const subscription = {
175
+ id: 'sub_123',
176
+ planId: 'pro',
177
+ planName: 'Pro Plan',
178
+ status: 'active',
179
+ currentPeriodStart: new Date('2024-01-01'),
180
+ currentPeriodEnd: new Date('2024-02-01'),
181
+ cancelAtPeriodEnd: false,
182
+ amount: 1999,
183
+ currency: 'usd',
184
+ interval: 'month',
185
+ };
186
+
187
+ export default function BillingPage() {
188
+ return (
189
+ <SubscriptionManager
190
+ subscription={subscription}
191
+ onSubscriptionChange={action => {
192
+ console.log('Subscription action:', action);
193
+ // Handle upgrade, downgrade, pause, resume
194
+ }}
195
+ onCancel={() => {
196
+ console.log('Cancel subscription');
197
+ // Handle cancellation
198
+ }}
199
+ />
200
+ );
201
+ }
202
+ ```
203
+
204
+ **Billing History Component:**
205
+
206
+ ```tsx
207
+ import { BillingHistory } from '@digilogiclabs/saas-factory-payments/web';
208
+
209
+ const invoices = [
210
+ {
211
+ id: 'inv_123',
212
+ amount: 1999,
213
+ currency: 'usd',
214
+ status: 'paid',
215
+ date: new Date('2024-01-01'),
216
+ description: 'Pro Plan - Monthly',
217
+ downloadUrl: 'https://example.com/invoice.pdf',
218
+ invoiceNumber: 'INV-001',
219
+ },
220
+ ];
221
+
222
+ export default function BillingHistoryPage() {
223
+ return (
224
+ <BillingHistory
225
+ invoices={invoices}
226
+ onInvoiceDownload={invoiceId => {
227
+ console.log('Download invoice:', invoiceId);
228
+ // Handle invoice download
229
+ }}
230
+ />
231
+ );
232
+ }
233
+ ```
234
+
235
+ **Payment Methods Component:**
236
+
237
+ ```tsx
238
+ import { PaymentMethods } from '@digilogiclabs/saas-factory-payments/web';
239
+
240
+ const paymentMethods = [
241
+ {
242
+ id: 'pm_123',
243
+ type: 'card',
244
+ last4: '4242',
245
+ brand: 'visa',
246
+ expiryMonth: 12,
247
+ expiryYear: 2025,
248
+ isDefault: true,
249
+ },
250
+ ];
251
+
252
+ export default function PaymentMethodsPage() {
253
+ return (
254
+ <PaymentMethods
255
+ paymentMethods={paymentMethods}
256
+ onAdd={() => console.log('Add payment method')}
257
+ onEdit={methodId => console.log('Edit method:', methodId)}
258
+ onDelete={methodId => console.log('Delete method:', methodId)}
259
+ onSetDefault={methodId => console.log('Set default:', methodId)}
260
+ />
261
+ );
262
+ }
263
+ ```
264
+
265
+ ### 3. Use Utilities and Hooks
266
+
267
+ **Formatting Utilities:**
268
+
269
+ ```tsx
270
+ import {
271
+ formatCurrency,
272
+ formatDate,
273
+ } from '@digilogiclabs/saas-factory-payments';
274
+
275
+ // Format currency amounts
276
+ const price = formatCurrency(1999, 'USD'); // "$19.99"
277
+
278
+ // Format dates
279
+ const date = formatDate(new Date()); // "January 1, 2024"
280
+ ```
281
+
282
+ **Payment Hooks:**
283
+
284
+ ```tsx
285
+ import { usePayments } from '@digilogiclabs/saas-factory-payments';
286
+
287
+ function SubscriptionStatus({ customerId }) {
288
+ const { customer, subscriptions, loading } = usePayments({ customerId });
289
+
290
+ if (loading) return <div>Loading...</div>;
291
+
292
+ return (
293
+ <div>
294
+ <h3>Customer: {customer?.name}</h3>
295
+ <p>Active Subscriptions: {subscriptions?.length || 0}</p>
296
+ </div>
297
+ );
298
+ }
299
+ ```
300
+
301
+ ### 4. Multi-Provider Support (v1.1.0)
302
+
303
+ The package now supports multiple payment providers with automatic detection and unified components.
304
+
305
+ **Environment Variables for Auto-Detection:**
306
+
307
+ ```bash
308
+ # Stripe (optional)
309
+ NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
310
+ STRIPE_SECRET_KEY=sk_test_...
311
+
312
+ # PayPal (optional)
313
+ NEXT_PUBLIC_PAYPAL_CLIENT_ID=your_paypal_client_id
314
+ PAYPAL_CLIENT_SECRET=your_paypal_client_secret
315
+ PAYPAL_CURRENCY=USD
316
+
317
+ # Apple Pay (optional)
318
+ NEXT_PUBLIC_APPLE_PAY_MERCHANT_ID=merchant.yourapp.com
319
+ NEXT_PUBLIC_APPLE_PAY_MERCHANT_NAME=Your Store
320
+ NEXT_PUBLIC_APPLE_PAY_COUNTRY_CODE=US
321
+ NEXT_PUBLIC_APPLE_PAY_CURRENCY_CODE=USD
322
+ ```
323
+
324
+ **Multi-Provider Payment Component:**
325
+
326
+ ```tsx
327
+ import { MultiProviderPayment } from '@digilogiclabs/saas-factory-payments/web';
328
+ import { PaymentProviderFactory } from '@digilogiclabs/saas-factory-payments';
329
+
330
+ function CheckoutPage() {
331
+ const providers = {
332
+ stripe: {
333
+ provider: 'stripe' as const,
334
+ publishableKey: process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!,
335
+ environment: 'development' as const,
336
+ stripeConfig: {
337
+ publishableKey: process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!,
338
+ },
339
+ },
340
+ paypal: {
341
+ provider: 'paypal' as const,
342
+ environment: 'development' as const,
343
+ paypalConfig: {
344
+ clientId: process.env.NEXT_PUBLIC_PAYPAL_CLIENT_ID!,
345
+ environment: 'sandbox',
346
+ currency: 'USD',
347
+ },
348
+ },
349
+ applepay: {
350
+ provider: 'applepay' as const,
351
+ environment: 'development' as const,
352
+ applePayConfig: {
353
+ merchantId: process.env.NEXT_PUBLIC_APPLE_PAY_MERCHANT_ID!,
354
+ merchantName: 'Your Store',
355
+ countryCode: 'US',
356
+ currencyCode: 'USD',
357
+ environment: 'sandbox',
358
+ },
359
+ },
360
+ };
361
+
362
+ return (
363
+ <MultiProviderPayment
364
+ amount={1999} // $19.99 for one-time payments
365
+ currency="USD"
366
+ label="Complete Purchase"
367
+ description="Pro Plan - Monthly Subscription"
368
+ providers={providers}
369
+ preferredProvider="stripe"
370
+ allowProviderSelection={true}
371
+ layout="vertical"
372
+ showProviderLogos={true}
373
+ merchantValidationEndpoint="/api/apple-pay/validate" // Required for Apple Pay
374
+ onPaymentSuccess={(provider, details) => {
375
+ console.log(`Payment successful with ${provider}:`, details);
376
+ }}
377
+ onPaymentError={(provider, error) => {
378
+ console.error(`Payment failed with ${provider}:`, error);
379
+ }}
380
+ />
381
+ );
382
+ }
383
+ ```
384
+
385
+ **Provider-Specific Components:**
386
+
387
+ ```tsx
388
+ import {
389
+ PayPalButton,
390
+ PayPalSubscriptionButton,
391
+ ApplePayButton,
392
+ ApplePaySubscriptionButton
393
+ } from '@digilogiclabs/saas-factory-payments/web';
394
+
395
+ // PayPal one-time payment
396
+ <PayPalButton
397
+ amount={1999}
398
+ currency="USD"
399
+ config={paypalConfig}
400
+ onSuccess={(details) => console.log('PayPal payment:', details)}
401
+ onError={(error) => console.error('PayPal error:', error)}
402
+ />
403
+
404
+ // PayPal subscription
405
+ <PayPalSubscriptionButton
406
+ planId="P-5ML4271244454362WXNWU5NQ"
407
+ config={paypalConfig}
408
+ onSubscriptionSuccess={(subscriptionId, details) => {
409
+ console.log('PayPal subscription:', subscriptionId, details);
410
+ }}
411
+ />
412
+
413
+ // Apple Pay one-time payment
414
+ <ApplePayButton
415
+ amount={1999}
416
+ currency="USD"
417
+ label="Buy Pro Plan"
418
+ config={applePayConfig}
419
+ merchantValidationEndpoint="/api/apple-pay/validate"
420
+ onPaymentSuccess={(payment) => console.log('Apple Pay:', payment)}
421
+ />
422
+
423
+ // Apple Pay subscription
424
+ <ApplePaySubscriptionButton
425
+ subscriptionDescription="Pro Plan Monthly"
426
+ regularBilling={{ label: "Pro Plan", amount: 1999 }}
427
+ managementURL="https://yourapp.com/billing"
428
+ config={applePayConfig}
429
+ merchantValidationEndpoint="/api/apple-pay/validate"
430
+ onPaymentSuccess={(payment) => console.log('Apple Pay subscription:', payment)}
431
+ />
432
+ ```
433
+
434
+ ### 5. Subscription Analytics (v1.1.0)
435
+
436
+ Get insights into your subscription business with built-in analytics hooks.
437
+
438
+ **Subscription Analytics Hook:**
439
+
440
+ ```tsx
441
+ import { useSubscriptionAnalytics } from '@digilogiclabs/saas-factory-payments';
442
+
443
+ function DashboardPage({ subscriptions }) {
444
+ const analytics = useSubscriptionAnalytics(subscriptions, {
445
+ period: 'month',
446
+ realTime: true,
447
+ refreshInterval: 60000, // 1 minute
448
+ });
449
+
450
+ if (analytics.loading) return <div>Loading analytics...</div>;
451
+
452
+ return (
453
+ <div>
454
+ <h2>Subscription Analytics</h2>
455
+
456
+ {/* Key Metrics */}
457
+ <div className="metrics-grid">
458
+ <div>
459
+ <h3>Monthly Recurring Revenue</h3>
460
+ <p>${analytics.metrics?.monthlyRecurringRevenue.toFixed(2)}</p>
461
+ </div>
462
+ <div>
463
+ <h3>Active Subscribers</h3>
464
+ <p>{analytics.metrics?.activeSubscribers}</p>
465
+ </div>
466
+ <div>
467
+ <h3>Churn Rate</h3>
468
+ <p>{analytics.metrics?.monthlyChurnRate.toFixed(1)}%</p>
469
+ </div>
470
+ <div>
471
+ <h3>Growth Rate</h3>
472
+ <p>{analytics.metrics?.growthRate.toFixed(1)}%</p>
473
+ </div>
474
+ </div>
475
+
476
+ {/* Health Status */}
477
+ <div className={`status ${analytics.isHealthy ? 'healthy' : 'warning'}`}>
478
+ Status: {analytics.isHealthy ? 'Healthy' : 'Needs Attention'}
479
+ </div>
480
+
481
+ {/* Insights */}
482
+ <div className="insights">
483
+ <h3>Insights</h3>
484
+ {analytics.insights.map((insight, index) => (
485
+ <p key={index}>{insight}</p>
486
+ ))}
487
+ </div>
488
+
489
+ {/* Alerts */}
490
+ {analytics.alerts.length > 0 && (
491
+ <div className="alerts">
492
+ <h3>Alerts</h3>
493
+ {analytics.alerts.map((alert, index) => (
494
+ <div key={index} className={`alert alert-${alert.type}`}>
495
+ <strong>{alert.title}</strong>: {alert.message}
496
+ </div>
497
+ ))}
498
+ </div>
499
+ )}
500
+ </div>
501
+ );
502
+ }
503
+ ```
504
+
505
+ **Revenue Analytics Hook:**
506
+
507
+ ```tsx
508
+ import { useRevenueAnalytics } from '@digilogiclabs/saas-factory-payments';
509
+
510
+ function RevenuePage({ subscriptions }) {
511
+ const revenue = useRevenueAnalytics(subscriptions, {
512
+ period: 'month',
513
+ includeBreakdown: true,
514
+ includeForecasting: true,
515
+ currency: 'USD',
516
+ });
517
+
518
+ return (
519
+ <div>
520
+ <h2>Revenue Analytics</h2>
521
+
522
+ <div className="revenue-overview">
523
+ <div>
524
+ <h3>Total Revenue</h3>
525
+ <p>${revenue.totalRevenue.toFixed(2)}</p>
526
+ </div>
527
+ <div>
528
+ <h3>Recurring Revenue</h3>
529
+ <p>${revenue.recurringRevenue.toFixed(2)}</p>
530
+ </div>
531
+ <div>
532
+ <h3>Growth Rate</h3>
533
+ <p>{revenue.revenueGrowth.toFixed(1)}%</p>
534
+ </div>
535
+ <div>
536
+ <h3>Revenue Quality</h3>
537
+ <p>{revenue.revenueQuality}</p>
538
+ </div>
539
+ <div>
540
+ <h3>Predictability Score</h3>
541
+ <p>{revenue.predictability}/100</p>
542
+ </div>
543
+ </div>
544
+
545
+ {revenue.revenueBreakdown && (
546
+ <div className="revenue-breakdown">
547
+ <h3>Revenue Breakdown</h3>
548
+ <div>
549
+ New Revenue: ${revenue.revenueBreakdown.newRevenue.toFixed(2)}
550
+ </div>
551
+ <div>
552
+ Expansion: ${revenue.revenueBreakdown.expansionRevenue.toFixed(2)}
553
+ </div>
554
+ <div>
555
+ Contraction: -$
556
+ {revenue.revenueBreakdown.contractionRevenue.toFixed(2)}
557
+ </div>
558
+ <div>Churned: -${revenue.revenueBreakdown.churned.toFixed(2)}</div>
559
+ <div>
560
+ <strong>
561
+ Net New: ${revenue.revenueBreakdown.netNewRevenue.toFixed(2)}
562
+ </strong>
563
+ </div>
564
+ </div>
565
+ )}
566
+
567
+ {revenue.forecast && (
568
+ <div className="revenue-forecast">
569
+ <h3>6-Month Forecast</h3>
570
+ {revenue.forecast.map((forecast, index) => (
571
+ <div key={index}>
572
+ {forecast.period}: ${forecast.predictedRevenue.toFixed(2)}
573
+ (±$
574
+ {(
575
+ forecast.confidenceInterval.high -
576
+ forecast.confidenceInterval.low
577
+ ).toFixed(2)}
578
+ )
579
+ </div>
580
+ ))}
581
+ </div>
582
+ )}
583
+ </div>
584
+ );
585
+ }
586
+ ```
587
+
588
+ ### 6. Server-Side Integration
589
+
590
+ **Create Checkout Session:**
591
+
592
+ ```tsx
593
+ import { createStripeCheckoutSession } from '@digilogiclabs/saas-factory-payments/server';
594
+ import Stripe from 'stripe';
595
+
596
+ const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
597
+
598
+ export default async function handler(req, res) {
599
+ try {
600
+ const session = await createStripeCheckoutSession(stripe, {
601
+ priceId: 'price_pro_monthly',
602
+ successUrl: 'https://yourapp.com/success',
603
+ cancelUrl: 'https://yourapp.com/cancel',
604
+ customerId: 'cus_123', // optional
605
+ });
606
+
607
+ res.json({ sessionId: session.id });
608
+ } catch (error) {
609
+ res.status(500).json({ error: error.message });
610
+ }
611
+ }
612
+ ```
613
+
614
+ **Process Payment:**
615
+
616
+ ```tsx
617
+ import { processPayment } from '@digilogiclabs/saas-factory-payments/server';
618
+ import Stripe from 'stripe';
619
+
620
+ const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
621
+
622
+ export default async function handler(req, res) {
623
+ try {
624
+ const paymentIntent = await processPayment(stripe, {
625
+ amount: 1999, // $19.99 in cents
626
+ currency: 'usd',
627
+ paymentMethodId: 'pm_123',
628
+ customerId: 'cus_123',
629
+ description: 'Pro Plan Subscription',
630
+ });
631
+
632
+ res.json({ paymentIntent });
633
+ } catch (error) {
634
+ res.status(500).json({ error: error.message });
635
+ }
636
+ }
637
+ ```
638
+
639
+ **Manage Subscriptions:**
640
+
641
+ ```tsx
642
+ import {
643
+ createSubscription,
644
+ updateSubscription,
645
+ cancelSubscription,
646
+ } from '@digilogiclabs/saas-factory-payments/server';
647
+ import Stripe from 'stripe';
648
+
649
+ const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
650
+
651
+ // Create subscription
652
+ const subscription = await createSubscription(stripe, {
653
+ customerId: 'cus_123',
654
+ priceId: 'price_pro_monthly',
655
+ paymentMethodId: 'pm_123',
656
+ });
657
+
658
+ // Update subscription
659
+ const updatedSubscription = await updateSubscription(stripe, {
660
+ subscriptionId: 'sub_123',
661
+ priceId: 'price_enterprise_monthly',
662
+ });
663
+
664
+ // Cancel subscription
665
+ const canceledSubscription = await cancelSubscription(stripe, 'sub_123', true);
666
+ ```
667
+
668
+ **Webhook Handling:**
669
+
670
+ ```tsx
671
+ import {
672
+ validateStripeSignature,
673
+ handleStripeWebhook,
674
+ } from '@digilogiclabs/saas-factory-payments/server';
675
+
676
+ export default async function handler(req, res) {
677
+ const signature = req.headers['stripe-signature'];
678
+
679
+ try {
680
+ const event = validateStripeSignature(
681
+ req.body,
682
+ signature,
683
+ process.env.STRIPE_WEBHOOK_SECRET!
684
+ );
685
+
686
+ await handleStripeWebhook(event, {
687
+ onPaymentSucceeded: async paymentIntent => {
688
+ console.log('Payment succeeded:', paymentIntent.id);
689
+ // Update your database
690
+ },
691
+ onSubscriptionCreated: async subscription => {
692
+ console.log('Subscription created:', subscription.id);
693
+ // Update your database
694
+ },
695
+ onInvoicePaid: async invoice => {
696
+ console.log('Invoice paid:', invoice.id);
697
+ // Send confirmation email
698
+ },
699
+ });
700
+
701
+ res.json({ received: true });
702
+ } catch (error) {
703
+ res.status(400).json({ error: error.message });
704
+ }
705
+ }
706
+ ```
707
+
708
+ ## API Reference
709
+
710
+ ### UI Components (v0.3.0)
711
+
712
+ #### SubscriptionPlans
713
+
714
+ Display pricing plans with selection functionality.
715
+
716
+ **Props:**
717
+
718
+ - `plans` (PricingPlan[]): Array of pricing plans
719
+ - `onPlanSelect` (function): Callback when plan is selected
720
+ - `currentPlan?` (string): Currently active plan ID
721
+ - `loading?` (boolean): Loading state
722
+ - `className?` (string): Additional CSS classes
723
+
724
+ #### SubscriptionManager
725
+
726
+ Manage subscription status and actions.
727
+
728
+ **Props:**
729
+
730
+ - `subscription` (Subscription): Current subscription object
731
+ - `onSubscriptionChange` (function): Handle subscription actions
732
+ - `onCancel` (function): Handle subscription cancellation
733
+ - `className?` (string): Additional CSS classes
734
+
735
+ #### BillingHistory
736
+
737
+ Display invoice history with download functionality.
738
+
739
+ **Props:**
740
+
741
+ - `invoices` (Invoice[]): Array of invoice objects
742
+ - `loading?` (boolean): Loading state
743
+ - `onInvoiceDownload?` (function): Handle invoice downloads
744
+ - `className?` (string): Additional CSS classes
745
+
746
+ #### PaymentMethods
747
+
748
+ Manage payment methods with CRUD operations.
749
+
750
+ **Props:**
751
+
752
+ - `paymentMethods` (PaymentMethod[]): Array of payment methods
753
+ - `onAdd` (function): Add new payment method
754
+ - `onEdit` (function): Edit existing payment method
755
+ - `onDelete` (function): Delete payment method
756
+ - `onSetDefault` (function): Set default payment method
757
+ - `loading?` (boolean): Loading state
758
+ - `className?` (string): Additional CSS classes
759
+
760
+ ### Legacy Components
761
+
762
+ #### CheckoutButton
763
+
764
+ A button component that handles subscription or one-time payment checkout.
765
+
766
+ **Props:**
767
+
768
+ - `priceId` (string): Stripe price ID
769
+ - `customerId?` (string): Existing customer ID
770
+ - `customerEmail?` (string): Customer email for new customers
771
+ - `successUrl?` (string): Redirect URL after successful payment
772
+ - `cancelUrl?` (string): Redirect URL after cancelled payment
773
+ - `onSuccess?` (function): Callback for successful payment
774
+ - `onError?` (function): Callback for payment errors
775
+ - `children` (ReactNode): Button content
776
+
777
+ #### PricingTable
778
+
779
+ A responsive pricing table component with multiple plans.
780
+
781
+ **Props:**
782
+
783
+ - `plans` (PricingPlan[]): Array of pricing plans
784
+ - `customerId?` (string): Customer ID for checkout
785
+ - `showFeatures?` (boolean): Whether to show plan features
786
+ - `layout?` ('grid' | 'list' | 'carousel'): Layout style
787
+ - `onPlanSelect?` (function): Callback when plan is selected
788
+
789
+ #### PaymentForm
790
+
791
+ An inline payment form for direct payment processing.
792
+
793
+ **Props:**
794
+
795
+ - `clientSecret?` (string): Payment intent client secret
796
+ - `amount?` (number): Payment amount in cents
797
+ - `currency?` (string): Payment currency
798
+ - `onSuccess?` (function): Success callback
799
+ - `onError?` (function): Error callback
800
+
801
+ #### BillingPortal (Web only)
802
+
803
+ A button that opens the Stripe Customer Portal for subscription management.
804
+
805
+ **Props:**
806
+
807
+ - `customerId` (string): Customer ID
808
+ - `returnUrl?` (string): Return URL after portal session
809
+ - `onSuccess?` (function): Success callback
810
+ - `onError?` (function): Error callback
811
+
812
+ ### Hooks
813
+
814
+ #### usePayments
815
+
816
+ High-level hook that combines customer and subscription management.
817
+
818
+ ```tsx
819
+ const {
820
+ customer,
821
+ subscriptions,
822
+ activeSubscription,
823
+ loading,
824
+ createCustomer,
825
+ subscribe,
826
+ cancelSubscription,
827
+ hasActiveSubscription,
828
+ isSubscribedToPlan,
829
+ } = usePayments({ customerId });
830
+ ```
831
+
832
+ #### useSubscription
833
+
834
+ Hook for managing customer subscriptions.
835
+
836
+ ```tsx
837
+ const {
838
+ subscription,
839
+ subscriptions,
840
+ loading,
841
+ error,
842
+ refetch,
843
+ cancel,
844
+ reactivate,
845
+ updatePaymentMethod,
846
+ } = useSubscription({ customerId });
847
+ ```
848
+
849
+ #### useCheckout
850
+
851
+ Hook for handling checkout processes.
852
+
853
+ ```tsx
854
+ const {
855
+ loading,
856
+ error,
857
+ createCheckoutSession,
858
+ redirectToCheckout,
859
+ createPaymentIntent,
860
+ } = useCheckout({
861
+ onSuccess: sessionId => console.log('Success:', sessionId),
862
+ onError: error => console.error('Error:', error),
863
+ });
864
+ ```
865
+
866
+ #### useCustomer
867
+
868
+ Hook for customer management.
869
+
870
+ ```tsx
871
+ const {
872
+ customer,
873
+ paymentMethods,
874
+ loading,
875
+ error,
876
+ createCustomer,
877
+ updateCustomer,
878
+ fetchPaymentMethods,
879
+ } = useCustomer({ customerId });
880
+ ```
881
+
882
+ ### Utilities
883
+
884
+ #### Formatting Functions
885
+
886
+ ```tsx
887
+ import {
888
+ formatCurrency,
889
+ formatDate,
890
+ } from '@digilogiclabs/saas-factory-payments';
891
+
892
+ // Format currency with proper symbols and decimals
893
+ const price = formatCurrency(1999, 'USD'); // "$19.99"
894
+ const euroPrice = formatCurrency(2499, 'EUR'); // "€24.99"
895
+
896
+ // Format dates in user-friendly format
897
+ const date = formatDate(new Date()); // "January 1, 2024"
898
+ const shortDate = formatDate(new Date(), { short: true }); // "Jan 1, 2024"
899
+ ```
900
+
901
+ #### Validation Functions
902
+
903
+ ```tsx
904
+ import {
905
+ validateAmount,
906
+ validateEmail,
907
+ validatePricingPlan,
908
+ } from '@digilogiclabs/saas-factory-payments';
909
+
910
+ // Validate payment amounts
911
+ const isValidAmount = validateAmount(1999); // true
912
+ const isInvalidAmount = validateAmount(-100); // false
913
+
914
+ // Validate email addresses
915
+ const isValidEmail = validateEmail('user@example.com'); // true
916
+
917
+ // Validate pricing plan structure
918
+ const isValidPlan = validatePricingPlan({
919
+ id: 'basic',
920
+ name: 'Basic Plan',
921
+ price: 999,
922
+ interval: 'month',
923
+ features: ['Feature 1'],
924
+ stripePriceId: 'price_123',
925
+ }); // true
926
+ ```
927
+
928
+ #### Constants
929
+
930
+ ```tsx
931
+ import {
932
+ BILLING_INTERVALS,
933
+ CURRENCY_SYMBOLS,
934
+ SUBSCRIPTION_STATUS,
935
+ } from '@digilogiclabs/saas-factory-payments';
936
+
937
+ // Available billing intervals
938
+ console.log(BILLING_INTERVALS); // ['day', 'week', 'month', 'year']
939
+
940
+ // Currency symbols
941
+ console.log(CURRENCY_SYMBOLS.USD); // '$'
942
+ console.log(CURRENCY_SYMBOLS.EUR); // ''
943
+
944
+ // Subscription statuses
945
+ console.log(SUBSCRIPTION_STATUS.ACTIVE); // 'active'
946
+ console.log(SUBSCRIPTION_STATUS.CANCELED); // 'canceled'
947
+ ```
948
+
949
+ ### Server-Side Utilities
950
+
951
+ #### Stripe Integration Helpers
952
+
953
+ ```tsx
954
+ import {
955
+ createStripeCheckoutSession,
956
+ processPayment,
957
+ createSubscription,
958
+ updateSubscription,
959
+ cancelSubscription,
960
+ validateStripeSignature,
961
+ handleStripeWebhook,
962
+ } from '@digilogiclabs/saas-factory-payments/server';
963
+ ```
964
+
965
+ All server utilities require a Stripe instance as the first parameter:
966
+
967
+ ```tsx
968
+ import Stripe from 'stripe';
969
+ const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
970
+ ```
971
+
972
+ ## Configuration
973
+
974
+ ### Environment Variables
975
+
976
+ Create a `.env.local` file (Next.js) or configure your environment:
977
+
978
+ ```bash
979
+ # Stripe Configuration
980
+ NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
981
+ STRIPE_SECRET_KEY=sk_test_...
982
+ STRIPE_WEBHOOK_SECRET=whsec_...
983
+
984
+ # For React Native (Expo)
985
+ EXPO_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
986
+ ```
987
+
988
+ ### PaymentsProvider Configuration
989
+
990
+ ```tsx
991
+ interface PaymentsConfig {
992
+ provider: 'stripe'; // More providers coming soon
993
+ publishableKey: string;
994
+ secretKey?: string; // Server-side only
995
+ webhookSecret?: string; // Server-side only
996
+ environment: 'development' | 'production';
997
+ }
998
+ ```
999
+
1000
+ ### Type Definitions
1001
+
1002
+ ```tsx
1003
+ interface PricingPlan {
1004
+ id: string;
1005
+ name: string;
1006
+ description?: string;
1007
+ price: number; // In cents
1008
+ currency?: string;
1009
+ interval: 'day' | 'week' | 'month' | 'year';
1010
+ stripePriceId?: string;
1011
+ features: string[];
1012
+ popular?: boolean;
1013
+ trialPeriodDays?: number;
1014
+ }
1015
+
1016
+ interface Subscription {
1017
+ id: string;
1018
+ planId: string;
1019
+ planName: string;
1020
+ status: 'active' | 'canceled' | 'past_due' | 'unpaid' | 'incomplete';
1021
+ currentPeriodStart: Date;
1022
+ currentPeriodEnd: Date;
1023
+ cancelAtPeriodEnd: boolean;
1024
+ amount: number;
1025
+ currency: string;
1026
+ interval: 'month' | 'year';
1027
+ }
1028
+
1029
+ interface Invoice {
1030
+ id: string;
1031
+ amount: number;
1032
+ currency: string;
1033
+ status: 'paid' | 'pending' | 'failed' | 'draft' | 'open';
1034
+ date: Date;
1035
+ description: string;
1036
+ downloadUrl?: string;
1037
+ invoiceNumber?: string;
1038
+ }
1039
+
1040
+ interface PaymentMethod {
1041
+ id: string;
1042
+ type: 'card' | 'bank_account';
1043
+ last4: string;
1044
+ brand?: string;
1045
+ expiryMonth?: number;
1046
+ expiryYear?: number;
1047
+ isDefault: boolean;
1048
+ bankName?: string;
1049
+ accountType?: 'checking' | 'savings';
1050
+ }
1051
+ ```
1052
+
1053
+ ## CLI Integration
1054
+
1055
+ This package is designed to work seamlessly with `create-saas-app`:
1056
+
1057
+ ```bash
1058
+ npx @digilogiclabs/create-saas-app create web ui-auth-payments my-saas-app
1059
+ ```
1060
+
1061
+ The CLI will generate a complete SaaS application with:
1062
+
1063
+ - ✅ **Home page** with success confirmation
1064
+ - ✅ **Checkout page** with 3-tier pricing (Basic $9.99, Pro $19.99, Enterprise $49.99)
1065
+ - ✅ **Billing page** with subscription management and payment methods
1066
+ - **Responsive design** that works on all devices
1067
+ - ✅ **TypeScript support** with full type safety
1068
+ - ✅ **Working payment flows** using v0.3.0 utilities
1069
+
1070
+ ### Generated Features
1071
+
1072
+ When using the `ui-auth-payments` template, you get:
1073
+
1074
+ 1. **Complete Pricing Page**: Three-tier subscription plans with "Most Popular" highlighting
1075
+ 2. **Subscription Management**: Current plan display with upgrade/downgrade options
1076
+ 3. **Payment Methods**: Multiple payment method support with default selection
1077
+ 4. **Billing History**: Invoice history with download functionality
1078
+ 5. **Responsive Design**: Mobile-first design that works on all screen sizes
1079
+ 6. **Error Handling**: Proper loading states and error management
1080
+ 7. **TypeScript Integration**: Full type safety throughout the application
1081
+
1082
+ ## Examples
1083
+
1084
+ ### Complete SaaS Application Structure
1085
+
1086
+ ```
1087
+ my-saas-app/
1088
+ ├── pages/
1089
+ │ ├── index.tsx # Home page with feature overview
1090
+ │ ├── checkout.tsx # Pricing plans and subscription
1091
+ │ ├── billing.tsx # Subscription management
1092
+ │ └── api/
1093
+ │ ├── checkout.ts # Create checkout sessions
1094
+ │ └── webhooks/
1095
+ │ └── stripe.ts # Handle Stripe webhooks
1096
+ ├── components/
1097
+ │ ├── SubscriptionPlans.tsx
1098
+ │ ├── BillingHistory.tsx
1099
+ │ └── PaymentMethods.tsx
1100
+ └── lib/
1101
+ └── stripe.ts # Stripe configuration
1102
+ ```
1103
+
1104
+ ### Real-World Implementation
1105
+
1106
+ Based on successful implementation in `create-saas-app`:
1107
+
1108
+ ```tsx
1109
+ // pages/checkout.tsx
1110
+ import { SubscriptionPlans } from '@digilogiclabs/saas-factory-payments/web';
1111
+ import { formatCurrency } from '@digilogiclabs/saas-factory-payments';
1112
+
1113
+ const plans = [
1114
+ {
1115
+ id: 'basic',
1116
+ name: 'Basic Plan',
1117
+ price: 999,
1118
+ interval: 'month',
1119
+ features: [
1120
+ 'Up to 10 projects',
1121
+ 'Basic support',
1122
+ '1GB storage',
1123
+ 'Standard templates',
1124
+ ],
1125
+ stripePriceId: 'price_basic_monthly',
1126
+ },
1127
+ {
1128
+ id: 'pro',
1129
+ name: 'Pro Plan',
1130
+ price: 1999,
1131
+ interval: 'month',
1132
+ features: [
1133
+ 'Unlimited projects',
1134
+ 'Priority support',
1135
+ '10GB storage',
1136
+ 'Premium templates',
1137
+ 'Advanced analytics',
1138
+ ],
1139
+ popular: true,
1140
+ stripePriceId: 'price_pro_monthly',
1141
+ },
1142
+ {
1143
+ id: 'enterprise',
1144
+ name: 'Enterprise Plan',
1145
+ price: 4999,
1146
+ interval: 'month',
1147
+ features: [
1148
+ 'Everything in Pro',
1149
+ 'Custom integrations',
1150
+ '100GB storage',
1151
+ 'Dedicated support',
1152
+ 'White-label options',
1153
+ ],
1154
+ stripePriceId: 'price_enterprise_monthly',
1155
+ },
1156
+ ];
1157
+
1158
+ export default function CheckoutPage() {
1159
+ return (
1160
+ <div className="min-h-screen bg-gray-50 py-12">
1161
+ <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
1162
+ <div className="text-center">
1163
+ <h1 className="text-3xl font-extrabold text-gray-900 sm:text-4xl">
1164
+ Choose Your Plan
1165
+ </h1>
1166
+ <p className="mt-4 text-xl text-gray-600">
1167
+ Start building your SaaS application today
1168
+ </p>
1169
+ </div>
1170
+
1171
+ <div className="mt-12">
1172
+ <SubscriptionPlans
1173
+ plans={plans}
1174
+ onPlanSelect={planId => {
1175
+ // Handle plan selection
1176
+ window.location.href = `/api/checkout?priceId=${plans.find(p => p.id === planId)?.stripePriceId}`;
1177
+ }}
1178
+ className="max-w-5xl mx-auto"
1179
+ />
1180
+ </div>
1181
+ </div>
1182
+ </div>
1183
+ );
1184
+ }
1185
+ ```
1186
+
1187
+ ## TypeScript Support
1188
+
1189
+ This package is built with TypeScript and provides full type safety:
1190
+
1191
+ ```tsx
1192
+ import type {
1193
+ PricingPlan,
1194
+ Subscription,
1195
+ Customer,
1196
+ PaymentsConfig,
1197
+ Invoice,
1198
+ PaymentMethod,
1199
+ SubscriptionStatus,
1200
+ SubscriptionAction,
1201
+ } from '@digilogiclabs/saas-factory-payments';
1202
+
1203
+ // All components and hooks are fully typed
1204
+ const subscription: Subscription = {
1205
+ id: 'sub_123',
1206
+ planId: 'pro',
1207
+ planName: 'Pro Plan',
1208
+ status: 'active',
1209
+ currentPeriodStart: new Date(),
1210
+ currentPeriodEnd: new Date(),
1211
+ cancelAtPeriodEnd: false,
1212
+ amount: 1999,
1213
+ currency: 'usd',
1214
+ interval: 'month',
1215
+ };
1216
+ ```
1217
+
1218
+ ## Contributing
1219
+
1220
+ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
1221
+
1222
+ ## License
1223
+
1224
+ MIT License - see [LICENSE](LICENSE) file for details.
1225
+
1226
+ ## Support
1227
+
1228
+ - 📧 Email: support@digilogiclabs.com
1229
+ - 💬 Discord: [Join our community](https://discord.gg/digilogiclabs)
1230
+ - 📖 Documentation: [docs.digilogiclabs.com](https://docs.digilogiclabs.com)
1231
+ - 🐛 Issues: [GitHub Issues](https://github.com/DigiLogicLabs/saas-factory-payments/issues)
1232
+
1233
+ ---
1234
+
1235
+ Built with ❤️ by [DigiLogicLabs](https://digilogiclabs.com)