Skip to content

feat(iedu): add typed IEDU complement helpers#104

Open
alejandrobalderas wants to merge 1 commit intoFacturAPI:mainfrom
alejandrobalderas:feat/iedu-complement
Open

feat(iedu): add typed IEDU complement helpers#104
alejandrobalderas wants to merge 1 commit intoFacturAPI:mainfrom
alejandrobalderas:feat/iedu-complement

Conversation

@alejandrobalderas
Copy link
Copy Markdown

@alejandrobalderas alejandrobalderas commented May 8, 2026

Summary

Adds typed support for the IEDU (Instituciones Educativas) complement that schools include on K-12 tuition CFDIs, so callers no longer need to construct the SAT XML by hand.

The PR is intentionally scoped as pure helpers:

  • IeduComplementInput and IeduEducationLevel — typed input shape
  • buildIeduComplement(input) — returns the SAT-required <iedu:instEducativas .../> XML fragment that goes into items[].complement on a tuition invoice
  • IEDU_NAMESPACE — constant to push into the invoice's top-level namespaces array

No changes to invoices.create() or any other resource method. Non-IEDU callers are completely unaffected; users opt in explicitly when they need IEDU.

Why

The IEDU complement is what enables parents of K-12 students in Mexico to claim the Decreto de Deducción de Colegiaturas on their annual ISR return (Decreto 26-Dic-2013). Without it, parents lose the deduction (capped per nivel: ~$12,900–$24,500 MXN/year). It applies to Preescolar, Primaria, Secundaria, Profesional Técnico, and Bachillerato — university tuition is excluded.

The Facturapi REST API already accepts IEDU via the per-item complement XML string + the top-level namespaces array, but the SDK requires users to build the XML themselves. This PR provides typed helpers for that.

Usage

import Facturapi, { buildIeduComplement, IEDU_NAMESPACE } from 'facturapi';

const invoice = await facturapi.invoices.create({
  customer: 'YOUR_CUSTOMER_ID',
  use: Facturapi.InvoiceUse.SERVICIOS_EDUCATIVOS,
  payment_form: Facturapi.PaymentForm.TRANSFERENCIA_ELECTRONICA_DE_FONDOS,
  items: [{
    quantity: 1,
    product: {
      description: 'Colegiatura Mayo 2026 - Primaria',
      product_key: '86121503',
      unit_key: 'E48',
      price: 5000,
      taxes: [],
    },
    complement: buildIeduComplement({
      nombreAlumno: 'JUAN PEREZ GARCIA',
      CURP: 'PEGJ100515HDFRRN09',
      nivelEducativo: 'Primaria',
      autRVOE: 'ABC-123456',
      rfcPago: 'PEGM800101AB1', // optional
    }),
  }],
  namespaces: [IEDU_NAMESPACE],
});

What's new

File Change
src/types/complements.ts New types: IeduComplementInput, IeduEducationLevel
src/utils/iedu.ts New helpers: buildIeduComplement, IEDU_NAMESPACE
src/index.ts Re-export buildIeduComplement and IEDU_NAMESPACE
README.md New "Educational services (IEDU complement)" section
test/invoice.spec.ts tsd type-check example
test/node/iedu.node.test.ts 9 unit tests on the helpers
test/web/iedu.web.test.ts 2 jsdom smoke tests

Backward compatibility

Fully backward compatible. No existing methods or types were modified. The PR only adds new exports.

Testing

  • npm run lint — clean
  • npm run test:types (tsd) — clean
  • npm run test:node — 24/24 passing (15 existing + 9 new)
  • npm run test:web — 10/10 passing (8 existing + 2 new)
  • npm run build — succeeds, ESM 47.69 kB / CJS 40.50 kB

Notes for review

  • IEDU_NAMESPACE.schema_location matches the form documented in the FacturAPI OpenAPI spec (http://www.sat.gob.mx/sitio_interet/cfd/iedu/iedu.xsd). Happy to switch to the sitio_internet (correctly spelled) form if preferred — the constant is exported so users can also override.
  • IeduComplementInput.CURP uses uppercase to mirror the SAT XML attribute. Open to renaming to curp if camelCase consistency is preferred SDK-wide.
  • Validation is conservative — only required-field presence is asserted. CURP shape and RVOE shape validation could be a follow-up.

🤖 Generated with Claude Code

Adds typed support for the IEDU (Instituciones Educativas) complement
that schools include on K-12 tuition CFDIs:

- IeduComplementInput, IeduEducationLevel — typed input shape
- buildIeduComplement(input) — returns the SAT-required XML fragment
  that goes into items[].complement on a tuition invoice
- IEDU_NAMESPACE — constant to push into the invoice's top-level
  namespaces array

Pure helpers — no changes to invoices.create() or any other resource
method, so non-IEDU callers are completely unaffected. Users opt in by
explicitly calling the helper and registering the namespace.

The IEDU complement is what enables parents of K-12 students to claim
the colegiaturas deduction on their annual ISR return (Decreto
26-Dic-2013).

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@alejandrobalderas alejandrobalderas changed the title feat(iedu): add typed IEDU complement support feat(iedu): add typed IEDU complement helpers May 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant