import axios from 'axios'; const WREN_API_BASE_URL = 'https://www.wren.co/api'; /** * Create a carbon offset order via Wren Climate API * @param {Object} orderData - Order data * @param {number} orderData.tons - Number of tons to offset * @param {number} orderData.portfolioId - Portfolio ID * @param {string} orderData.customerEmail - Customer email * @param {string} orderData.currency - Currency code * @param {number} orderData.amountCents - Amount in cents * @param {boolean} orderData.dryRun - Dry run mode (default: false) * @returns {Promise} Wren order response */ export async function createWrenOffsetOrder({ tons, portfolioId, customerEmail, currency, amountCents, dryRun = false }) { const startTime = Date.now(); const apiToken = process.env.WREN_API_TOKEN; console.log('🔵 [WREN API SERVER] ========================================'); console.log('🔵 [WREN API SERVER] POST /offset_orders - Request initiated'); console.log('🔵 [WREN API SERVER] Timestamp:', new Date().toISOString()); console.log('🔵 [WREN API SERVER] API Token:', apiToken ? `${apiToken.substring(0, 8)}...${apiToken.substring(apiToken.length - 4)}` : 'NOT SET'); console.log('🔵 [WREN API SERVER] Request URL:', `${WREN_API_BASE_URL}/offset_orders`); console.log('🔵 [WREN API SERVER] Parameters:', JSON.stringify({ tons: parseFloat(tons), portfolioId, customerEmail, currency: currency.toUpperCase(), amountCents, dryRun }, null, 2)); if (!apiToken) { console.error('❌ [WREN API SERVER] WREN_API_TOKEN not configured'); throw new Error('WREN_API_TOKEN environment variable is required'); } try { const response = await axios.post( `${WREN_API_BASE_URL}/offset-orders`, { tons: parseFloat(tons), portfolio: portfolioId, currency: currency.toUpperCase(), amount_charged: amountCents, dry_run: dryRun, source: { name: 'Puffin App', email: customerEmail } }, { headers: { 'Authorization': `Bearer ${apiToken}`, 'Content-Type': 'application/json' } } ); const duration = Date.now() - startTime; console.log('✅ [WREN API SERVER] POST /offset_orders - Success'); console.log('✅ [WREN API SERVER] Status:', response.status); console.log('✅ [WREN API SERVER] Duration:', duration + 'ms'); console.log('✅ [WREN API SERVER] Order ID:', response.data.id); console.log('✅ [WREN API SERVER] Response:', JSON.stringify(response.data, null, 2)); console.log('🔵 [WREN API SERVER] ========================================'); return response.data; } catch (error) { const duration = Date.now() - startTime; console.error('❌ [WREN API SERVER] POST /offset_orders - Failed'); console.error('❌ [WREN API SERVER] Status:', error.response?.status || 'No response'); console.error('❌ [WREN API SERVER] Duration:', duration + 'ms'); console.error('❌ [WREN API SERVER] Error message:', error.message); console.error('❌ [WREN API SERVER] Error response:', JSON.stringify(error.response?.data, null, 2)); console.error('❌ [WREN API SERVER] Full error:', error); console.log('🔵 [WREN API SERVER] ========================================'); throw new Error(`Wren API failed: ${error.response?.data?.message || error.message}`); } } /** * Get Wren offset order details * @param {string} orderId - Wren order ID * @returns {Promise} Wren order details */ export async function getWrenOffsetOrder(orderId) { const startTime = Date.now(); const apiToken = process.env.WREN_API_TOKEN; console.log('🔵 [WREN API SERVER] ========================================'); console.log('🔵 [WREN API SERVER] GET /offset_orders/:id - Request initiated'); console.log('🔵 [WREN API SERVER] Timestamp:', new Date().toISOString()); console.log('🔵 [WREN API SERVER] API Token:', apiToken ? `${apiToken.substring(0, 8)}...${apiToken.substring(apiToken.length - 4)}` : 'NOT SET'); console.log('🔵 [WREN API SERVER] Request URL:', `${WREN_API_BASE_URL}/offset_orders/${orderId}`); console.log('🔵 [WREN API SERVER] Order ID:', orderId); if (!apiToken) { console.error('❌ [WREN API SERVER] WREN_API_TOKEN not configured'); throw new Error('WREN_API_TOKEN environment variable is required'); } try { const response = await axios.get( `${WREN_API_BASE_URL}/offset-orders/${orderId}`, { headers: { 'Authorization': `Bearer ${apiToken}`, 'Content-Type': 'application/json' } } ); const duration = Date.now() - startTime; console.log('✅ [WREN API SERVER] GET /offset_orders/:id - Success'); console.log('✅ [WREN API SERVER] Status:', response.status); console.log('✅ [WREN API SERVER] Duration:', duration + 'ms'); console.log('✅ [WREN API SERVER] Response:', JSON.stringify(response.data, null, 2)); console.log('🔵 [WREN API SERVER] ========================================'); return response.data; } catch (error) { const duration = Date.now() - startTime; console.error('❌ [WREN API SERVER] GET /offset_orders/:id - Failed'); console.error('❌ [WREN API SERVER] Status:', error.response?.status || 'No response'); console.error('❌ [WREN API SERVER] Duration:', duration + 'ms'); console.error('❌ [WREN API SERVER] Error message:', error.message); console.error('❌ [WREN API SERVER] Error response:', JSON.stringify(error.response?.data, null, 2)); console.error('❌ [WREN API SERVER] Full error:', error); console.log('🔵 [WREN API SERVER] ========================================'); throw new Error(`Wren API failed: ${error.response?.data?.message || error.message}`); } } export default { createWrenOffsetOrder, getWrenOffsetOrder };