Created
January 10, 2024 23:39
-
-
Save harryfear/76c1869f9d37cc9b2214d683255eb284 to your computer and use it in GitHub Desktop.
A versatile JavaScript tool for calculating PayPal transaction fees, supporting UK, EEA, and worldwide transactions with both forward and reverse fee calculations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
PayPal Fee Calculator - Accurate and Comprehensive | |
Last updated: 10 January 2024 | |
0 x-border fees for UK-UK | |
1.29 x-border fees from EEA to UK | |
1.99 x-border fees from Rest of World to UK | |
This script is an essential tool for anyone dealing with PayPal transactions, particularly those who need to calculate fees for various types of international transactions. Whether you are a freelancer, running an online business, or simply need to manage personal transactions, this calculator is designed to make your financial planning easier and more precise. | |
Features: | |
- Accurate calculation of PayPal fees for different regions: UK, EEA, and Rest of the World. | |
- Functions for both forward and reverse fee calculations. | |
- Customizable for different fee structures and transaction types. | |
- Includes a precise rounding function to handle JavaScript's floating-point arithmetic issues, ensuring your financial calculations are always spot on. | |
- Comprehensive test functions to validate calculations. | |
The script is straightforward to use, and you can easily integrate it into your financial applications or use it as a standalone tool for quick calculations. Whether you're calculating the net amount after fees for a transaction or figuring out the gross amount to ensure a specific net receipt, this script has got you covered! | |
Make your PayPal transactions more predictable and financially manageable with this comprehensive fee calculator! | |
*/ | |
function roundAccurately(number, decimalPlaces) { | |
// Dealing with JavaScript's floating-point arithmetic issues. This ensures that your financial calculations are precise | |
// https://chat.openai.com/c/2277a669-5ae5-48d0-a3c2-cdb3eebcc2cb | |
return Number(Math.round(number + "e" + decimalPlaces) + "e-" + decimalPlaces); | |
} | |
function createPPChargeCalculator(fixed_fee, variable_fee_percentage, international_percentage) { | |
return function (working_number, international = international_percentage) { | |
// Add a fixed transaction fee | |
var fixedFee = fixed_fee; | |
// Calculate the variable fee as a percentage of the working number | |
var variableFee = (working_number * variable_fee_percentage) / 100; | |
// Calculate cross-border fee based on the international percentage | |
var crossBorderFee = working_number * international; | |
// Calculate the net amount after all fees and round to 2 decimal places | |
var netAllFees = roundAccurately(working_number - fixedFee - variableFee - crossBorderFee, 2); | |
return netAllFees; | |
}; | |
} | |
// For domestic senders PayPal | |
const calculatePayPalUKCharge = createPPChargeCalculator(0.3, 2.9, 0); | |
// For EEA-Based Senders PayPal | |
const calculatePayPalEEACharge = createPPChargeCalculator(0.3, 2.9, 0.0129); | |
// For Rest-of-World Senders PayPal | |
const calculatePayPalROWCharge = createPPChargeCalculator(0.3, 2.9, 0.0199); | |
// Test function | |
function testCalculateCharge(calculator, gross, net) { | |
const result = calculator(gross); | |
const epsilon = 0; // Acceptable error margin for floating point comparisons | |
// Check if the absolute difference is within the acceptable range | |
const diff = Math.abs(result - net); | |
const isWithinRange = (diff == 0); | |
console.log(`Test Passed: ${isWithinRange} | Test with amount: £${gross} | Expected: £${net} | Result: £${result} | Diff: £${diff}`); | |
} | |
function calculateReverseCharge(calculator, input) { | |
if (input === 0) return 0; | |
// Start from a number that is definitely higher than the input | |
let level = input * 2 * 100; // Start from twice the input (to ensure we're above the desired net) and convert to 'cents' | |
let brutingValue = calculator(level / 100); | |
// Decrease the level until the brutingValue is just less than the input | |
while (input < brutingValue) { | |
level--; | |
brutingValue = calculator(level / 100); | |
if (brutingValue <= input) break; // Stop if we are now less than or equal to the input | |
} | |
// Adjust by one to get the last level before the value went below the input if needed | |
if (brutingValue < input) { | |
level++; | |
} | |
var solution = level / 100; | |
return roundAccurately(solution,2); | |
} | |
// Test function for reverse calculation | |
function testCalculateReverseCharge(forwardAgent, gross, net) { | |
const calculatedGrossAmount = calculateReverseCharge(forwardAgent,net); | |
const diff = Math.abs(calculatedGrossAmount - gross); | |
const isCorrect = (diff === 0); | |
console.log(`Test Passed: ${isCorrect} | Expected Gross Amount: £${gross} | Calculated Gross Amount: £${calculatedGrossAmount} | Diff: £${diff}`); | |
} | |
// Tests with provided data | |
testCalculateCharge(calculatePayPalUKCharge, 250.00, 242.45); | |
testCalculateReverseCharge(calculatePayPalUKCharge, 250.00, 242.45); | |
testCalculateCharge(calculatePayPalEEACharge, 44.00, 41.86); | |
testCalculateReverseCharge(calculatePayPalEEACharge, 44.00, 41.86); | |
testCalculateCharge(calculatePayPalROWCharge, 40.00, 37.74); | |
testCalculateReverseCharge(calculatePayPalROWCharge, 40.00, 37.74); | |
// PayPalUKForward: Wrapper for forward calculation for PayPal UK senders | |
function PayPalUKForward(amount) { | |
return calculatePayPalUKCharge(amount); | |
} | |
// PayPalUKReverse: Wrapper for reverse calculation for PayPal UK senders | |
function PayPalUKReverse(desiredNetAmount) { | |
return calculateReverseCharge(calculatePayPalUKCharge, desiredNetAmount); | |
} | |
// PayPalROWForward: Wrapper for forward calculation for PayPal ROW senders | |
function PayPalROWForward(amount) { | |
return calculatePayPalROWCharge(amount); | |
} | |
// PayPalROWReverse: Wrapper for reverse calculation for PayPal ROW senders | |
function PayPalROWReverse(desiredNetAmount) { | |
return calculateReverseCharge(calculatePayPalROWCharge, desiredNetAmount); | |
} | |
// PayPalEEAForward: Wrapper for forward calculation for PayPal EEA senders | |
function PayPalEEAForward(amount) { | |
return calculatePayPalEEACharge(amount); | |
} | |
// PayPalEEAReverse: Wrapper for reverse calculation for PayPal EEA senders | |
function PayPalEEAReverse(desiredNetAmount) { | |
return calculateReverseCharge(calculatePayPalEEACharge, desiredNetAmount); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment