Matt 06733cb2cb
All checks were successful
Build and Push Docker Image / docker (push) Successful in 42s
Integrate Stripe Checkout and add comprehensive UI enhancements
## Stripe Payment Integration
- Add Express.js backend server with Stripe Checkout Sessions
- Create SQLite database for order tracking
- Implement Stripe webhook handlers for payment events
- Integrate with Wren Climate API for carbon offset fulfillment
- Add CheckoutSuccess and CheckoutCancel pages
- Create checkout API client for frontend
- Update OffsetOrder component to redirect to Stripe Checkout
- Add processing fee calculation (3% of base amount)
- Implement order status tracking (pending → paid → fulfilled)

Backend (server/):
- Express server with CORS and middleware
- SQLite database with Order schema
- Stripe configuration and client
- Order CRUD operations model
- Checkout session creation endpoint
- Webhook handler for payment confirmation
- Wren API client for offset fulfillment

Frontend:
- CheckoutSuccess page with order details display
- CheckoutCancel page with retry encouragement
- Updated OffsetOrder to use Stripe checkout flow
- Added checkout routes to App.tsx
- TypeScript interfaces for checkout flow

## Visual & UX Enhancements
- Add CertificationBadge component for project verification status
- Create PortfolioDonutChart for visual portfolio allocation
- Implement RadialProgress for percentage displays
- Add reusable form components (FormInput, FormTextarea, FormSelect, FormFieldWrapper)
- Refactor OffsetOrder with improved layout and animations
- Add offset percentage slider with visual feedback
- Enhance MobileOffsetOrder with better responsive design
- Improve TripCalculator with cleaner UI structure
- Update CurrencySelect with better styling
- Add portfolio distribution visualization
- Enhance project cards with hover effects and animations
- Improve color palette and gradient usage throughout

## Configuration
- Add VITE_API_BASE_URL environment variable
- Create backend .env.example template
- Update frontend .env.example with API URL
- Add Stripe documentation references

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 21:45:14 +01:00

74 lines
2.0 KiB
JavaScript

import Database from 'better-sqlite3';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const dbPath = process.env.DATABASE_PATH || join(__dirname, '..', 'orders.db');
// Initialize database
export const db = new Database(dbPath);
// Enable foreign keys
db.pragma('foreign_keys = ON');
// Create orders table
const createOrdersTable = () => {
const sql = `
CREATE TABLE IF NOT EXISTS orders (
id TEXT PRIMARY KEY,
stripe_session_id TEXT UNIQUE NOT NULL,
stripe_payment_intent TEXT,
wren_order_id TEXT,
customer_email TEXT,
tons REAL NOT NULL,
portfolio_id INTEGER NOT NULL,
base_amount INTEGER NOT NULL,
processing_fee INTEGER NOT NULL,
total_amount INTEGER NOT NULL,
currency TEXT DEFAULT 'USD',
status TEXT DEFAULT 'pending',
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
)
`;
// Using better-sqlite3's prepare/run for safety (not child_process)
db.prepare(sql).run();
console.log('✅ Orders table created successfully');
};
// Create indexes for faster lookups
const createIndexes = () => {
const indexes = [
'CREATE INDEX IF NOT EXISTS idx_stripe_session_id ON orders(stripe_session_id)',
'CREATE INDEX IF NOT EXISTS idx_status ON orders(status)',
'CREATE INDEX IF NOT EXISTS idx_created_at ON orders(created_at)'
];
indexes.forEach(indexSql => db.prepare(indexSql).run());
console.log('✅ Database indexes created successfully');
};
// Initialize database schema
export const initializeDatabase = () => {
try {
createOrdersTable();
createIndexes();
console.log('✅ Database initialized successfully');
return true;
} catch (error) {
console.error('❌ Database initialization failed:', error);
return false;
}
};
// Run initialization if called directly
if (import.meta.url === `file://${process.argv[1]}`) {
initializeDatabase();
db.close();
}
export default db;