Using connected accounts on Stripe, and using javascript, I need to show user the total amount that he will pay for an invoice from a net amount. For example, user has an invoice of 1500$ to pay, and I need to include Stripe fee and the application fee (my fee), and I need to show user that he will be charged 1500$ plus 68.68$ in fees which makes it a total of 1568.68$. I need this amount to match exactly what Stripe will charge to process the payment.
For that, I currently have this small script:
const stripeCommissionRate = 0.029;
const stripeFixedFee = 0.30;
const myFeeRate = 0.0146;
function calculateFees(netAmount) {
// Calculate gross amount to do calculations (reverse engeneering from Stripe's math)
let grossAmount = (netAmount + stripeFixedFee) / (1 - stripeCommissionRate - myFeeRate);
// Calculate individual fees
let stripeFee = stripeFixedFee + (grossAmount * stripeCommissionRate);
let myFee = grossAmount * myFeeRate;
// Round individual fees
stripeFee = parseFloat(stripeFee.toFixed(2));
myFee = parseFloat(myFee.toFixed(2));
// Calculate total fees
let totalFees = stripeFee + myFee;
// Calculate final gross amount from rounded amounts
grossAmount = netAmount + stripeFee + myFee;
return {
grossAmount: grossAmount,
stripeFee: stripeFee,
myFee: myFee,
totalFees: totalFees,
};
}
However, this is not matching all the time. There's got to be some special roundings or another way to do the math and that is the help I'm hoping to find here.
Examples:
Working example 1
For a net amount of 1500.00$, that returns grossAmount: 1568.69 stripeFee: 45.79, myAppFee: 22.90, totalFees: 68.69
Working example 2
For a net amount of 1000.00$, that returns grossAmount: 1045.90 stripeFee: 30.63, myAppFee: 15.27, totalFees: 45.90
Failing example 1
For a net amount of 49.99$, that returns grossAmount: 52.58 <-- on Stripe is 52.59 stripeFee: 1.83, myAppFee: 0.77, totalFees: 2.59 <-- on Stripe is 2.60
Failing example 2
For a net amount of 299.98$, that returns
grossAmount: 313.97 <-- on Stripe is 313.98
stripeFee: 9.41, <-- on Stripe is 9.40
myAppFee: 4.58,
totalFees: 13.99 <-- on Stripe is 13.98
Whenever I try to adjust something to fix one failing example, it ends up breaking something that is now working.
Using connected accounts on Stripe, and using javascript, I need to show user the total amount that he will pay for an invoice from a net amount. For example, user has an invoice of 1500$ to pay, and I need to include Stripe fee and the application fee (my fee), and I need to show user that he will be charged 1500$ plus 68.68$ in fees which makes it a total of 1568.68$. I need this amount to match exactly what Stripe will charge to process the payment.
For that, I currently have this small script:
const stripeCommissionRate = 0.029;
const stripeFixedFee = 0.30;
const myFeeRate = 0.0146;
function calculateFees(netAmount) {
// Calculate gross amount to do calculations (reverse engeneering from Stripe's math)
let grossAmount = (netAmount + stripeFixedFee) / (1 - stripeCommissionRate - myFeeRate);
// Calculate individual fees
let stripeFee = stripeFixedFee + (grossAmount * stripeCommissionRate);
let myFee = grossAmount * myFeeRate;
// Round individual fees
stripeFee = parseFloat(stripeFee.toFixed(2));
myFee = parseFloat(myFee.toFixed(2));
// Calculate total fees
let totalFees = stripeFee + myFee;
// Calculate final gross amount from rounded amounts
grossAmount = netAmount + stripeFee + myFee;
return {
grossAmount: grossAmount,
stripeFee: stripeFee,
myFee: myFee,
totalFees: totalFees,
};
}
However, this is not matching all the time. There's got to be some special roundings or another way to do the math and that is the help I'm hoping to find here.
Examples:
Working example 1
For a net amount of 1500.00$, that returns grossAmount: 1568.69 stripeFee: 45.79, myAppFee: 22.90, totalFees: 68.69
Working example 2
For a net amount of 1000.00$, that returns grossAmount: 1045.90 stripeFee: 30.63, myAppFee: 15.27, totalFees: 45.90
Failing example 1
For a net amount of 49.99$, that returns grossAmount: 52.58 <-- on Stripe is 52.59 stripeFee: 1.83, myAppFee: 0.77, totalFees: 2.59 <-- on Stripe is 2.60
Failing example 2
For a net amount of 299.98$, that returns
grossAmount: 313.97 <-- on Stripe is 313.98
stripeFee: 9.41, <-- on Stripe is 9.40
myAppFee: 4.58,
totalFees: 13.99 <-- on Stripe is 13.98
Whenever I try to adjust something to fix one failing example, it ends up breaking something that is now working.
Share Improve this question edited Nov 20, 2024 at 15:36 SlashString asked Nov 20, 2024 at 15:34 SlashStringSlashString 11 bronze badge 1 |3 Answers
Reset to default 0A fee can very likely vary depending on different factors. To me it sounds like this might be useful to you Payment Intent Object.
A PaymentIntent guides you through the process of collecting a payment from your customer. We recommend that you create exactly one PaymentIntent for each order or customer session in your system.
Send this before and check out the response attribute application_fee_amount
You should contact Stripe support for guidance about fees: https://support.stripe/contact
However, your own calculation rounding appears inconsistent:
Failing example 1 stripeFee: 1.83, myAppFee: 0.77, totalFees: 2.59
Your own calculation has 1.83+0.77 which should be 2.60, so why are you arriving at 2.59? You should verify your addition rounds before summing consistently.
After contacting Stripe support, for what they said, and the examples they provided, this was the solution, in case it helps someone else.
const stripeCommissionRate = 0.029;
const stripeFixedFee = 0.30;
const myFeeRate = 0.0146;
function calculateFees(netAmount) {
// Calculate gross amount to do calculations
let grossAmount = (netAmount + stripeFixedFee) / (1 - stripeCommissionRate - myFeeRate);
// Calculate individual fees
let stripeFee = stripeFixedFee + (grossAmount * stripeCommissionRate);
let myFee = grossAmount * myFeeRate;
// Round individual fees
stripeFee = parseFloat(stripeFee.toFixed(2));
cookieFee = parseFloat(cookieFee.toFixed(2));
// Calculate total fees
let totalFees = stripeFee + myFee;
// Calculate final gross amount from rounded amounts
grossAmount = netAmount + stripeFee + myFee;
grossAmount = parseFloat(grossAmount.toFixed(2));
return {
grossAmount: grossAmount,
stripeFee: stripeFee,
myFee: myFee,
totalFees: totalFees,
};
}
0.1 + 0.2 !== 0.3
. As a debugging strategy you could step throughcalculateFees(...)
in the debugger or use a lot ofconsole.log(...)
to see the values of everything after each calculation, possibly even breaking down calculations such as yourlet grossAmount = ...
into individual steps, to see if & where floating point rounding errors could be affecting your result. See this answer for use of EPSILON. – Stephen P Commented Nov 20, 2024 at 18:07