#!/usr/bin/env node /** * Setup Stripe Products and Prices for Koha Donation System * Creates the "Tractatus Framework Support" product and all required price tiers */ require('dotenv').config(); const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY); const fs = require('fs'); const path = require('path'); // Multi-currency conversion rates (approximate, for initial setup) // Stripe will handle actual conversion at checkout time const CURRENCY_OPTIONS = { usd: { unit_amount: 320 }, // ~$3.20 USD eur: { unit_amount: 290 }, // ~€2.90 EUR gbp: { unit_amount: 250 }, // ~Ā£2.50 GBP aud: { unit_amount: 480 }, // ~$4.80 AUD cad: { unit_amount: 430 }, // ~$4.30 CAD jpy: { unit_amount: 48000 }, // ~Ā„480 JPY (yen has no decimals) chf: { unit_amount: 280 }, // ~CHF 2.80 sgd: { unit_amount: 430 }, // ~$4.30 SGD hkd: { unit_amount: 2500 } // ~$25 HKD }; const TIER_CONFIGS = { foundation: { name: 'Foundation', nzd_amount: 500, // $5.00 NZD multiplier: 1, description: 'Essential support for hosting and infrastructure. Every contribution counts.' }, advocate: { name: 'Advocate', nzd_amount: 1500, // $15.00 NZD multiplier: 3, description: 'Support development and research. Help expand the framework\'s capabilities.' }, champion: { name: 'Champion', nzd_amount: 5000, // $50.00 NZD multiplier: 10, description: 'Sustained support for community building and advanced features.' } }; async function setupStripeProducts() { console.log('\nšŸš€ Setting up Stripe products and prices for Koha donation system...\n'); try { // Step 1: Create or find the product console.log('šŸ“¦ Step 1: Creating product "Tractatus Framework Support"...'); // Check if product already exists const existingProducts = await stripe.products.search({ query: 'name:"Tractatus Framework Support"', }); let product; if (existingProducts.data.length > 0) { product = existingProducts.data[0]; console.log(`āœ… Product already exists: ${product.id}`); } else { product = await stripe.products.create({ name: 'Tractatus Framework Support', description: 'Koha (reciprocal gift) to support the Tractatus AI Safety Framework - architectural safeguards for AI governance that preserve human agency and pluralistic values.', metadata: { project: 'tractatus', type: 'koha_donation' } }); console.log(`āœ… Created product: ${product.id}`); } // Step 2: Create monthly subscription prices for each tier console.log('\nšŸ’° Step 2: Creating monthly subscription prices...\n'); const createdPrices = {}; for (const [tierKey, tierConfig] of Object.entries(TIER_CONFIGS)) { console.log(` Creating ${tierConfig.name} tier ($${tierConfig.nzd_amount / 100} NZD/month)...`); // Calculate currency options for this tier const currencyOptions = {}; for (const [currency, baseAmount] of Object.entries(CURRENCY_OPTIONS)) { currencyOptions[currency] = { unit_amount: Math.round(baseAmount.unit_amount * tierConfig.multiplier) }; } try { const price = await stripe.prices.create({ product: product.id, currency: 'nzd', unit_amount: tierConfig.nzd_amount, recurring: { interval: 'month', interval_count: 1 }, currency_options: currencyOptions, nickname: `Koha ${tierConfig.name} - Monthly`, metadata: { tier: tierKey, tier_name: tierConfig.name, description: tierConfig.description } }); createdPrices[tierKey] = price.id; console.log(` āœ… Created: ${price.id}`); } catch (error) { console.error(` āŒ Error creating ${tierConfig.name} price:`, error.message); } } // Step 3: Display results and generate .env updates console.log('\nāœ… Stripe setup complete!\n'); console.log('šŸ“‹ Product and Price IDs:\n'); console.log(`STRIPE_KOHA_PRODUCT_ID=${product.id}`); console.log(`STRIPE_KOHA_5_PRICE_ID=${createdPrices.foundation || 'NOT_CREATED'}`); console.log(`STRIPE_KOHA_15_PRICE_ID=${createdPrices.advocate || 'NOT_CREATED'}`); console.log(`STRIPE_KOHA_50_PRICE_ID=${createdPrices.champion || 'NOT_CREATED'}`); console.log('\nšŸ“ Next steps:'); console.log(' 1. Update .env file with the price IDs above'); console.log(' 2. Create webhook endpoint for: ' + (process.env.FRONTEND_URL || 'http://localhost:9000') + '/api/koha/webhook'); console.log(' 3. Update STRIPE_KOHA_WEBHOOK_SECRET in .env'); console.log(' 4. Test with Stripe test cards\n'); // Step 4: Save IDs to a JSON file for easy reference const idsFilePath = path.join(__dirname, '..', '.stripe-ids.json'); const idsData = { product_id: product.id, prices: { foundation_5_nzd: createdPrices.foundation, advocate_15_nzd: createdPrices.advocate, champion_50_nzd: createdPrices.champion }, created_at: new Date().toISOString(), mode: 'test' }; fs.writeFileSync(idsFilePath, JSON.stringify(idsData, null, 2)); console.log(`šŸ’¾ Saved IDs to ${idsFilePath}\n`); } catch (error) { console.error('\nāŒ Setup failed:', error.message); console.error('\nFull error:', error); process.exit(1); } } setupStripeProducts();