All checks were successful
Build and Push Docker Image / docker (push) Successful in 42s
## 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>
74 lines
2.0 KiB
JavaScript
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;
|