Search by

pairus / product-data

pairus_st

SDK oficial da PAIRUS para integração com catálogo GTIN/EAN, predição fiscal (IBS/CBS/IS), saneamento em lote e emissão de NF-e/NFC-e e NFS-e Nacional.

1.7.0 2026-09-25 19:29 UTC

This package is auto-updated.

Last update: 2026-09-25 19:31:28 UTC


README

Latest Version on Packagist Software License PHP Version

SDK oficial da PAIRUS Soluções Tecnológicas para PHP moderno (8.1+). Integração nativa de alta performance com o catálogo global de produtos GTIN/EAN, motor preditivo de inteligência artificial para a Reforma Tributária (IBS, CBS e Imposto Seletivo), saneamento fiscal em lote, emissão de NF-e / NFC-e com Autocura SEFAZ e NFS-e Nacional.

⚡ Quickstart em 3 Linhas

composer require pairus/product-data
use Pairus\PairusClient;

$pairus = new PairusClient(apiKey: getenv('PAIRUS_API_KEY'));
$produto = $pairus->products->get('7891000100103');
echo "{$produto->xProd} | NCM: {$produto->ncm} | CEST: {$produto->cest}";

🧭 Formas de Uso e Flexibilidade

O SDK foi desenhado para respeitar as melhores práticas do PHP moderno (tipagem estrita, DTOs imutáveis public readonly, named arguments e suporte a arrays associativos flexíveis):

// Forma 1: Argumentos nomeados do PHP 8 (alta legibilidade)
$predicao = $pairus->fiscal->predict(
    regimeTributario: 'simples_nacional',
    ufOrigem: 'SP',
    ufDestino: 'RJ',
    xProd: 'Coca-Cola 2L',
    gtin: '7894900010015'
);

// Forma 2: Injeção de dependência em frameworks (Laravel, Symfony)
class FiscalController {
    public function __construct(private PairusClient $pairus) {}
}

📚 Guia de Recursos

1. Produtos e Catálogo Global

// Consulta simples por GTIN
$produto = $pairus->products->get('7891000100103');

// Consulta cadastral enriquecida (SEO, dimensões logísticas, imagem HD)
$produto = $pairus->products->getEnriched('7891000100103');

// Busca semântica por texto e IA
$busca = $pairus->products->search('leite condensado sem lactose', limite: 5);
foreach ($busca['resultados'] as $item) {
    echo "[Score {$item['score']}] {$item['produto']['xProd']} - GTIN: {$item['produto']['GTIN']}" . PHP_EOL;
}

// Identificação por imagem fotográfica (OCR + Visão Computacional)
$scan = $pairus->products->scan('/caminho/foto_embalagem.jpg', tipo: 'gtin');
// Também aceita bytes brutos em memória:
// $scan = $pairus->products->scan($bytesFoto, nomeArquivo: 'rotulo.png');

2. Predição Fiscal & Reforma Tributária (IBS / CBS / IS)

Calcula automaticamente a matriz tributária completa para 27 UFs e rotas interestaduais:

$predicao = $pairus->fiscal->predict(
    regimeTributario: 'simples_nacional', // 'simples_nacional' | 'lucro_presumido' | 'lucro_real'
    ufOrigem: 'SP',
    ufDestino: 'MG',
    finalidade: 'revenda',               // 'revenda' | 'consumo_final' | 'industrializacao'
    destinatarioContribuinte: true,
    gtin: '7894900010015',
    xProd: 'REFRIGERANTE COCA COLA 2L'
);

$trib = $predicao->dadosTributarios;
// CFOP interno (mesma UF) e externo (interestadual): use o que corresponde à operação
echo "NCM: {$trib->ncmSugerido} | CFOP: {$trib->cfopInterno} / {$trib->cfopExterno} | CSOSN: {$trib->icmsCstCsosn}" . PHP_EOL;
echo "IBS/CBS CST: {$trib->ibscbs->cst} | ClassTrib: {$trib->ibscbs->cClassTrib}" . PHP_EOL;
echo "CBS Efetiva: {$trib->ibscbs->cbsAliquotaEfetiva}% | IBS Efetivo: {$trib->ibscbs->ibsAliquotaEfetiva}%" . PHP_EOL;

3. Saneamento Fiscal em Lote

Audite e higienize cadastros inteiros de ERPs e e-commerces em uma única requisição:

$lote = [
    ['xProd' => 'CERVEJA HEINEKEN LATA 350ML', 'id' => '7896045506163', 'NCM' => '22030000', 'CEST' => '0302100'],
    ['xProd' => 'ARROZ BRANCO TIPO 1 5KG', 'NCM' => '10063021'],
];

$resultado = $pairus->fiscal->sanitize($lote);
foreach ($resultado['itens'] as $item) {
    $auditoria = $item['auditoria_fiscal'];
    $vigente = $auditoria['ncm_vigente'] ? 'vigente' : 'INATIVO';
    echo "{$item['xProd']} -> NCM {$item['NCM_informado']} ({$vigente}) | CEST: {$auditoria['cest_sugerido']}" . PHP_EOL;
}

4. Emissão de NF-e / NFC-e com Autocura SEFAZ

// NF-e com enquadramento fiscal assistido
$nfe = $pairus->emissao->emitirNfe([
    'cnpj_emitente' => '11222333000181',
    'natureza_operacao' => 'Venda de Mercadoria',
    'destinatario' => ['cpf_cnpj' => '12345678000195', 'razao_social' => 'Cliente Exemplo LTDA', 'uf' => 'SP'],
    'itens' => [
        ['descricao' => 'Teclado Mecânico USB', 'ncm' => '84716052', 'cfop' => '5102', 'quantidade' => 1, 'valor_unitario' => 250.0],
    ],
]);

echo "{$nfe->statusSefaz} [{$nfe->cStat}] {$nfe->xMotivo}" . PHP_EOL;

// NFC-e no PDV: troco gerado pela API e reenvio seguro com Idempotency-Key
$nfce = $pairus->emissao->emitirNfce([
    'cnpj_emitente' => '11222333000181',
    'tipo_documento' => 'NFCE',
    'itens' => [['descricao' => 'Refrigerante 2L', 'ncm' => '22021000', 'valor_unitario' => 9.90, 'quantidade' => 2]],
    'pagamentos' => [['forma_pagamento' => '01', 'valor' => 50.0]],
], 'pdv03-cupom-000123');

// Simulação prévia com CUSTO ZERO de créditos
$simulacao = $pairus->emissao->simular([
    'cnpj_emitente' => '11222333000181',
    'destinatario' => ['cpf_cnpj' => '12345678000195', 'razao_social' => 'Cliente Teste', 'uf' => 'SP'],
    'itens' => [['descricao' => 'Item Teste', 'valor_unitario' => 10.0]],
]);

Toda emissão envia o cabeçalho Idempotency-Key. Sem chave informada, o SDK gera um UUID e o reutiliza nas retentativas automáticas: se a primeira tentativa já tiver emitido a nota, a API devolve essa mesma nota ($nfce->repeticaoIdempotente === true, sem novo faturamento) em vez de emitir outra. A chave vale por 24 h e é liberada se a nota for rejeitada.

Contingência off-line da NFC-e: com a opção ativada na conta (tela de emissão da Área do Cliente), a venda não trava quando a SEFAZ não responde: a resposta vem com sucesso verdadeiro, $nfce->statusSefaz igual a CONTINGENCIA (cStat 9, código da PAIRUS) e o DANFE com a tarja de contingência e a via do estabelecimento, sem consumir créditos. A nota é transmitida automaticamente depois, e o desfecho chega por webhook (nfe.autorizada, nfe.contingencia_rejeitada, nfe.substituida_cancelada, nfe.substituida_inutilizada, nfe.regularizacao_manual). Para recusar a contingência numa venda, envie 'permitir_contingencia' => false.

Autorização com alerta (cStat 120, NT 2026.002): a nota está autorizada e não deve ser reemitida; os alertas da SEFAZ (cMsg/xMsg, até 5) vêm em $nfce->alertasSefaz. Venda em marketplace (NT 2020.006): informe o marketplace no payload, 'intermediador' => ['cnpj' => '03007331000141', 'id_cadastro' => 'MINHA-LOJA'], para a nota sair com indIntermed=1 e o grupo infIntermed; o campo indicador_presenca define o indPres (padrão: 1 na NFC-e e 2 na NF-e). DIFAL: na NF-e interestadual a consumidor final não contribuinte, a API gera o grupo ICMSUFDest com a alíquota modal da UF de destino; para outra alíquota interna ou FCP, envie no item 'difal' => ['aliquota_interna_destino' => 19.0, 'fcp_percentual' => 2.0].

5. NFS-e Nacional de Serviços

$nota = [
    'ambiente' => 'homologacao',
    'prestador' => ['cnpj' => '12345678000199', 'inscricao_municipal' => '87654321', 'razao_social' => 'Minha Empresa Ltda'],
    'tomador' => ['cpf_cnpj' => '98765432000188', 'razao_social' => 'Cliente Ltda'],
    'servico' => [
        'item_lista_servico' => '1.01',
        'discriminacao' => 'Serviços de Programação PHP',
        'municipio_prestacao_ibge' => '3550308',
        'valor_servicos' => 2500.0,
        'aliquota_iss' => 2.0,
        // Opcional: IBS/CBS do serviço (LC 214/2025)
        'reforma_tributaria' => ['cClassTrib' => '000001', 'aliquota_cbs' => 0.9],
    ],
];

// 1. Simulação prévia de tributos (sem custo)
$simulacao = $pairus->nfse->simular($nota);

// 2. Emissão definitiva
$nfse = $pairus->nfse->emitir($nota);
echo "NFS-e Nº: {$nfse->numeroNfse} | Consulta: {$nfse->linkVisualizacao}" . PHP_EOL;

// 3. Consulta de situação
$status = $pairus->nfse->consultar($nfse->chaveAcessoNacional ?? $nfse->numeroNfse);

// 4. Cancelamento homologado
$cancel = $pairus->nfse->cancelar([
    'numero_nfse' => $nfse->numeroNfse,
    'chave_acesso_nacional' => $nfse->chaveAcessoNacional,
    'cnpj_prestador' => '12345678000199',
    'inscricao_municipal' => '87654321',
    'codigo_municipio_ibge' => '3550308',
    'motivo_codigo' => '1', // '1' erro de emissão, '2' serviço não prestado, '3' duplicidade, '9' outros
    'justificativa' => 'Cancelamento solicitado pelo cliente por erro cadastral',
]);

6. DF-e Inbound & Captura Ativa SEFAZ (Gestão de Compras)

Capture ativamente as notas fiscais emitidas por fornecedores contra o CNPJ da sua empresa via WebService NFeDistribuicaoDFe da SEFAZ Nacional:

// 1. Sincronizar e consultar novos documentos na SEFAZ Nacional
$sync = $pairus->dfe->sincronizar(cnpj: '12345678000195', ambiente: 'producao');

echo "Status SEFAZ [{$sync['cstat']}]: {$sync['xmotivo']}" . PHP_EOL;
echo "Novos documentos capturados: {$sync['novos_documentos']}" . PHP_EOL;
echo "Avanço de NSU: {$sync['ult_nsu']} -> {$sync['max_nsu']}" . PHP_EOL;

foreach ($sync['documentos'] as $doc) {
    echo "NF-e {$doc['numero']}/{$doc['serie']} - R$ {$doc['valor_total']} ({$doc['nome_emitente']})" . PHP_EOL;
}

// 2. Listar notas fiscais de compras capturadas
$compras = $pairus->dfe->listarDocumentos(cnpj: '12345678000195', limite: 50);

// 3. Manifestação do Destinatário perante a SEFAZ
// Eventos: '210210' (Ciência), '210200' (Confirmação), '210220' (Desconhecimento), '210240' (Não Realizada)
$manif = $pairus->dfe->manifestar(
    chaveAcesso: '35260912345678000195550010000000451234567890',
    cnpj: '12345678000195',
    tipoEvento: '210210' // Ciência da Emissão para liberar download do XML completo
);
echo "Manifestação homologada. Protocolo: {$manif['protocolo']}" . PHP_EOL;

// 4. Download do XML autorizado (procNFe) e DANFE em PDF
$chave = '35260912345678000195550010000000451234567890';
$xmlString = $pairus->dfe->baixarXml($chave);
file_put_contents("{$chave}.xml", $xmlString);

$danfePdfBytes = $pairus->dfe->baixarDanfe($chave);
file_put_contents("DANFE_{$chave}.pdf", $danfePdfBytes);

7. Validação Segura de Webhooks (HMAC-SHA256)

use Pairus\Webhooks;
use Pairus\Exceptions\InvalidSignatureException;

$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_PAIRUS_SIGNATURE'] ?? '';

try {
    $event = Webhooks::constructEvent($payload, $signature, getenv('PAIRUS_WEBHOOK_SECRET'));
    
    if ($event->event === 'nfe.autorizada') {
        // Processar faturamento concluído
    }
} catch (InvalidSignatureException $e) {
    http_response_code(401);
    exit('Assinatura inválida');
}

📋 Tabela de Parâmetros: Obrigatório vs. Opcional

Predição Fiscal ($pairus->fiscal->predict)

Parâmetro Tipo Obrigatório? Descrição & Regra Fiscal
regimeTributario string Sim 'simples_nacional', 'lucro_presumido' ou 'lucro_real'.
ufOrigem string Sim Sigla da UF do emitente (ex: 'SP').
ufDestino string Não Sigla da UF do destinatário. Se omitido, assume operação interna ($ufOrigem).
finalidade string Não 'revenda' (padrão), 'consumo_final' ou 'industrializacao'.
destinatarioContribuinte bool Não Define aplicação de DIFAL / ST (padrão: true).
gtin string Não* Código de barras GTIN/EAN numérico (8, 12, 13 ou 14 dígitos).
xProd string Não* Descrição comercial da mercadoria (para predição por IA/RAG).
ncm string Não NCM atual de 8 dígitos para validação e auditoria.
cest string Não Código CEST de 7 dígitos para validação de ICMS-ST.
itens array Não Lista de itens para cálculo consolidado de NF-e completa em lote.

*Nota: Pelo menos um identificador (gtin, xProd ou ncm) deve ser informado no modo individual.

NFS-e Nacional ($pairus->nfse->emitir)

Parâmetro Tipo Obrigatório? Descrição
prestador.cnpj string Sim CNPJ do emissor prestador de serviços.
tomador.cpf_cnpj string Sim CPF ou CNPJ do tomador do serviço.
tomador.razao_social string Sim Razão social ou nome completo do tomador.
servico.discriminacao string Sim Descrição clara dos serviços prestados.
servico.valor_servicos float Sim Valor bruto total dos serviços (R$).
servico.item_lista_servico string Não Item da LC 116/2003 (ex: '01.01').
servico.codigo_tributacao_municipio string Não Código municipal de tributação da prefeitura.
servico.aliquota_iss float Não Alíquota nominal do ISS (ex: 2.0 para 2%).
servico.iss_retido bool Não True se o ISS for retido na fonte pelo tomador.

Manifestação do Destinatário ($pairus->dfe->manifestar)

Parâmetro Tipo Obrigatório? Descrição & Regras Fiscais
chaveAcesso string Sim Chave de 44 dígitos da NF-e emitida pelo fornecedor.
cnpj string Sim CNPJ da sua empresa compradora/destinatária.
tipoEvento string Sim '210210' (Ciência), '210200' (Confirmação), '210220' (Desconhecimento), '210240' (Não Realizada).
justificativa string Condicional Obrigatória estritamente para '210240' (mínimo de 15 caracteres).
ambiente string Não 'producao' (padrão) ou 'homologacao'.

🛠️ Exemplos em Frameworks

Laravel (Controller & Service)

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Pairus\PairusClient;

class FiscalController extends Controller
{
    public function consultar(string $gtin, PairusClient $pairus)
    {
        try {
            $produto = $pairus->products->get($gtin);
            return response()->json($produto);
        } catch (\Pairus\Exceptions\PairusApiException $e) {
            return response()->json(['erro' => $e->xMotivo], $e->statusCode);
        }
    }
}

WordPress / WooCommerce

add_action('woocommerce_process_product_meta', function ($postId) {
    $gtin = get_post_meta($postId, '_gtin', true);
    if (!empty($gtin)) {
        $pairus = new \Pairus\PairusClient(apiKey: defined('PAIRUS_API_KEY') ? PAIRUS_API_KEY : '');
        $produto = $pairus->products->get($gtin);
        
        update_post_meta($postId, '_ncm', $produto->ncm);
        update_post_meta($postId, '_cest', $produto->cest);
    }
});

🛡️ Tratamento de Erros e Padrão SEFAZ

Todas as exceções estendem PairusApiException, expondo os códigos de status e descrições do layout SEFAZ:

try {
    $pairus->products->get('0000000000000');
} catch (\Pairus\Exceptions\AuthenticationException $e) {
    // Chave de API inválida ou expirada (HTTP 401)
    echo "Erro de autenticação: {$e->getMessage()}";
} catch (\Pairus\Exceptions\RateLimitException $e) {
    // Limite de requisições atingido (HTTP 429)
    echo "Aguarde {$e->retryAfter} segundos.";
} catch (\Pairus\Exceptions\PairusApiException $e) {
    // Erros de negócio ou rejeição fiscal
    echo "SEFAZ cStat: {$e->cStat} | Motivo: {$e->xMotivo}";
} catch (\Pairus\Exceptions\NetworkException $e) {
    // Falha de rede após retentativas exponenciais
    echo "Falha de conexão: {$e->getMessage()}";
}

📄 Licença

Distribuído sob a licença MIT. Consulte o arquivo LICENSE para mais detalhes.