Номера JavaScript не добавляются правильно каждый раз, когда parseFloat toFixed
Я рассчитываю промежуточные итоги, налоги, доставку и страхование на основе следующего:
public getSubTotal() {
this.subTotal =
document.getElementById("total").value -
(document.getElementById("total").value * 0.07 +
document.getElementById("total").value * 0.03 +
document.getElementById("total").value * 0.01 +
1.0);
document.getElementById("tax").value =
document.getElementById("total").value * 0.07;
document.getElementById("shipping").value =
document.getElementById("total").value * 0.03;
document.getElementById("insurance").value =
document.getElementById("total").value * 0.01;
console.log(
"tax: " +
document.getElementById("total").value * 0.07 +
" shipping: " +
document.getElementById("total").value * 0.03 +
" ins: " +
document.getElementById("total").value * 0.01 +
" total: " +
document.getElementById("total").value +
" subtotal: " +
this.subTotal
);
return this.subTotal.toFixed(2);
}
details: {
subtotal: document.getElementById("subTotal").value,
tax: parseFloat(document.getElementById("tax").value).toFixed(
2
),
shipping: parseFloat(
document.getElementById("shipping").value
).toFixed(2),
handling_fee: "1.00",
shipping_discount: "0.00",
insurance: parseFloat(
document.getElementById("insurance").value
).toFixed(2)
}
Итого фиксируется с каждым продуктом.
Когда я публикую это в PayPal API, цифры иногда складываются, а иногда нет. Я потеря для того, как это исправить.
Ниже приведен пример того, что опубликовано, и я не понимаю, почему PayPal отклоняет этот пример:
details {…}
handling_fee 1.00
insurance 0.23
shipping 0.68
shipping_discount 0.00
subtotal 19.30
tax 1.60
total 22.81
Все эти цифры основаны на 22,81, и консоль показывает:
tax: 1.5967
shipping: 0.6842999999999999
ins: 0.2281
total: 22.81
subtotal: 19.3009
Как я могу сохранить parseFloat(). ToFixed(2) от изменения чисел? И если я оставляю числа с числом более двух десятичных разрядов, PayPal отклоняет его за неправильное форматирование.
Когда я использую калькулятор для этих чисел, я получаю результат 22,81
Ниже приводится ошибка, которую я получаю от PayPal - если я закомментирую раздел с подробностями, то сообщение проходит без ошибок:
Error: Request to post https://www.sandbox.paypal.com/v1/payments/payment failed with 400 error. Correlation id: 12d500c6247f1, 12d500c6247f1
{
"name": "VALIDATION_ERROR",
"details": [
{
"field": "transactions[0]",
"issue": "Item amount must add up to specified amount subtotal (or total if amount details not specified)"
}
],
"message": "Invalid request - see details",
"information_link": "https://developer.paypal.com/docs/api/payments/#errors",
"debug_id": "12d500c6247f1"
}
Ниже приведены несколько снимков экрана:
Конечно, с увеличением количества продуктов увеличивается и разница в том, что добавляется вместе с общим количеством, что приводит к моему общему вопросу.
Как мне правильно рассчитать эти позиции?
заранее спасибо
2 ответа
Когда вы работаете с денежными значениями, вы можете избежать многих ошибок округления, работая в центах, располагая все свои затраты в центах, а при отображении их вы можете отобразить
(cost/100).toFixed(2)
Это будет использовать целочисленную математику над плавающей точкой, и вы получите гораздо меньше ошибок округления.
После того, как мы пошли по кругу, взяв цену продукта, затем вычтя сумму налога, доставки, обработки и страхования, чтобы получить промежуточный итог - я понял, что я занимался этим фоном, и, поскольку точки с плавающей точкой были несколько " непредсказуемо,"тогда суммы никогда не будут соответствовать 100% времени.
Вот когда это поразило меня, и это было так очевидно. Я должен добавить все эти цифры к цене продукта:
getFinalAmount() {
this.model.subTotal = this.subTotal = this.prdSrvc.getPriceTotal();
this.subTotal = parseFloat(this.subTotal).toFixed(2);
document.getElementById("tax").value = this.model.tax = this.tax =
this.subTotal * 0.07;
document.getElementById(
"shipping"
).value = this.model.shipping = this.shipping = this.subTotal * 0.03;
document.getElementById(
"insurance"
).value = this.model.insurance = this.insurance = this.subTotal * 0.01;
this.total = this.payPalSrvc.finalAmount =
parseFloat(this.tax) +
parseFloat(this.shipping) +
parseFloat(this.insurance) +
parseFloat(this.subTotal) +
1.0;
this.payPalSrvc.finalAmount = parseFloat(
this.payPalSrvc.finalAmount
).toFixed(2);
this.total = parseFloat(this.total).toFixed(2);
document.getElementById(
"subTotal"
).value = this.model.subTotal = this.subTotal;
document.getElementById("total").value = this.model.total = this.total;
this.tax = parseFloat(this.tax).toFixed(2);
this.shipping = parseFloat(this.shipping).toFixed(2);
this.insurance = parseFloat(this.insurance).toFixed(2);
return this.payPalSrvc.finalAmount;
}
Я также удалил валютный канал из HTML, оставив меня с прямыми числами с двумя десятичными знаками:
<input type="hidden" name="tax" id="tax" value="{{ this.tax }}" />
<input
type="hidden"
name="shipping"
id="shipping"
value="{{ this.shipping }}"
/>
<input
type="hidden"
name="insurance"
id="insurance"
value="{{ this.insurance }}"
/>
Ниже показано, как выглядит заказ на панели инструментов PayPal: