Exemplos de Integracao
Exemplos completos para integrar com a API Axiom NFe. Escolha sua linguagem e copie o codigo.
Listar empresas cadastradas
GET
/empresas
Retorna todas as empresas (CNPJs) cadastradas na sua conta.
curl
Node.js
Python
PHP
Copiar
curl -u "nfe_SuaApiKeyAqui:" \
https://southamerica-east1-axiom-nfe.cloudfunctions.net/api/empresas
const API_KEY = 'nfe_SuaApiKeyAqui' ;
const BASE_URL = 'https://southamerica-east1-axiom-nfe.cloudfunctions.net/api' ;
const response = await fetch (`${BASE_URL}/empresas` , {
headers: {
'Authorization' : 'Basic ' + btoa(`${API_KEY}:` )
}
});
const { empresas } = await response.json ();
console.log (empresas);
import requests
API_KEY = "nfe_SuaApiKeyAqui"
BASE_URL = "https://southamerica-east1-axiom-nfe.cloudfunctions.net/api"
response = requests.get (
f"{BASE_URL} /empresas" ,
auth=(API_KEY, "" )
)
empresas = response.json ()
print (empresas)
<?php
$apiKey = "nfe_SuaApiKeyAqui" ;
$baseUrl = "https://southamerica-east1-axiom-nfe.cloudfunctions.net/api" ;
$ch = curl_init ("{$baseUrl} /empresas" );
curl_setopt_array ($ch , [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_USERPWD => "{$apiKey} :"
]);
$response = curl_exec ($ch );
curl_close ($ch );
$data = json_decode ($response , true );
print_r ($data );
Emitir NF-e (modelo 55)
POST
/nfe/emitir
Emite uma NF-e com processamento assincrono. Envie o header X-Empresa-Id com o ID da empresa emitente.
curl
Node.js
Python
PHP
Copiar
curl -X POST -u "nfe_SuaApiKeyAqui:" \
-H "Content-Type: application/json" \
-H "X-Empresa-Id: abc123" \
-d '{
"ide": { "natOp": "VENDA", "indPag": 0 },
"dest": {
"CNPJ": "11222333000181",
"xNome": "EMPRESA TESTE LTDA",
"endereco": {
"xLgr": "Rua Teste", "nro": "100",
"xBairro": "Centro", "cMun": "4314902",
"xMun": "Porto Alegre", "UF": "RS", "CEP": "90000000"
},
"indIEDest": 1,
"IE": "1234567890"
},
"produtos": [{
"cProd": "001",
"xProd": "PRODUTO TESTE",
"NCM": "61091000",
"CFOP": "5102",
"uCom": "UN",
"qCom": 2,
"vUnCom": 50.00,
"vProd": 100.00,
"icms": { "orig": 0, "CST": "00", "modBC": 3, "vBC": 100.00, "pICMS": 18, "vICMS": 18.00 },
"pis": { "CST": "01", "vBC": 100.00, "pPIS": 1.65, "vPIS": 1.65 },
"cofins": { "CST": "01", "vBC": 100.00, "pCOFINS": 7.60, "vCOFINS": 7.60 }
}],
"pagamentos": [{ "tPag": "01", "vPag": 100.00 }]
}' \
https://southamerica-east1-axiom-nfe.cloudfunctions.net/api/nfe/emitir
const API_KEY = 'nfe_SuaApiKeyAqui' ;
const BASE_URL = 'https://southamerica-east1-axiom-nfe.cloudfunctions.net/api' ;
const EMPRESA_ID = 'abc123' ;
const nfe = {
ide: { natOp: 'VENDA' , indPag: 0 },
dest: {
CNPJ: '11222333000181' ,
xNome: 'EMPRESA TESTE LTDA' ,
endereco: {
xLgr: 'Rua Teste' , nro: '100' ,
xBairro: 'Centro' , cMun: '4314902' ,
xMun: 'Porto Alegre' , UF: 'RS' , CEP: '90000000'
},
indIEDest: 1 ,
IE: '1234567890'
},
produtos: [{
cProd: '001' ,
xProd: 'PRODUTO TESTE' ,
NCM: '61091000' ,
CFOP: '5102' ,
uCom: 'UN' ,
qCom: 2 ,
vUnCom: 50.00 ,
vProd: 100.00 ,
icms: { orig: 0 , CST: '00' , modBC: 3 , vBC: 100.00 , pICMS: 18 , vICMS: 18.00 },
pis: { CST: '01' , vBC: 100.00 , pPIS: 1.65 , vPIS: 1.65 },
cofins: { CST: '01' , vBC: 100.00 , pCOFINS: 7.60 , vCOFINS: 7.60 }
}],
pagamentos: [{ tPag: '01' , vPag: 100.00 }]
};
const response = await fetch (`${BASE_URL}/nfe/emitir` , {
method: 'POST' ,
headers: {
'Authorization' : 'Basic ' + btoa(`${API_KEY}:` ),
'Content-Type' : 'application/json' ,
'X-Empresa-Id' : EMPRESA_ID
},
body: JSON.stringify (nfe)
});
const result = await response.json ();
console.log (result.chaveAcesso);
console.log (result.status);
import requests
API_KEY = "nfe_SuaApiKeyAqui"
BASE_URL = "https://southamerica-east1-axiom-nfe.cloudfunctions.net/api"
EMPRESA_ID = "abc123"
nfe = {
"ide" : { "natOp" : "VENDA" , "indPag" : 0 },
"dest" : {
"CNPJ" : "11222333000181" ,
"xNome" : "EMPRESA TESTE LTDA" ,
"endereco" : {
"xLgr" : "Rua Teste" , "nro" : "100" ,
"xBairro" : "Centro" , "cMun" : "4314902" ,
"xMun" : "Porto Alegre" , "UF" : "RS" , "CEP" : "90000000"
},
"indIEDest" : 1 ,
"IE" : "1234567890"
},
"produtos" : [{
"cProd" : "001" ,
"xProd" : "PRODUTO TESTE" ,
"NCM" : "61091000" ,
"CFOP" : "5102" ,
"uCom" : "UN" ,
"qCom" : 2 ,
"vUnCom" : 50.00 ,
"vProd" : 100.00 ,
"icms" : { "orig" : 0 , "CST" : "00" , "modBC" : 3 , "vBC" : 100.00 , "pICMS" : 18 , "vICMS" : 18.00 },
"pis" : { "CST" : "01" , "vBC" : 100.00 , "pPIS" : 1.65 , "vPIS" : 1.65 },
"cofins" : { "CST" : "01" , "vBC" : 100.00 , "pCOFINS" : 7.60 , "vCOFINS" : 7.60 }
}],
"pagamentos" : [{ "tPag" : "01" , "vPag" : 100.00 }]
}
response = requests.post (
f"{BASE_URL} /nfe/emitir" ,
json=nfe,
auth=(API_KEY, "" ),
headers={"X-Empresa-Id" : EMPRESA_ID}
)
result = response.json ()
print (result["chaveAcesso" ])
print (result["status" ])
<?php
$apiKey = "nfe_SuaApiKeyAqui" ;
$baseUrl = "https://southamerica-east1-axiom-nfe.cloudfunctions.net/api" ;
$empresaId = "abc123" ;
$nfe = [
"ide" => ["natOp" => "VENDA" , "indPag" => 0 ],
"dest" => [
"CNPJ" => "11222333000181" ,
"xNome" => "EMPRESA TESTE LTDA" ,
"endereco" => [
"xLgr" => "Rua Teste" , "nro" => "100" ,
"xBairro" => "Centro" , "cMun" => "4314902" ,
"xMun" => "Porto Alegre" , "UF" => "RS" , "CEP" => "90000000"
],
"indIEDest" => 1 ,
"IE" => "1234567890"
],
"produtos" => [[
"cProd" => "001" ,
"xProd" => "PRODUTO TESTE" ,
"NCM" => "61091000" ,
"CFOP" => "5102" ,
"uCom" => "UN" ,
"qCom" => 2 ,
"vUnCom" => 50.00 ,
"vProd" => 100.00 ,
"icms" => ["orig" => 0 , "CST" => "00" , "modBC" => 3 , "vBC" => 100.00 , "pICMS" => 18 , "vICMS" => 18.00 ],
"pis" => ["CST" => "01" , "vBC" => 100.00 , "pPIS" => 1.65 , "vPIS" => 1.65 ],
"cofins" => ["CST" => "01" , "vBC" => 100.00 , "pCOFINS" => 7.60 , "vCOFINS" => 7.60 ]
]],
"pagamentos" => [["tPag" => "01" , "vPag" => 100.00 ]]
];
$ch = curl_init ("{$baseUrl} /nfe/emitir" );
curl_setopt_array ($ch , [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_USERPWD => "{$apiKey} :" ,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json" ,
"X-Empresa-Id: {$empresaId} "
],
CURLOPT_POSTFIELDS => json_encode ($nfe )
]);
$response = curl_exec ($ch );
curl_close ($ch );
$result = json_decode ($response , true );
echo $result ["chaveAcesso" ];
echo $result ["status" ];
Resposta (200 - Autorizado)
{
"message" : "NF-e authorized" ,
"chaveAcesso" : "35260212345678000195550010000000011234567890" ,
"protocolo" : {
"nProt" : "135260000001234" ,
"dhRecbto" : "2026-02-15T10:30:00-03:00" ,
"cStat" : "100" ,
"xMotivo" : "Autorizado o uso da NF-e"
},
"status" : "authorized"
}
Consultar nota por chave
GET
/nfe/:chaveAcesso
Consulta os detalhes de uma NF-e pela chave de acesso (44 digitos).
curl
Node.js
Python
PHP
Copiar
CHAVE ="35260212345678000195550010000000011234567890"
curl -u "nfe_SuaApiKeyAqui:" \
https://southamerica-east1-axiom-nfe.cloudfunctions.net/api/nfe/${CHAVE}
const chave = '35260212345678000195550010000000011234567890' ;
const response = await fetch (`${BASE_URL}/nfe/${chave}` , {
headers: {
'Authorization' : 'Basic ' + btoa(`${API_KEY}:` )
}
});
const nfe = await response.json ();
console.log (nfe.status);
console.log (nfe.protocolo);
chave = "35260212345678000195550010000000011234567890"
response = requests.get (
f"{BASE_URL} /nfe/{chave} " ,
auth=(API_KEY, "" )
)
nfe = response.json ()
print (nfe["status" ])
print (nfe["protocolo" ])
$chave = "35260212345678000195550010000000011234567890" ;
$ch = curl_init ("{$baseUrl} /nfe/{$chave} " );
curl_setopt_array ($ch , [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_USERPWD => "{$apiKey} :"
]);
$response = curl_exec ($ch );
curl_close ($ch );
$nfe = json_decode ($response , true );
echo $nfe ["status" ];
print_r ($nfe ["protocolo" ]);
Download XML autorizado
GET
/xml/:chaveAcesso
Retorna o XML autorizado (nfeProc) para download. Obrigatorio guardar por 5 anos.
curl
Node.js
Python
PHP
Copiar
CHAVE ="35260212345678000195550010000000011234567890"
curl -u "nfe_SuaApiKeyAqui:" \
-o "nfe_${CHAVE}.xml" \
https://southamerica-east1-axiom-nfe.cloudfunctions.net/api/xml/${CHAVE}
const chave = '35260212345678000195550010000000011234567890' ;
const response = await fetch (`${BASE_URL}/xml/${chave}` , {
headers: {
'Authorization' : 'Basic ' + btoa(`${API_KEY}:` )
}
});
const xml = await response.text ();
import { writeFileSync } from 'fs' ;
writeFileSync (`nfe_${chave}.xml` , xml);
chave = "35260212345678000195550010000000011234567890"
response = requests.get (
f"{BASE_URL} /xml/{chave} " ,
auth=(API_KEY, "" )
)
with open (f"nfe_{chave} .xml" , "w" ) as f:
f.write (response.text)
$chave = "35260212345678000195550010000000011234567890" ;
$ch = curl_init ("{$baseUrl} /xml/{$chave} " );
curl_setopt_array ($ch , [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_USERPWD => "{$apiKey} :"
]);
$xml = curl_exec ($ch );
curl_close ($ch );
file_put_contents ("nfe_{$chave} .xml" , $xml );
Download DANFE (PDF)
GET
/danfe/:chaveAcesso
Retorna o PDF do DANFE. NF-e gera A4, NFC-e gera formato termico 80mm. Use /danfe/:chave/download para forcar download.
curl
Node.js
Python
PHP
Copiar
CHAVE ="35260212345678000195550010000000011234567890"
curl -u "nfe_SuaApiKeyAqui:" \
-o "danfe_${CHAVE}.pdf" \
https://southamerica-east1-axiom-nfe.cloudfunctions.net/api/danfe/${CHAVE}
curl -u "nfe_SuaApiKeyAqui:" \
-o "danfe_${CHAVE}.pdf" \
https://southamerica-east1-axiom-nfe.cloudfunctions.net/api/danfe/${CHAVE}/download
const chave = '35260212345678000195550010000000011234567890' ;
const response = await fetch (`${BASE_URL}/danfe/${chave}` , {
headers: {
'Authorization' : 'Basic ' + btoa(`${API_KEY}:` )
}
});
const pdfBuffer = await response.arrayBuffer ();
import { writeFileSync } from 'fs' ;
writeFileSync (`danfe_${chave}.pdf` , Buffer.from (pdfBuffer));
chave = "35260212345678000195550010000000011234567890"
response = requests.get (
f"{BASE_URL} /danfe/{chave} " ,
auth=(API_KEY, "" )
)
with open (f"danfe_{chave} .pdf" , "wb" ) as f:
f.write (response.content)
$chave = "35260212345678000195550010000000011234567890" ;
$ch = curl_init ("{$baseUrl} /danfe/{$chave} " );
curl_setopt_array ($ch , [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_USERPWD => "{$apiKey} :"
]);
$pdf = curl_exec ($ch );
curl_close ($ch );
file_put_contents ("danfe_{$chave} .pdf" , $pdf );
Cancelar nota
POST
/eventos/cancelar
Cancela uma NF-e ou NFC-e autorizada. Permitido ate 24 horas apos a autorizacao. Justificativa minima de 15 caracteres.
curl
Node.js
Python
PHP
Copiar
curl -X POST -u "nfe_SuaApiKeyAqui:" \
-H "Content-Type: application/json" \
-H "X-Empresa-Id: abc123" \
-d '{
"chaveAcesso": "35260212345678000195550010000000011234567890",
"justificativa": "Erro no cadastro do destinatario da nota fiscal"
}' \
https://southamerica-east1-axiom-nfe.cloudfunctions.net/api/eventos/cancelar
const response = await fetch (`${BASE_URL}/eventos/cancelar` , {
method: 'POST' ,
headers: {
'Authorization' : 'Basic ' + btoa(`${API_KEY}:` ),
'Content-Type' : 'application/json' ,
'X-Empresa-Id' : 'abc123'
},
body: JSON.stringify ({
chaveAcesso: '35260212345678000195550010000000011234567890' ,
justificativa: 'Erro no cadastro do destinatario da nota fiscal'
})
});
const result = await response.json ();
console.log (result.status);
response = requests.post (
f"{BASE_URL} /eventos/cancelar" ,
json={
"chaveAcesso" : "35260212345678000195550010000000011234567890" ,
"justificativa" : "Erro no cadastro do destinatario da nota fiscal"
},
auth=(API_KEY, "" ),
headers={"X-Empresa-Id" : "abc123" }
)
result = response.json ()
print (result["status" ])
$cancel = [
"chaveAcesso" => "35260212345678000195550010000000011234567890" ,
"justificativa" => "Erro no cadastro do destinatario da nota fiscal"
];
$ch = curl_init ("{$baseUrl} /eventos/cancelar" );
curl_setopt_array ($ch , [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_USERPWD => "{$apiKey} :" ,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json" ,
"X-Empresa-Id: abc123"
],
CURLOPT_POSTFIELDS => json_encode ($cancel )
]);
$response = curl_exec ($ch );
curl_close ($ch );
$result = json_decode ($response , true );
echo $result ["status" ];
Resposta (200 - Cancelado)
{
"message" : "Cancellation approved" ,
"chaveAcesso" : "35260212345678000195550010000000011234567890" ,
"protocolo" : "135260000005678" ,
"status" : "cancelled"
}
Emitir NFC-e (PDV)
POST
/nfce/emitir
Emite uma NFC-e (modelo 65) com processamento sincrono. Ideal para PDV. Requer CSC configurado. Destinatario opcional abaixo de R$ 200.
curl
Node.js
Python
PHP
Copiar
curl -X POST -u "nfe_SuaApiKeyAqui:" \
-H "Content-Type: application/json" \
-H "X-Empresa-Id: abc123" \
-d '{
"produtos": [{
"cProd": "7891234560012",
"xProd": "CAMISETA ALGODAO P",
"NCM": "61091000",
"CFOP": "5102",
"uCom": "UN",
"qCom": 1,
"vUnCom": 59.90,
"vProd": 59.90,
"icms": { "orig": 0, "CSOSN": "102" },
"pis": { "CST": "49" },
"cofins": { "CST": "49" }
}],
"pagamentos": [{ "tPag": "17", "vPag": 59.90 }]
}' \
https://southamerica-east1-axiom-nfe.cloudfunctions.net/api/nfce/emitir
const nfce = {
produtos: [{
cProd: '7891234560012' ,
xProd: 'CAMISETA ALGODAO P' ,
NCM: '61091000' ,
CFOP: '5102' ,
uCom: 'UN' ,
qCom: 1 ,
vUnCom: 59.90 ,
vProd: 59.90 ,
icms: { orig: 0 , CSOSN: '102' },
pis: { CST: '49' },
cofins: { CST: '49' }
}],
pagamentos: [{ tPag: '17' , vPag: 59.90 }]
};
const response = await fetch (`${BASE_URL}/nfce/emitir` , {
method: 'POST' ,
headers: {
'Authorization' : 'Basic ' + btoa(`${API_KEY}:` ),
'Content-Type' : 'application/json' ,
'X-Empresa-Id' : EMPRESA_ID
},
body: JSON.stringify (nfce)
});
const result = await response.json ();
console.log (result.chaveAcesso);
console.log (result.qrCodeUrl);
nfce = {
"produtos" : [{
"cProd" : "7891234560012" ,
"xProd" : "CAMISETA ALGODAO P" ,
"NCM" : "61091000" ,
"CFOP" : "5102" ,
"uCom" : "UN" ,
"qCom" : 1 ,
"vUnCom" : 59.90 ,
"vProd" : 59.90 ,
"icms" : { "orig" : 0 , "CSOSN" : "102" },
"pis" : { "CST" : "49" },
"cofins" : { "CST" : "49" }
}],
"pagamentos" : [{ "tPag" : "17" , "vPag" : 59.90 }]
}
response = requests.post (
f"{BASE_URL} /nfce/emitir" ,
json=nfce,
auth=(API_KEY, "" ),
headers={"X-Empresa-Id" : EMPRESA_ID}
)
result = response.json ()
print (result["chaveAcesso" ])
print (result["qrCodeUrl" ])
$nfce = [
"produtos" => [[
"cProd" => "7891234560012" ,
"xProd" => "CAMISETA ALGODAO P" ,
"NCM" => "61091000" ,
"CFOP" => "5102" ,
"uCom" => "UN" ,
"qCom" => 1 ,
"vUnCom" => 59.90 ,
"vProd" => 59.90 ,
"icms" => ["orig" => 0 , "CSOSN" => "102" ],
"pis" => ["CST" => "49" ],
"cofins" => ["CST" => "49" ]
]],
"pagamentos" => [["tPag" => "17" , "vPag" => 59.90 ]]
];
$ch = curl_init ("{$baseUrl} /nfce/emitir" );
curl_setopt_array ($ch , [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_USERPWD => "{$apiKey} :" ,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json" ,
"X-Empresa-Id: abc123"
],
CURLOPT_POSTFIELDS => json_encode ($nfce )
]);
$response = curl_exec ($ch );
curl_close ($ch );
$result = json_decode ($response , true );
echo $result ["chaveAcesso" ];
echo $result ["qrCodeUrl" ];
Resposta (200 - NFC-e Autorizada)
{
"message" : "NFC-e authorized" ,
"chaveAcesso" : "35260212345678000195650010000000021234567891" ,
"status" : "authorized" ,
"protocolo" : {
"nProt" : "135260000009876" ,
"dhRecbto" : "2026-03-06T14:22:00-03:00"
},
"qrCodeUrl" : "https://www.sefaz.rs.gov.br/NFCE/NFCE-COM.aspx?p=..."
}
Registrar webhook
POST
/webhooks
Registra uma URL para receber callbacks em tempo real. Cada callback inclui assinatura HMAC-SHA256 para verificacao.
curl
Node.js
Python
PHP
Copiar
curl -X POST -u "nfe_SuaApiKeyAqui:" \
-H "Content-Type: application/json" \
-H "X-Empresa-Id: abc123" \
-d '{
"url": "https://meusite.com/webhook/nfe",
"events": ["nfe.authorized", "nfe.rejected", "evento.cancelamento"],
"secret": "meu-secret-hmac-256"
}' \
https://southamerica-east1-axiom-nfe.cloudfunctions.net/api/webhooks
const response = await fetch (`${BASE_URL}/webhooks` , {
method: 'POST' ,
headers: {
'Authorization' : 'Basic ' + btoa(`${API_KEY}:` ),
'Content-Type' : 'application/json' ,
'X-Empresa-Id' : 'abc123'
},
body: JSON.stringify ({
url: 'https://meusite.com/webhook/nfe' ,
events: ['nfe.authorized' , 'nfe.rejected' , 'evento.cancelamento' ],
secret: 'meu-secret-hmac-256'
})
});
const result = await response.json ();
console.log (result.webhookId);
response = requests.post (
f"{BASE_URL} /webhooks" ,
json={
"url" : "https://meusite.com/webhook/nfe" ,
"events" : ["nfe.authorized" , "nfe.rejected" , "evento.cancelamento" ],
"secret" : "meu-secret-hmac-256"
},
auth=(API_KEY, "" ),
headers={"X-Empresa-Id" : "abc123" }
)
result = response.json ()
print (result["webhookId" ])
$webhook = [
"url" => "https://meusite.com/webhook/nfe" ,
"events" => ["nfe.authorized" , "nfe.rejected" , "evento.cancelamento" ],
"secret" => "meu-secret-hmac-256"
];
$ch = curl_init ("{$baseUrl} /webhooks" );
curl_setopt_array ($ch , [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_USERPWD => "{$apiKey} :" ,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json" ,
"X-Empresa-Id: abc123"
],
CURLOPT_POSTFIELDS => json_encode ($webhook )
]);
$response = curl_exec ($ch );
curl_close ($ch );
$result = json_decode ($response , true );
echo $result ["webhookId" ];
Resposta (201 - Webhook Registrado)
{
"webhookId" : "wh_abc123def456" ,
"url" : "https://meusite.com/webhook/nfe" ,
"events" : ["nfe.authorized" , "nfe.rejected" , "evento.cancelamento" ],
"message" : "Webhook registered"
}
Verificar assinatura do webhook
Quando voce configura um secret, cada callback inclui os headers X-Axiom-Signature e X-Axiom-Timestamp. Use HMAC-SHA256 para verificar a autenticidade.
Node.js
Python
PHP
Copiar
import crypto from 'crypto' ;
function verifyWebhookSignature (req, secret) {
const signature = req.headers['x-axiom-signature' ];
const timestamp = req.headers['x-axiom-timestamp' ];
const body = JSON.stringify (req.body);
const expected = crypto
.createHmac ('sha256' , secret)
.update (`${timestamp}.${body}` )
.digest ('hex' );
return signature === `sha256=${expected}` ;
}
app.post ('/webhook/nfe' , (req, res) => {
const valid = verifyWebhookSignature (req, 'meu-secret-hmac-256' );
if (!valid) {
return res.status (401 ).json ({ error: 'Invalid signature' });
}
const { event, data } = req.body;
console.log (`Evento: ${event}` , data);
res.status (200 ).json ({ received: true });
});
import hmac
import hashlib
import json
def verify_webhook_signature (payload, timestamp, signature, secret):
"""Verifica a assinatura HMAC-SHA256 do webhook"""
body = json.dumps (payload, separators=("," , ":" ))
message = f"{timestamp} .{body} "
expected = hmac.new (
secret.encode ("utf-8" ),
message.encode ("utf-8" ),
hashlib.sha256
).hexdigest ()
return signature == f"sha256={expected} "
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route ("/webhook/nfe" , methods=["POST" ])
def handle_webhook ():
signature = request.headers.get ("X-Axiom-Signature" )
timestamp = request.headers.get ("X-Axiom-Timestamp" )
valid = verify_webhook_signature (
request.json, timestamp, signature, "meu-secret-hmac-256"
)
if not valid:
return jsonify ({"error" : "Invalid signature" }), 401
event = request.json["event" ]
data = request.json["data" ]
print (f"Evento: {event} " , data)
return jsonify ({"received" : True })
<?php
function verifyWebhookSignature ($payload , $timestamp , $signature , $secret ) {
$body = json_encode ($payload );
$message = "{$timestamp} .{$body} " ;
$expected = hash_hmac ("sha256" , $message , $secret );
return $signature === "sha256={$expected} " ;
}
$payload = json_decode (file_get_contents ("php://input" ), true );
$signature = $_SERVER ["HTTP_X_AXIOM_SIGNATURE" ] ?? "" ;
$timestamp = $_SERVER ["HTTP_X_AXIOM_TIMESTAMP" ] ?? "" ;
$valid = verifyWebhookSignature (
$payload , $timestamp , $signature , "meu-secret-hmac-256"
);
if (!$valid ) {
http_response_code (401 );
echo json_encode (["error" => "Invalid signature" ]);
exit ;
}
$event = $payload ["event" ];
$data = $payload ["data" ];
error_log ("Evento: {$event} " );
http_response_code (200 );
echo json_encode (["received" => true ]);
Payload recebido no webhook
{
"event" : "nfe.authorized" ,
"data" : {
"chaveAcesso" : "35260212345678000195550010000000011234567890" ,
"modelo" : 55 ,
"nProt" : "135260000001234" ,
"dhRecbto" : "2026-02-15T10:30:00-03:00"
},
"timestamp" : "2026-02-15T13:30:00.000Z"
}