Round balance amounts to cents before applying
Prevents sub-cent precision (e.g. $0.883125) from accumulating in BalanceApplied and payment records. All balance math now rounds to nearest cent first. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c580e6ec78
commit
c65cd8242b
2 changed files with 6 additions and 4 deletions
|
|
@ -79,7 +79,7 @@
|
|||
<cfset taxRate = (isNumeric(qOrder.TaxRate) AND val(qOrder.TaxRate) GT 0) ? val(qOrder.TaxRate) : 0>
|
||||
<cfset taxAmount = subtotal * taxRate>
|
||||
<cfset deliveryFee = (val(qOrder.OrderTypeID) EQ 3) ? val(qOrder.DeliveryFee) : 0>
|
||||
<cfset orderTotal = subtotal + taxAmount + platformFee + Tip + deliveryFee>
|
||||
<cfset orderTotal = round((subtotal + taxAmount + platformFee + Tip + deliveryFee) * 100) / 100>
|
||||
|
||||
<!--- Auto-apply user balance (silently reduces cash owed) --->
|
||||
<cfset balanceApplied = 0>
|
||||
|
|
@ -92,7 +92,8 @@
|
|||
)>
|
||||
<cfset userBalance = val(qBalance.Balance)>
|
||||
<cfif userBalance GT 0>
|
||||
<cfset balanceToApply = min(userBalance, orderTotal)>
|
||||
<!--- Round to cents to avoid sub-cent precision issues --->
|
||||
<cfset balanceToApply = round(min(userBalance, orderTotal) * 100) / 100>
|
||||
<!--- Atomic deduct: only succeeds if balance is still sufficient --->
|
||||
<cfset qDeduct = queryExecute(
|
||||
"UPDATE Users SET Balance = Balance - ? WHERE ID = ? AND Balance >= ?",
|
||||
|
|
|
|||
|
|
@ -134,13 +134,14 @@ try {
|
|||
userBalance = val(qOrder.Balance ?: 0);
|
||||
orderUserID = val(qOrder.UserID ?: 0);
|
||||
if (userBalance > 0 && orderUserID > 0) {
|
||||
balanceApplied = min(userBalance, totalBeforeCardFee);
|
||||
// Round to cents to avoid sub-cent precision issues
|
||||
balanceApplied = round(min(userBalance, totalBeforeCardFee) * 100) / 100;
|
||||
// Ensure Stripe minimum: adjusted amount after card fee must be >= $0.50
|
||||
adjustedTest = ((totalBeforeCardFee - balanceApplied) + cardFeeFixed) / (1 - cardFeePercent);
|
||||
if (adjustedTest < 0.50) {
|
||||
// Cap balance so Stripe charge stays >= $0.50
|
||||
maxBalance = totalBeforeCardFee - ((0.50 * (1 - cardFeePercent)) - cardFeeFixed);
|
||||
balanceApplied = max(0, min(userBalance, maxBalance));
|
||||
balanceApplied = round(max(0, min(userBalance, maxBalance)) * 100) / 100;
|
||||
}
|
||||
// Store intent on order (actual deduction happens in webhook after payment succeeds)
|
||||
if (balanceApplied > 0) {
|
||||
|
|
|
|||
Reference in a new issue