ROOT CAUSE (Zen Debug Investigation):
The API_BASE_URL constant was being evaluated when the module loaded,
BEFORE window.env was populated by env-config.js. This caused the app
to permanently use the fallback localhost:3001 instead of reading the
production URL from the .env file.
TIMING ISSUE:
1. Browser loads index.html
2. env-config.js loads (creates window.env)
3. main.tsx loads as ES module (DEFERRED)
4. Module imports checkoutClient → const API_BASE_URL executes
5. window.env NOT READY YET → falls back to localhost:3001
6. API_BASE_URL locked to wrong value forever
THE FIX:
Changed from module-level constants to request-time lazy evaluation.
Now getApiBaseUrl() is called WHEN THE API REQUEST HAPPENS, not when
the module loads. At that point window.env is guaranteed to exist.
FILES CHANGED:
- src/api/checkoutClient.ts:
* Removed constant API_BASE_URL
* All 3 functions now call getApiBaseUrl() at request time
* Added logging to show which URL is being used
- src/api/aisClient.ts:
* Removed constant API_KEY
* Added getApiKey() function with lazy evaluation
* Same pattern for consistency and future-proofing
This fixes: "FetchEvent for http://localhost:3001 resulted in network error"
Now uses: https://puffinoffset.com/api (from .env file)
🔒 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
CRITICAL FIX: Checkout was failing because API calls went to localhost
The checkoutClient was hardcoded to use import.meta.env.VITE_API_BASE_URL
which is build-time only. In production, this defaulted to localhost:3001
instead of the actual backend URL.
Changed to read from window.env.API_BASE_URL (runtime config) first,
then fall back to build-time config. This matches the pattern used
in src/utils/config.ts.
Frontend will now correctly connect to:
- Development: http://localhost:3001
- Production: https://puffinoffset.com/api (from .env file)
Fixes network error: "Failed to fetch" when creating checkout session
🔒 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
FIX: TypeError: z.info is not a function in production
The logger object was missing .info() and .debug() methods that were
being called in OffsetOrder.tsx and other components. This caused
checkout to fail in production with "z.info is not a function" error.
Added:
- logger.info() - Info level logging (dev only)
- logger.debug() - Debug level logging (dev only)
All logger methods now follow the same pattern:
- log, info, warn, debug: Only log in development
- error: Always log (production + development)
🔒 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
## 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>
- Create logger utility that only logs in development mode
- Update wrenClient.ts to use logger instead of console.log/warn
- Update OffsetOrder.tsx to use logger for debug messages
- Update config.ts to only log environment loading in dev mode
- Keeps console.error for actual errors (always shown)
Fixes: Console clutter in production deployment
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add comma-separated number formatting for better readability in all calculator inputs
- Move offset percentage selection from calculator to offset order page for clearer workflow
- Improve project card layout with consistent height alignment in OffsetOrder
- Change number inputs to text inputs to support formatted display
- Update form messages to reflect chosen offset percentage
- Add CLAUDE.md documentation for repository guidance
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Increase max widths and improve responsive spacing across components
- Add responsive grid columns (xl:grid-cols-4) for better large screen layout
- Remove redundant click area overlay and hover effects for cleaner code
- Consolidate padding management to main container level
- Install framer-motion dependency (v12.15.0)
- Add smooth transitions to forms and buttons in TripCalculator
- Implement hover and tap animations for interactive elements
- Add entrance/exit animations for component state changes
- Enhance user experience with motion effects in Home and OffsetOrder components