---
title: "Exemplos de integração — C#, Node.js, Python, PHP"
description: "Código pronto para integrar com o NFe/CTe Inbound em C#, Node.js, Python e PHP: busca por chave, consumo de webhook, listagem OData e ativação."
source_url: https://nfe.io/docs/distribuicao-nfe-cte-exemplos-integracao/
last_updated: 2026-07-30
---

# 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-1--buscar-nf-e-por-chave-de-acesso-c)
- [Exemplo 2 — Consumir Webhook e Baixar XML (Node.js)](#exemplo-2--consumir-webhook-e-baixar-xml-nodejs)
- [Exemplo 3 — Listar CT-es do Último Mês com Paginação (Python)](#exemplo-3--listar-ct-es-do-último-mês-com-paginação-python)
- [Exemplo 4 — Ativar Inbound e Aguardar Primeiro Documento (PHP)](#exemplo-4--ativar-inbound-e-aguardar-primeiro-documento-php)

## Exemplo 1 — Buscar NF-e por Chave de Acesso (C#)

```csharp
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)

```javascript
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](../reference/webhook-events.md).

## Exemplo 3 — Listar CT-es do Último Mês com Paginação (Python)

```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
<?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'];
```

## Veja também

- [Primeiros passos](./primeiros-passos.md)
- [Ativar via API](../how-to/ativar-via-api.md)
- [Configurar webhook](../how-to/configurar-webhook.md)
- [Webhook events + validação HMAC](../reference/webhook-events.md)
- [Endpoints de NF-e](../reference/endpoints-nfe.md)
- [Endpoints de CT-e](../reference/endpoints-cte.md)
