Skip to content

pametan/eft-canada

Repository files navigation

eft-canada

A Canadian EFT toolkit: validate and convert account identifiers (transit / institution / account), parse cheque MICR lines, validate Interac e-Transfer aliases, and build/parse AFT (Payments Canada Standard 005) files. The Canadian counterpart to @pametan/modulus-check-uk.

import { validateAccount, toElectronicRouting, buildAftFile } from '@pametan/eft-canada';

validateAccount({ transit: '12345', institution: '003', account: '1234567' }).valid; // true (RBC)
toElectronicRouting({ transit: '12345', institution: '003' });                        // '000312345'

⚠️ Two things to know.

  1. Canada has no national checkdigit scheme (unlike UK modulus checking), so identifier validation here is structural + reference-based — it confirms the shape and that the institution number is a known FI, but cannot prove an account exists.
  2. The AFT Standard 005 layout is implemented from the published spec plus public reverse-engineering. The official docs are incomplete and FIs vary, so verify the byte layout against your processing FI's specification and a real sample file before production use. Not financial advice.

TypeScript-first, zero runtime dependencies.

Install

npm install @pametan/eft-canada

Requires Node 24+. Ships ESM + types.

Identifiers & conversion

import {
  validateTransit, validateAccount, getInstitution,
  toElectronicRouting, fromElectronicRouting, parseMicr,
} from '@pametan/eft-canada';

validateTransit('12345');                 // true (5 digits)
getInstitution('003');                    // { number: '003', name: 'Royal Bank of Canada', shortName: 'RBC' }

validateAccount({ transit: '12345', institution: '003', account: '1234567' });
// { valid, transitValid, institutionKnown, accountPlausible, institution, normalized }

toElectronicRouting({ transit: '12345', institution: '003' });  // '000312345' (0 + inst + transit)
fromElectronicRouting('000312345');                             // { institution: '003', transit: '12345' }

parseMicr('⑈12345-003⑈ 1234567⑆');         // { transit, institution, account }

Interac aliases

import { validateInteracAlias } from '@pametan/eft-canada';
validateInteracAlias('a.b@example.com');  // { valid: true, type: 'email' }
validateInteracAlias('+1 416 555 0199');  // { valid: true, type: 'phone' }

AFT (Standard 005) files

import { buildAftFile, parseAftFile } from '@pametan/eft-canada';

const text = buildAftFile({
  header: {
    originatorId: 'ORIG123456',
    fileCreationNumber: 13,
    creationDate: '2026-06-01',
    destinationDataCentre: '00320',
    originatorShortName: 'PAMETAN',
  },
  transactions: [
    { kind: 'credit', transactionType: '200', amountCents: 123456, dueDate: '2026-06-02',
      payee: { institution: '003', transit: '12345', account: '1234567', name: 'A Payee' } },
    { kind: 'debit', transactionType: '370', amountCents: 250000, dueDate: '2026-06-03',
      payee: { institution: '010', transit: '33333', account: '5555', name: 'Mortgage Co' } },
  ],
});
// 1464-char lines: A header, C/D detail records (6 segments each), Z trailer with totals.

const parsed = parseAftFile(text);  // { header, transactions, totals }

Amounts are integer cents; dates use the 0YYDDD Julian form (toJulian / fromJulian are exported). Credits and debits are batched into separate C/D records, six transactions per record. The trailer carries control totals, which the parser recomputes.

What's covered

A solid A / C / D / Z core with the common transaction fields (type, amount, due date, payee institution/transit/account/name, return path, cross-reference, settlement code). The long tail of optional Standard 005 fields and return/notice record types is intentionally out of scope for v1 — see CONTRIBUTING.md.

API

Export Description
validateTransit, validateAccount Structural identifier validation.
getInstitution, institutions, normalizeInstitution Institution registry.
toElectronicRouting, fromElectronicRouting, parseMicr Routing & MICR.
validateInteracAlias Interac alias (email/phone) check.
buildAftFile, parseAftFile AFT Standard 005 build/parse.
toJulian, fromJulian CPA date conversion.

Types Institution, AccountResult, MicrResult, AftFile, AftHeader, AftTransaction, AftTotals are exported.

Data

The institution registry is a curated set of major Canadian FIs (not exhaustive), sourced from Payments Canada and date-stamped — see data/institutions.json and DATA.md. Payments Canada's directory is the authoritative, complete source.

Development

npm install
npm run build:data   # regenerate src/generated.ts from data/institutions.json
npm run typecheck
npm test             # identifiers, conversion, MICR, AFT round-trip, registry
npm run build

Disclaimer

An engineering aid, not financial or compliance advice. Verify the AFT layout and institution data against authoritative sources before relying on them. MIT licensed — see LICENSE.


Need the production version of this?

We're Pametan — a specialist fintech/regtech engineering agency working across UK, US and Canadian rails (FCA · CFPB · FCAC). We build the Canadian payment integrations behind this — AFT origination, returns handling, reconciliation and bank connectivity.

Talk to us →

About

Canadian EFT toolkit: validate/convert account identifiers (transit/institution/account), parse cheque MICR, validate Interac aliases, and build/parse AFT (Payments Canada Standard 005) files.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors