Skip to content

Instantly share code, notes, and snippets.

@harryfear
Created January 10, 2024 23:39
Show Gist options
  • Save harryfear/76c1869f9d37cc9b2214d683255eb284 to your computer and use it in GitHub Desktop.
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
/*
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