puffin-app/server/routes/webhooks.js

528 lines
19 KiB
JavaScript
Raw Normal View History

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
import express from 'express';
import { stripe, webhookSecret } from '../config/stripe.js';
import { Order } from '../models/Order.js';
import { createWrenOffsetOrder, getWrenPortfolios } from '../utils/wrenClient.js';
import { sendReceiptEmail, sendAdminNotification } from '../utils/emailService.js';
import { selectComparisons } from '../utils/carbonComparisons.js';
import { formatPortfolioProjects } from '../utils/portfolioColors.js';
Add NocoDB integration for order management with comprehensive Stripe webhook logging Features: - Complete NocoDB schema with 42 fields supporting B2B and B2C customers - Server-side NocoDB client (REST API integration) - Stripe session data mapper with automatic field mapping - Enhanced webhook handler with comprehensive logging - Automatic order creation in NocoDB after payment - Fulfillment data updates with Wren order IDs - Support for business customers (VAT/EIN, business names) - Complete billing address capture - Non-blocking error handling (webhook succeeds even if NocoDB fails) Files Added: - server/utils/nocodbClient.js - NocoDB REST API client - server/utils/nocodbMapper.js - Stripe to NocoDB data mapper - docs/NOCODB_SCHEMA.md - Complete field reference (42 columns) - docs/NOCODB_INTEGRATION_GUIDE.md - Testing and deployment guide - docs/TESTING_STRIPE_WEBHOOK.md - Webhook testing instructions - docs/STRIPE_INTEGRATION_SUMMARY.md - Project overview Files Modified: - server/routes/webhooks.js - Added NocoDB integration and enhanced logging - src/types.ts - Updated OrderRecord interface with new fields - src/api/nocodbClient.ts - Added createOrder() method - .env.example - Added NocoDB configuration template Schema includes: - Payment tracking (Stripe session/intent/customer IDs, amounts, fees) - Carbon offset details (tons, portfolio, Wren order ID) - Customer information (name, email, phone, business name) - Tax ID collection (VAT, EIN, etc.) - Complete billing address - Optional vessel/trip details for yacht calculations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 16:35:15 +01:00
import { nocodbClient } from '../utils/nocodbClient.js';
import { mapStripeSessionToNocoDBOrder, mapWrenFulfillmentData } from '../utils/nocodbMapper.js';
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
const router = express.Router();
Add NocoDB integration for order management with comprehensive Stripe webhook logging Features: - Complete NocoDB schema with 42 fields supporting B2B and B2C customers - Server-side NocoDB client (REST API integration) - Stripe session data mapper with automatic field mapping - Enhanced webhook handler with comprehensive logging - Automatic order creation in NocoDB after payment - Fulfillment data updates with Wren order IDs - Support for business customers (VAT/EIN, business names) - Complete billing address capture - Non-blocking error handling (webhook succeeds even if NocoDB fails) Files Added: - server/utils/nocodbClient.js - NocoDB REST API client - server/utils/nocodbMapper.js - Stripe to NocoDB data mapper - docs/NOCODB_SCHEMA.md - Complete field reference (42 columns) - docs/NOCODB_INTEGRATION_GUIDE.md - Testing and deployment guide - docs/TESTING_STRIPE_WEBHOOK.md - Webhook testing instructions - docs/STRIPE_INTEGRATION_SUMMARY.md - Project overview Files Modified: - server/routes/webhooks.js - Added NocoDB integration and enhanced logging - src/types.ts - Updated OrderRecord interface with new fields - src/api/nocodbClient.ts - Added createOrder() method - .env.example - Added NocoDB configuration template Schema includes: - Payment tracking (Stripe session/intent/customer IDs, amounts, fees) - Carbon offset details (tons, portfolio, Wren order ID) - Customer information (name, email, phone, business name) - Tax ID collection (VAT, EIN, etc.) - Complete billing address - Optional vessel/trip details for yacht calculations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 16:35:15 +01:00
/**
* Log all available Stripe session data for schema verification
* This helps us verify what fields are actually available from Stripe
*/
function logStripeSessionData(session) {
console.log('\n╔════════════════════════════════════════════════════════════════╗');
console.log('║ STRIPE CHECKOUT SESSION - COMPREHENSIVE DATA ║');
console.log('╚════════════════════════════════════════════════════════════════╝\n');
// Core Session Info
console.log('📋 SESSION INFORMATION:');
console.log(' Session ID:', session.id || 'N/A');
console.log(' Payment Intent:', session.payment_intent || 'N/A');
console.log(' Payment Status:', session.payment_status || 'N/A');
console.log(' Status:', session.status || 'N/A');
console.log(' Mode:', session.mode || 'N/A');
console.log(' Created:', session.created ? new Date(session.created * 1000).toISOString() : 'N/A');
console.log(' Expires At:', session.expires_at ? new Date(session.expires_at * 1000).toISOString() : 'N/A');
// Amount Details
console.log('\n💰 PAYMENT AMOUNT:');
console.log(' Amount Total:', session.amount_total ? `${session.amount_total} cents ($${(session.amount_total / 100).toFixed(2)})` : 'N/A');
console.log(' Amount Subtotal:', session.amount_subtotal ? `${session.amount_subtotal} cents ($${(session.amount_subtotal / 100).toFixed(2)})` : 'N/A');
console.log(' Currency:', session.currency ? session.currency.toUpperCase() : 'N/A');
// Customer Details
console.log('\n👤 CUSTOMER DETAILS:');
if (session.customer_details) {
console.log(' Name (Display):', session.customer_details.name || 'N/A');
console.log(' Business Name:', session.customer_details.business_name || 'N/A');
console.log(' Individual Name:', session.customer_details.individual_name || 'N/A');
console.log(' Email:', session.customer_details.email || 'N/A');
console.log(' Phone:', session.customer_details.phone || 'N/A');
console.log(' Tax Exempt:', session.customer_details.tax_exempt || 'N/A');
// Billing Address
console.log('\n📬 BILLING ADDRESS:');
if (session.customer_details.address) {
const addr = session.customer_details.address;
console.log(' Line 1:', addr.line1 || 'N/A');
console.log(' Line 2:', addr.line2 || 'N/A');
console.log(' City:', addr.city || 'N/A');
console.log(' State:', addr.state || 'N/A');
console.log(' Postal Code:', addr.postal_code || 'N/A');
console.log(' Country:', addr.country || 'N/A');
} else {
console.log(' No address provided');
}
} else {
console.log(' No customer details provided');
}
// Customer Object Reference
console.log('\n🔗 CUSTOMER OBJECT:');
console.log(' Customer ID:', session.customer || 'N/A');
// Payment Method Details
console.log('\n💳 PAYMENT METHOD:');
if (session.payment_method_types && session.payment_method_types.length > 0) {
console.log(' Types:', session.payment_method_types.join(', '));
} else {
console.log(' Types: N/A');
}
// Metadata (our custom data)
console.log('\n🏷 METADATA (Our Custom Fields):');
if (session.metadata && Object.keys(session.metadata).length > 0) {
Object.entries(session.metadata).forEach(([key, value]) => {
console.log(` ${key}:`, value);
});
} else {
console.log(' No metadata');
}
// Line Items (what they purchased)
console.log('\n🛒 LINE ITEMS:');
if (session.line_items) {
console.log(' Available in session object');
} else {
console.log(' Not expanded (need to fetch separately)');
}
// Additional Fields
console.log('\n🔧 ADDITIONAL FIELDS:');
console.log(' Client Reference ID:', session.client_reference_id || 'N/A');
console.log(' Locale:', session.locale || 'N/A');
console.log(' Success URL:', session.success_url || 'N/A');
console.log(' Cancel URL:', session.cancel_url || 'N/A');
// Shipping (if collected)
if (session.shipping) {
console.log('\n📦 SHIPPING (if collected):');
console.log(' Name:', session.shipping.name || 'N/A');
if (session.shipping.address) {
const addr = session.shipping.address;
console.log(' Address Line 1:', addr.line1 || 'N/A');
console.log(' Address Line 2:', addr.line2 || 'N/A');
console.log(' City:', addr.city || 'N/A');
console.log(' State:', addr.state || 'N/A');
console.log(' Postal Code:', addr.postal_code || 'N/A');
console.log(' Country:', addr.country || 'N/A');
}
}
// Tax IDs (if collected)
if (session.customer_details?.tax_ids && session.customer_details.tax_ids.length > 0) {
console.log('\n🆔 TAX IDS (if collected):');
session.customer_details.tax_ids.forEach((taxId, index) => {
console.log(` Tax ID ${index + 1}:`, taxId.type, '-', taxId.value);
});
}
console.log('\n╔════════════════════════════════════════════════════════════════╗');
console.log('║ END OF STRIPE DATA LOG ║');
console.log('╚════════════════════════════════════════════════════════════════╝\n');
}
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
/**
* POST /api/webhooks/stripe
* Handle Stripe webhook events
*
* IMPORTANT: This endpoint requires raw body, not JSON parsed
*/
router.post('/stripe', express.raw({ type: 'application/json' }), async (req, res) => {
const sig = req.headers['stripe-signature'];
let event;
try {
// Verify webhook signature
event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
} catch (err) {
console.error('❌ Webhook signature verification failed:', err.message);
return res.status(400).send(`Webhook Error: ${err.message}`);
}
console.log(`📬 Received webhook: ${event.type}`);
Add NocoDB integration for order management with comprehensive Stripe webhook logging Features: - Complete NocoDB schema with 42 fields supporting B2B and B2C customers - Server-side NocoDB client (REST API integration) - Stripe session data mapper with automatic field mapping - Enhanced webhook handler with comprehensive logging - Automatic order creation in NocoDB after payment - Fulfillment data updates with Wren order IDs - Support for business customers (VAT/EIN, business names) - Complete billing address capture - Non-blocking error handling (webhook succeeds even if NocoDB fails) Files Added: - server/utils/nocodbClient.js - NocoDB REST API client - server/utils/nocodbMapper.js - Stripe to NocoDB data mapper - docs/NOCODB_SCHEMA.md - Complete field reference (42 columns) - docs/NOCODB_INTEGRATION_GUIDE.md - Testing and deployment guide - docs/TESTING_STRIPE_WEBHOOK.md - Webhook testing instructions - docs/STRIPE_INTEGRATION_SUMMARY.md - Project overview Files Modified: - server/routes/webhooks.js - Added NocoDB integration and enhanced logging - src/types.ts - Updated OrderRecord interface with new fields - src/api/nocodbClient.ts - Added createOrder() method - .env.example - Added NocoDB configuration template Schema includes: - Payment tracking (Stripe session/intent/customer IDs, amounts, fees) - Carbon offset details (tons, portfolio, Wren order ID) - Customer information (name, email, phone, business name) - Tax ID collection (VAT, EIN, etc.) - Complete billing address - Optional vessel/trip details for yacht calculations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 16:35:15 +01:00
// Log comprehensive Stripe data for schema verification
if (event.type === 'checkout.session.completed') {
logStripeSessionData(event.data.object);
}
// Log full webhook payload for debugging and data extraction
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
console.log('📦 Full Stripe Webhook Payload:');
console.log(JSON.stringify(event, null, 2));
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
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
// Handle different event types
switch (event.type) {
case 'checkout.session.completed':
await handleCheckoutSessionCompleted(event.data.object);
break;
case 'checkout.session.async_payment_succeeded':
await handleAsyncPaymentSucceeded(event.data.object);
break;
case 'checkout.session.async_payment_failed':
await handleAsyncPaymentFailed(event.data.object);
break;
Implement comprehensive Stripe security fixes and production deployment CRITICAL SECURITY FIXES: - Add webhook secret validation to prevent signature bypass - Implement idempotency protection across all webhook handlers - Add atomic database updates to prevent race conditions - Improve CORS security with origin validation and logging - Remove .env from git tracking to protect secrets STRIPE INTEGRATION: - Add support for checkout.session.expired webhook event - Add Stripe publishable key to environment configuration - Fix webhook handlers with proper idempotency checks - Update Order model with atomic updatePaymentAndStatus method - Add comprehensive logging for webhook processing DEPLOYMENT ARCHITECTURE: - Split into two Docker images (frontend-latest, backend-latest) - Update CI/CD to build separate frontend and backend images - Configure backend on port 3801 (internal 3001) - Add production-ready docker-compose.yml - Remove redundant docker-compose.portainer.yml - Update nginx configuration for both frontend and backend DOCUMENTATION: - Add PRODUCTION-SETUP.md with complete deployment guide - Add docs/stripe-security-fixes.md with security audit details - Add docs/stripe-checkout-sessions.md with integration docs - Add docs/stripe-webhooks.md with webhook configuration - Update .env.example with all required variables including Stripe publishable key CONFIGURATION: - Consolidate to single .env.example template - Update .gitignore to protect all .env variants - Add server/Dockerfile for backend container - Update DEPLOYMENT.md with new architecture 🔒 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 12:18:57 +01:00
case 'checkout.session.expired':
await handleCheckoutSessionExpired(event.data.object);
break;
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
default:
console.log(` Unhandled event type: ${event.type}`);
}
// Return 200 to acknowledge receipt
res.json({ received: true });
});
/**
* Handle checkout.session.completed event
* This fires when payment succeeds (or session completes for delayed payment methods)
*/
async function handleCheckoutSessionCompleted(session) {
console.log(`✅ Checkout session completed: ${session.id}`);
try {
// Find order in database
const order = Order.findBySessionId(session.id);
if (!order) {
console.error(`❌ Order not found for session: ${session.id}`);
return;
}
Implement comprehensive Stripe security fixes and production deployment CRITICAL SECURITY FIXES: - Add webhook secret validation to prevent signature bypass - Implement idempotency protection across all webhook handlers - Add atomic database updates to prevent race conditions - Improve CORS security with origin validation and logging - Remove .env from git tracking to protect secrets STRIPE INTEGRATION: - Add support for checkout.session.expired webhook event - Add Stripe publishable key to environment configuration - Fix webhook handlers with proper idempotency checks - Update Order model with atomic updatePaymentAndStatus method - Add comprehensive logging for webhook processing DEPLOYMENT ARCHITECTURE: - Split into two Docker images (frontend-latest, backend-latest) - Update CI/CD to build separate frontend and backend images - Configure backend on port 3801 (internal 3001) - Add production-ready docker-compose.yml - Remove redundant docker-compose.portainer.yml - Update nginx configuration for both frontend and backend DOCUMENTATION: - Add PRODUCTION-SETUP.md with complete deployment guide - Add docs/stripe-security-fixes.md with security audit details - Add docs/stripe-checkout-sessions.md with integration docs - Add docs/stripe-webhooks.md with webhook configuration - Update .env.example with all required variables including Stripe publishable key CONFIGURATION: - Consolidate to single .env.example template - Update .gitignore to protect all .env variants - Add server/Dockerfile for backend container - Update DEPLOYMENT.md with new architecture 🔒 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 12:18:57 +01:00
// 🔒 IDEMPOTENCY CHECK: Prevent duplicate processing
if (order.status === 'fulfilled' || order.wren_order_id) {
console.log(`⚠️ Order ${order.id} already fulfilled (status: ${order.status}), skipping duplicate webhook`);
return;
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
}
Implement comprehensive Stripe security fixes and production deployment CRITICAL SECURITY FIXES: - Add webhook secret validation to prevent signature bypass - Implement idempotency protection across all webhook handlers - Add atomic database updates to prevent race conditions - Improve CORS security with origin validation and logging - Remove .env from git tracking to protect secrets STRIPE INTEGRATION: - Add support for checkout.session.expired webhook event - Add Stripe publishable key to environment configuration - Fix webhook handlers with proper idempotency checks - Update Order model with atomic updatePaymentAndStatus method - Add comprehensive logging for webhook processing DEPLOYMENT ARCHITECTURE: - Split into two Docker images (frontend-latest, backend-latest) - Update CI/CD to build separate frontend and backend images - Configure backend on port 3801 (internal 3001) - Add production-ready docker-compose.yml - Remove redundant docker-compose.portainer.yml - Update nginx configuration for both frontend and backend DOCUMENTATION: - Add PRODUCTION-SETUP.md with complete deployment guide - Add docs/stripe-security-fixes.md with security audit details - Add docs/stripe-checkout-sessions.md with integration docs - Add docs/stripe-webhooks.md with webhook configuration - Update .env.example with all required variables including Stripe publishable key CONFIGURATION: - Consolidate to single .env.example template - Update .gitignore to protect all .env variants - Add server/Dockerfile for backend container - Update DEPLOYMENT.md with new architecture 🔒 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 12:18:57 +01:00
if (order.status === 'paid') {
console.log(`⚠️ Order ${order.id} already marked as paid, skipping payment update`);
// Still attempt fulfillment if not fulfilled yet
await fulfillOrder(order, session);
return;
}
// Atomically update payment intent and status to prevent race conditions
if (session.payment_intent) {
Order.updatePaymentAndStatus(order.id, session.payment_intent, 'paid');
} else {
Order.updateStatus(order.id, 'paid');
}
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
console.log(`💳 Payment confirmed for order: ${order.id}`);
console.log(` Amount: $${(order.total_amount / 100).toFixed(2)}`);
Add NocoDB integration for order management with comprehensive Stripe webhook logging Features: - Complete NocoDB schema with 42 fields supporting B2B and B2C customers - Server-side NocoDB client (REST API integration) - Stripe session data mapper with automatic field mapping - Enhanced webhook handler with comprehensive logging - Automatic order creation in NocoDB after payment - Fulfillment data updates with Wren order IDs - Support for business customers (VAT/EIN, business names) - Complete billing address capture - Non-blocking error handling (webhook succeeds even if NocoDB fails) Files Added: - server/utils/nocodbClient.js - NocoDB REST API client - server/utils/nocodbMapper.js - Stripe to NocoDB data mapper - docs/NOCODB_SCHEMA.md - Complete field reference (42 columns) - docs/NOCODB_INTEGRATION_GUIDE.md - Testing and deployment guide - docs/TESTING_STRIPE_WEBHOOK.md - Webhook testing instructions - docs/STRIPE_INTEGRATION_SUMMARY.md - Project overview Files Modified: - server/routes/webhooks.js - Added NocoDB integration and enhanced logging - src/types.ts - Updated OrderRecord interface with new fields - src/api/nocodbClient.ts - Added createOrder() method - .env.example - Added NocoDB configuration template Schema includes: - Payment tracking (Stripe session/intent/customer IDs, amounts, fees) - Carbon offset details (tons, portfolio, Wren order ID) - Customer information (name, email, phone, business name) - Tax ID collection (VAT, EIN, etc.) - Complete billing address - Optional vessel/trip details for yacht calculations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 16:35:15 +01:00
// (Detailed session data already logged above via logStripeSessionData())
// Save order to NocoDB
await saveOrderToNocoDB(order, session);
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
// Fulfill order via Wren API
await fulfillOrder(order, session);
} catch (error) {
console.error('❌ Error handling checkout session completed:', error);
}
}
/**
* Handle async payment succeeded (e.g., ACH, bank transfer)
*/
async function handleAsyncPaymentSucceeded(session) {
console.log(`✅ Async payment succeeded: ${session.id}`);
try {
const order = Order.findBySessionId(session.id);
if (!order) {
console.error(`❌ Order not found for session: ${session.id}`);
return;
}
Implement comprehensive Stripe security fixes and production deployment CRITICAL SECURITY FIXES: - Add webhook secret validation to prevent signature bypass - Implement idempotency protection across all webhook handlers - Add atomic database updates to prevent race conditions - Improve CORS security with origin validation and logging - Remove .env from git tracking to protect secrets STRIPE INTEGRATION: - Add support for checkout.session.expired webhook event - Add Stripe publishable key to environment configuration - Fix webhook handlers with proper idempotency checks - Update Order model with atomic updatePaymentAndStatus method - Add comprehensive logging for webhook processing DEPLOYMENT ARCHITECTURE: - Split into two Docker images (frontend-latest, backend-latest) - Update CI/CD to build separate frontend and backend images - Configure backend on port 3801 (internal 3001) - Add production-ready docker-compose.yml - Remove redundant docker-compose.portainer.yml - Update nginx configuration for both frontend and backend DOCUMENTATION: - Add PRODUCTION-SETUP.md with complete deployment guide - Add docs/stripe-security-fixes.md with security audit details - Add docs/stripe-checkout-sessions.md with integration docs - Add docs/stripe-webhooks.md with webhook configuration - Update .env.example with all required variables including Stripe publishable key CONFIGURATION: - Consolidate to single .env.example template - Update .gitignore to protect all .env variants - Add server/Dockerfile for backend container - Update DEPLOYMENT.md with new architecture 🔒 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 12:18:57 +01:00
// 🔒 IDEMPOTENCY CHECK: Prevent duplicate processing
if (order.status === 'fulfilled' || order.wren_order_id) {
console.log(`⚠️ Order ${order.id} already fulfilled, skipping duplicate webhook`);
return;
}
if (order.status === 'paid') {
console.log(`⚠️ Order ${order.id} already marked as paid, attempting fulfillment only`);
await fulfillOrder(order, session);
return;
}
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
// Update status to paid
Order.updateStatus(order.id, 'paid');
// Fulfill order
await fulfillOrder(order, session);
} catch (error) {
console.error('❌ Error handling async payment succeeded:', error);
}
}
/**
* Handle async payment failed
*/
async function handleAsyncPaymentFailed(session) {
console.log(`❌ Async payment failed: ${session.id}`);
try {
const order = Order.findBySessionId(session.id);
if (!order) {
console.error(`❌ Order not found for session: ${session.id}`);
return;
}
Implement comprehensive Stripe security fixes and production deployment CRITICAL SECURITY FIXES: - Add webhook secret validation to prevent signature bypass - Implement idempotency protection across all webhook handlers - Add atomic database updates to prevent race conditions - Improve CORS security with origin validation and logging - Remove .env from git tracking to protect secrets STRIPE INTEGRATION: - Add support for checkout.session.expired webhook event - Add Stripe publishable key to environment configuration - Fix webhook handlers with proper idempotency checks - Update Order model with atomic updatePaymentAndStatus method - Add comprehensive logging for webhook processing DEPLOYMENT ARCHITECTURE: - Split into two Docker images (frontend-latest, backend-latest) - Update CI/CD to build separate frontend and backend images - Configure backend on port 3801 (internal 3001) - Add production-ready docker-compose.yml - Remove redundant docker-compose.portainer.yml - Update nginx configuration for both frontend and backend DOCUMENTATION: - Add PRODUCTION-SETUP.md with complete deployment guide - Add docs/stripe-security-fixes.md with security audit details - Add docs/stripe-checkout-sessions.md with integration docs - Add docs/stripe-webhooks.md with webhook configuration - Update .env.example with all required variables including Stripe publishable key CONFIGURATION: - Consolidate to single .env.example template - Update .gitignore to protect all .env variants - Add server/Dockerfile for backend container - Update DEPLOYMENT.md with new architecture 🔒 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 12:18:57 +01:00
// 🔒 IDEMPOTENCY CHECK: Only update if not already failed
if (order.status === 'failed') {
console.log(`⚠️ Order ${order.id} already marked as failed, skipping duplicate webhook`);
return;
}
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
// Update status to failed
Order.updateStatus(order.id, 'failed');
console.log(`💔 Order ${order.id} marked as failed`);
// TODO: Send notification to customer about failed payment
} catch (error) {
console.error('❌ Error handling async payment failed:', error);
}
}
Implement comprehensive Stripe security fixes and production deployment CRITICAL SECURITY FIXES: - Add webhook secret validation to prevent signature bypass - Implement idempotency protection across all webhook handlers - Add atomic database updates to prevent race conditions - Improve CORS security with origin validation and logging - Remove .env from git tracking to protect secrets STRIPE INTEGRATION: - Add support for checkout.session.expired webhook event - Add Stripe publishable key to environment configuration - Fix webhook handlers with proper idempotency checks - Update Order model with atomic updatePaymentAndStatus method - Add comprehensive logging for webhook processing DEPLOYMENT ARCHITECTURE: - Split into two Docker images (frontend-latest, backend-latest) - Update CI/CD to build separate frontend and backend images - Configure backend on port 3801 (internal 3001) - Add production-ready docker-compose.yml - Remove redundant docker-compose.portainer.yml - Update nginx configuration for both frontend and backend DOCUMENTATION: - Add PRODUCTION-SETUP.md with complete deployment guide - Add docs/stripe-security-fixes.md with security audit details - Add docs/stripe-checkout-sessions.md with integration docs - Add docs/stripe-webhooks.md with webhook configuration - Update .env.example with all required variables including Stripe publishable key CONFIGURATION: - Consolidate to single .env.example template - Update .gitignore to protect all .env variants - Add server/Dockerfile for backend container - Update DEPLOYMENT.md with new architecture 🔒 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 12:18:57 +01:00
/**
* Handle checkout session expired
* This fires when a session expires (24 hours) without payment
*/
async function handleCheckoutSessionExpired(session) {
console.log(`⏰ Checkout session expired: ${session.id}`);
try {
const order = Order.findBySessionId(session.id);
if (!order) {
console.error(`❌ Order not found for session: ${session.id}`);
return;
}
// 🔒 IDEMPOTENCY CHECK: Only update if still pending
if (order.status !== 'pending') {
console.log(`⚠️ Order ${order.id} already processed (status: ${order.status}), skipping expiration`);
return;
}
// Update status to expired
Order.updateStatus(order.id, 'expired');
console.log(`🕐 Order ${order.id} marked as expired (abandoned cart)`);
console.log(` Session was created but never completed`);
// TODO: Optional - Send abandoned cart reminder email
// TODO: Optional - Track abandonment metrics
} catch (error) {
console.error('❌ Error handling checkout session expired:', error);
}
}
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
/**
* Fulfill order by creating carbon offset via Wren API
* @param {Object} order - Database order object
* @param {Object} session - Stripe session object
*/
async function fulfillOrder(order, session) {
try {
Implement comprehensive Stripe security fixes and production deployment CRITICAL SECURITY FIXES: - Add webhook secret validation to prevent signature bypass - Implement idempotency protection across all webhook handlers - Add atomic database updates to prevent race conditions - Improve CORS security with origin validation and logging - Remove .env from git tracking to protect secrets STRIPE INTEGRATION: - Add support for checkout.session.expired webhook event - Add Stripe publishable key to environment configuration - Fix webhook handlers with proper idempotency checks - Update Order model with atomic updatePaymentAndStatus method - Add comprehensive logging for webhook processing DEPLOYMENT ARCHITECTURE: - Split into two Docker images (frontend-latest, backend-latest) - Update CI/CD to build separate frontend and backend images - Configure backend on port 3801 (internal 3001) - Add production-ready docker-compose.yml - Remove redundant docker-compose.portainer.yml - Update nginx configuration for both frontend and backend DOCUMENTATION: - Add PRODUCTION-SETUP.md with complete deployment guide - Add docs/stripe-security-fixes.md with security audit details - Add docs/stripe-checkout-sessions.md with integration docs - Add docs/stripe-webhooks.md with webhook configuration - Update .env.example with all required variables including Stripe publishable key CONFIGURATION: - Consolidate to single .env.example template - Update .gitignore to protect all .env variants - Add server/Dockerfile for backend container - Update DEPLOYMENT.md with new architecture 🔒 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 12:18:57 +01:00
// 🔒 IDEMPOTENCY CHECK: Don't fulfill if already fulfilled
if (order.wren_order_id) {
console.log(`⚠️ Order ${order.id} already has Wren order ID: ${order.wren_order_id}, skipping fulfillment`);
return;
}
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
console.log(`🌱 Fulfilling order ${order.id} via Wren API...`);
// Determine if we should use dry run mode based on environment
const isDryRun = process.env.WREN_DRY_RUN === 'true';
if (isDryRun) {
console.log('⚠️ DRY RUN MODE: No real offset will be created');
}
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
// Create Wren offset order
const wrenOrder = await createWrenOffsetOrder({
tons: order.tons,
portfolioId: order.portfolio_id,
customerEmail: session.customer_details?.email || order.customer_email,
dryRun: isDryRun,
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
});
// Update order with Wren order ID
Order.updateWrenOrder(order.id, wrenOrder.id, 'fulfilled');
console.log(`✅ Order ${order.id} fulfilled successfully`);
console.log(` Wren Order ID: ${wrenOrder.id}`);
console.log(` Tons offset: ${order.tons}`);
Add NocoDB integration for order management with comprehensive Stripe webhook logging Features: - Complete NocoDB schema with 42 fields supporting B2B and B2C customers - Server-side NocoDB client (REST API integration) - Stripe session data mapper with automatic field mapping - Enhanced webhook handler with comprehensive logging - Automatic order creation in NocoDB after payment - Fulfillment data updates with Wren order IDs - Support for business customers (VAT/EIN, business names) - Complete billing address capture - Non-blocking error handling (webhook succeeds even if NocoDB fails) Files Added: - server/utils/nocodbClient.js - NocoDB REST API client - server/utils/nocodbMapper.js - Stripe to NocoDB data mapper - docs/NOCODB_SCHEMA.md - Complete field reference (42 columns) - docs/NOCODB_INTEGRATION_GUIDE.md - Testing and deployment guide - docs/TESTING_STRIPE_WEBHOOK.md - Webhook testing instructions - docs/STRIPE_INTEGRATION_SUMMARY.md - Project overview Files Modified: - server/routes/webhooks.js - Added NocoDB integration and enhanced logging - src/types.ts - Updated OrderRecord interface with new fields - src/api/nocodbClient.ts - Added createOrder() method - .env.example - Added NocoDB configuration template Schema includes: - Payment tracking (Stripe session/intent/customer IDs, amounts, fees) - Carbon offset details (tons, portfolio, Wren order ID) - Customer information (name, email, phone, business name) - Tax ID collection (VAT, EIN, etc.) - Complete billing address - Optional vessel/trip details for yacht calculations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 16:35:15 +01:00
// Update NocoDB with fulfillment data
await updateNocoDBFulfillment(order.id, wrenOrder);
// Send receipt email to customer
const customerEmail = session.customer_details?.email || order.customer_email;
if (customerEmail) {
try {
// Fetch portfolio data from Wren API
let portfolioProjects = [];
try {
const portfolios = await getWrenPortfolios();
const portfolio = portfolios.find(p => p.id === order.portfolio_id);
if (portfolio && portfolio.projects) {
// Format projects with colors and percentages
portfolioProjects = formatPortfolioProjects(portfolio.projects);
console.log(`✅ Portfolio data fetched: ${portfolioProjects.length} projects`);
}
} catch (portfolioError) {
console.warn('⚠️ Failed to fetch portfolio data (non-fatal):', portfolioError.message);
// Continue without portfolio data
}
// Calculate carbon impact comparisons
const carbonComparisons = selectComparisons(order.tons, 3);
console.log(`✅ Carbon comparisons calculated: ${carbonComparisons.length} items`);
await sendReceiptEmail(customerEmail, {
tons: order.tons,
portfolioId: order.portfolio_id,
baseAmount: (order.base_amount / 100).toFixed(2),
processingFee: (order.processing_fee / 100).toFixed(2),
totalAmount: (order.total_amount / 100).toFixed(2),
orderId: order.id,
stripeSessionId: session.id,
projects: portfolioProjects,
comparisons: carbonComparisons,
});
console.log(`📧 Receipt email sent to ${customerEmail}`);
// Send admin notification (non-blocking)
sendAdminNotification({
tons: order.tons,
portfolioId: order.portfolio_id,
totalAmount: (order.total_amount / 100).toFixed(2),
orderId: order.id,
}, customerEmail).catch(err => {
console.error('⚠️ Admin notification failed (non-fatal):', err.message);
});
} catch (emailError) {
console.error('❌ Failed to send receipt email:', emailError);
// Don't fail the order fulfillment if email fails
}
} else {
console.warn('⚠️ No customer email available, skipping receipt email');
}
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
} catch (error) {
console.error(`❌ Order fulfillment failed for order ${order.id}:`, error);
// Mark order as paid but unfulfilled (manual intervention needed)
Order.updateStatus(order.id, 'paid');
// Send alert to admin about failed fulfillment
const customerEmail = session.customer_details?.email || order.customer_email || 'unknown@example.com';
sendAdminNotification({
tons: order.tons,
portfolioId: order.portfolio_id,
totalAmount: (order.total_amount / 100).toFixed(2),
orderId: order.id,
}, customerEmail).catch(err => {
console.error('❌ Failed to send admin alert for failed fulfillment:', err.message);
});
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
}
}
Add NocoDB integration for order management with comprehensive Stripe webhook logging Features: - Complete NocoDB schema with 42 fields supporting B2B and B2C customers - Server-side NocoDB client (REST API integration) - Stripe session data mapper with automatic field mapping - Enhanced webhook handler with comprehensive logging - Automatic order creation in NocoDB after payment - Fulfillment data updates with Wren order IDs - Support for business customers (VAT/EIN, business names) - Complete billing address capture - Non-blocking error handling (webhook succeeds even if NocoDB fails) Files Added: - server/utils/nocodbClient.js - NocoDB REST API client - server/utils/nocodbMapper.js - Stripe to NocoDB data mapper - docs/NOCODB_SCHEMA.md - Complete field reference (42 columns) - docs/NOCODB_INTEGRATION_GUIDE.md - Testing and deployment guide - docs/TESTING_STRIPE_WEBHOOK.md - Webhook testing instructions - docs/STRIPE_INTEGRATION_SUMMARY.md - Project overview Files Modified: - server/routes/webhooks.js - Added NocoDB integration and enhanced logging - src/types.ts - Updated OrderRecord interface with new fields - src/api/nocodbClient.ts - Added createOrder() method - .env.example - Added NocoDB configuration template Schema includes: - Payment tracking (Stripe session/intent/customer IDs, amounts, fees) - Carbon offset details (tons, portfolio, Wren order ID) - Customer information (name, email, phone, business name) - Tax ID collection (VAT, EIN, etc.) - Complete billing address - Optional vessel/trip details for yacht calculations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 16:35:15 +01:00
/**
* Save order to NocoDB
* @param {Object} order - Local database order object
* @param {Object} session - Stripe session object
*/
async function saveOrderToNocoDB(order, session) {
// Skip if NocoDB is not configured
if (!nocodbClient.isConfigured()) {
console.log(' NocoDB not configured, skipping database save');
return;
}
try {
console.log(`💾 Saving order ${order.id} to NocoDB...`);
// Map Stripe session data to NocoDB format
const nocodbOrderData = mapStripeSessionToNocoDBOrder(session, order);
// Create record in NocoDB
const response = await nocodbClient.createOrder(nocodbOrderData);
console.log(`✅ Order saved to NocoDB successfully`);
console.log(` NocoDB Record ID: ${response.Id}`);
console.log(` Order ID: ${nocodbOrderData.orderId}`);
console.log(` Customer: ${nocodbOrderData.customerName} (${nocodbOrderData.customerEmail})`);
if (nocodbOrderData.businessName) {
console.log(` Business: ${nocodbOrderData.businessName}`);
}
if (nocodbOrderData.taxIdType && nocodbOrderData.taxIdValue) {
console.log(` Tax ID: ${nocodbOrderData.taxIdType} - ${nocodbOrderData.taxIdValue}`);
}
} catch (error) {
console.error('❌ Failed to save order to NocoDB:', error.message);
console.error(' This is non-fatal - order is still saved locally');
// Don't throw - we don't want to fail the webhook if NocoDB is down
}
}
/**
* Update NocoDB with fulfillment data
* @param {string} orderId - Order ID
* @param {Object} wrenOrder - Wren order response
*/
async function updateNocoDBFulfillment(orderId, wrenOrder) {
// Skip if NocoDB is not configured
if (!nocodbClient.isConfigured()) {
return;
}
try {
console.log(`💾 Updating NocoDB with fulfillment data for order ${orderId}...`);
// Map Wren fulfillment data
const fulfillmentData = mapWrenFulfillmentData(orderId, wrenOrder);
// Update NocoDB record
await nocodbClient.updateOrderFulfillment(orderId, fulfillmentData);
console.log(`✅ NocoDB updated with fulfillment data`);
console.log(` Wren Order ID: ${fulfillmentData.wrenOrderId}`);
console.log(` Status: ${fulfillmentData.status}`);
} catch (error) {
console.error('❌ Failed to update NocoDB with fulfillment:', error.message);
// Non-fatal - don't throw
}
}
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
export default router;