Skip to main content

SDK PHP

O SDK PHP está em desenvolvimento. Os exemplos abaixo mostram como integrar usando Guzzle diretamente enquanto o pacote não é publicado no Packagist.

Integração direta com Guzzle

<?php

use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;

class EngineAPI
{
    private Client $client;

    public function __construct(string $baseUrl, string $apiKey)
    {
        $this->client = new Client([
            'base_uri' => $baseUrl,
            'headers' => [
                'x-api-key' => $apiKey,
                'Content-Type' => 'application/json',
                'Accept' => 'application/json',
            ],
            'timeout' => 30,
        ]);
    }

    public function emitirNfe(array $dados): array
    {
        $response = $this->client->post('/v1/nfe', [
            'json' => $dados,
        ]);
        return json_decode($response->getBody(), true);
    }

    public function listarNfes(int $page = 1, int $limit = 20): array
    {
        $response = $this->client->get('/v1/nfe', [
            'query' => ['page' => $page, 'limit' => $limit],
        ]);
        return json_decode($response->getBody(), true);
    }

    public function cancelarNfe(string $accessKey, string $motivo): array
    {
        $response = $this->client->post("/v1/nfe/{$accessKey}/cancelar", [
            'json' => ['motivo' => $motivo],
        ]);
        return json_decode($response->getBody(), true);
    }

    public function downloadPdf(string $accessKey): string
    {
        $response = $this->client->get("/v1/nfe/pdf/{$accessKey}");
        return $response->getBody()->getContents();
    }

    public function downloadXml(string $accessKey): string
    {
        $response = $this->client->get("/v1/nfe/xml/{$accessKey}");
        return $response->getBody()->getContents();
    }
}

Uso

$engine = new EngineAPI(
    'https://api.engineapi.com.br',
    'ek_live_SEU_API_KEY'
);

$nfe = $engine->emitirNfe([
    'issuerId' => 'ISSUER_UUID',
    'naturezaOperacao' => 'VENDA DE MERCADORIA',
    'destinatario' => [
        'cnpj' => '99888777000155',
        'nome' => 'Cliente Exemplo SA',
        'indicadorIE' => 9,
        'endereco' => [
            'logradouro' => 'Av Brasil', 'numero' => '500',
            'bairro' => 'Centro', 'codigoMunicipio' => '3550308',
            'municipio' => 'São Paulo', 'uf' => 'SP', 'cep' => '01001000',
        ],
    ],
    'itens' => [[
        'numero' => 1, 'codigo' => 'PROD001',
        'descricao' => 'Camiseta Azul M', 'ncm' => '61091000',
        'cfop' => '5102', 'unidade' => 'UN', 'quantidade' => 1,
        'valorUnitario' => 89.90, 'valorTotal' => 89.90,
        'icms' => ['origem' => 0, 'csosn' => '400'],
    ]],
    'pagamento' => ['forma' => '01', 'valor' => 89.90],
]);

echo "NFe autorizada: " . $nfe['data']['accessKey'] . PHP_EOL;

Laravel

Service Provider

// app/Providers/EngineApiServiceProvider.php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class EngineApiServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(EngineAPI::class, function () {
            return new EngineAPI(
                config('services.engineapi.url'),
                config('services.engineapi.key'),
            );
        });
    }
}

Config

// config/services.php
'engineapi' => [
    'url' => env('ENGINE_API_URL', 'https://api.engineapi.com.br'),
    'key' => env('ENGINE_API_KEY'),
],

Controller

// app/Http/Controllers/NfeController.php
class NfeController extends Controller
{
    public function emitir(Request $request, EngineAPI $engine)
    {
        try {
            $nfe = $engine->emitirNfe($request->all());
            return response()->json($nfe);
        } catch (ClientException $e) {
            $body = json_decode($e->getResponse()->getBody(), true);
            return response()->json($body, $e->getCode());
        }
    }
}

Tratamento de erros

use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ServerException;

try {
    $nfe = $engine->emitirNfe($dados);
} catch (ClientException $e) {
    $status = $e->getResponse()->getStatusCode();
    $body = json_decode($e->getResponse()->getBody(), true);

    match ($status) {
        400 => logger()->error('Dados inválidos', $body),
        422 => logger()->error("Rejeição SEFAZ {$body['sefazCode']}: {$body['sefazMessage']}"),
        429 => logger()->warning('Rate limit — retry após Retry-After'),
        default => logger()->error("Erro {$status}", $body),
    };
} catch (ServerException $e) {
    // 500+ — retry com backoff
    logger()->critical('Erro no servidor Engine API', [
        'status' => $e->getResponse()->getStatusCode(),
    ]);
}

Próximos passos

SDK TypeScript

SDK oficial com tipagem completa

API Reference

Documentação completa de todos os endpoints