Fix pricing calculation by passing pricePerTon from frontend to backend
All checks were successful
Build and Push Docker Images / docker (push) Successful in 51s

The backend was using a hardcoded PORTFOLIO_PRICING map that only had prices
for portfolios 1, 2, 3 (defaulting to $18/ton for others). When Wren API
returns Portfolio ID 37 at $237/ton, the backend was calculating with $18/ton
instead, causing massive pricing discrepancies.

Changes:
- Frontend now passes pricePerTon (from Wren API) in checkout request
- Backend uses the received pricePerTon instead of lookup table
- Removed dependency on hardcoded PORTFOLIO_PRICING map
- Added validation for pricePerTon parameter

Example fix:
- Before: 0.03 tons × $18/ton = $0.54 (wrong!)
- After: 0.03 tons × $237/ton = $7.11 (correct!)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Matt 2025-10-30 13:00:13 +01:00
parent 0177707921
commit 09e3c13eaf
3 changed files with 14 additions and 7 deletions

View File

@ -17,11 +17,10 @@ const PROCESSING_FEE_PERCENT = 0.03; // 3%
/**
* Calculate pricing with processing fee
* @param {number} tons - Number of tons
* @param {number} portfolioId - Portfolio ID
* @param {number} pricePerTon - Price per ton from Wren API
* @returns {Object} Pricing breakdown
*/
function calculatePricing(tons, portfolioId) {
const pricePerTon = PORTFOLIO_PRICING[portfolioId] || 18; // Default to $18/ton
function calculatePricing(tons, pricePerTon) {
const baseAmount = Math.round(tons * pricePerTon * 100); // Convert to cents
const processingFee = Math.round(baseAmount * PROCESSING_FEE_PERCENT);
const totalAmount = baseAmount + processingFee;
@ -40,7 +39,7 @@ function calculatePricing(tons, portfolioId) {
*/
router.post('/create-session', async (req, res) => {
try {
const { tons, portfolioId, customerEmail } = req.body;
const { tons, portfolioId, pricePerTon, customerEmail } = req.body;
// Validation
if (!tons || tons <= 0) {
@ -53,10 +52,16 @@ router.post('/create-session', async (req, res) => {
return res.status(400).json({ error: 'Invalid portfolio ID' });
}
console.log(`📦 Creating checkout for portfolio ID: ${portfolioId}, tons: ${tons}`);
// Validate price per ton
if (!pricePerTon || pricePerTon <= 0) {
console.error('❌ Invalid pricePerTon received:', pricePerTon);
return res.status(400).json({ error: 'Invalid price per ton' });
}
// Calculate pricing
const { baseAmount, processingFee, totalAmount, pricePerTon } = calculatePricing(tons, portfolioId);
console.log(`📦 Creating checkout for portfolio ID: ${portfolioId}, tons: ${tons}, price: $${pricePerTon}/ton`);
// Calculate pricing using the price from frontend (Wren API)
const { baseAmount, processingFee, totalAmount } = calculatePricing(tons, pricePerTon);
// Create line items for Stripe
const lineItems = [

View File

@ -17,6 +17,7 @@ const getApiBaseUrl = (): string => {
export interface CreateCheckoutSessionParams {
tons: number;
portfolioId: number;
pricePerTon: number; // Price per ton from Wren API
customerEmail?: string;
}

View File

@ -150,6 +150,7 @@ export function OffsetOrder({ tons, monetaryAmount, onBack, calculatorType }: Pr
const checkoutSession = await createCheckoutSession({
tons: actualOffsetTons,
portfolioId: portfolio.id,
pricePerTon: portfolio.pricePerTon || 18, // Pass the actual price from Wren
});
logger.info('[OffsetOrder] Checkout session created:', checkoutSession.sessionId);