Nova consulta de Fretes do WebServices do Correios

Licença Creative Commons
FreightCorreios de Thiago Zampieri é licenciado sob uma Licença Creative Commons Attribution


UPDATE: O Correios ama os desenvolvedores… Recebi um e-mail informado que eles alterarão as URL de acesso para MELHORAR e FACILITAR a conexão… Bom vamos as alterações então neh..

A unica coisa que deve ser alterado é a parte de atributos blz? Segue abaixo:

/* ATRIBUTOS */
//private $wsdlSchema    = 'https://';
private $wsdlSchema    = 'http://';
//private $wsdlSock      = 'ssl://';
private $wsdlSock      = 'http://';
//private $wsdlHost      = 'shopping.correios.com.br';
private $wsdlHost      = 'ws.correios.com.br';
//private $wsdlQuery     = '/wbm/shopping/script/CalcPrecoPrazo.asmx?wsdl';
private $wsdlQuery     = '/calculador/CalcPrecoPrazo.asmx?wsdl';
//private $wsdlPort      = 443;
private $wsdlPort      = 80;
private $function      = 'CalcPrecoPrazo';
private $soapAction    = 'http://tempuri.org/';

Bom mais uma vez estou aqui para mostrar a implementação da consulta de frete dos correios, que entrará em vigor apartir do dia 30/07/2010 ( o suporte a forma antiga acabou 30 dias antes .aff).

Estava eu na minha mesa de trabalho quando verifico meus e-mail e la estava uma mensagem assim

“Mais uma integração espero que essa seja mais facil! rss”

Bom vi o conteudo do material e comecei a codificação. Após alguns detalhes e ligações ao suporte dessa grande empresa (rss) consegui fazer tudo funcionar.

Antes de postar o codigo fonte quero fazer algumas resalvas sobre esse novo metodo:

– É necessário agora informar as dimensões da embalagem dos itens ( o que é muito ruim ), ou seja, Altura x Largura x Comprimento.

– Quem já implementou a regra anterior sabe que antigamente você não repassava nenhum serviço dos correios, nessa versão é necessário informá-los (o que eu achei muito bacana, evitando retirar serviços que não uso na minha empresa)

– Outro detalhe é que a versão nova utiliza outro usuário e senha (putz até descobri isso foi complicado porque na empresa em que trabalho temos varios cartões de identificação)

Bom vamos ao código, e galera por favor quem utiizar o código favor manter os créditos.

Abraço e qualquer coisa me avisem. (Todas as classes estão funcionando em ambientes produtivos).

Abaixo o código:

<?php
/**
* Class......: FreightCorreios
* Author.....: Thiago Zampieri
* E-mail.....:
* Site.......: thiagozampieri.wordpress.com
* Post date..: 20.06.2010
* Description: Conexão com o webservices do correios para calcular o frete e prazo de entrega
* @access public
*/
class FreightCorreios
{
/* ATRIBUTOS */
private $wsdlSchema    = 'https://';
private $wsdlSock      = 'ssl://';
private $wsdlHost      = 'shopping.correios.com.br';
private $wsdlQuery     = '/wbm/shopping/script/CalcPrecoPrazo.asmx?wsdl';
private $wsdlPort      = 443;
private $function      = 'CalcPrecoPrazo';
private $soapAction    = 'http://tempuri.org/';

//Login
private $username      = 'USER_8_CHARS';
private $password      = 'PASS_8_CHARS';

//Services
/*
* Os codigos abaixos são alguns dos codigos disponíveis para consulta, porém o código 41106 é um código que permite ser consultado sem
* login e senha já que é um serviço liberado pelo correio. Caso deseje saber mais sobre os código entre no site do correios
* www.correios.com.br
* Parametros:
* name  = Nome do serviço
* title = Descrição do serviço
* cost  = AdValore individual
*
* PS: o valor assim será somado com o adValore Geral.
*
* Ad Valore é utilizando muito pelas empresas para evitar erros nos calculos e também custiar os seguros de transporte,
* ou seja, não é incorreto.
*/
private $_services     = array(
'40444' => array('name' => 'SEDEX', 	'title' => 'Sedex Convencional',			'cost' => 0.00), 	//SEDEX com contrato
'81019' => array('name' => 'e-SEDEX', 	'title' => 'Contrato especial e-commerce',	'cost' => 0.00), 	//e-SEDEX com contrato
'41068' => array('name' => 'PAC', 		'title' => 'PAC - Diferenciado',			'cost' => 0.00),	//PAC com contrato
'41025' => array('name' => 'CORREIOS', 	'title' => 'Encomenda Normal',				'cost' => 0.00),	//Encomenda Normal
'41106' => array('name' => 'PAC', 		'title' => 'PAC - Comum',					'cost' => 0.00),	//PAC sem contrato
);
//Config.
private $zipcodeSRC    = '86025040';	//LONDRINA - PR
private $zipcodeDST    = '12345000';	//SAO PAULO - SP
//TIPO DA EMBALAGEM:
private $format        = 1;				//1 - Formato caixa/pacote 2 - Formato rolo/prisma
private $width         = 0.00;			//Largura
private $length        = 0.00;			//Comprimento
private $height	       = 0.00;			//Altura
private $diameter      = 0.00;			//Diametro
private $weight        = 0.00;			//Peso
private $price         = 0.00;			//Valor Declarado
//ServiÁos
private $maoPropria    = 'N';			//ServiÁo M„o PrÛpria
private $receipt       = 'N';			//Aviso de Recebimento
//Adicionais
private $cost 		   = 0.00;			//AdValore (Caso deseja adicionar um valor no retorno dos valores (Geral))
private $timeProcedure = 0;				//Valor Minimo (Numeros de dias para aumentar com o retorno dos correios (Geral))
private $weightAdd     = 0.000;			//Kg (Peso adicional)

//Dados
private $_data         = array();		//Registro - retorno do Correio

/* CONSTRUTOR */
public function __construct($src_zipcode, $dst_zipcode, $width=0.00, $length=0.00, $height=0.00, $diameter=0.00, $weight=0.00, $price=0.00)
{
//Limpa os vetores de dados.
$this->reset();

$this->setZipcodeSRC($src_zipcode);
$this->setZipcodeDST($dst_zipcode);

$this->setWidth($width);
$this->setLength($length);
$this->setHeight($height);
$this->setDiameter($diameter);
$this->setWeight($weight);
$this->setPrice($price);
}

/* METODOS */
private function getUsername()
{
return $this->username;
}
private function getPassword()
{
return $this->password;
}

private function getWsdlSchema()
{
return $this->wsdlSchema;
}
private function getWsdlSock()
{
return $this->wsdlSock;
}
private function getWsdlHost()
{
return $this->wsdlHost;
}
private function getWsdlPort()
{
return $this->wsdlPort;
}
private function getWsdlQuery()
{
return $this->wsdlQuery;
}
private function getFunction()
{
return $this->function;
}
private function getSoapAction()
{
return $this->soapAction;
}
private function getWsdl()
{
return $this->getWsdlSchema().$this->getWsdlHost().$this->getWsdlQuery();
}

private function checkConnect()
{
/*
//		 * Testa a conexão antes de tentar buscar dados no WebServices do Correios
*/
$fp = fsockopen($this->getWsdlSock().$this->getWsdlHost(), $this->getWsdlPort(), $errno, $errstr, 5);
if (!$fp) return false;
return true;
}

private function setZipcodeSRC($zipcode)
{
$zipcode = str_replace(array('(', ')', '-', '.', ' '), '', $zipcode);

if (is_numeric($zipcode) & strlen($zipcode) == 8 )
{
$this->zipcodeSRC = $zipcode;
return true;
}
return false;
}
private function getZipcodeSRC()
{
return $this->zipcodeSRC;
}

private function setZipcodeDST($zipcode)
{
$zipcode = str_replace(array('(', ')', '-', '.', ' '), '', $zipcode);

if (is_numeric($zipcode) & strlen($zipcode) == 8 )
{
$this->zipcodeDST = $zipcode;
return true;
}
return false;
}
private function getZipcodeDST()
{
return $this->zipcodeDST;
}

private function setWeight($weight)
{
$weight = doubleval($weight);
if (is_double($weight))
{
$this->weight = $weight;
return true;
}
return false;
}

private function getWeight()
{
return ($this->weight + $this->getWeightAdd()) * 1;	//peso deve ser informado em Kilograma.
}
private function getWeightAdd()
{
return $this->weightAdd;
}

private function setDiameter($diameter)
{
$diameter = doubleval($diameter);
if (is_double($diameter))
{
$this->diameter = $diameter;
return true;
}
return false;
}
private function getDiameter()
{
return $this->diameter;
}

private function setWidth($width)
{
$width = doubleval($width);
if (is_double($width))
{
$this->width = $width;
return true;
}
return false;
}
private function getWidth()
{
return $this->width;
}

private function setLength($length)
{
$length = doubleval($length);
if (is_double($length))
{
$this->length = $length;
return true;
}
return false;
}
public function getLength()
{
return $this->length;
}

private function setHeight($height)
{
$height = doubleval($height);
if (is_double($height))
{
$this->height = $height;
return true;
}
return false;
}
private function getHeight()
{
return $this->height;
}

private function setPrice($price)
{
$price = doubleval($price);
if (is_double($price))
{
$this->price = $price;
return true;
}
return false;
}
private function getPrice()
{
return $this->price;
}

private function getMaoPropria()
{
return $this->maoPropria;
}
private function getFormat()
{
return $this->format;
}
private function getReceipt()
{
return $this->receipt;
}
private function getCost()
{
return $this->cost;
}

private function getTimeProcedure()
{
return $this->timeProcedure;
}

private function reset()
{
$this->width     = 0.00;		//Largura
$this->length    = 0.00;		//Comprimento
$this->height	 = 0.00;		//Altura
$this->diameter  = 0.00;		//Diametro
$this->weight    = 0.00;		//Peso
$this->price     = 0.00;		//Valor Declarado
}

private function getServicesId()
{
$_services = $this->_services;
$_keys = array_keys($_services);

return $_keys;
}

private function getServicesName($code)
{
$_services = $this->_services;
$name      = $_services[$code]['name'];
return $name;
}

private function getServicesCost($code)
{
$_services = $this->_services;
$cost      = $_services[$code]['cost'];
return $cost;
}

private function getServicesTitle($code)
{
$_services = $this->_services;
$name      = $_services[$code]['title'];
return $name;
}

private function getConnect()
{
$wsdl   = $this->getWsdl();
$client = new soap_client($wsdl, true); // true = sem namespace

return $client;
}

private function toDecimal($value)
{
if ($value > 0) return number_format($value, 2, '.', '');
return '0';
}

private function toNumber($value)
{
return number_format($value, 2, ',', '.');
}

private function convertDecimal($value)
{
$l_value = str_replace(".", "", $value);
$l_value = str_replace(",", ".", $l_value);
$l_value = $this->toDecimal(doubleval($l_value));

return $l_value;
}

private function check()
{
$l_weight = $this->getWeight();
if ($l_weight > 0 & $l_weight <= 30) 		{ 			$l_block  = $this->checkConnect();
return $l_block;
}
return false;
}

private function addCost($code, $price)
{
$l_cost  = $price;
$l_price = $this->getPrice();
$v_cost  = $this->getCost();
$v_cost2 = $this->getServicesCost($code);

$v_cost  = $v_cost + $v_cost2;
switch($code)
{
default: $l_cost = ($v_cost * $l_price) + $price; break;
}
return doubleval($l_cost);
}

public function getData()
{
$error   = false;
$check   = $this->check();
if ($check)
{
$client  = $this->getConnect();

$_param  = array (
array (
'nCdEmpresa'	      => $this->getUsername(),
'sDsSenha'		      => $this->getPassword(),
'nCdServico'		  => implode(',', $this->getServicesId()),
'sCepOrigem'	      => $this->getZipcodeSRC(),
'sCepDestino'	      => $this->getZipcodeDST(),
'nVlPeso'		      => $this->toDecimal($this->getWeight()),
'nCdFormato'	      => $this->getFormat(),
'nVlComprimento'      => $this->toDecimal($this->getLength()),
'nVlAltura'           => $this->toDecimal($this->getHeight()),
'nVlLargura'          => $this->toDecimal($this->getWidth()),
'nVlDiametro'         => $this->toDecimal($this->getDiameter()),
'sCdMaoPropria'       => $this->getMaoPropria(),
'nVlValorDeclarado'   => $this->toDecimal($this->getPrice()),
'sCdAvisoRecebimento' => $this->getReceipt()
)
);

$_result = $client->call($this->getFunction(), $_param);

$error   = $client->getError();
if($client->fault) $error = true;

$_data = array();
if (!$error)
{
$_data = $_result[$this->getFunction().'Result']['Servicos']['cServico'];
$_keys = array_keys($_data);
if (!is_numeric($_keys[0])) $_data = array($_data);
}

$this->_data = $_data;
}
return $this;
}

public function getSecure($value)
{
if($value > 0) return 'S'; else return 'N';
}

/*
* Regra de Prazo de Entrega
* Aqui é possível ajustar a sua realidade
*/
private function getDeliveryTime($time)
{
return intval($time)+$this->getTimeProcedure();
}

public function procedure()
{
$_data   = $this->_data;
$l_count = sizeof($_data);
if ($l_count > 0)
{
$x = 0;	//Inicio
while($x < $l_count) 			{ 				$l_value = $this->convertDecimal($_data[$x]['Valor']);
$l_time1 = intval($_data[$x]['PrazoEntrega']);
$l_code  = $_data[$x]['Codigo'];

//Validação dos resultados retornados
//No Manual é possível encontrar mais detalhes sobre os retornos inválidos.
if ($l_code != '' & $l_value > 0.00 & $l_time1 > 0)
{
$l_time = $this->getDeliveryTime($l_time1);

$_data[$x]['Nome']      			 = $this->getServicesName($l_code);
$_data[$x]['Descricao'] 			 = $this->getServicesTitle($l_code);
$_data[$x]['ValorReal'] 			 = $this->convertDecimal($_data[$x]['Valor']);
$_data[$x]['Valor']    				 = $this->convertDecimal($this->toNumber($this->addCost($l_code, $_data[$x]['ValorReal'])));
$_data[$x]['ValorMaoPropria'] 		 = $this->convertDecimal($_data[$x]['ValorMaoPropria']);
$_data[$x]['ValorAvisoRecebimento']  = $this->convertDecimal($_data[$x]['ValorAvisoRecebimento']);
$_data[$x]['ValorValorDeclarado'] 	 = $this->convertDecimal($_data[$x]['ValorValorDeclarado']);
$_data[$x]['ValorTotal'] 			 = $this->toDecimal($_data[$x]['Valor'] + $_data[$x]['ValorMaoPropria'] + $_data[$x]['ValorAvisoRecebimento'] + $_data[$x]['ValorValorDeclarado']);
$_data[$x]['PrazoEntrega'] 			 = $l_time;
$_data[$x]['PrazoEntregaReal']       = $l_time1;
$_data[$x]['Seguro']				 = $this->getSecure($_data[$x]['ValorValorDeclarado']);

//Elimina os resultados que não possuem dados
}else unset($_data[$x]);
$x++;
}
}
else return -1;
return $_data;
}
}
?>

Buscar CEP via WebService dos Correios

Ae galera,

para quando algum de nós precisar está ai.

Lembrando que ele busca em http://republicavirtual.com.br/
********************

<?
/*
* Função de busca de Endereço pelo CEP
* – Desenvolvido Felipe Olivaes para ajaxbox.com.br
* – Utilizando WebService de CEP da republicavirtual.com.br
*/
function busca_cep($cep){
$resultado = @file_get_contents(’http://republicavirtual.com.br/web_cep.php?cep=’.urlencode($cep).’&formato=query_string’);
if(!$resultado){
$resultado = “&resultado=0&resultado_txt=erro+ao+buscar+cep”;
}
parse_str($resultado, $retorno);
return $retorno;
}

/*
* Exemplo de utilização
*/

//Vamos buscar o CEP 90020022
//$resultado_busca = busca_cep(’90020022′);
$resultado_busca = busca_cep(’29111320′);

echo “  Array Retornada:
“.print_r($resultado_busca, true).””;

switch($resultado_busca[’resultado’]){
case ‘2′:
$texto = “
Cidade com logradouro único
Cidade: “.$resultado_busca[’cidade’].”
UF: “.$resultado_busca[’uf’].”
“;
break;

case ‘1′:
$texto = “
Cidade com logradouro completo
Tipo de Logradouro: “.$resultado_busca[’tipo_logradouro’].”
Logradouro: “.$resultado_busca[’logradouro’].”
Bairro: “.$resultado_busca[’bairro’].”
Cidade: “.$resultado_busca[’cidade’].”
UF: “.$resultado_busca[’uf’].”
“;
break;

default:
$texto = “Fala ao buscar cep: “.$resultado_busca[’resultado’];
break;
}

echo $texto;
?>