GuideApril 18, 2026By Rachid El Kedmiri, Senior Odoo Architect

Canadian Payroll in Odoo:
Complete CPP, EI, T4, RL-1 Setup

OVERVIEW

The Canadian Payroll Regulatory Landscape — Why Odoo Canada Is Not Odoo US

Canadian payroll is deceptively complex. On paper it's one country with one payroll engine; in practice it's two parallel tax administrations, thirteen provincial and territorial tax schedules, two public pension schemes, two unemployment insurance programs, four distinct workers' compensation regimes, and an employer health tax that changes name and rate at every provincial border. If you are migrating to Odoo from ADP, Ceridian Dayforce, Nethris, or QuickBooks Payroll, the first rule is that the Canadian Odoo localization is not a minor skin on the US module — it is a separate module, l10n_ca_hr_payroll, with its own structures, rules, and year-end reporting engine.

At the federal level, the Canada Revenue Agency (CRA) administers income tax withholding, Canada Pension Plan (CPP and CPP2) contributions, Employment Insurance (EI) premiums, and the T4/T4A information return for every province except Quebec. For Quebec-resident employees, almost everything splits: Revenu Québec administers Quebec provincial income tax (via the TP-1 return), the Quebec Pension Plan (QPP) replaces CPP, the Quebec Parental Insurance Plan (QPIP) runs alongside a reduced federal EI rate, and year-end slips are filed as RL-1 instead of T4. An employee based in Gatineau who crosses the river to work in Ottawa has federal CPP and EI on their payslip; their coworker one desk over who lives and works in Montreal has QPP, QPIP, and reduced EI. Both work for the same company. Both run through the same Odoo database. Different rules fire for each.

On top of this sit the provincial payroll taxes. Ontario employers pay the Employer Health Tax (EHT) on the portion of annual payroll above the exemption threshold. Quebec employers pay the Fonds des services de santé (FSS), a health services fund with a sliding rate depending on total payroll. British Columbia has its own EHT. Manitoba has the Health and Post-Secondary Education Tax Levy. None of these are employee deductions — they are employer-only costs computed on the payroll base, and they need journal entries on every payslip run even though they never appear on the employee's T4.

Workers' compensation is another four-way split. In Ontario it's WSIB billed quarterly on assessable earnings. In Quebec it's CNESST with monthly remittance and an annual reconciliation. In Alberta it's the WCB-Alberta. In British Columbia it's WorkSafeBC. Each province publishes its own classification units, rate groups, and maximum assessable earnings ceilings. Odoo models these as separate "contribution" rules tied to the employee's work-location province, not the company's head-office province — a distinction that trips up implementations where the head office is in Toronto but half the crew is on a job site in Calgary.

The upshot is that "Canadian payroll in Odoo" is not one configuration — it's a matrix of federal rules, provincial rules, and Quebec-specific overrides that must be bound to the right employee contract through the right work-location record. Get the matrix right on day one and month-end close takes twenty minutes; get it wrong and your first RL-1 run in February will surface errors that have compounded for twelve months. The rest of this guide walks through that matrix, with the exact module configuration, Python salary rule logic, and year-end filing workflow we use for Octura Solutions clients running Odoo in Canada.

01

Installing and Configuring the Canadian Payroll Module in Odoo 19

The Canadian payroll localization lives in the l10n_ca_hr_payroll module (Enterprise only). Installing l10n_ca — the Canadian accounting chart — does not install the payroll pieces. These are separate modules, and on a fresh database you typically need to install both plus the Quebec-specific overlay if you employ anyone in Quebec.

Bash — Install Canadian payroll modules from the shell
# From odoo-bin, install the full Canadian stack
./odoo-bin -c /etc/odoo/odoo.conf -d octura_prod \
  -i l10n_ca,l10n_ca_hr_payroll,l10n_ca_hr_payroll_account,hr_payroll \
  --stop-after-init

# If you employ anyone in Quebec, also install:
./odoo-bin -c /etc/odoo/odoo.conf -d octura_prod \
  -i l10n_ca_qc_hr_payroll \
  --stop-after-init

Once installed, the module ships with pre-built salary structure types for Canadian federal and provincial regimes, pre-loaded CRA tax tables (T4127 federal and provincial brackets) and Revenu Québec tables (TP-1015.F), contribution rules for CPP, CPP2, QPP, EI, QPIP, and wrappers for employer-only items like EHT, FSS, CNESST, and WSIB. The default data is a starting point — every rate and ceiling still needs to be verified against the current year's CRA and RQ publications before you confirm your first payslip batch.

Company Configuration — The Employer Identity

Payroll journal entries, T4 and RL-1 slips all pull their identifying numbers from the res.company record. Before you run anything, the company must carry: the CRA Business Number (BN) with the RP payroll account suffix (for example 123456789RP0001), the Quebec enterprise number (NEQ), the Revenu Québec identification number for source deductions, the CNESST numéro d'employeur, the WSIB/WorkSafe account number, and the EI reduced-rate classification if you employ anyone in Quebec.

Python — Validate employer identifiers before first payroll run
from odoo.exceptions import ValidationError

company = env.company
missing = []

if not company.l10n_ca_cra_business_number:
    missing.append('CRA Business Number (BN15 with RP suffix)')
if company.country_id.code == 'CA':
    if not company.vat:
        missing.append('GST/HST number')
    # Quebec-specific
    quebec_employees = env['hr.employee'].search_count([
        ('address_id.state_id.code', '=', 'QC'),
        ('company_id', '=', company.id),
    ])
    if quebec_employees and not company.l10n_ca_qc_enterprise_number:
        missing.append('Quebec NEQ')
    if quebec_employees and not company.l10n_ca_rq_identification_number:
        missing.append('Revenu Québec identification number')

if missing:
    raise ValidationError(
        "Cannot run Canadian payroll. Missing: " + ", ".join(missing)
    )

Employee Contract Configuration

Canadian payroll is driven almost entirely by the contract. The fields that matter on every hr.contract record: structure_type_id must point to "CA Employee" (or "QC Employee" for Quebec residents), wage_type is monthly, hourly, or fixed, schedule_pay sets the pay period (weekly, bi-weekly, semi-monthly, monthly), and l10n_ca_claim_code_federal and l10n_ca_claim_code_provincial store the TD1 claim amounts from the employee's signed TD1/TD1-provincial form. Quebec employees also need l10n_ca_claim_code_qc from their TP-1015.3-V form.

Pay ScheduleCodeAnnualization FactorTypical Use
Weeklyweekly52Unionized trades, hourly site workers
Bi-weeklybi-weekly26Most Canadian private-sector employers
Semi-monthlysemi-monthly24Salaried office staff, professional services
Monthlymonthly12Executives, small-company owner-operators

Salary Structure Inheritance

Odoo's Canadian module uses the same inheritance model covered in our Odoo 19 Payroll Setup guide. One "CA Employee" structure type contains multiple concrete structures: Regular Pay, Bonus, Commission, Severance, and Stock Option Benefit. Each structure inherits the federal and provincial contribution rules but varies the basic rule — so a bonus payslip still triggers CPP, EI, and income tax withholding, but uses the bonus tax method (TD1X) rather than the periodic method.

Work Entry Types for Canadian Payroll

The default WORK100 entry type covers regular hours, but Canadian payroll usually needs additional types to keep the T4/RL-1 boxes clean at year-end: STAT for statutory holiday pay (required separately by most provincial Employment Standards Acts), VAC for vacation pay (accrual tracking is a legal obligation), OVT for overtime premium hours (Ontario's 44-hour threshold differs from BC's 40-hour threshold — configure per province), SICK for paid sick leave (mandatory in BC, QC, PEI, federally-regulated sectors), and BRVMT for bereavement. Each type maps to a salary rule that decides whether hours are pensionable, insurable, vacationable, and which T4/RL-1 box they land in.

Vacation Pay Is Not Optional

Every Canadian jurisdiction requires employers to either pay vacation pay on each cheque or accrue it to a liability account. In Odoo, this is a VAC salary rule that computes as categories['GROSS'] * vacation_rate, where vacation_rate is 4% for most employees (minimum), 6% after 5 years in Saskatchewan, 8% in Nunavut. Misconfigure this and you will owe employees retroactive vacation pay plus interest — a common finding in provincial Employment Standards audits.

02

CPP and CPP2: Configuring Canada Pension Plan Contributions for 2026

The Canada Pension Plan has been running through its enhancement schedule since 2019, and 2026 is the first full year with the second-tier CPP2 bracket fully phased in. There are now two separate ceilings, two rates, and two corresponding boxes on the T4 slip. For 2026, the Year's Maximum Pensionable Earnings (YMPE) sits at approximately CAD $72,400, with a basic exemption of $3,500. The employee contribution rate on earnings between the exemption and the YMPE is 5.95%, matched by the employer. Earnings between the YMPE and the Year's Additional Maximum Pensionable Earnings (YAMPE) — roughly $82,400 for 2026 — are subject to CPP2 at 4.00% employee and 4.00% employer.

Python — CPP + CPP2 salary rule (per-pay-period calculation)
# Rule code: CPP — sequence 61, category DED
# 2026 parameters (verify annually against CRA T4127)
YMPE = 72400.00
YAMPE = 82400.00
BASIC_EXEMPTION = 3500.00
CPP_RATE = 0.0595
CPP2_RATE = 0.0400

# Pay period gross (pensionable earnings for this cheque)
pensionable = categories['GROSS']

# Annualize for ceiling comparison using the contract's pay schedule
periods = {
    'weekly': 52, 'bi-weekly': 26,
    'semi-monthly': 24, 'monthly': 12,
}[contract.schedule_pay]

# Per-period exemption (basic exemption pro-rated)
period_exemption = BASIC_EXEMPTION / periods
period_ympe = YMPE / periods
period_yampe = YAMPE / periods

# Tier 1: CPP on earnings above exemption up to YMPE
tier1_base = max(0, min(pensionable, period_ympe) - period_exemption)
cpp = tier1_base * CPP_RATE

# Tier 2: CPP2 on earnings between YMPE and YAMPE
tier2_base = max(0, min(pensionable, period_yampe) - period_ympe)
cpp2 = tier2_base * CPP2_RATE

# Deductions are negative
result = -round(cpp + cpp2, 2)

The employer-side matching contribution runs as a separate rule (category Employer Cost, sequence 200 range) that mirrors the calculation but does not reduce net pay — it posts to an employer CPP expense account and an employer CPP payable account in the payroll journal. Odoo's Canadian module ships with this pair already wired; the only thing you typically override is the rate constants at the turn of each calendar year.

Year-to-Date Ceiling Is Per Employer

CPP ceilings apply per employer, not per person. If an employee changes jobs mid-year they may over-contribute across the two employers; CRA reconciles this on their personal T1 return. Do not try to credit previous-employer contributions in Odoo — your only obligation is to stop deducting once your cumulative YTD pensionable earnings hit the YMPE for the tier.

03

Employment Insurance (EI): Federal Rate, Quebec Reduced Rate, Employer 1.4x Match

Employment Insurance premiums are simpler than CPP: a flat percentage up to an annual Maximum Insurable Earnings (MIE) ceiling, with no exemption. For 2026, the MIE is approximately CAD $65,700. The federal employee rate is 1.64%, and employers pay 1.4 times the employee premium. For employees resident in Quebec, the federal EI rate is reduced (to roughly 1.31% for 2026) because QPIP covers maternity and parental benefits separately.

Python — EI salary rule with Quebec reduced rate branch
# Rule code: EI — sequence 62, category DED
MIE = 65700.00                       # 2026 Maximum Insurable Earnings
EI_RATE_FEDERAL = 0.0164             # rest of Canada
EI_RATE_QUEBEC = 0.0131              # Quebec reduced rate (QPIP offset)

insurable = categories['GROSS']
periods = {
    'weekly': 52, 'bi-weekly': 26,
    'semi-monthly': 24, 'monthly': 12,
}[contract.schedule_pay]
period_cap = MIE / periods
capped = min(insurable, period_cap)

# Branch on employee's province of residence
is_qc = employee.address_id.state_id.code == 'QC'
rate = EI_RATE_QUEBEC if is_qc else EI_RATE_FEDERAL

result = -round(capped * rate, 2)

The 1.4x employer match is a separate rule on the employer-cost side; if your business qualifies for an EI Premium Reduction (short-term disability plans, certain registered programs), the employer multiplier drops below 1.4 — Odoo stores this as l10n_ca_ei_employer_rate on the company record and the rule reads it as a parameter instead of hardcoding 1.4.

04

Provincial Income Tax: Ten Provinces, Three Territories, One Rule Engine

Every Canadian employee pays two income taxes on every cheque: federal income tax and one provincial (or territorial) income tax. The federal tax is uniform across the country; the provincial tax varies in both rates and brackets. Alberta has a nearly-flat structure. Ontario layers a "surtax" on the basic calculation once tax payable exceeds a threshold. BC has seven brackets. Quebec is not handled by CRA at all and has its own section below.

Odoo's l10n_ca_hr_payroll module stores the bracket tables in hr.rule.parameter records keyed by year and province. Each jurisdiction has a distinct parameter — l10n_ca_tax_federal_brackets_2026, l10n_ca_tax_on_brackets_2026, l10n_ca_tax_bc_brackets_2026, and so on. The salary rule reads the parameter at compute time, so when CRA publishes the new T4127 tables each January, you update the parameter record and every payslip from that date forward uses the new rates without touching the rule code.

Python — Provincial income tax rule using province-keyed parameters
# Rule code: TAX_PROV — sequence 63, category DED
from datetime import date

province = employee.work_location_id.state_id.code or employee.address_id.state_id.code
year = payslip.date_to.year

# Fetch bracket table for this province + year
param_key = f'l10n_ca_tax_{province.lower()}_brackets_{year}'
brackets = env['hr.rule.parameter'].get_param(param_key) or []

# Annualize per-period gross for bracket lookup
periods = {
    'weekly': 52, 'bi-weekly': 26,
    'semi-monthly': 24, 'monthly': 12,
}[contract.schedule_pay]
annual_gross = categories['GROSS'] * periods

# Apply the TD1 provincial claim code exemption
claim_amount = contract.l10n_ca_claim_code_provincial or 0
taxable = max(0, annual_gross - claim_amount)

# Progressive bracket walk: brackets = [(upper, rate, constant), ...]
annual_tax = 0
for upper, rate, constant in brackets:
    if taxable <= upper:
        annual_tax = taxable * rate - constant
        break
else:
    upper, rate, constant = brackets[-1]
    annual_tax = taxable * rate - constant

# Convert to per-period and negate
result = -round(annual_tax / periods, 2)

The critical configuration detail: Odoo binds the province to the employee's work location, not their residence. This matters for remote workers. An employee living in Gatineau (Quebec) but reporting to an Ottawa office has their payroll taxes computed on the Ontario bracket table and pays Ontario provincial tax, with a reconciliation on their personal T1 at year-end. CRA's rule is that the "province of employment" for withholding is determined by the employer's permanent establishment where the employee reports. Odoo exposes this via the work_location_id field on the employee; if that's left blank the rule falls back to the home address province, which is almost always wrong for cross-province workers.

ProvinceTop Marginal (2026)Notes
Ontario~13.16% + surtaxSurtax kicks in once provincial tax exceeds the threshold
Quebec~25.75%Administered by Revenu Québec, not CRA
British Columbia~20.5%7 brackets, highest top rate outside QC
Alberta~15.0%Near-flat structure, minimal bracket complexity
Nova Scotia~21.0%Brackets not fully indexed to inflation
Manitoba~17.4%Also collects Health & Post-Secondary Education Tax Levy
Update Brackets on January 1, Not January 15

CRA publishes T4127 in late December for the coming year. Update your hr.rule.parameter bracket records before your first pay period of the new year, not after the fact. A bi-weekly employer running the January 10 payroll on old brackets will under- or over-withhold for every employee on that cheque and have to issue amendments.

05

Quebec: QPP, QPIP, CNESST, FSS, TP-1 Withholding, and RL-1

Employing one person in Quebec doubles your Canadian payroll configuration. Quebec operates its own pension plan (QPP), its own parental insurance plan (QPIP), its own income tax administration (Revenu Québec, via the TP-1015 source deduction tables), its own workers' compensation regime (CNESST), and its own employer health tax (FSS). T4 slips don't cover Quebec-only items — you also issue RL-1 slips. Every Quebec-resident contract needs the QC Employee structure type instead of the federal CA Employee.

QPP — Quebec Pension Plan

QPP mirrors CPP structurally but uses higher rates. For 2026 the QPP employee rate is approximately 6.40% on the same $3,500 basic exemption up to the YMPE, versus 5.95% for CPP. The enhanced QPP2 on the YMPE-to-YAMPE bracket runs at roughly 4.00%, matching CPP2. Employer match is 1:1. Revenu Québec publishes the annual parameters in TP-1015.F.

QPIP — Quebec Parental Insurance Plan

QPIP is Quebec's answer to federal EI maternity/parental benefits and runs as a separate deduction on every Quebec payslip. 2026 rates sit near 0.494% employee, 0.692% employer, with maximum insurable earnings around CAD $98,000 — notably higher than federal EI's MIE. The employee still pays federal EI (at the reduced Quebec rate) plus QPIP; these are two separate lines on the payslip, two separate remittances, and two separate year-end boxes.

Python — QPIP employee + employer rules
# Rule code: QPIP_EE — sequence 64, category DED (Quebec only)
QPIP_MIE = 98000.00
QPIP_RATE_EE = 0.00494
QPIP_RATE_ER = 0.00692

periods = {
    'weekly': 52, 'bi-weekly': 26,
    'semi-monthly': 24, 'monthly': 12,
}[contract.schedule_pay]

period_cap = QPIP_MIE / periods
capped = min(categories['GROSS'], period_cap)

result = -round(capped * QPIP_RATE_EE, 2)

# Separate rule for employer side, same base, different rate
# Rule code: QPIP_ER — sequence 205, category COMP

TP-1 Quebec Provincial Income Tax

Quebec provincial income tax withholding uses the TP-1015.TI tables, not the CRA T4127. The brackets (roughly 14%, 19%, 24%, 25.75% for 2026) are applied against the Quebec-specific claim amount from the employee's TP-1015.3-V form, which is a distinct form from the federal TD1. Odoo stores this in l10n_ca_claim_code_qc on the contract. The salary rule is structurally identical to the provincial tax rule above, but reads the l10n_ca_qc_tax_brackets_2026 parameter and posts to a Revenu Québec payable account instead of CRA.

CNESST — Quebec Workers' Compensation

CNESST (Commission des normes, de l'équité, de la santé et de la sécurité du travail) is employer-only and computed as a percentage of assessable earnings, with the percentage determined by your classification unit and claims history. Rates range from under 0.5% for low-risk office work to well over 10% for construction and forestry. CNESST is not deducted from the employee — it's an employer expense. Configure it as a rule in the Employer Cost category that debits a CNESST expense account and credits a CNESST payable, with monthly remittance.

FSS — Employer Health Services Fund

The FSS is a sliding-scale employer payroll tax on total Quebec payroll. For 2026 the rate ranges from approximately 1.25% on the first tranche for small employers up to 4.26% for employers with large Quebec payrolls. Configure this as a monthly or per-payslip employer-cost rule reading a company-level parameter for the rate band.

06

Year-End Reporting: T4, T4 Summary, RL-1, and XML Filing

At year-end, every Canadian employer issues T4 slips to every employee (and a T4 Summary to CRA). Employers with Quebec-resident staff additionally issue RL-1 slips to Revenu Québec. Both are due by the last day of February following the calendar year. Odoo's l10n_ca_hr_payroll module ships a T4/RL-1 generation wizard that walks the year's confirmed payslips, aggregates by employee and by T4/RL-1 box, and produces both the employee-facing PDF slip and the XML file for electronic transmission.

T4 Box Mapping — Salary Rules to Tax Boxes

Every salary rule must be tagged with the T4 box it contributes to. Odoo models this via the l10n_ca_t4_box field on hr.salary.rule. The canonical mapping:

T4 BoxDescriptionTypical Salary Rules
14Employment incomeBASIC, GROSS, BONUS, COMMISSION, VAC, STAT, OVT
16Employee CPP contributionsCPP tier 1 deduction
16AEmployee CPP2 contributionsCPP2 deduction
17Employee QPP contributionsQPP (Quebec) — T4 still shows this
18Employee EI premiumsEI deduction
22Income tax deductedFederal + provincial tax withheld
24EI insurable earningsCumulative capped insurable base
26CPP/QPP pensionable earningsCumulative capped pensionable base
44Union duesDUES rule if configured
46Charitable donationsIf payroll-deducted
52Pension adjustment (PA)RPP/DPSP contributions

Taxable benefits — employer-paid group insurance above the exempt threshold, employer-paid parking, company vehicle personal-use benefit — land in Box 14 (employment income) and usually require Other Information codes such as 40 (other taxable allowances and benefits), 30 (board and lodging), or 34 (personal use of employer's automobile). Configure each taxable benefit as a salary rule with both the l10n_ca_t4_box and l10n_ca_t4_other_info_code set so the wizard routes the amount correctly.

RL-1 Box Mapping

RL-1 boxes map similarly: A = employment income, B = QPP contribution, C = EI premium, D = RRSP deduction at source, E = Quebec income tax withheld, F = union dues, G = pensionable salary for QPP, H = QPIP premium, I = insurable salary for QPIP. Quebec employees effectively have two sets of year-end slips — a T4 for federal items and an RL-1 for Quebec items — and the Odoo wizard generates both from the same consolidated payslip data.

XML Upload to CRA and Revenu Québec

Once slips are validated, the wizard produces two XML files: one in the CRA's T619 schema for the T4 batch (uploaded via CRA's Web Forms or Internet File Transfer), and one in Revenu Québec's XML schema for the RL-1 batch (uploaded via clicSÉQUR-entreprises). Both require a valid certifier identifier; for CRA it's your BN with RP suffix, for RQ it's your NEQ plus the identification number. Odoo stores the generated XML on the payroll period record so you have an audit trail of what was actually filed.

07

January Close Checklist — Getting Year-End Right the First Time

The biggest reason Canadian employers miss the February filing deadline is not year-end itself — it's that bonus adjustments, taxable benefit true-ups, and CPP/EI over-contribution reconciliations all land on the final December payslip. Plan for a structured January close with discrete steps.

StepActionDeadline
1Run final bonus / retro payroll for the calendar yearBefore December 31
2Post year-end taxable benefit adjustments (group insurance, parking, auto benefit)First week of January
3Verify CPP/QPP maximum hit for fully-loaded employees; refund over-contributions on a final adjustment payslipMid-January
4Reconcile EI insurable earnings YTD against Box 24 for every employeeMid-January
5Generate draft T4 / RL-1 slips, review box-by-box with financeEnd of January
6Distribute slips to employees (electronic with consent, otherwise paper)Last day of February
7File T4 XML with CRA and RL-1 XML with Revenu QuébecLast day of February

For hands-on help with this close cycle, our Odoo Partner Quebec and Odoo Partner Canada teams run a January compliance review for client databases — verifying box mappings, XML generation, and deadline adherence end to end.

FAQ

Canadian Payroll in Odoo — Frequently Asked Questions

1

Can Odoo Community run Canadian payroll?

No. The l10n_ca_hr_payroll module and its Quebec overlay are Enterprise-only. Odoo Community ships the generic hr_payroll framework but none of the Canadian tax tables, CPP/QPP/EI/QPIP rules, or T4/RL-1 generation. You need Odoo Enterprise or Odoo.sh to run legal Canadian payroll.

2

Does Odoo file T4 and RL-1 slips electronically for me?

Odoo generates the XML files in CRA T619 and Revenu Québec formats, but you upload them yourself through CRA's Internet File Transfer portal and the RQ clicSÉQUR-entreprises portal. There is no direct API integration — the slips are your employer obligation, Odoo gives you the file.

3

How does Odoo handle an employee who moves from Ontario to Quebec mid-year?

Create a new contract (or update work_location_id) with the Quebec work location starting on the effective date. Payslips before that date use the Ontario / CA Employee structure; payslips after use the Quebec / QC Employee structure. At year-end the employee receives a T4 covering federal items for the full year plus an RL-1 covering only the Quebec portion.

4

What about bilingual payslips?

Quebec's Charter of the French Language requires French-language payslips for Quebec-resident employees. Odoo's salary rule names and T4/RL-1 slip templates support French translations out of the box; set the employee's language preference on res.partner to fr_CA and the payslip PDF, email notifications, and RL-1 will render in French. Employees outside Quebec can opt into English (en_CA) or keep French.

5

How do I configure ROE (Record of Employment) generation?

Service Canada's ROE Web accepts XML uploads. Odoo's Canadian module includes an ROE generation wizard that pulls the last 53 weeks of insurable earnings and hours from work entries, computes the reason for issuance, and exports the ROE XML. File it through ROE Web within five calendar days of the interruption of earnings.

6

Can I run CRA remittances directly from Odoo?

Odoo generates the PD7A remittance voucher data and the payroll journal entries that feed accounts payable. The actual remittance is paid through your bank's CRA Payroll (RP) payment channel or directly via CRA My Business Account. Use Odoo's batch payment feature to create the ACH file if you remit via business banking.

7

How are bonus payments taxed in Odoo?

Use the separate Bonus salary structure with the TD1X bonus tax method, which annualizes the bonus differently from a regular cheque. Running a bonus through the regular structure over-withholds on high bonuses and under-withholds on small ones. The Canadian module ships with the bonus structure preconfigured; make sure HR uses it when generating bonus payslips rather than manually adjusting a regular payslip.

8

What support does Octura provide for Canadian payroll implementations?

As an Odoo Ready Partner based in Canada, we configure the full stack end to end: company registration setup, structure and rule configuration per province, Quebec-specific overlays, T4/RL-1 mapping audits, CRA/RQ XML validation, and first-cycle payroll review. See our services page for the full scope.

Canadian Payroll Is a Matrix — Configure It Like One

The single biggest mistake in Canadian Odoo implementations is treating payroll like a checklist. It isn't. It's a matrix of federal rules, provincial rules, and Quebec overrides that only work correctly when every employee's work location, contract structure, and year-end box mapping line up. When one cell is wrong — a Quebec employee accidentally assigned the CA Employee structure, a British Columbia worker with the Ontario bracket table, a taxable benefit rule missing its T4 box — the error compounds silently for months and surfaces in February when slips don't reconcile.

Octura Solutions is an Odoo Ready Partner operating bilingually across Canada. We implement, audit, and fix Canadian payroll in Odoo for clients from Halifax to Vancouver, with deep Quebec expertise for QPP/QPIP/CNESST/FSS/RL-1 compliance. If you're running your first year-end in Odoo — or inherited a configuration that's generating incorrect slips — we can help.

Book a Free Canadian Payroll Review