Webhooks
注册 Webhook
注册或更新接收开票结果等事件的回调 URL。
/openapi/v1/webhookstoken、timestamp、sign 三个签名头,参见认证与签名。每个应用只有一份回调配置:webHookId 即应用标识,再次调用会覆盖配置。它与控制台里编辑的是同一份配置:在这里注册还是在控制台保存,效果完全一致,后保存的覆盖先保存的;回调格式只由事件类型决定。连续投递失败触发熔断后,再次调用注册接口即可恢复投递。投递模型、验签与重试策略见 Webhooks。
请求体
id*更新时必填。 | string | Webhook 标识 |
uri* | string | 回调地址 |
contentType* | string | 回调正文格式 |
token* | string | 校验令牌 |
eventos | array | 订阅事件 |
* 必填字段
webHookId | string | Webhook 标识 |
平台向 uri 发起 POST,JSON 请求体(Content-Type: application/json; charset=utf-8)。10 秒内返回 HTTP 2xx 视为投递成功;其他响应按 1 分钟、5 分钟、30 分钟、2 小时、6 小时重试。连续失败 10 次会停用该 Webhook,再次调用本注册接口即恢复投递并清零计数。Node.js 与 Java 的验签示例见 Webhooks。
每次投递的请求头
按事件 id 去重,对原始请求体字节验签。
{"Content-Type": "application/json; charset=utf-8","X-Tffiscal-Event": "invoice.authorized","X-Tffiscal-Event-Id": "1950000000000001","X-Tffiscal-Delivery-Id": "1950000000000002","X-Tffiscal-Timestamp": "1758200000","X-Tffiscal-Signature": "9f2c...e1","token": "dGt6eXp5ZGRra2tzc3Nra2hoaGFha2tha2FhamFoaGFoNzc3Nz","x-token": "dGt6eXp5ZGRra2tzc3Nra2hoaGFha2tha2FhamFoaGFoNzc3Nz"}
X-Tffiscal-Event* | string | 事件编码 |
X-Tffiscal-Event-Id* | string | 事件 id |
X-Tffiscal-Delivery-Id* | string | 投递 id |
X-Tffiscal-Timestamp* | string | 签名时间戳 |
X-Tffiscal-Signature* | string | 签名 |
token*设置了令牌时。 | string | 校验令牌 |
x-token*设置了令牌时。 | string | 令牌副本 |
* 必填字段
载荷有两种格式。结果对象是无包装的 JSON 对象,首字段为 tipo(NF-e / NFC-e / CT-e / DC-e / NFS-e),各单据的授权、驳回、取消事件用它;它没有 event_id,请按请求头去重。统一事件体(version / event_id / event_type / occurred_at / data)用于 invoice.canceled、invoice.cce.registered、invoice.verify.completed、cte.event.registered、nfse.inbound.* 各事件与 email.sent / email.failed。无值的字段以 null 出现。
NF-e 结果对象
事件 invoice.authorized 与 invoice.rejected。驳回时链接、授权时间与协议号为空。
{"tipo": "NF-e","empresaId": "1934811222334455","nfeId": "NFe-000014553","nfeStatus": "Autorizada","nfeMotivoStatus": null,"nfeLinkDanfe": "https://api.v2.tffiscal.com/openapi/files/danfe/35241204893402000113650010000117691017244265?token=...","nfeLinkXml": "https://api.v2.tffiscal.com/openapi/files/xml/8801?token=...","nfeNumero": "11769","nfeSerie": "10","nfeChaveAcesso": "35241204893402000113650010000117691017244265","nfeDataEmissao": "2024-12-04T17:44:26Z","nfeDataAutorizacao": "2024-12-04T17:44:26Z","nfeNumeroProtocolo": "135240002599237","nfeDigestValue": null}
tipo* | string | 单据类型 |
empresaId* | string | 主体标识 |
nfeId* | string | 单据 id |
nfeStatus* | string | 结果状态 |
nfeMotivoStatus | string | 驳回原因 |
nfeLinkDanfe | string | DANFE 下载链接 |
nfeLinkXml | string | 授权 XML 下载链接 |
nfeNumero | string | 票号 |
nfeSerie | string | 系列号 |
nfeChaveAcesso | string | 访问密钥 |
nfeDataEmissao* | string | 开票时间 |
nfeDataAutorizacao | string | 授权时间 |
nfeNumeroProtocolo | string | 授权协议号 |
nfeDigestValue | string | 签名摘要 |
* 必填字段
NFS-e 结果对象
事件 nfse.authorized、nfse.rejected、nfse.canceled、nfse.cancel_requested、nfse.cancel_denied 与 nfse.substituted;各自的 nfseStatus 见枚举。
{"tipo": "NFS-e","empresaId": "1001","nfseId": "PED-20260918-001","nfseStatus": "Autorizada","nfseMotivoStatus": null,"nfseLinkDanfse": "https://api.v2.tffiscal.com/openapi/files/danfse/35503082406730610001340000000000000000000000000077?token=...","nfseLinkXml": "https://api.v2.tffiscal.com/openapi/files/xml/9001?token=...","nfseNumero": "1287","nfseSerie": "1","nfseChaveAcesso": "35503082406730610001340000000000000000000000000077","nfseIdentificacaoDps": "DPS355030824067306100013400001000000000000042","nfseDataEmissao": "2026-09-18T13:00:00Z","nfseDataAutorizacao": "2026-09-18T13:00:03Z","nfseNumeroProtocolo": null,"nfseAtualizadoEm": "2026-09-18T13:00:03Z"}
tipo* | string | 单据类型 |
empresaId* | string | 主体标识 |
nfseId* | string | 单据 id |
nfseStatus* | string | 结果状态 |
nfseMotivoStatus | string | 结论说明 |
nfseLinkDanfse | string | DANFSe 下载链接 |
nfseLinkXml | string | 官方 XML 下载链接 |
nfseNumero | string | 票号 |
nfseSerie | string | 系列号 |
nfseChaveAcesso | string | 访问密钥 |
nfseIdentificacaoDps | string | DPS 标识 |
nfseDataEmissao* | string | 开票时间 |
nfseDataAutorizacao | string | 授权时间 |
nfseNumeroProtocolo | string | 发行方协议号 |
nfseAtualizadoEm* | string | 本次状态变更时刻 |
nfseChaveSubstituta*仅 nfse.substituted。 | string | 替代票密钥 |
* 必填字段
CT-e 结果对象
事件 cte.authorized、cte.rejected 与 cte.canceled。平台侧终局失败不发回调,请用 CT-e 查询接口。
{"tipo": "CT-e","empresaId": "1934811222334455","cteId": "CTe-000000321","cteStatus": "Autorizada","cteMotivoStatus": null,"cteLinkDacte": "https://api.v2.tffiscal.com/openapi/files/dacte/35260940673061000134570010000003211000000321?token=...","cteLinkXml": "https://api.v2.tffiscal.com/openapi/files/xml/7701?token=...","cteNumero": "321","cteSerie": "1","cteChaveAcesso": "35260940673061000134570010000003211000000321","cteDataEmissao": "2026-09-06T12:00:00Z","cteDataAutorizacao": "2026-09-06T12:00:04Z","cteNumeroProtocolo": "135260000000321","cteDigestValue": "tasG40Ic6Zh7PIBiLEEH7Hb940Y="}
tipo* | string | 单据类型 |
empresaId* | string | 主体标识 |
cteId* | string | 单据 id |
cteStatus* | string | 结果状态 |
cteMotivoStatus | string | 驳回原因 |
cteLinkDacte | string | DACTE 下载链接 |
cteLinkXml | string | 授权 XML 下载链接 |
cteNumero | string | 单据号 |
cteSerie | string | 系列号 |
cteChaveAcesso | string | 访问密钥 |
cteDataEmissao* | string | 发行时间 |
cteDataAutorizacao | string | 授权时间 |
cteNumeroProtocolo | string | 授权协议号 |
cteDigestValue | string | 授权 XML 的签名摘要 |
* 必填字段
DC-e 结果对象
事件 dce.authorized、dce.rejected、dce.canceled 与 dce.cancel_rejected。编号前失败同样以 dce.rejected 到达,单据字段为 null。
{"tipo": "DC-e","empresaId": "1934811222334455","dceId": "DCe-000012333","dceStatus": "Autorizada","dceMotivoStatus": null,"dceLinkDace": "https://api.v2.tffiscal.com/openapi/files/dace/41260940673061000134990010000000011101234565?token=...","dceLinkXml": "https://api.v2.tffiscal.com/openapi/files/xml/7?token=...","dceNumero": "1","dceSerie": "1","dceChaveAcesso": "41260940673061000134990010000000011101234565","dceDataEmissao": "2026-09-06T12:00:00Z","dceDataAutorizacao": "2026-09-06T12:00:03Z","dceNumeroProtocolo": "141260000000001","dceDigestValue": "tasG40Ic6Zh7PIBiLEEH7Hb940Y="}
tipo* | string | 单据类型 |
empresaId* | string | 主体标识 |
dceId* | string | 单据 id |
dceStatus* | string | 结果状态 |
dceMotivoStatus | string | 结论说明 |
dceLinkDace | string | DACE 下载链接 |
dceLinkXml | string | 授权 XML 下载链接 |
dceNumero | string | 单据号 |
dceSerie | string | 系列号 |
dceChaveAcesso | string | 访问密钥 |
dceDataEmissao* | string | 发行时间 |
dceDataAutorizacao | string | 授权时间 |
dceNumeroProtocolo | string | 协议号 |
dceDigestValue | string | 授权 XML 的签名摘要 |
* 必填字段
统一事件体
以 invoice.canceled 为例:data 含 invoice_id、chave、protocolo。cte.event.registered 的 data 含 event_code、n_seq、protocolo;invoice.cce.registered(预留,暂不推送)含 invoice_id、chave、n_seq。
{"version": "1.0","event_id": "1950000000000001","event_type": "invoice.canceled","occurred_at": "2026-09-06T13:00:00Z","data": {"invoice_id": "1934811222330001","chave": "35241204893402000113650010000117691017244265","protocolo": "135260000000099"}}
version* | string | 统一事件体的版本 |
event_id* | string | 事件 id |
event_type* | string | 事件编码 |
occurred_at* | string | 事件时间 |
data* | object | 事件数据 |
* 必填字段
进项 NFS-e 的 data
nfse.inbound.received、nfse.inbound.canceled、nfse.inbound.substituted 需显式订阅。三者都带 inbound_id、chave、prestador_doc;示例为到达事件。
{"version": "1.0","event_id": "1950000000000003","event_type": "nfse.inbound.received","occurred_at": "2026-09-21T12:15:41Z","data": {"inbound_id": "1950000000000777","chave": "35095022112223330001810000100000000000007710001234","prestador_doc": "40673061000134","n_nfse": "77","valor_servico": "1000.00","competencia": "2026-09-01"}}
inbound_id* | string | 进项票平台 id |
chave* | string | 访问密钥 |
prestador_doc* | string | 开票方证件号 |
n_nfse*仅 nfse.inbound.received。 | string | 票号 |
valor_servico*仅 nfse.inbound.received。 | string | 服务金额 |
competencia*仅 nfse.inbound.received。 | string | 服务归属月 |
evento*仅 nfse.inbound.canceled。 | string | 取消事件官方码 |
chave_substituta*仅 nfse.inbound.substituted。 | string | 替代票密钥 |
* 必填字段
表态结果的 data
nfse.inbound.manifested 表示表态已登记;nfse.inbound.manifest_failed 表示任务失败,请在默示确认期限前重新表态。两者都需显式订阅;示例为成功事件。
{"version": "1.0","event_id": "1950000000000004","event_type": "nfse.inbound.manifested","occurred_at": "2026-09-21T14:00:05Z","data": {"inbound_id": "1950000000000777","chave": "35095022112223330001810000100000000000007710001234","tipo": "Rejeicao","evento": "203206","codigo_motivo": "3","motivo": "Servico nao prestado ao tomador","protocolo": "3550308000000000000000000000000000000000000000000001"}}
inbound_id*仅 nfse.inbound.manifested。 | string | 进项票平台 id |
chave* | string | 访问密钥 |
tipo* | string | 表态类型 |
evento*仅 nfse.inbound.manifested。 | string | 登记的事件官方码 |
codigo_motivo*仅 nfse.inbound.manifested。 | string | 拒绝原因码 |
motivo* | string | 原因说明 |
protocolo*仅 nfse.inbound.manifested。 | string | 发行方登记号 |
codigo*仅 nfse.inbound.manifest_failed。 | string | 失败码 |
* 必填字段
验证结论的 data
invoice.verify.completed 是 NF-e 验证最终结论的唯一推送通道,按密钥查询可作兜底。
{"version": "1.0","event_id": "1950000000000005","event_type": "invoice.verify.completed","occurred_at": "2026-07-23T17:16:23Z","data": {"chaveAcesso": "35260764962869000108550990001366171195929648","validationStatus": "VALIDATED","status": "Autorizada","cStat": "100","xMotivo": "Autorizado o uso da NF-e","protocolo": { "numero": "135262955451772", "digestValue": "oAEE...HwY=" },"dataAutorizacao": "2026-07-23T14:30:09Z","eventos": [],"verifiedAt": "2026-07-23T17:16:23Z"}}
chaveAcesso* | string | 被验证发票密钥 |
validationStatus* | string | 最终结论 |
status* | string | SEFAZ 税务状态 |
cStat | string | SEFAZ 返回码 |
xMotivo | string | SEFAZ 返回说明 |
protocolo | object | 官方协议 |
dataAutorizacao | string | SEFAZ 授权时间 |
eventos* | array | 已登记税务事件 |
verifiedAt* | string | 核验完成时间 |
reason*仅 REJECTED / VALIDATION_ERROR。 | string | 结论说明 |
* 必填字段
发票邮件结果的 data
email.sent 表示发信服务已接收;email.failed 表示邮件终态失败(等待超时、重试用尽、票已不再授权)。两者都需显式订阅,收到任一即可对同一张票再次发送;示例为成功事件。见发票邮件。
{"version": "1.0","event_id": "1950000000000006","event_type": "email.sent","occurred_at": "2026-09-28T12:00:31Z","data": {"email_id": "2103160000000000001","id": "email-pedido-8842-1","tipo_documento": "NFe","documento_id": "pedido-8842","chave": "35241204893402000113650010000117691017244265","destinatarios": ["comprador@exemplo.com"],"status": "Enviado","motivo_falha": null}}
email_id* | string | 邮件标识 |
id* | string | 请求标识 |
tipo_documento* | string | 发票类型 |
documento_id* | string | 单据标识 |
chave | string | 访问密钥 |
destinatarios* | array | 实际收件邮箱 |
status* | string | 结果状态 |
motivo_falha | string | 失败原因 |
* 必填字段
eventos[]事件编码
不传只订 invoice.authorized 与 invoice.rejected。NFC-e 不在缺省订阅里,要收 NFC-e 回调必须显式列出 nfce.* 事件。nfse.inbound.* 与 email.* 只投递给在此列出它们的应用。
| 取值 | 含义 |
|---|---|
| invoice.authorized | NF-e 被 SEFAZ 授权;结果对象,nfeStatus = Autorizada |
| invoice.rejected | NF-e 被 SEFAZ 驳回;nfeStatus = Negada,原因在 nfeMotivoStatus |
| invoice.canceled | NF-e 取消在 SEFAZ 登记完成;统一事件体,data 含 invoice_id、chave、protocolo |
| invoice.cce.registered | NF-e 更正函登记完成;预留,目前不推送 |
| invoice.verify.completed | NF-e 验证得出最终结论;统一事件体,data 含 validationStatus |
| cte.authorized | CT-e 授权通过;cteStatus = Autorizada |
| cte.rejected | CT-e 被 SEFAZ 驳回;cteStatus = Negada |
| cte.canceled | CT-e 取消登记完成;cteStatus = Cancelada |
| cte.event.registered | CT-e 其他事件登记成功(更正函、送达凭证、服务异议);统一事件体,data 含 event_code、n_seq、protocolo |
| dce.authorized | DC-e 授权通过;dceStatus = Autorizada |
| dce.rejected | DC-e 被 SEFAZ 驳回或发行终局失败;dceStatus = Negada |
| dce.canceled | DC-e 取消登记成功;dceStatus = Cancelada |
| dce.cancel_rejected | DC-e 取消被 SEFAZ 拒绝或取消任务终局失败;dceStatus = CancelamentoNegado,单据仍已授权 |
| nfce.authorized | NFC-e 授权通过,含离线票补传后授权;结果对象,tipo = NFC-e,nfeStatus = Autorizada |
| nfce.rejected | NFC-e 被 SEFAZ 驳回或平台侧失败,含离线票补传被拒;nfeStatus = Negada |
| nfce.canceled | NFC-e 取消登记成功,含替代取消;nfeStatus = Cancelada |
| nfce.cancel_rejected | NFC-e 取消被 SEFAZ 拒绝;nfeStatus = CancelamentoNegado,票仍已授权 |
| nfce.contingency_issued | SEFAZ 不可用时 NFC-e 已离线开出;nfeStatus = ContingenciaPendente,补传后再推 nfce.authorized 或 nfce.rejected |
| nfse.authorized | NFS-e 发行成功;nfseStatus = Autorizada |
| nfse.rejected | NFS-e 被发行方驳回或平台侧失败;nfseStatus = Negada |
| nfse.canceled | NFS-e 取消完成,含分析准予;nfseStatus = Cancelada |
| nfse.cancel_requested | NFS-e 取消分析申请已受理;nfseStatus = EmProcessoDeCancelamento |
| nfse.cancel_denied | NFS-e 取消未成功,票仍已授权:同步拒绝、重试耗尽或分析驳回;nfseStatus = Autorizada |
| nfse.substituted | NFS-e 被替代票取代;nfseStatus = Substituida,多一个 nfseChaveSubstituta |
| nfse.inbound.received | 进项 NFS-e 到达,本主体为接收方或中介方;统一事件体,需显式订阅 |
| nfse.inbound.canceled | 进项 NFS-e 被取消;统一事件体,需显式订阅 |
| nfse.inbound.substituted | 进项 NFS-e 被替代;统一事件体,需显式订阅 |
| nfse.inbound.manifested | 本主体表态登记成功,确认与拒绝都推;统一事件体,需显式订阅 |
| nfse.inbound.manifest_failed | 本主体表态登记失败;请在默示确认前重试;统一事件体,需显式订阅 |
| email.sent | 发票邮件已交发信服务;统一事件体,data.status = Enviado,需显式订阅 |
| email.failed | 发票邮件终态失败;统一事件体,data.status = Falha,原因在 data.motivo_falha,需显式订阅 |
nfeStatusNF-e 结果状态
| 取值 | 含义 |
|---|---|
| Autorizada | SEFAZ 已授权 |
| Negada | SEFAZ 驳回 |
nfseStatusNFS-e 结果状态
| 取值 | 含义 |
|---|---|
| Autorizada | 发行成功(nfse.authorized)或取消被拒(nfse.cancel_denied) |
| Negada | 驳回或平台侧失败(nfse.rejected) |
| Cancelada | 已取消(nfse.canceled) |
| EmProcessoDeCancelamento | 取消分析申请中(nfse.cancel_requested) |
| Substituida | 已被替代(nfse.substituted) |
cteStatusCT-e 结果状态
| 取值 | 含义 |
|---|---|
| Autorizada | 已授权(cte.authorized) |
| Negada | SEFAZ 驳回(cte.rejected) |
| Cancelada | 已取消(cte.canceled) |
dceStatusDC-e 结果状态
| 取值 | 含义 |
|---|---|
| Autorizada | 已授权(dce.authorized) |
| Negada | 驳回或发行终局失败(dce.rejected) |
| Cancelada | 已取消(dce.canceled) |
| CancelamentoNegado | 取消被拒,单据仍已授权(dce.cancel_rejected) |
data.validationStatus验证结论
| 取值 | 含义 |
|---|---|
| VALIDATED | 发票有效,可放行 |
| REJECTED | SEFAZ 判定发票无效,reason 说明原因 |
| VALIDATION_ERROR | 平台侧核验失败,不是对发票的判定;带 forceRevalidate 重新提交 |
data.status发票邮件结果
| 取值 | 含义 |
|---|---|
| Enviado | 已交发信服务(email.sent);该票可再次发送 |
| Falha | 终态失败(email.failed);motivo_falha 说明原因,该票可再次发送 |
| 错误码 | HTTP | |
|---|---|---|
| 10009033 | 400 | 注册无效:id 不属于当前应用、contentType 不是 application/json 或 eventos 含未知编码;消息指明是哪一项。 |
| 10001001 | 400 | 字段校验失败:uri 或 token 为空或超长,token 含可见 ASCII 以外的字符(空格、重音字母、换行等),eventos 含空白项或超过 64 项。 |
