The stateless bridge model
fiscaliacore is explicitly not a facturador, not a system of record, not a SaaS for contribuyentes. It's a stateless pipe.
Mental model
(1 account per integrator company)
↓
[ your product ] ─────────► fiscaliacore ─────────► [ DGII ]
↑ (stateless) ↑
(your end customers — (the fiscal authority)
RNC holders, invisible to us)Three things fiscaliacore actually does
- Sign. You open a session with a
.p12+ password; we hand back a 15-minute opaque bearer token. The unlocked key stays in JVM memory. - Submit to DGII. You send us typed payloads; we build the XML per XSD, sign, and POST to the right DGII endpoint.
- Receive from DGII. Inbound e-CFs / ACECFs hit
{rnc}.ecf.fiscaliacore.com; we verify XAdES, forward to your registered callback URL with an HMAC-signed envelope, proxy the response back.
Everything else — invoice history, audit logs, emisor profiles, billing, retry-on-outage — lives in your product.
What we durably store
Just two things:
| Kind | What | Why |
|---|---|---|
| Integrator accounts | API keys, billing, usage counters | We need to authenticate + meter you. |
| Receiver registry | RNC → your callback URL + HMAC secret | DGII-originated inbound traffic has to route somewhere. |
Nothing fiscal. No certs. No invoices. No audit trail of submissions. The integrator keeps all of that on their side.
Why one account per integrator
There's no "org + tenant" hierarchy. Each integrator company (you) has one account. Your end-customers (RNC holders) are invisible to fiscaliacore — they stay inside your product and we only see transactions crossing the wire.
If your product serves 500 RNC holders, that's 500 concurrent signing sessions on our side during their active issuance windows — but zero accounts, zero organization-tenant rows, zero audit trails. Every transaction stands alone.
Consequences you can rely on
- A DB leak on our side costs you nothing fiscally signable. Our DB doesn't hold signing keys or invoices.
- A JVM restart on our side invalidates every active session. Clients handle this transparently via the 401-retry pattern.
- You are the book of record, always. If DGII audits, you have the signed XMLs + DGII TrackIDs; we have nothing to contribute.
- Contingency + retry logic lives in your product. If DGII is down, we return the error; you decide when to retry and when to give up.
- Your end-customers' compliance path stays inside your product. DGII's 15-step certification portal is something they walk through with your help — not ours.
When the model breaks
There are two places where perfect statelessness isn't achievable:
- Inbound routing. When DGII sends your end-customer an e-CF, we need to know where to forward it. That's the
receiver_registry— one row per receiver RNC, mapping to your callback URL. It's a small, static configuration, not per-transaction state. - API key auth. To bill you and rate-limit you, we need an account record for your integrator company. That lives in
platform_auth.*and has nothing to do with end-customers.
Everything else is per-request, in-memory, and evaporates when the request completes.
Further reading
- Refactor phase plan — how we get from where we are to the target.
- Session authentication — the bearer-token model in depth.
- Integration guide — concrete patterns for your client.