Exemplos de Integração
Código pronto para acelerar a integração. Use como ponto de partida e adapte para o seu stack.
Sumário
- Exemplo 1 — Buscar NF-e por Chave de Acesso (C#)
- Exemplo 2 — Consumir Webhook e Baixar XML (Node.js)
- Exemplo 3 — Listar CT-es do Último Mês com Paginação (Python)
- Exemplo 4 — Ativar Inbound e Aguardar Primeiro Documento (PHP)
Exemplo 1 — Buscar NF-e por Chave de Acesso (C#)
using System.Net.Http;
using System.Text.Json;
public class NfeIoClient
{
private readonly HttpClient _http;
private readonly string _companyId;
private readonly string _baseUrl = "https://api.nfe.io";
public NfeIoClient(string apiKey, string companyId)
{
_companyId = companyId;
_http = new HttpClient();
_http.DefaultRequestHeaders.Add("Authorization", $"ApiKey {apiKey}");
}
public async Task<NfeMetadata> GetNfeAsync(string accessKey)
{
var url = $"{_baseUrl}/v2/companies/{_companyId}/inbound/productinvoices/{accessKey}";
var response = await _http.GetAsync(url);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<NfeMetadata>(content);
}
public async Task<Stream> GetNfeXmlAsync(string accessKey)
{
var url = $"{_baseUrl}/v2/companies/{_companyId}/inbound/{accessKey}/xml";
return await _http.GetStreamAsync(url);
}
}
Exemplo 2 — Consumir Webhook e Baixar XML (Node.js)
const express = require('express');
const axios = require('axios');
const crypto = require('crypto');
const app = express();
app.use(express.raw({ type: 'application/json' })); // raw para validar assinatura
const API_KEY = 'sk_live_sua_chave_aqui';
const COMPANY_ID = 'comp_123';
const WEBHOOK_SECRET = 'seu_webhook_secret';
const BASE_URL = 'https://api.nfe.io';
function validateSignature(rawBody, signatureHeader, secret) {
// Contrato canonico nfe.io: HMAC-SHA1, hex MAIUSCULO, prefixo sha1=
if (!signatureHeader || !signatureHeader.startsWith('sha1=')) return false;
const expected = 'sha1=' + crypto
.createHmac('sha1', secret)
.update(rawBody)
.digest('hex')
.toUpperCase();
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signatureHeader));
}
app.post('/webhooks/nfeio', async (req, res) => {
const signature = req.headers['x-hub-signature'] || '';
if (!validateSignature(req.body, signature, WEBHOOK_SECRET)) {
return res.status(401).send('Assinatura inválida');
}
const payload = JSON.parse(req.body);
const { event, accessKey, type, issuer, totalAmount } = payload;
console.log(`Novo documento: ${accessKey} - ${event}`);
try {
const xmlResponse = await axios.get(
`${BASE_URL}/v2/companies/${COMPANY_ID}/inbound/${accessKey}/xml`,
{ headers: { 'Authorization': `ApiKey ${API_KEY}` }, responseType: 'text' }
);
await saveDocumentToDatabase({ accessKey, type, issuer, totalAmount, xml: xmlResponse.data });
res.status(200).json({ status: 'ok' });
} catch (error) {
console.error('Erro:', error);
res.status(500).json({ error: error.message });
}
});
app.listen(3000);
Detalhes completos do contrato HMAC (header, encoding, vetor de teste) em Webhook events + validação HMAC.
Exemplo 3 — Listar CT-es do Último Mês com Paginação (Python)
import requests
from datetime import datetime, timedelta
API_KEY = "sk_live_sua_chave"
COMPANY_ID = "comp_123"
BASE_URL = "https://api.nfe.io"
def get_all_ctes_last_month():
"""Busca todos os CT-es do último mês usando paginação OData."""
today = datetime.utcnow()
last_month = today - timedelta(days=30)
start_date = last_month.strftime("%Y-%m-%dT%H:%M:%SZ")
end_date = today.strftime("%Y-%m-%dT%H:%M:%SZ")
url = (
f"{BASE_URL}/v2/companies/{COMPANY_ID}/inbound/odata/TransportationInvoices"
f"?$filter=issuedOn ge {start_date} and issuedOn lt {end_date}"
f"&$top=100"
f"&$orderby=issuedOn desc"
)
headers = {"Authorization": f"ApiKey {API_KEY}"}
all_ctes = []
while url:
response = requests.get(url, headers=headers)
response.raise_for_status()
data = response.json()
all_ctes.extend(data.get("value", []))
# OData retorna próxima página via @odata.nextLink
url = data.get("@odata.nextLink")
print(f"Buscados {len(all_ctes)} CT-es até agora...")
return all_ctes
ctes = get_all_ctes_last_month()
print(f"Total: {len(ctes)} CT-es")
for cte in ctes[:5]:
print(f" - {cte['accessKey']} | Emitido em: {cte['issuedOn']}")
Exemplo 4 — Ativar Inbound e Aguardar Primeiro Documento (PHP)
<?php
class NfeIoInbound
{
private string $apiKey;
private string $companyId;
private string $baseUrl = 'https://api.nfe.io';
public function __construct(string $apiKey, string $companyId)
{
$this->apiKey = $apiKey;
$this->companyId = $companyId;
}
private function makeRequest(string $method, string $path, ?array $body = null): array
{
$url = "{$this->baseUrl}/v2/companies/{$this->companyId}/{$path}";
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => [
"Authorization: ApiKey {$this->apiKey}",
"Content-Type: application/json"
],
]);
if ($body) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
}
$response = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($statusCode >= 400) {
throw new RuntimeException("API Error {$statusCode}: {$response}");
}
return json_decode($response, true);
}
public function enableNfeInbound(string $startDate = null): array
{
return $this->makeRequest('POST', 'inbound/productinvoices', [
'StartFromNsu' => 0,
'StartFromDate' => $startDate ?? date('Y-m-d\TH:i:s\Z', strtotime('-90 days')),
'EnvironmentSEFAZ' => 'Production',
'WebhookVersion' => 2,
]);
}
public function getNfeMetadata(string $accessKey): array
{
return $this->makeRequest('GET', "inbound/productinvoices/{$accessKey}");
}
}
// Uso:
$client = new NfeIoInbound('sk_live_abc123', 'comp_123');
$config = $client->enableNfeInbound('2024-01-01T00:00:00Z');
echo "Inbound ativado! Status: " . $config['status'];