What it actually takes for a third-party application to send its invoices through this gateway and get them processed by DGII — the integration steps, and the regulatory gates that decide whether you're allowed to offer it.
The ERP is built for your own companies' invoicing — it is not the integration point for outside applications. The piece built for "an external app sends me a document, I sign it and transmit it to DGII" is this gateway. Point any external integration here directly, not at the ERP's own invoice routes.
| Environment | Base URL |
|---|---|
| Local | http://127.0.0.1:8090 |
| Deployed | https://portal.easy-ims.com |
Technical — applies once Part 2's gates are actually cleared.
X-Admin-Key, form fields:
| Field | Required | Notes |
|---|---|---|
| name | yes | Their company name |
| rnc | no | Their RNC |
| callback_url | no | A webhook you own for status pushes |
password + the uploaded .p12/.pfx file. This is their own DGII digital certificate for their own RNC — see Part 2, this is not optional and not yours to substitute.
Authorization: Bearer <their token>:
{
"file_type": "JSON",
"is_signed": false,
"content": "<their e-CF payload, as a JSON string>"
}
is_signed: false — the gateway signs with their cert from step 2.
is_signed: true — already signed by them; relayed as-is, no cert custody needed here.
Response: 202 Accepted with a submission_id.
content actually holds (JSON-stringified)ecf_mapper.build_payload():indicador_monto_gravado — "0" = each line's monto_item
is without ITBIS; "1" = it includes the ITBIS (then precio_unitario = monto_item ÷ cantidad).
It's the issuing company's setting (EasyIMS: Configuración de Empresa → ITBIS en la línea), sent on every
e-CF of types 31, 32, 33, 34, 41 and 45. tramos_itbis[].base and totales are always without
ITBIS in the base, either way. Credit/debit notes follow the invoice they modify. Accepted by DGII (TesteCF, 2026-10-09).
{
"source_system": "external_app",
"tipo_ecf": "32",
"reference": { "type": "invoice", "id": 304, "number": "INV-2026-00077" },
"currency": "DOP",
"indicador_monto_gravado": "0",
"fecha_emision": "2026-09-10",
"tipo_pago": "1",
"emisor": {
"rnc": "132307739",
"razon_social": "CESEHE CENTRO DE SERVICIOS HIDRAULICOS ESPECIALIZADOS SRL",
"direccion": "Zona Industrial de Herrera, Santo Domingo"
},
"comprador": {
"rnc": null,
"razon_social": "Consumidor Final",
"direccion": null,
"phone": null
},
"lineas": [
{
"linea": 1,
"item_sku": "HOSE-12-100-SB",
"nombre_item": "1/2\" x 100ft Stainless Braid Hose",
"cantidad": 1,
"precio_unitario": 72.60,
"monto_item": 72.60,
"tax_category": "ITBIS",
"tax_rate": 0.18,
"impuesto": 13.07,
"indicador": 1,
"unidad_medida": "UND"
}
],
"totales": {
"subtotal": 72.60,
"total_impuesto": 13.07,
"total": 85.67
},
"tramos_itbis": [
{ "indicador": 1, "tasa": 0.18, "base": 72.60, "impuesto": 13.07 }
]
}
comprador.rnc is null here because this is a walk-in Consumidor Final sale — populate it for a Crédito Fiscal (tipo 31) buyer. lineas[].indicador is DGII's IndicadorFacturacion tier (1 = ITBIS 18%, 2 = ITBIS 0% exento, etc.) — one entry per distinct tier feeds tramos_itbis. Omit fecha_limite_pago entirely unless tipo_pago is "2" (credit terms).
status (RECEIVED → SENT → EN_PROCESO → ACCEPTED/CONDITIONAL/REJECTED), plus dgii_status, security_code, e_ncf. With a callback_url set, you push updates instead of them polling.
All ten types, same field vocabulary throughout. Click a type to expand its example.
| Type | Name | Builder |
|---|---|---|
| 31 | Crédito Fiscal | build_payload() |
| 32 | Consumo | build_payload() |
| 33 | Nota de Débito | build_debit_note_payload() |
| 34 | Nota de Crédito | build_credit_note_payload() |
| 41 | Comprobante de Compras | build_ap_bill_payload() |
| 43 | Gastos Menores | build_ap_bill_payload() |
| 44 | Régimen Especial | build_payload() |
| 45 | Gubernamental | build_payload() |
| 46 | Exportaciones | build_export_payload() |
| 47 | Pagos al Exterior | build_ap_bill_payload() |
{
"source_system": "external_app",
"tipo_ecf": "31",
"reference": { "type": "invoice", "id": 305, "number": "INV-2026-00078" },
"currency": "DOP",
"indicador_monto_gravado": "0",
"fecha_emision": "2026-09-10",
"fecha_vencimiento_secuencia": "31-12-2028",
"tipo_pago": "1",
"emisor": {
"rnc": "132307739",
"razon_social": "CESEHE CENTRO DE SERVICIOS HIDRAULICOS ESPECIALIZADOS SRL",
"direccion": "Zona Industrial de Herrera, Santo Domingo"
},
"comprador": {
"rnc": "101234567",
"razon_social": "G FABRICA DE JUNTAS GIOVANNY SRL",
"direccion": "Santo Domingo",
"phone": null
},
"lineas": [
{
"linea": 1,
"item_sku": "HOSE-14-50-PU",
"nombre_item": "1/4\" x 50ft Polyurethane Whip Hose",
"cantidad": 2,
"precio_unitario": 76.54,
"monto_item": 153.08,
"tax_category": "ITBIS",
"tax_rate": 0.18,
"impuesto": 27.55,
"indicador": 1,
"unidad_medida": "UND"
}
],
"totales": { "subtotal": 153.08, "total_impuesto": 27.55, "total": 180.63 },
"tramos_itbis": [ { "indicador": 1, "tasa": 0.18, "base": 153.08, "impuesto": 27.55 } ]
}
tipo_ecf is resolved from the buyer (RNC present → 31, absent → 32).{
"source_system": "external_app",
"tipo_ecf": "32",
"reference": { "type": "invoice", "id": 304, "number": "INV-2026-00077" },
"currency": "DOP",
"indicador_monto_gravado": "0",
"fecha_emision": "2026-09-10",
"tipo_pago": "1",
"emisor": {
"rnc": "132307739",
"razon_social": "CESEHE CENTRO DE SERVICIOS HIDRAULICOS ESPECIALIZADOS SRL",
"direccion": "Zona Industrial de Herrera, Santo Domingo"
},
"comprador": { "rnc": null, "razon_social": "Consumidor Final", "direccion": null, "phone": null },
"lineas": [
{
"linea": 1, "item_sku": "HOSE-12-100-SB", "nombre_item": "1/2\" x 100ft Stainless Braid Hose",
"cantidad": 1, "precio_unitario": 72.60, "monto_item": 72.60,
"tax_category": "ITBIS", "tax_rate": 0.18, "impuesto": 13.07, "indicador": 1, "unidad_medida": "UND"
}
],
"totales": { "subtotal": 72.60, "total_impuesto": 13.07, "total": 85.67 },
"tramos_itbis": [ { "indicador": 1, "tasa": 0.18, "base": 72.60, "impuesto": 13.07 } ]
}
fecha_vencimiento_secuencia is omitted for 32 (and 34) — DGII's own schema doesn't carry that field for these two types.{
"source_system": "external_app",
"tipo_ecf": "33",
"reference": { "type": "debit_note", "id": 12, "number": "ND-2026-00003" },
"currency": "DOP",
"fecha_emision": "2026-09-10",
"fecha_vencimiento_secuencia": "31-12-2028",
"emisor": {
"rnc": "132307739",
"razon_social": "CESEHE CENTRO DE SERVICIOS HIDRAULICOS ESPECIALIZADOS SRL",
"direccion": "Zona Industrial de Herrera, Santo Domingo"
},
"comprador": { "rnc": "101234567", "razon_social": "G FABRICA DE JUNTAS GIOVANNY SRL", "direccion": "Santo Domingo" },
"lineas": [
{
"linea": 1, "item_sku": "HOSE-14-50-PU", "nombre_item": "Ajuste de precio",
"cantidad": 1, "precio_unitario": 15.00, "monto_item": 15.00,
"tax_category": "ITBIS", "tax_rate": 0.18, "impuesto": 2.70, "indicador": 1, "unidad_medida": "UND"
}
],
"totales": { "subtotal": 15.00, "total_impuesto": 2.70, "total": 17.70 },
"tramos_itbis": [ { "indicador": 1, "tasa": 0.18, "base": 15.00, "impuesto": 2.70 } ],
"modified_reference": {
"ncf_modificado": "E310000000184",
"fecha_ncf_modificado": "2026-09-07",
"codigo_modificacion": "3"
}
}
modified_reference.codigo_modificacion is always "3" (corrección de montos) for a debit note — it only ever increases amounts.{
"source_system": "external_app",
"tipo_ecf": "34",
"reference": { "type": "credit_note", "id": 8, "number": "NC-2026-00002" },
"currency": "DOP",
"fecha_emision": "2026-09-10",
"indicador_nota_credito": "0",
"indicador_monto_gravado": "0",
"tipo_ingresos": "01",
"emisor": {
"rnc": "132307739",
"razon_social": "CESEHE CENTRO DE SERVICIOS HIDRAULICOS ESPECIALIZADOS SRL",
"direccion": "Zona Industrial de Herrera, Santo Domingo"
},
"comprador": { "rnc": null, "razon_social": "Consumidor Final", "direccion": null },
"lineas": [
{
"linea": 1, "item_sku": "HOSE-12-100-SB", "nombre_item": "1/2\" x 100ft Stainless Braid Hose",
"cantidad": 1, "precio_unitario": 72.60, "monto_item": 72.60,
"tax_category": "ITBIS", "tax_rate": 0.18, "impuesto": 13.07, "indicador": 1, "unidad_medida": "UND"
}
],
"totales": { "subtotal": 72.60, "total_impuesto": 13.07, "total": 85.67 },
"tramos_itbis": [ { "indicador": 1, "tasa": 0.18, "base": 72.60, "impuesto": 13.07 } ],
"modified_reference": {
"ncf_modificado": "E320000000060",
"fecha_ncf_modificado": "2026-09-09",
"codigo_modificacion": "1"
}
}
indicador_nota_credito is "1" only when issued more than the configured window (default 30 days) after the original invoice. codigo_modificacion: 1 = anula, 2 = corrige texto, 3 = corrige montos.{
"source_system": "external_app",
"tipo_ecf": "41",
"reference": { "type": "ap_bill", "id": 44, "number": "BILL-2026-00021" },
"currency": "DOP",
"fecha_emision": "2026-09-10",
"fecha_vencimiento_secuencia": "31-12-2028",
"emisor": {
"rnc": "132307739",
"razon_social": "CESEHE CENTRO DE SERVICIOS HIDRAULICOS ESPECIALIZADOS SRL",
"direccion": "Zona Industrial de Herrera, Santo Domingo"
},
"comprador": { "rnc": "220987654", "razon_social": "Proveedor Local SRL", "direccion": "Santiago" },
"lineas": [
{
"linea": 1, "item_sku": null, "nombre_item": "Materiales de oficina",
"cantidad": 1, "precio_unitario": 1200.00, "monto_item": 1200.00,
"tax_rate": 0.18, "impuesto": 216.00, "indicador": 1,
"retencion": { "indicador_agente": "1", "itbis_retenido": 108.00, "isr_retenido": 0.0 }
}
],
"tramos_itbis": [ { "indicador": 1, "tasa": 0.18, "base": 1200.00, "impuesto": 216.00 } ],
"totales": { "subtotal": 1200.00, "total_impuesto": 216.00, "total": 1416.00 }
}
retencion is optional on 41 (ITBIS and/or ISR withheld).{
"source_system": "external_app",
"tipo_ecf": "43",
"reference": { "type": "ap_bill", "id": 51, "number": "BILL-2026-00022" },
"currency": "DOP",
"fecha_emision": "2026-09-10",
"fecha_vencimiento_secuencia": "31-12-2028",
"emisor": {
"rnc": "132307739",
"razon_social": "CESEHE CENTRO DE SERVICIOS HIDRAULICOS ESPECIALIZADOS SRL",
"direccion": "Zona Industrial de Herrera, Santo Domingo"
},
"lineas": [
{
"linea": 1, "item_sku": null, "nombre_item": "Compra menor sin RNC del vendedor",
"cantidad": 1, "precio_unitario": 350.00, "monto_item": 350.00,
"tax_rate": 0.0, "impuesto": 0.0, "indicador": 3
}
],
"tramos_itbis": [],
"totales": { "subtotal": 350.00, "total_impuesto": 0.0, "total": 350.00 }
}
comprador key at all for 43 — by design, there's no seller identity to carry. No retencion either.{
"source_system": "external_app",
"tipo_ecf": "44",
"reference": { "type": "invoice", "id": 306, "number": "INV-2026-00079" },
"currency": "DOP",
"fecha_emision": "2026-09-10",
"fecha_vencimiento_secuencia": "31-12-2028",
"tipo_pago": "1",
"emisor": {
"rnc": "132307739",
"razon_social": "CESEHE CENTRO DE SERVICIOS HIDRAULICOS ESPECIALIZADOS SRL",
"direccion": "Zona Industrial de Herrera, Santo Domingo"
},
"comprador": { "rnc": "130555222", "razon_social": "Zona Franca Ejemplo SAS", "direccion": "San Pedro de Macoris", "phone": null },
"lineas": [
{
"linea": 1, "item_sku": "HOSE-12-100-SB", "nombre_item": "1/2\" x 100ft Stainless Braid Hose",
"cantidad": 5, "precio_unitario": 72.60, "monto_item": 363.00,
"tax_category": "ITBIS", "tax_rate": 0.0, "impuesto": 0.0, "indicador": 2, "unidad_medida": "UND"
}
],
"totales": { "subtotal": 363.00, "total_impuesto": 0.0, "total": 363.00 },
"tramos_itbis": [ { "indicador": 2, "tasa": 0.0, "base": 363.00, "impuesto": 0.0 } ]
}
tipo_ecf is forced to 44 purely by the customer's own ecf_regime classification — ITBIS is typically exempt (indicador 2), same field shape as 31/32 otherwise.{
"source_system": "external_app",
"tipo_ecf": "45",
"reference": { "type": "invoice", "id": 307, "number": "INV-2026-00080" },
"currency": "DOP",
"indicador_monto_gravado": "0",
"fecha_emision": "2026-09-10",
"fecha_vencimiento_secuencia": "31-12-2028",
"tipo_pago": "1",
"emisor": {
"rnc": "132307739",
"razon_social": "CESEHE CENTRO DE SERVICIOS HIDRAULICOS ESPECIALIZADOS SRL",
"direccion": "Zona Industrial de Herrera, Santo Domingo"
},
"comprador": { "rnc": "401500333", "razon_social": "Ayuntamiento Municipal Ejemplo", "direccion": "Santo Domingo", "phone": null },
"lineas": [
{
"linea": 1, "item_sku": "HOSE-38-25-NM", "nombre_item": "3/8\" x 25ft Non-Marking PW Hose",
"cantidad": 3, "precio_unitario": 306.49, "monto_item": 919.47,
"tax_category": "ITBIS", "tax_rate": 0.18, "impuesto": 165.50, "indicador": 1, "unidad_medida": "UND"
}
],
"totales": { "subtotal": 919.47, "total_impuesto": 165.50, "total": 1084.97 },
"tramos_itbis": [ { "indicador": 1, "tasa": 0.18, "base": 919.47, "impuesto": 165.50 } ]
}
ecf_regime == "GUBERNAMENTAL" classification — same field shape as 31/32, no special tax treatment on its own.{
"source_system": "external_app",
"tipo_ecf": "46",
"reference": { "type": "export", "id": 5, "number": "EXP-2026-00002" },
"currency": "DOP",
"fecha_emision": "2026-09-10",
"fecha_vencimiento_secuencia": "31-12-2028",
"emisor": {
"rnc": "132307739",
"razon_social": "CESEHE CENTRO DE SERVICIOS HIDRAULICOS ESPECIALIZADOS SRL",
"direccion": "Zona Industrial de Herrera, Santo Domingo"
},
"comprador": { "rnc": null, "razon_social": "Overseas Buyer Inc", "direccion": "Miami, FL, USA" },
"lineas": [
{
"linea": 1, "item_sku": "HOSE-38-50-NM", "nombre_item": "3/8\" x 50ft Non-Marking PW Hose",
"cantidad": 10, "precio_unitario": 3495.90, "monto_item": 34959.00,
"tax_category": null, "tax_rate": 0.0, "impuesto": 0.0, "indicador": 3, "unidad_medida": "UND",
"otra_moneda_detalle": {
"precio_otra_moneda": 61.59, "descuento_otra_moneda": null,
"recargo_otra_moneda": null, "monto_item_otra_moneda": 615.90
}
}
],
"totales": { "subtotal": 34959.00, "total_impuesto": 0.0, "total": 34959.00 },
"tramos_itbis": [],
"export_info": {
"fecha_embarque": "2026-09-12", "numero_embarque": "EMB-0021",
"nombre_puerto_embarque": "Puerto de Haina", "condiciones_entrega": "FOB",
"total_fob": 615.90, "regimen_aduanero": "Exportacion Definitiva"
},
"transporte": { "via_transporte": "Maritima", "pais_origen": "DO", "pais_destino": "US" },
"otra_moneda": {
"tipo_moneda": "USD", "tipo_cambio": 56.79,
"monto_gravado_total": 615.90, "total_itbis": 0.0, "monto_total": 615.90
}
}
totales/line amounts are always DOP; the foreign-currency figures actually invoiced live in otra_moneda/otra_moneda_detalle. Lines are always indicador 3 (gravado 0%) — export has no exento slot. export_info/transporte have more optional fields than shown (weights, container, route, driver, etc.) — see build_export_payload() for the full list.{
"source_system": "external_app",
"tipo_ecf": "47",
"reference": { "type": "ap_bill", "id": 60, "number": "BILL-2026-00023" },
"currency": "USD",
"fecha_emision": "2026-09-10",
"fecha_vencimiento_secuencia": "31-12-2028",
"emisor": {
"rnc": "132307739",
"razon_social": "CESEHE CENTRO DE SERVICIOS HIDRAULICOS ESPECIALIZADOS SRL",
"direccion": "Zona Industrial de Herrera, Santo Domingo"
},
"comprador": { "identificador_extranjero": "US-EIN-123456789", "razon_social": "Foreign Vendor LLC" },
"lineas": [
{
"linea": 1, "item_sku": null, "nombre_item": "Servicio de consultoria",
"cantidad": 1, "precio_unitario": 500.00, "monto_item": 500.00,
"tax_rate": 0.0, "impuesto": 0.0, "indicador": 3,
"retencion": { "indicador_agente": "1", "itbis_retenido": 0.0, "isr_retenido": 45.00 }
}
],
"tramos_itbis": [],
"totales": { "subtotal": 500.00, "total_impuesto": 0.0, "total": 500.00 }
}
comprador uses identificador_extranjero instead of rnc — no RNC exists for a foreign payee. retencion.isr_retenido is required on 47 (ISR only, never ITBIS).Two independent requirements. Satisfying one does not satisfy the other — both must hold before you transmit real e-CF for an unrelated third party.
Per-RNC, never shared. Certification belongs to the taxpayer, not the software. Your own certified companies' status never transfers to anyone else — every RNC that wants to transmit real e-CF must independently complete DGII's own certification (Postulación → Set de Pruebas → Pruebas de Datos) before going to REAL mode, regardless of gateway or software.
Without their certification you can: run them in SIM mode freely, let them practice on /test-client. You cannot: transmit anything real on their behalf.
DGII requires formal PSFE (Proveedor de Servicios de Facturación Electrónica) authorization the moment your infrastructure signs or transmits e-CF on behalf of an unrelated third party — true regardless of:
.p12 on your server is still the "Software como servicio" PSFE model — using their cert instead of yours does not exempt you.The one architecture needing no PSFE authorization: give the third party their own standalone deployment — their own server, their own certificate, their own RNC. That's "a local install signing its own RNC" — you become a software vendor, not a transmission intermediary.
Their certification does not substitute for yours. DGII's own emisor-certification form requires declaring Tipo de Software: EXTERNO, which in turn requires naming the software provider's RNC, Razón Social and Nombre Comercial ("Datos del Proveedor") — DGII expects to see your PSFE identity referenced inside their certification paperwork, not replaced by it.
Run their signing/transmission on your own infrastructure, as described in Part 1. Not available until 3 emisores are certified and the PSFE Solicitud → Certificación → Declaración Jurada process is complete.
Give them their own copy of the software — their own server, their own cert, their own RNC. No PSFE needed; you're licensing software, not operating shared transmission infrastructure. Requires only that they complete their own emisor certification (Gate A).
REAL_DGII.md — requirements table (Gate A + Gate B), operating-model tradeoffs.PSFE_PLAYBOOK.md — full PSFE application process, eligibility gate, "Datos del Proveedor" mechanism.CERTECF_PLAYBOOK.md — the per-RNC emisor certification process (Gate A).app/routers/admin.py — tenant provisioning + certificate upload endpoints (Part 1).app/routers/ecf.py — the POST /v1/ecf submission contract (Part 1, step 4).