Lo que pide la DGII y lo que te ahorras
Emitir un e-CF «a mano» contra la DGII implica armar el XML del formato oficial, firmarlo con el
certificado digital del emisor (XAdES), pedir una semilla, firmarla para obtener un token, enviar el
comprobante, guardar el TrackID y consultar su estado hasta que la DGII lo acepte o lo
rechace. Antes de eso, el emisor tiene que pasar la certificación de la DGII.
Con Aura, tu sistema manda la venta en JSON y recibe el e-NCF al momento. Aura valida las reglas de cada tipo de comprobante antes de reservar el número, firma el XML, lo envía, consulta el resultado y te avisa por webhook. Si la DGII no responde, reintenta sola.
Antes de empezar
- El RNC de la empresa que va a emitir y su certificado digital
(archivo
.p12) de una persona autorizada ante la DGII. Si todavía no tienes los roles asignados, sigue la guía de roles en la Oficina Virtual. - Una cuenta de Aura. El plan gratis incluye 100 e-CF al mes.
- Node 18 o superior, o PHP, si vas a usar los SDK. La API también se usa con cualquier cliente HTTP.
Los pasos
- Crea la cuenta en aura.nexo.com.do.
- Registra la empresa emisora (en Aura se llama cliente) con su RNC. Su
identificador es el
clientIdque mandarás en cada comprobante. - Sube el certificado
.p12desde el panel. Aura lo guarda cifrado y firma con él cada comprobante de esa empresa. - Crea una API Key de pruebas en la sección API Keys del panel. Empieza por
aura_test_y emite contra el ambiente de pruebas de la DGII. El token completo se muestra una sola vez. - Emite tu primer comprobante con los ejemplos de abajo.
aura_test_…
emite en el ambiente de pruebas; una aura_live_…, en producción. Las dos no se mezclan:
una key de pruebas no ve ni emite comprobantes reales.
Emitir con una llamada HTTP
Este ejemplo emite una factura de crédito fiscal (E31) por un servicio de RD$10,000 más ITBIS:
curl -X POST https://aura.nexo.com.do/api/v1/vouchers \
-H "X-API-Key: $AURA_API_KEY" \
-H "Idempotency-Key: venta-1043" \
-H "Content-Type: application/json" \
-d '{
"clientId": "00000000-0000-0000-0000-000000000000",
"typeId": "31",
"counterpart": { "rnc": "131234567", "legalName": "Cliente Demo SRL" },
"paymentType": 1,
"items": [
{ "description": "Servicio", "quantity": 1, "unitPrice": 10000, "itbisRate": 18 }
]
}'
Aura responde 202 en milisegundos con el número ya reservado:
{ "id": "…", "ncf": "E310000000001", "status": "PENDING" }
typeIdes el tipo de comprobante, del31al47. Si no sabes cuál usar, mira la guía de los 10 tipos de e-CF.counterpartes el comprador: RNC, razón social o los dos.paymentType:1contado,2crédito,3gratuito.itbisRatepor línea:18,16o0.
Con el SDK de Node
npm install @nexo-do/aura-sdk
import { Aura } from '@nexo-do/aura-sdk'
const aura = new Aura({ apiKey: process.env.AURA_API_KEY })
const voucher = await aura.vouchers.issueAndWait(
{
clientId: '00000000-0000-0000-0000-000000000000',
typeId: '31',
counterpart: { rnc: '131234567', legalName: 'Cliente Demo SRL' },
paymentType: 1,
items: [{ description: 'Servicio', quantity: 1, unitPrice: 10000, itbisRate: 18 }],
},
{ idempotencyKey: 'venta-1043' }
)
console.log(voucher.ncf, voucher.qrUrl, voucher.securityCode)
issueAndWait emite y espera unos segundos a que el comprobante esté firmado, para que tengas
el QR y el código de seguridad en el mismo flujo: lo que necesitas para imprimir el ticket o la factura.
Si prefieres no esperar, usa issue y recibe el resultado por webhook.
Con el SDK de PHP
composer require nexo-do/aura-ecf-sdk
<?php
require 'vendor/autoload.php';
use Aura\Ecf\Client;
$aura = new Client(getenv('AURA_API_KEY'));
$result = $aura->vouchers->issue([
'clientId' => '00000000-0000-0000-0000-000000000000',
'typeId' => '31',
'counterpart' => ['rnc' => '131234567', 'legalName' => 'Cliente Demo SRL'],
'paymentType' => 1,
'items' => [
['description' => 'Servicio', 'quantity' => 1, 'unitPrice' => 10000, 'itbisRate' => 18],
],
], idempotencyKey: 'venta-1043');
echo $result['ncf'];
Cómo saber si la DGII lo aceptó
La firma y el envío ocurren en segundo plano. El comprobante pasa por estos estados:
PENDING → SIGNED → IN_PROCESS → ACCEPTED,
CONDITIONAL (aceptado con observaciones) o REJECTED.
- Por webhook (recomendado): registra una URL y Aura te avisa con eventos como
voucher.acceptedyvoucher.rejected. Cada aviso va firmado con HMAC-SHA256 (cabeceraX-ECF-Signature); los SDK traenverifyWebhookpara comprobarlo. - Consultando:
GET /v1/vouchers/{id}, oaura.vouchers.retrieve(id)en los SDK.
voucher.accepted.
Tres errores que conviene evitar
- Reintentar sin
Idempotency-Key. Si se cae la red a mitad de la llamada y reintentas, puedes consumir un segundo número. Con la mismaIdempotency-Key, Aura devuelve la respuesta original durante 24 horas sin reservar otro e-NCF. Usa un valor ligado a la venta, como su número interno. - Calcular los impuestos por tu cuenta y mandarlos redondeados distinto. Manda cantidad, precio y tasa de ITBIS por línea, y deja que Aura arme los totales con las reglas de la DGII.
- Probar directo en producción. Un e-CF real consume un número de la secuencia y no
se deshace: sólo se anula. Haz todas las pruebas con la key
aura_test_.
Pasar a producción
Para emitir comprobantes reales, la empresa tiene que estar certificada como emisor electrónico ante la
DGII. Aura acompaña los pasos de la certificación desde el panel. Cuando termines, crea una key
aura_live_ y cámbiala en tu sistema: el código es el mismo. Una key de producción no
emite para una empresa que no esté certificada.
¿No programas y sólo quieres facturar desde tu negocio? La facturación electrónica viene incluida en el sistema POS Nexo, sin escribir código.