From 33277de727df27efaf8f548d67a45a1c68db5c31 Mon Sep 17 00:00:00 2001 From: Scott Pouliot Date: Wed, 20 May 2026 13:20:47 -0400 Subject: [PATCH] Payment hardening: InvariantCulture on JS literals, remove dead CustomerEmail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Razor numeric expressions emitted into JS literals (MAX_TOTAL, SURCHARGE_VALUE) now use InvariantCulture, matching the pattern already used on the deposit page. Without this, a server culture with comma decimal separators would silently truncate values like 2.5% to 2. CustomerEmail removed from PaymentPageViewModel and DepositPaymentPageViewModel — it was populated from the DB on every payment page load but never consumed after receipt_email was removed from the Stripe PaymentIntent. Co-Authored-By: Claude Sonnet 4.6 --- src/PowderCoating.Web/Controllers/PaymentController.cs | 4 ---- src/PowderCoating.Web/Views/Payment/Index.cshtml | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/PowderCoating.Web/Controllers/PaymentController.cs b/src/PowderCoating.Web/Controllers/PaymentController.cs index 9e2b8be..8227eaf 100644 --- a/src/PowderCoating.Web/Controllers/PaymentController.cs +++ b/src/PowderCoating.Web/Controllers/PaymentController.cs @@ -75,7 +75,6 @@ public class PaymentController : Controller CustomerName = customer != null ? $"{customer.ContactFirstName} {customer.ContactLastName}".Trim() : "Valued Customer", - CustomerEmail = customer?.Email ?? string.Empty, CompanyName = company!.CompanyName, BalanceDue = invoice.BalanceDue, InvoiceTotal = invoice.Total, @@ -258,7 +257,6 @@ public class PaymentController : Controller CustomerName = customer != null ? $"{customer.ContactFirstName} {customer.ContactLastName}".Trim() : quote.ProspectContactName ?? "Valued Customer", - CustomerEmail = customer?.Email ?? quote.ProspectEmail ?? string.Empty, CompanyName = company!.CompanyName, DepositAmount = depositAmount, QuoteTotal = quote.Total, @@ -937,7 +935,6 @@ public class PaymentPageViewModel public int InvoiceId { get; set; } public string Token { get; set; } = string.Empty; public string CustomerName { get; set; } = string.Empty; - public string CustomerEmail { get; set; } = string.Empty; public string CompanyName { get; set; } = string.Empty; public decimal BalanceDue { get; set; } public decimal InvoiceTotal { get; set; } @@ -958,7 +955,6 @@ public class DepositPaymentPageViewModel public int QuoteId { get; set; } public string Token { get; set; } = string.Empty; public string CustomerName { get; set; } = string.Empty; - public string CustomerEmail { get; set; } = string.Empty; public string CompanyName { get; set; } = string.Empty; public decimal DepositAmount { get; set; } public decimal QuoteTotal { get; set; } diff --git a/src/PowderCoating.Web/Views/Payment/Index.cshtml b/src/PowderCoating.Web/Views/Payment/Index.cshtml index 6f40a74..db4ca00 100644 --- a/src/PowderCoating.Web/Views/Payment/Index.cshtml +++ b/src/PowderCoating.Web/Views/Payment/Index.cshtml @@ -116,9 +116,9 @@ const STRIPE_PK = '@Model.StripePublishableKey'; const ACCOUNT_ID = '@Model.StripeAccountId'; const TOKEN = '@Model.Token'; - const MAX_TOTAL = @Model.TotalWithSurcharge.ToString("F2"); + const MAX_TOTAL = @Model.TotalWithSurcharge.ToString("F2", System.Globalization.CultureInfo.InvariantCulture); const SURCHARGE_TYPE = '@Model.SurchargeType'; - const SURCHARGE_VALUE = @Model.SurchargeValue.ToString("F4"); + const SURCHARGE_VALUE = @Model.SurchargeValue.ToString("F4", System.Globalization.CultureInfo.InvariantCulture); const SUCCESS_URL = `/pay/${TOKEN}/success`; const stripe = Stripe(STRIPE_PK, { stripeAccount: ACCOUNT_ID });