Skip to content

Latest commit

 

History

History
375 lines (286 loc) · 9.67 KB

File metadata and controls

375 lines (286 loc) · 9.67 KB

Installation Guide

Step-by-Step Setup for Any Firebase Project

1. Prerequisites

  • Firebase project with Functions enabled
  • Node.js 20+ and npm installed
  • TypeScript configured in your project
  • Stripe account (test and/or live)

2. Copy Files to Your Project

# Navigate to your Firebase project directory
cd YOUR_PROJECT_DIR

# Copy all Stripe service files
cp -r /path/to/Firebase-TypeScript-Stripe-API/src/services/stripe src/services/

# Copy all Stripe type files
cp -r /path/to/Firebase-TypeScript-Stripe-API/src/types/stripe src/types/

# Copy Stripe components (optional)
cp -r /path/to/Firebase-TypeScript-Stripe-API/src/components/stripe src/components/

# Copy configuration files
cp /path/to/Firebase-TypeScript-Stripe-API/src/config/environment.ts src/config/
cp /path/to/Firebase-TypeScript-Stripe-API/src/utils/firebase/config.ts src/utils/firebase/
cp /path/to/Firebase-TypeScript-Stripe-API/src/services/errorHandler.ts src/services/

# Copy Firebase Function files
cp /path/to/Firebase-TypeScript-Stripe-API/functions/src/stripe-proxy.ts functions/src/
cp /path/to/Firebase-TypeScript-Stripe-API/functions/src/cors-helper.ts functions/src/
cp /path/to/Firebase-TypeScript-Stripe-API/functions/src/environment.ts functions/src/
cp /path/to/Firebase-TypeScript-Stripe-API/functions/src/services/errorHandler.ts functions/src/services/

3. Install Dependencies

# Frontend dependencies
npm install firebase

# Functions dependencies
cd functions
npm install firebase-functions firebase-admin stripe
cd ..

4. Configure Firebase

Update src/utils/firebase/config.ts with your Firebase project details:

const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_PROJECT.firebaseapp.com",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_PROJECT.firebasestorage.app",
  messagingSenderId: "YOUR_SENDER_ID",
  appId: "YOUR_APP_ID"
};

5. Set Up Stripe Secrets

# Test environment secrets
firebase functions:secrets:set STRIPE_TEST_SECRET_KEY
# Enter: sk_test_...

firebase functions:secrets:set STRIPE_TEST_PUBLISHABLE_KEY
# Enter: pk_test_...

firebase functions:secrets:set STRIPE_TEST_ACCOUNT_ID
# Enter: acct_... (optional, for Connect)

# Live environment secrets
firebase functions:secrets:set STRIPE_LIVE_SECRET_KEY
# Enter: sk_live_...

firebase functions:secrets:set STRIPE_LIVE_PUBLISHABLE_KEY
# Enter: pk_live_...

firebase functions:secrets:set STRIPE_LIVE_ACCOUNT_ID
# Enter: acct_... (optional, for Connect)

6. Create Firestore Configuration

Create a document at /config/stripe in Firestore:

{
  "environment": "test",
  "testPublishableKey": "pk_test_...",
  "livePublishableKey": "pk_live_...",
  "createdAt": "2025-10-01T00:00:00.000Z",
  "updatedAt": "2025-10-01T00:00:00.000Z"
}

7. Update Functions index.ts

Add the stripeProxy export to functions/src/index.ts:

export { stripeProxy } from './stripe-proxy';

8. Update CORS Configuration

In functions/src/cors-helper.ts, update the allowed origins:

export const CORS_CONFIG = {
  origins: [
    'https://YOUR_PROJECT.web.app',
    'https://YOUR_PROJECT.firebaseapp.com',
    'http://localhost:3000',
    'http://localhost:5173',
    // Add your custom domains
  ],
  // ... rest of config
};

9. Deploy Firebase Function

firebase deploy --only functions:stripeProxy

Wait for deployment to complete. You'll get a function URL like:

https://us-central1-YOUR_PROJECT.cloudfunctions.net/stripeProxy

10. Test the Integration

import { customersCreateService } from 'src/services/stripe';

async function testStripeIntegration() {
  try {
    const result = await customersCreateService.create({
      email: 'test@example.com',
      name: 'Test Customer'
    });
    
    if (result.success) {
      console.log('✅ Stripe integration working!', result.customer);
    } else {
      console.error('❌ Error:', result.error);
    }
  } catch (error) {
    console.error('❌ Failed:', error);
  }
}

🔄 Switching Between Test and Live

Runtime Switching (No Redeployment)

Update the Firestore document at /config/stripe:

// Switch to LIVE
await updateDoc(doc(db, 'config', 'stripe'), {
  environment: 'live',
  updatedAt: new Date()
});

// Switch to TEST
await updateDoc(doc(db, 'config', 'stripe'), {
  environment: 'test',
  updatedAt: new Date()
});

Changes take effect immediately - no redeployment needed!

🐛 Troubleshooting

CORS Errors

  1. Check functions/src/cors-helper.ts has your domain
  2. Redeploy functions: firebase deploy --only functions:stripeProxy
  3. Clear browser cache

404 Errors on stripeProxy

  1. Verify function is deployed: firebase functions:list
  2. Check function logs: firebase functions:log --only stripeProxy
  3. Ensure Firebase config points to correct project

Type Errors

  1. Verify all files copied correctly
  2. Check tsconfig.json includes src directory
  3. Restart TypeScript server in your IDE

Environment Not Switching

  1. Verify Firestore document exists at /config/stripe
  2. Check Firebase Functions has Firestore permissions
  3. Review function logs for environment retrieval errors

📚 Usage Examples

Create Customer

import { customersCreateService } from 'src/services/stripe';

const result = await customersCreateService.create({
  email: 'customer@example.com',
  name: 'John Doe',
  phone: '+1234567890',
  metadata: {
    userId: 'user_123'
  }
});

Create Payment Intent

import { paymentIntentsCreateService } from 'src/services/stripe';

const result = await paymentIntentsCreateService.create({
  amount: 10000, // $100.00 in cents
  currency: 'usd',
  customer: 'cus_...',
  metadata: {
    orderId: 'order_123'
  }
});

Create Checkout Session

import { checkoutSessionsCreateService } from 'src/services/stripe';

const result = await checkoutSessionsCreateService.create({
  success_url: 'https://yoursite.com/success',
  cancel_url: 'https://yoursite.com/cancel',
  mode: 'payment',
  line_items: [{
    price: 'price_...',
    quantity: 1
  }]
});

Create Subscription

import { subscriptionsCreateService } from 'src/services/stripe';

const result = await subscriptionsCreateService.create({
  customer: 'cus_...',
  items: [{
    price: 'price_...'
  }],
  payment_behavior: 'default_incomplete',
  payment_settings: {
    payment_method_types: ['card']
  }
});

🔐 Security Notes

  1. Never expose secret keys in frontend code
  2. All Stripe API calls go through the Cloud Function proxy
  3. Secret keys stored in Firebase Secret Manager
  4. Frontend only has access to publishable keys
  5. CORS configuration restricts allowed origins

📊 File Structure

Firebase-TypeScript-Stripe-API/
├── src/
│   ├── services/
│   │   ├── stripe/              # 87 folders, 290+ service files
│   │   │   ├── accounts/
│   │   │   ├── customers/
│   │   │   ├── paymentIntents/
│   │   │   └── ...
│   │   └── errorHandler.ts
│   ├── types/
│   │   └── stripe/              # 77 type files
│   │       ├── common.ts
│   │       ├── accounts.ts
│   │       ├── customers.ts
│   │       ├── index.ts         # Barrel export
│   │       └── ...
│   ├── components/
│   │   └── stripe/              # Reusable UI components
│   ├── config/
│   │   └── environment.ts       # Frontend env config
│   └── utils/
│       └── firebase/
│           └── config.ts        # Firebase init
└── functions/
    └── src/
        ├── stripe-proxy.ts      # Main proxy function
        ├── cors-helper.ts       # CORS utilities
        ├── environment.ts       # Runtime env switching
        └── services/
            └── errorHandler.ts  # Error handling

✨ Key Benefits

  1. No CORS Issues - All Stripe API calls proxied through Firebase Function
  2. Type Safety - Complete TypeScript coverage prevents errors
  3. Environment Switching - Runtime switch between test/live
  4. AI-Friendly - Consistent structure prevents AI coding mistakes
  5. Production-Ready - Comprehensive error handling
  6. Easy to Use - Simple, predictable API
  7. Fully Documented - JSDoc comments throughout

🎓 Advanced Features

Custom Error Handling

import { ErrorHandler, ErrorContext } from 'src/services/errorHandler';

const context: ErrorContext = {
  operation: 'createCustomer',
  customerEmail: email,
  orderId: orderId
};

const errorResult = ErrorHandler.handleStripeError(error, context);
// Returns user-friendly error message

Environment Detection

import { getStripeEnvironment } from 'src/config/environment';

const env = await getStripeEnvironment();
console.log('Current environment:', env); // 'test' or 'live'

🌟 What Makes This Special

  • Complete Coverage - Every Stripe API endpoint implemented
  • Zero Compromises - No shortcuts, all parameters properly typed
  • Battle-Tested - Running in production
  • Maintainable - Consistent patterns throughout
  • Future-Proof - Easy to add new Stripe features

📞 Support

For issues or questions:

  1. Check Stripe API docs: https://docs.stripe.com/api
  2. Review function logs: firebase functions:log
  3. Verify Firestore config document exists

Built with ❤️ by Eric Wiedemann for the Firebase + Stripe developer community

Repository: github.com/Twizbee/firebase-typescript-stripe-api