/** * Vela Payroll Engine — Canada Tax Jurisdiction * * Based on CRA 2025 tax year. * Source: https://www.canada.ca/en/revenue-agency/services/tax/individuals/topics/about-your-tax-return/tax-return/completing-a-tax-return/personal-income-tax-line-numbers.html * * Federal Income Tax — 2025 * ┌──────────────────────────────────┬────────┐ * │ Taxable Income │ Rate │ * ├──────────────────────────────────┼────────┤ * │ $0 – $57,375 │ 15.0% │ * │ $57,376 – $114,750 │ 20.5% │ * │ $114,751 – $177,882 │ 26.0% │ * │ $177,883 – $253,414 │ 29.0% │ * │ $253,415 and over │ 33.0% │ * └──────────────────────────────────┴────────┘ * * Basic Personal Amount (Federal): $15,705 (2025) * * Canada Pension Plan (CPP) — 2025 * - Employee rate: 5.95% on pensionable earnings between YMIP and YAMPE * - Employer rate: 5.95% matching * - Year's Maximum Pensionable Earnings (YAMPE): $71,300 * - Year's Maximum Insurable Pension (YMIP / basic exemption): $3,500 * - Additional CPP (enhancement): 4.00% on earnings between YAMPE and * the additional CPP ceiling ($81,200) — both employee and employer. * For MVP simplicity, this is NOT included. Only base CPP. * * Employment Insurance (EI) — 2025 * - Employee rate: 1.37% (approximate — set annually) * - Maximum insurable earnings: $65,700 * - Employer rate: 1.4 × employee rate (not included in employee deductions) * * Provincial Tax: Not included in MVP. Use FlatRateTax with * a combined federal+provincial rate for non-Canada jurisdictions, * or extend with a province-specific plugin. */ import { TaxJurisdiction, TaxBracket, DeductionLineItem, EmployerContribution, progressiveTaxCalc, round2, } from "../types"; // ── 2025 Federal Tax Brackets ── const FEDERAL_BRACKETS: TaxBracket[] = [ { min: 0, max: 57_375, rate: 0.150 }, { min: 57_375, max: 114_750, rate: 0.205 }, { min: 114_750, max: 177_882, rate: 0.260 }, { min: 177_882, max: 253_414, rate: 0.290 }, { min: 253_414, max: null, rate: 0.330 }, ]; const BASIC_PERSONAL_AMOUNT = 15_705; // 2025 federal // ── CPP 2025 ── const CPP_RATE = 0.0595; // 5.95% employee + 5.95% employer const CPP_YAMPE = 71_300; // Year's Maximum Pensionable Earnings const CPP_YMIP = 3_500; // Basic exemption // ── EI 2025 ── const EI_RATE = 0.0137; // 1.37% employee const EI_MAX_INSURABLE = 65_700; // Maximum insurable earnings const EI_EMPLOYER_MULTIPLIER = 1.4; // Employer pays 1.4× employee export class CanadaTax implements TaxJurisdiction { readonly name = "Canada"; readonly countryCode = "CA"; readonly currency = "CAD"; calculate(grossAnnual: number): { deductions: DeductionLineItem[]; employerContributions: EmployerContribution[]; } { // 1. Federal Income Tax (on taxable income after basic personal amount) const taxableIncome = Math.max(0, grossAnnual - BASIC_PERSONAL_AMOUNT); const federalTax = progressiveTaxCalc(taxableIncome, FEDERAL_BRACKETS); // 2. CPP Contributions const cppPensionableEarnings = Math.max( 0, Math.min(grossAnnual, CPP_YAMPE) - CPP_YMIP ); const cppEmployee = round2(cppPensionableEarnings * CPP_RATE); const cppEmployer = cppEmployee; // 3. EI Premiums const eiInsurableEarnings = Math.min(grossAnnual, EI_MAX_INSURABLE); const eiEmployee = round2(eiInsurableEarnings * EI_RATE); const eiEmployer = round2(eiEmployee * EI_EMPLOYER_MULTIPLIER); // Build results const deductions: DeductionLineItem[] = [ { name: "Federal Income Tax", amount: round2(federalTax), type: "tax", description: `CRA federal withholding (2025, BPA: $${BASIC_PERSONAL_AMOUNT.toLocaleString()})`, }, { name: "CPP Contribution", amount: cppEmployee, type: "pension", description: `5.95% on pensionable earnings ($${CPP_YMIP.toLocaleString()} – $${CPP_YAMPE.toLocaleString()})`, }, { name: "EI Premium", amount: eiEmployee, type: "insurance", description: `1.37% on insurable earnings (max $${EI_MAX_INSURABLE.toLocaleString()})`, }, ]; const employerContributions: EmployerContribution[] = [ { name: "CPP (Employer)", amount: cppEmployer, description: "5.95% matching contribution", }, { name: "EI (Employer)", amount: eiEmployer, description: "1.4× employee premium", }, ]; return { deductions, employerContributions }; } }