Parsed SEFAZ business outcome. A SOAP envelope that we understood is
{:ok, t} even when c_stat != 100 — that is a rejection, not a crash.
The two XML fields
:signed_xml is what was actually sent to SEFAZ, always present after an
authorization attempt. :xml is the nfeProc — the signed document plus its
protocol — and is only set once a protocol exists. The nfeProc is the
document that has to be archived and delivered to the recipient, so losing
either of them loses something legally required: without the protocol there
is nothing to prove, and without the signed bytes the protocol cannot be
attached to anything later.
A batch answer wraps the real outcome one level down — protNFe/infProt for a
document, retEvento/infEvento for an event — so parse/1 reads the nested
cStat when there is one and the envelope's otherwise. 150 is 100 with
the authorization recorded outside the deadline, 135 and 136 are the
event equivalents, and 102 is the one for a voided number range, so all
five are :authorized.
Summary
Types
@type status() ::
:authorized | :batch_received | :batch_processed | :processing | :rejected
Functions
Maps a SEFAZ SOAP body to t/0.
A body we could read is {:ok, t} even when cStat is a rejection: 204
(duplicate) is a business outcome, not a transport failure (SEFAZ-03). Only an
unreadable body or a SOAP fault is {:error, _}.
The cStat values mapped to a status are the ones the MOC defines for these
flows — 100 authorized, 103 lote received, 104 lote processed, 105 in
processing. Everything else is :rejected with the raw code preserved; this
library does not ship a cStat dictionary it would have to chase.
Assembles the nfeProc from a signed document and the SEFAZ response.
Both halves are spliced verbatim: the signature covers the document exactly
as it was sent, and the protocol is SEFAZ's own bytes. Returns nil when the
answer carries no protocol, which is the normal case for a receipt or a
rejection.