Question:
I need to make an integration with the SIGEP API of Correios just to generate the labels. I'm using the ready-made module from GitHub ( https://github.com/stavarengo/php-sigep ).
He makes the connection normally, but the return that the Post Office gives is "It was not possible to obtain the requested labels."
I asked the Post Office staff and they informed us that it is because it is no longer possible to request just the labels, and the following integrations are necessary beforehand:
- Check card status
- Request contract/card data
- And only then request the labels
The funny thing is that the template that the GitHub module has doesn't do any of that, and the template website makes it look like they connect directly.
Could anyone help me on how I can do it?
Answer:
Thanks for the help, but I came up with a solution of my own.
If interested, follow the class below.
The connect class mentioned (and related to the class by composition in the constructor method) is authored by me and is for database connection only. (Details about it can be seen here: https://www.facebook.com/notes/tmw-technology/classe-conecta-7-auxiliando-voc%C3%AA-na-comunica%C3%A7%C3%A3o -with-your-phpmysql-database/516582278382242 )
The getData() method checks the data from the database and whether the store in question purchased the integration package with SIGEP ( $this->lojaAuthorizada ).
Only this part you will have to adapt if you want to make use of this class.
<?php
/**
* SIGEP WEB - Geração de etiquetas
* @author TMW E-commerce Solutions
*/
require_once __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'conecta.class.php';
class Sigep
{
const
SIGEP = 'https://apps.correios.com.br/SigepMasterJPA/AtendeClienteService/AtendeCliente?wsdl'; # API Url
private
$soap, # conexão soap
$result, # resultado das pesquisas
$pdo, # conexão com PDO
$dadosCliente, # dados do cliente junto ao SIGEP
$servicos = array(), # servicos disponiveis
$cnpj = NULL; # CNPJ do cliente
public
$erro = '', # erros no processamento
$sql = '', # execuções de sql
$lojaAutorizada = false, # autoriza o processamento?
$servicoConectado = false; # possui todos os dados?
/**
* Método Construtor
*/
public function __construct()
{
$this->pdo = new Conecta('sigep');
$this->getData();
}
/**
* Verifica dados
* @access private
*/
private function getData( $registerSql = true )
{
// Busca os dados do cliente se estiverem ativos
$this->pdo->zeraVars();
$this->pdo->setVars(array(
'where' => 'sig_ativo = 1',
'oneRow' => true
));
$this->dadosCliente = $this->pdo->execute();
if ( $registerSql ) $this->sql = $this->pdo->sql;
// Cliente está ativo?
if( ! isset( $this->dadosCliente->sig_ativo ) || $this->dadosCliente->sig_ativo != 1 ):
$this->lojaAutorizada = false;
$this->erro = 'Loja não autorizada';
else:
// Se está ativo, inicializa o serviço
$this->lojaAutorizada = true;
$this->startService();
endif;
}
/**
* Inicializa o serviço
* @access public
*/
private function startService()
{
// Loja autorizada?
if ( $this->lojaAutorizada ):
try{
$this->soap = new SoapClient('https://apps.correios.com.br/SigepMasterJPA/AtendeClienteService/AtendeCliente?wsdl');
// Verifica Cartão de Postagem
$soapArgs = array(
'numeroCartaoPostagem' => $this->dadosCliente->sig_cartao,
'usuario' => $this->dadosCliente->sig_user,
'senha' => $this->dadosCliente->sig_pass
);
// Resultados possíveis de $result->return: Normal | Cancelado
$this->result = $this->soap->getStatusCartaoPostagem( $soapArgs );
} catch( Exception $e ) {
$this->erro = 'Erro ao verificar cartão de postagem: ' . $e->getMessage();
$this->servicoConectado = false;
}
try{
if( $this->result->return == 'Normal' ):
// Busca os dados do Cliente, incluindo o código dos serviços de postagem
$soapArgs = array(
'idContrato' => $this->dadosCliente->sig_contrato,
'idCartaoPostagem' => $this->dadosCliente->sig_cartao,
'usuario' => $this->dadosCliente->sig_user,
'senha' => $this->dadosCliente->sig_pass
);
// Retorna os serviços disponíveis para o cliente, bem como alguns dados como CNPJ
$this->result = $this->soap->buscaCliente( $soapArgs );
// Pegando CNPJ e confirmando a existência dos dados
$this->cnpj = $this->result->return->cnpj;
if ( $this->cnpj != '' && count( $this->result->return->contratos->cartoesPostagem->servicos ) > 1 ):
// Pegando todos os códigos de serviço
foreach( $this->result->return->contratos->cartoesPostagem->servicos as $servico )
$this->servicos[ $servico->codigo * 1 ] = $servico->id * 1;
$this->servicoConectado = true;
else:
throw new Exception( 'Não foi possível localizar o cliente' );
endif;
else:
throw new Exception( 'Serviço não conectado' );
endif;
} catch( Exception $e ) {
$this->erro = 'Erro ao pegar serviços disponíveis: ' . $e->getMessage();
$this->servicoConectado = false;
}
endif;
}
/**
* Gera Etiquetas - retorna um array com as etiquetas geradas
* @access public
* @param integer $service Servicço dos correios conforme tabela ( Ex.: PAC = 41106 )
* @param integer $qtde Quantidade de etiquetas
*/
public function getLabels( $service, $qtde )
{
if ( $this->lojaAutorizada ):
try {
// Verifica se o serviço informado está disponível
if ( ! count( $this->servicos ) > 1 || ! $this->servicos[ $service ] > 0 )
throw new Exception( "Não foi possível identificar o serviço $service" );
// Solicita as etiquetas
$soapArgs = array(
'tipoDestinatario' => 'C',
'identificador' => $this->cnpj,
'idServico' => $this->servicos[ $service ],
'qtdEtiquetas' => $qtde,
'usuario' => $this->dadosCliente->sig_user,
'senha' => $this->dadosCliente->sig_pass
);
// Retorna a primeira e a última da sequencia de etiquetas reservadas, sem o dígito verificador
$this->result = $this->soap->solicitaEtiquetas( $soapArgs );
list( $etiquetaIni, $etiquetaFim ) = explode( ',', $this->result->return );
} catch( Exception $e ) {
$this->erro = 'Erro ao solicitar etiquetas: ' . $e->getMessage();
return array();
}
try {
// Se pegou as etiquetas
if( $etiquetaIni != '' && $etiquetaFim != '' ):
// Monta sequencia de etiquetas
$umaEtiqueta = ( $etiquetaIni == $etiquetaFim );
// Montando sequência
if( $umaEtiqueta ):
$etiquetas = $etiquetaIni;
else:
// Padrão de etiquetas:
// Qq/ coisa que não número com Zeros iniciais caso haja + Números + Qq/ coisa que não número
$regex = '/^([^0-9]+0*)([0-9]+)([^0-9]+)$/i';
// Caracteres inicias
$padraoIni = preg_replace( $regex, '$1', $etiquetaIni );
// Caracteres finais
$padraoFim = preg_replace( $regex, '$3', $etiquetaIni );
// Apenas números da etiqueta de início
$numInicial = preg_replace( $regex, '$2', $etiquetaIni );
// Apenas números da etiqueta de fim
$numFinal = preg_replace( $regex, '$2', $etiquetaFim );
$etiquetas = array();
for( $x = $numInicial; $x <= $numFinal; $x++ )
// Cada etiqueta é formado pelos caracteres inicias, número atual da sequencia, caracteres finais
$etiquetas[] = $padraoIni . $x . $padraoFim;
endif;
// Envia sequencia de etiquetas para solicitar dígitos verificadores
$soapArgs = array(
'etiquetas' => $etiquetas,
'usuario' => $this->dadosCliente->sig_user,
'senha' => $this->dadosCliente->sig_pass
);
// Retorna o dígito verificador para cada etiqueta informada
$this->result = $this->soap->geraDigitoVerificadorEtiquetas( $soapArgs );
// Pegou o dígito verificador?
if(
// Se tem mais de uma etiqueta
( is_array( $this->result->return ) && count( $this->result->return ) > 0 ) ||
// Se tem apenas uma etiqueta
( $this->result->return > 0 && $umaEtiqueta )
):
// Gera o número final das etiquetas
if ( ! $umaEtiqueta ):
// Gera dígito para cada etiqueta
$etiquetasFinais = array();
foreach( $this->result->return as $index => $digito )
$etiquetasFinais[] = str_replace( ' ', $digito, $etiquetas[ $index ] );
else:
// Gera dígito para unica etiqueta
$etiquetasFinais[] = str_replace( ' ', $this->result->return, $etiquetas );
endif;
// Retorna as etiquetas
return $etiquetasFinais;
else:
throw new Exception( 'Não foi possível gerar o dígito verificador');
return array();
endif;
else:
throw new Exception( 'Não foi possível gerar as etiquetas' );
endif;
} catch( Exception $e ) {
$this->erro = 'Erro ao solicitar dígito verificador: ' . $e->getMessage();
return array();
}
else:
return array();
endif;
}
/**
* Pega o usuário
* @access public
*/
public function getUser()
{
if ( $this->lojaAutorizada )
return $this->dadosCliente->sig_user;
else
return NULL;
}
/**
* Pega a senha
* @access public
*/
public function getPass()
{
if ( $this->lojaAutorizada )
return $this->dadosCliente->sig_pass;
else
return NULL;
}
/**
* Pega o número do cartão de postagem
* @access public
*/
public function getCard()
{
if ( $this->lojaAutorizada )
return $this->dadosCliente->sig_cartao;
else
return NULL;
}
/**
* Pega o número do contrato
* @access public
*/
public function getContract()
{
if ( $this->lojaAutorizada )
return $this->dadosCliente->sig_contrato;
else
return NULL;
}
/**
* Pega os serviços disponíveis
* @access public
*/
public function getServices()
{
if ( $this->lojaAutorizada )
return $this->servicos;
else
return array();
}
/**
* Modifica os dados
* @access public
* @param string $contract
* @param string $card
* @param string $user
* @param string $pass
*/
public function setClient( $contract, $card, $user, $pass )
{
if ( $this->lojaAutorizada ):
// Tenta atualizar os dados
$this->pdo->zeraVars();
$this->pdo->setVars(array(
'type' => 'UPDATE',
'campos' => array(
'sig_user' => $user,
'sig_pass' => $pass,
'sig_cartao' => $card,
'sig_contrato' => $contract
)
));
// Se bão atualizou, retorna falso
if( ! $this->pdo->execute() ):
$this->erro = $this->pdo->erro;
$this->sql = $this->pdo->sql;
return false;
endif;
$this->sql = $this->pdo->sql;
// Atualização feita com sucesso, pega novamente os dados
$this->getData( false );
return true;
else:
return false;
endif;
}
}