Created
April 12, 2026 18:03
-
-
Save ungive/1e1231c9e6e4cf8824b57bfee77f2e84 to your computer and use it in GitHub Desktop.
Formula to calculate fee coverage for Paddle for a given subtotal and VAT percentage. Also takes a source and target currency to add fee conversion fees. The source currency is the buyer currency, the target currency is your account balance currency. Note that with a payout, if your bank account's currency is different from your Paddle account c…
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
| """ | |
| total = 2500 | |
| tax = 399 | |
| subtotal = total - tax | |
| vat_percent = tax / subtotal = 0.19 | |
| wanted_revenue = total - tax = 2101 # revenue without fees | |
| new_subtotal = subtotal + X | |
| new_tax = new_subtotal * vat_percent | |
| new_total = new_subtotal + new_tax | |
| wanted_revenue = new_total - new_tax - new_total * 0.05 - 50 | |
| solve for X: | |
| wanted_revenue = new_total - new_tax - new_total * 0.05 - 50 | |
| wanted_revenue = new_total * 0.95 - new_tax - 50 | |
| wanted_revenue = (new_subtotal + new_tax) * 0.95 - new_tax - 50 | |
| wanted_revenue = new_subtotal * 0.95 + new_tax * 0.95 - new_tax - 50 | |
| wanted_revenue = new_subtotal * 0.95 - new_tax * 0.05 - 50 | |
| wanted_revenue = new_subtotal * 0.95 - new_subtotal * vat_percent * 0.05 - 50 | |
| wanted_revenue = new_subtotal * (0.95 - vat_percent * 0.05) - 50 | |
| wanted_revenue = (subtotal + X) * (0.95 - vat_percent * 0.05) - 50 | |
| wanted_revenue + 50 = (subtotal + X) * (0.95 - vat_percent * 0.05) | |
| (wanted_revenue + 50) / (0.95 - vat_percent * 0.05) = (subtotal + X) | |
| (wanted_revenue + 50) / (0.95 - vat_percent * 0.05) - subtotal = X | |
| solve for X (with 0.05 being a variable): | |
| F = 0.05 | |
| wanted_revenue = new_total - new_tax - new_total * F - 50 | |
| wanted_revenue = new_total * (1 - F) - new_tax - 50 | |
| wanted_revenue = (new_subtotal + new_tax) * (1 - F) - new_tax - 50 | |
| wanted_revenue = new_subtotal * (1 - F) + new_tax * (1 - F) - new_tax - 50 | |
| wanted_revenue = new_subtotal * (1 - F) - new_tax * F - 50 | |
| wanted_revenue = new_subtotal * (1 - F) - new_subtotal * vat_percent * F - 50 | |
| wanted_revenue = new_subtotal * ((1 - F) - vat_percent * F) - 50 | |
| wanted_revenue = (subtotal + X) * ((1 - F) - vat_percent * F) - 50 | |
| wanted_revenue + 50 = (subtotal + X) * ((1 - F) - vat_percent * F) | |
| (wanted_revenue + 50) / ((1 - F) - vat_percent * F) = subtotal + X | |
| (wanted_revenue + 50) / ((1 - F) - vat_percent * F) - subtotal = X | |
| (wanted_revenue + 50) / (1 + (-F) + vat_percent * (-F)) - subtotal = X | |
| (wanted_revenue + 50) / (1 + (-F) * (1 + vat_percent)) - subtotal = X | |
| (wanted_revenue + 50) / (1 - F * (1 + vat_percent)) - subtotal = X | |
| X = (wanted_revenue + 50) / (1 - F * (1 + vat_percent)) - subtotal | |
| X = (subtotal + 50) / (1 - F * (1 + vat_percent)) - subtotal | |
| """ | |
| # Platform fees: https://www.paddle.com/pricing | |
| # Currency conversion fees (2-3%): https://www.paddle.com/legal/terms | |
| PADDLE_BASE_FEE_FACTOR = 0.05 | |
| PADDLE_BASE_FEE_CENTS = 50 | |
| PADDLE_CONVERSION_BASE_FEE_FACTOR = 0.03 | |
| PADDLE_CONVERSION_FEE_FACTORS = { | |
| "USD": 0.02, | |
| "EUR": 0.02, | |
| "GBP": 0.02, | |
| "CZK": 0.025, | |
| "DKK": 0.025, | |
| "NOK": 0.025, | |
| "THB": 0.025, | |
| } | |
| # subtotal is in cents | |
| def calculate_fee_coverage_cents_external( | |
| subtotal: int, | |
| vat_percent: float, | |
| source_currency_code: str | None = None, | |
| target_currency_code: str | None = None, | |
| ) -> int: | |
| fee_factor = PADDLE_BASE_FEE_FACTOR | |
| if ( | |
| source_currency_code | |
| and target_currency_code | |
| and source_currency_code != target_currency_code | |
| ): | |
| target_currency_code = target_currency_code.strip().upper() | |
| if target_currency_code in PADDLE_CONVERSION_FEE_FACTORS: | |
| fee_factor += PADDLE_CONVERSION_FEE_FACTORS[target_currency_code] | |
| else: | |
| fee_factor += PADDLE_CONVERSION_BASE_FEE_FACTOR | |
| coverage = (subtotal + PADDLE_BASE_FEE_CENTS) / ( | |
| 1 - fee_factor * (1 + vat_percent) | |
| ) - subtotal | |
| print( | |
| "fee coverage:", | |
| coverage, | |
| source_currency_code, | |
| target_currency_code, | |
| fee_factor, | |
| file=sys.stderr, | |
| ) | |
| return int(Decimal(coverage).quantize(Decimal("1"), rounding=decimal.ROUND_HALF_UP)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment