betocampoy/champs-jadlog-sdk

SDK PHP da Champs para integração com a Jadlog (frete, pedidos, tracking, DACTE, PUDOs, QRCode e DCE)

Maintainers

Package info

github.com/betocampoy/champs-jadlog-sdk

pkg:composer/betocampoy/champs-jadlog-sdk

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-04-23 17:21 UTC

This package is auto-updated.

Last update: 2026-04-23 17:22:33 UTC


README

SDK PHP da Champs para integração com a Jadlog.

Esta versão já inclui:

  • suporte a DC-e no bloco dfe com tpDocumento = 5
  • DTOs para payloads mais previsíveis
  • config de endpoints por ambiente
  • fallback em cascata entre múltiplas URLs por serviço
  • histórico da última transação para debug e persistência em banco
  • callback opcional por tentativa para log na aplicação

Endpoints cobertos

  • inclusão de pedido
  • cancelamento de pedido
  • tracking completo
  • tracking simples
  • simulador de frete
  • consulta XML do DACTE
  • PUDOs por CEP
  • PUDOs sem CEP
  • QRCode pickup/dropoff
  • inclusão de tratativa

Requisitos

  • PHP 8.2+
  • Composer
  • symfony/http-client para o adapter HTTP padrão

Instalação

composer require betocampoy/champs-jadlog-sdk

Namespace principal

use BetoCampoy\Champs\JadlogSdk\JadlogClient;

Criação do client

Simples

use BetoCampoy\Champs\JadlogSdk\JadlogClient;

$client = JadlogClient::create('SEU_TOKEN');

Escolhendo ambiente

$client = JadlogClient::create(
    token: 'SEU_TOKEN',
    environment: 'production',
);

Com arquivo de endpoints próprio

use BetoCampoy\Champs\JadlogSdk\Http\SymfonyHttpClientAdapter;

$client = JadlogClient::create(
    token: 'SEU_TOKEN',
    endpointsFile: __DIR__ . '/config/jadlog_endpoints.php',
    http: new SymfonyHttpClientAdapter(),
    environment: 'homologation',
);

Com callback para logar tentativas

use BetoCampoy\Champs\JadlogSdk\Http\RequestAttemptResult;

$client = JadlogClient::create(
    token: 'SEU_TOKEN',
    attemptListener: function (RequestAttemptResult $attempt): void {
        // salvar em banco, monolog, etc.
        // $attempt->toArray()
    },
);

DTOs disponíveis

  • OrderRequest
  • QuoteRequest
  • QuoteItem
  • Party
  • DfeDocument
  • Volume
  • TrackingQuery

Builders disponíveis

  • OrderBuilder
  • QuoteBuilder
  • TrackingQueryBuilder

Enum de documento fiscal

use BetoCampoy\Champs\JadlogSdk\Enum\DocumentType;

DocumentType::DECLARACAO; // 0
DocumentType::NF;         // 1
DocumentType::NFE;        // 2
DocumentType::CTE;        // 4
DocumentType::DCE;        // 5

Como a configuração de endpoints funciona

O arquivo config/endpoints.php agora usa:

  • ambiente atual em environment
  • mapa por ambiente em environments
  • lista ordenada de uris por serviço

Exemplo resumido:

return [
    'environment' => 'production',
    'environments' => [
        'production' => [
            'frete_valor' => [
                'method' => 'POST',
                'uris' => [
                    'https://www.jadlog.com.br/embarcador/api/frete/valor',
                    'https://www.jadlog.com/embarcador/api/frete/valor',
                ],
            ],
        ],
    ],
];

Regra de fallback

Quando houver mais de uma URL para o mesmo serviço, o SDK tenta a próxima URL em caso de:

  • exceção de transporte
  • timeout
  • erro de conexão
  • HTTP 500, 502, 503, 504

Ele não troca de URL em erros típicos de negócio, como 400, 401, 403 ou payload inválido.

Debug e persistência de request/response

Após qualquer chamada, você pode recuperar:

$client->getLastRequestJson();
$client->getLastResponseRaw();
$client->getLastTransaction();

Exemplo de uso

$response = $client->quote($payload);

$requestJson = $client->getLastRequestJson();
$responseRaw = $client->getLastResponseRaw();
$transaction = $client->getLastTransaction();

// $transaction?->toArray()

getLastTransaction() devolve um objeto com:

  • serviço chamado
  • URL final usada com sucesso
  • lista de tentativas
  • request body
  • response body
  • status HTTP final

Exemplos de uso

1) Simulador de frete com builder

use BetoCampoy\Champs\JadlogSdk\Builders\QuoteBuilder;
use BetoCampoy\Champs\JadlogSdk\JadlogClient;

$client = JadlogClient::create('SEU_TOKEN');

$payload = QuoteBuilder::make()
    ->cepOrigem('14801000')
    ->cepDestino('04094002')
    ->modalidade(3)
    ->cnpj('00000000000000')
    ->conta('000000')
    ->peso(750)
    ->valorDeclarado(120.00)
    ->build();

$result = $client->quote($payload, pesoEmGramas: true);

2) Simulador de frete com DTO

use BetoCampoy\Champs\JadlogSdk\Dto\QuoteItem;
use BetoCampoy\Champs\JadlogSdk\Dto\QuoteRequest;

$request = new QuoteRequest([
    new QuoteItem(
        cepori: '14801000',
        cepdes: '04094002',
        peso: 0.75,
        cnpj: '00000000000000',
        modalidade: 3,
        vldeclarado: 120.00,
        conta: '000000',
    ),
]);

$result = $client->quote($request);

3) Inclusão de pedido com DTO e DC-e

use BetoCampoy\Champs\JadlogSdk\Dto\DfeDocument;
use BetoCampoy\Champs\JadlogSdk\Dto\OrderRequest;
use BetoCampoy\Champs\JadlogSdk\Dto\Party;
use BetoCampoy\Champs\JadlogSdk\Dto\Volume;
use BetoCampoy\Champs\JadlogSdk\Enum\DocumentType;

$order = new OrderRequest(
    codCliente: '000001',
    conteudo: 'DECLARACAO DE CONTEUDO',
    pedido: ['PED-123'],
    totPeso: 1.2,
    totValor: 199.90,
    modalidade: 3,
    rem: new Party('Remetente LTDA', '00000000000000', 'Rua A', '100', 'Centro', 'Araraquara', 'SP', '14800000'),
    des: new Party('Destinatário', '11111111111', 'Rua B', '200', 'Centro', 'São Paulo', 'SP', '01000000'),
    dfe: [
        new DfeDocument(
            tpDocumento: DocumentType::DCE,
            danfeCte: '41260111111111111111111111111111111111111111',
            nrDoc: 'DCE123',
            serie: '1',
            valor: 199.90,
        ),
    ],
    volume: [new Volume(1.2, altura: 5, comprimento: 20, largura: 10, identificador: 'VOL-001')],
    tpColeta: 'K',
    tipoFrete: 0,
);

$result = $client->createOrder($order);

4) Inclusão de pedido com array puro

$payload = [
    'codCliente' => '000001',
    'conteudo' => 'PRODUTO DIVERSO',
    'pedido' => ['PED-456'],
    'totPeso' => 1.2,
    'totValor' => 199.90,
    'modalidade' => 3,
    'tpColeta' => 'K',
    'tipoFrete' => 0,
    'rem' => [
        'nome' => 'Remetente LTDA',
        'cnpjCpf' => '00000000000000',
        'endereco' => 'Rua A',
        'numero' => '100',
        'bairro' => 'Centro',
        'cidade' => 'Araraquara',
        'uf' => 'SP',
        'cep' => '14800000',
    ],
    'des' => [
        'nome' => 'Destinatário',
        'cnpjCpf' => '11111111111',
        'endereco' => 'Rua B',
        'numero' => '200',
        'bairro' => 'Centro',
        'cidade' => 'São Paulo',
        'uf' => 'SP',
        'cep' => '01000000',
    ],
];

$result = $client->createOrder($payload);

5) Cancelamento por shipmentId

$result = $client->cancelOrderByShipmentId('00000000000000');

6) Cancelamento por código

$result = $client->cancelOrderByCodigo('123456789');

7) Tracking completo por shipmentId

$result = $client->track([
    ['shipmentId' => '00000000000000'],
]);

8) Tracking simples por código

$result = $client->track([
    ['codigo' => '000000000'],
], simples: true);

9) Tracking com builder

use BetoCampoy\Champs\JadlogSdk\Builders\TrackingQueryBuilder;

$query = TrackingQueryBuilder::make()
    ->addShipmentId('00000000000000')
    ->addCodigo('000000001')
    ->build();

$result = $client->track($query);

10) Consulta XML do DACTE

$xml = $client->getDacteXml('00000000000000000000000000000000000000000000');

11) PUDOs por CEP

$result = $client->listPudosByCep('02031-100');

12) PUDOs filtrando tipos

$result = $client->listPudosByCep('02031-100', 'LOCKER');
$result2 = $client->listPudos('PUBLICO');

13) QRCode pickup/dropoff

$base64 = $client->getPickupDropoffQrCode('07334200008233');

14) Inclusão de tratativa

$result = $client->incluirTratativa([
    'pedido' => '768070338',
    'usuario' => 'romulo',
    'acareacao' => false,
    'observacao' => 'Inclusão via SDK Champs Jadlog',
    'finalizar' => 'N',
]);

15) Exemplo de persistência em banco

$result = $client->createOrder($order);

$requestJson = $client->getLastRequestJson();
$responseRaw = $client->getLastResponseRaw();
$transaction = $client->getLastTransaction();

// persistir no banco
// request_json  => $requestJson
// response_raw  => $responseRaw
// transaction   => json_encode($transaction?->toArray(), JSON_UNESCAPED_UNICODE)

Observações sobre DC-e

No manual atualizado da Jadlog, o bloco documental do pedido aceita tpDocumento = 5 para DC-e. A integração usa a DC-e como documento dentro de dfe, distinta da etiqueta Jadlog. Isso permite gerar a etiqueta a partir de uma DC-e já autorizada no seu domínio, desde que você monte corretamente os dados documentais e operacionais no payload.

Tratamento de erros

O SDK lança exceções específicas:

  • ValidationException
  • TransportException
  • JadlogException

Exemplo:

use BetoCampoy\Champs\JadlogSdk\Exceptions\TransportException;
use BetoCampoy\Champs\JadlogSdk\Exceptions\ValidationException;

try {
    $result = $client->quote($payload);
} catch (ValidationException $e) {
    // payload inválido
} catch (TransportException $e) {
    // erro de transporte / timeout / todas as URLs falharam
}