Correios, SEDEX e o tão famigerado Cálculo de Frete

Opa?

Nesta vida de desenvolvedor web alguns desafio tendem a surgir em nosso caminho, um deles sem dúvida será este que abordarei aqui, de forma rápida de direta, o Cálculo de Frete dos Correios. Com base em cep de origem, cep de destino e o peso da encomenda, obteremos o valor do SEDEX. Recurso muito utilizado em lojas virtuais e sistemas com delivery na web =)

Algo que muitas pessoas não sabem, é que os Correios disponibilizam um serviço de consulta web, com resposta em XML(as possibilidades iniciam aí :P), de forma simples, acessado via URL, sem webservices, ai vai um exemplo deste acesso:

http://www.correios.com.br/encomendas/precos/calculo.cfm?resposta=xml&servico=40010& cepOrigem=17012-350&cepDestino=01102-000&peso=0.31

Percebam que ao acessarmos o endereço acima, obtemos um XML simples, com todos os dados necessários para a consulta. Tudo que devemos fazer é completar a URL acima com nossos dados, da seguinte forma:

servico=40010 é sedex, outros serviços tem que procurar no site dos correios
cepOrigem=17012-350 -> CEP de Origem (do teu cliente no caso)
cepDestino=88818-400 -> de quem vai receber
peso=0.62 -> peso da encomenda

Uma vez com nossa requisição devidamente configurada, basta tratarmos o XML da forma mais interessante para seu projeto. Javascript, Flash, PHP, Java, Ruby on Rails e por aí vai =P

Neste caso, criaremos uma função de exemplo em PHP para tratarmos esta resposta, e obtermos os dados de forma fácil e direta. Aí vai ela "mastigadinha":

PHP:
  1. <?php
  2.    
  3.     function getSEDEX($cepOrigem = "88818-520", $cepDestino = "88818-400", $peso = 0.5)
  4.     {
  5.         $urlCorreios = "http://www.correios.com.br/encomendas/precos/calculo.cfm?resposta=xml&servico=40010&cepOrigem=%s&cepDestino=%s&peso=%s";
  6.        
  7.         $urlCorreios = sprintf($urlCorreios, $cepOrigem, $cepDestino, $peso);
  8.        
  9.         //carregando url dos correios...
  10.         //caso o seu servidor não permita o uso da função file para url's externas
  11.         //recomenda-se a utilização de CURL - http://www.php.net/manual/en/ref.curl.php
  12.         $carrega = file($urlCorreios) or die("Problemas em obter os dados dos correios");
  13.        
  14.         //tratando string xml obtida. Removendo espaços e linhas para facilitar...
  15.         $conteudo = trim(str_replace(array("\n", chr(13)), "", implode($carrega, "")));
  16.        
  17.         if(strlen($conteudo) <1) return false;
  18.        
  19.         //informações de origem tratadas com RegExp...
  20.         preg_match_all("/<uf_origem>(.+)<\/uf_origem>/", $conteudo, $uf_origem);
  21.         preg_match_all("/<local_origem>(.+)<\/local_origem>/", $conteudo, $local_origem);
  22.         preg_match_all("/<cep_origem>(.+)<\/cep_origem>/", $conteudo, $cep_origem);
  23.        
  24.         //informações de destino tratadas com RegExp...
  25.         preg_match_all("/<uf_destino>(.+)<\/uf_destino>/", $conteudo, $uf_destino);
  26.         preg_match_all("/<local_destino>(.+)<\/local_destino>/", $conteudo, $local_destino);
  27.         preg_match_all("/<cep_destino>(.+)<\/cep_destino>/", $conteudo, $cep_destino);
  28.        
  29.         //informações sobre a encomenda tratadas com RegExp...
  30.         preg_match_all("/<peso>(.+)<\/peso>/", $conteudo, $peso);
  31.         preg_match_all("/<preco_postal>(.+)<\/preco_postal>/", $conteudo, $preco_postal);   
  32.        
  33.         //objeto contendo as informações sobre o frete...
  34.         $sedex = array(
  35.             "uf_origem" => $uf_origem[1][0],
  36.             "local_origem" => $local_origem[1][0],
  37.             "cep_origem" => $cep_origem[1][0],
  38.             "uf_destino" => $uf_destino[1][0],
  39.             "local_destino" => $local_destino[1][0],
  40.             "cep_destino" => $cep_destino[1][0],
  41.             "peso" => floatval($peso[1][0]),
  42.             "valor" => floatval($preco_postal[1][0])
  43.         );
  44.        
  45.         return $sedex;
  46.     }
  47.    
  48.     //informações processadas. Cep de Origem, Cep destino, Peso...
  49.     $sedex = getSEDEX("88818-520", "88818-400", 0.750);
  50.    
  51.     //enfim exibimos o valor de nossa encomenda...
  52.     echo "R$ " . number_format($sedex["valor"], 2, ",", ","); //valor do sedex, já formatado em reais...
  53.  
  54. ?>

Uma vez com a função getSEDEX executada, obtemos todos os dados tratado no retorno da mesma.

Fácil não?

Abracetas... ;)

45 Comments

rssComments RSS transmitTrackBack Identifier URI


Blz? Mas como pegar os dados de dias uteis de um cep para outro?

Obrigado

Comment by Marcelo on 06/04/2008 3:08 pm


Cara muito obrigado!

Comment by Fabio Issamu Oshiro on 24/04/2008 2:49 pm


Boa noite,
achei sua função muito boa.. me ajudou muito, só que tenho um dúvida e gostaria de sua ajuda.
caso a pessoal digite um cep inválido por exemplo: 000, o xml me retornaria um cod de erro diferente de 0, como poderia capiturar o propriedade “codigo” do xml? assim verificaria se codigo é diferente de 0 e informaria que o cep é inválido.. fui claro? obrigado!

Comment by Jannier on 25/04/2008 8:28 pm


Rapaz, você não sabe como essa rotina me ajudou no site que estou construindo. Parabéns.

Comment by Luciano on 13/05/2008 1:10 am


é impressão minha ou essa página fornecida pelo correios fica offline direto?

Comment by Bruno on 15/06/2008 4:56 pm


meu servidor esta com file-access desabilitado.
tem como ativar vai “.htaccess”?
se não, como faço para utilizar cURL?

Comment by Felipe Roberto on 28/06/2008 12:26 pm


Perfeito, obrigado pela ajuda.

Comment by Rodrigo on 20/07/2008 11:06 pm


Materia legal, acho que isso vai ajudar um pouco

function SEDEX($cepOrigem, $cepDestino , $peso){
$f = “http://www.correios.com.br/encomendas/precos/calculo.cfm?resposta=xml&servico=40010&cepOrigem=$cepOrigem&cepDestino=$cepDestino&peso=$peso”;
$entry = utf8_encode(simplexml_load_file($f));
$descricao = $entry->dados_postais->preco_postal;
return $descricao;
}
echo SEDEX(’88818-520′, ‘88818-400′, ‘0.5′);

Comment by Ariel on 02/08/2008 7:29 am


ops: tire a funcão utf8_encode da linha 3. tava so fazendo uns testes e esqueci de tirar….

Comment by Ariel on 02/08/2008 7:35 am


Para quem quiser os outros códigos do Sedex segue ae.

40010 -> SEDEX
40290 -> SEDEX Hoje
40215 -> SEDEX 10
40045 -> SEDEX a Cobrar
41017 -> Encomenda Normal

Aquele abraço

Comment by Tiago on 11/08/2008 4:23 pm


Alguém sabe me dizer se para o e-Sedex este código também funciona?

Comment by Márcio on 02/09/2008 3:56 pm


81019 -> e-SEDEX

Comment by Yuri Azambuja on 15/09/2008 3:46 pm


Funciona!
Parabéns!

Comment by Marcelo on 02/10/2008 11:06 pm


Eu acho q existe uma tarifa excedente sobre o valor da transação(tarifa valor declarado).
Eu coloquei o valor declarado(valor da transação) como mais um argumento na função.

# FRETE PAC = 41106
function getSEDEX($cepOrigem, $cepDestino, $peso, $valorDeclarado)
{
$urlCorreios = “http://www.correios.com.br/encomendas/precos/calculo.cfm?resposta=xml&servico=41106&cepOrigem=%s&cepDestino=%s&peso=%s&valorDeclarado=%s”;

$urlCorreios = sprintf($urlCorreios, $cepOrigem, $cepDestino, $peso, $valorDeclarado);

//carregando url dos correios…
//caso o seu servidor não permita o uso da função file para url’s externas
//recomenda-se a utilização de CURL - http://www.php.net/manual/en/ref.curl.php
$carrega = file($urlCorreios) or die(”Problemas em obter os dados dos correios”);

//tratando string xml obtida. Removendo espaços e linhas para facilitar…
$conteudo = trim(str_replace(array(”\n”, chr(13)), “”, implode($carrega, “”)));

if(strlen($conteudo) <1) return false;

//informações de origem tratadas com RegExp…
preg_match_all(”/(.+)/”, $conteudo, $uf_origem);
preg_match_all(”/(.+)/”, $conteudo, $local_origem);
preg_match_all(”/(.+)/”, $conteudo, $cep_origem);

//informações de destino tratadas com RegExp…
preg_match_all(”/(.+)/”, $conteudo, $uf_destino);
preg_match_all(”/(.+)/”, $conteudo, $local_destino);
preg_match_all(”/(.+)/”, $conteudo, $cep_destino);

//informações sobre a encomenda tratadas com RegExp…
preg_match_all(”/(.+)/”, $conteudo, $peso);
preg_match_all(”/(.+)/”, $conteudo, $valor_declarado);
preg_match_all(”/(.+)/”, $conteudo, $tarifa_valor_declarado);
preg_match_all(”/(.+)/”, $conteudo, $preco_postal);

//objeto contendo as informações sobre o frete…
$sedex = array(
“uf_origem” => $uf_origem[1][0],
“local_origem” => $local_origem[1][0],
“cep_origem” => $cep_origem[1][0],
“uf_destino” => $uf_destino[1][0],
“local_destino” => $local_destino[1][0],
“cep_destino” => $cep_destino[1][0],
“peso” => floatval($peso[1][0]),
“valor_declarado” => floatval($valor_declarado[1][0]),
“tarifa_valor_declarado” => floatval($tarifa_valor_declarado[1][0]),

“valor” => floatval($preco_postal[1][0])
);

return $sedex;
}

//informações processadas. Cep de Origem, Cep destino, Peso…
$sedex = getSEDEX(”20040-320″, “88818-400″, 0.750, 900);

//enfim exibimos o valor de nossa encomenda…
echo “R$ ” . number_format($sedex["valor"], 2, “,”, “,”); //valor do sedex, já formatado em reais…

}

Comment by Marcelo on 03/10/2008 3:16 pm


Desculpa só não si onde coloca ese código em qual arquivo ?? coloquei numa pagina e deu erro tipo apareceu o próprio código
como fazer ??
obrigada

Comment by katya on 04/10/2008 5:25 am


Fala Lucas,

Parabéns pela função, me ajudou muito, eu estava criando um formulário de compra com o Jquery, mas não encontrava nenhuma função que retornasse o valor do sedex, me ajudou muito!

Abraços!

Diego Soares

Comment by Diego Soares on 14/11/2008 1:54 pm


Amigão, não está funcionando. Está assim em todos os exemplos da internet… O que pode ser??? acho que os CORREIOS mudaram alguma coisa em seu WEBSERVICE.

Comment by Kleyton Barcelos on 26/11/2008 10:30 am


eles alteraram sim alguma coisa no sistema, todo mundo tá tendo problema com isso… o estagiário deve ter feito alguma cagada e o povão só se f***

Comment by clayton on 26/11/2008 3:09 pm


É galera,

Me desculpe mas eu só uso o webservice fornecido pelos Correios no script, se mesmo da pau é culpa dos Correios, eu só demonstrei uma forma mais fácil de acessa-lo!

Abraços ;)

Comment by Lucas Ferreira on 26/11/2008 3:28 pm


Pos é. Estou tendo o mesmo problema;

Foda!
Caso encontre alguma solução. Posto aqui.

Comment by Ricardo on 26/11/2008 3:31 pm


Estou com o mesmo problema, se alguem encontrar alguma solução ficarei grato se for informado

Comment by Ernane on 26/11/2008 4:12 pm


De acordo com a LocaWeb. Na qual entrei em contato agora a pouco;
Se trata de um erro passageiro no site dos Correios.

Att;

Comment by Ricardo on 26/11/2008 4:56 pm


Lucas Ferreira, muitíssimo obrigado.

Tomei a liberdade de enxugar seu código e acrescentar uma pequena melhoria: o código do serviço. Segue abaixo:

<?php

function CalculaFrete( $cepOrigem, $cepDestino, $peso, $servico )
{
$urlCorreios = “http://www.correios.com.br/encomendas/precos/calculo.cfm?resposta=xml&servico=$servico&cepOrigem=%s&cepDestino=%s&peso=%s”;

$urlCorreios = sprintf($urlCorreios, $cepOrigem, $cepDestino, $peso);

//carregando url dos correios…
//caso o seu servidor não permita o uso da função file para url’s externas
//recomenda-se a utilização de CURL - http://www.php.net/manual/en/ref.curl.php
$carrega = file($urlCorreios) or die(”Problemas em obter os dados dos correios”);

//tratando string xml obtida. Removendo espaços e linhas para facilitar…
$conteudo = trim(str_replace(array(”\n”, chr(13)), “”, implode($carrega, “”)));

if(strlen($conteudo) <1) return false;

preg_match_all(”/(.+)/”, $conteudo, $preco_postal);

//objeto contendo as informações sobre o frete…
$frete = floatval($preco_postal[1][0]);

return $frete;
}

//informações processadas. Cep de Origem, Cep destino, Peso…

@$sedex = CalculaFrete( “49085-050″, “81110-270″, 3, “40010″ );
@$pac = CalculaFrete( “49085-050″, “81110-270″, 3, “41017″ );
//@$sedexH = CalculaFrete( “49085-050″, “81110-270″, 1, “40290″ );
//@$sedex10 = CalculaFrete( “49085-050″, “81110-270″, 1, “40215″ );
//@$sedexC = CalculaFrete( “49085-050″, “81110-270″, 1, “40045″ );

//enfim exibimos o valor de nossa encomenda…
echo “Sedex - R$ ” . number_format( $sedex, 2, “,”, “,” ) . “”;
echo “Encomenda Normal - R$ ” . number_format( $pac, 2, “,”, “,” ) . “”;

?>

Comment by Manoel Neto on 16/12/2008 6:16 am


Este serviço é permitido pelos correios ?? ou é um furo no sistema que pode parar de funcionar ???

Se o serviço for PAC tem ainda as dimensoes da encomenda que precisa constar.

Achei o script otimo, so tenho estas duvidas, se nao vai parar de funcionar, como aconteceu com a busca de endereço pelo CEP, que tambem era feito + - desta maneira.

Entrando em contato com os correios a resposta sobre como calcular o frete na loja virtual foi: o calculador de preços é disponibilizado aos clientes com vínculo contratual com os Correios, utilizando-se dos dados do contrato, o Sr. póderá *baixar* o aplicativo. Aos clientes que não possuem vínculo os Coreios disponibilizam na sua página (www.correios.com.br) o simulador.

Mas pelo q entendi seria um programa para calcular o frete e nao um script para colocar no site.

Comment by Maicon on 28/01/2009 10:47 am


Manim… naum sou de dexa msg… mais cara esse teu scrip me ajudo d+++++..

muito boa sua explcação tbm…

vlw msm.

Comment by Fabiano on 09/02/2009 7:14 pm


Galera, acho que o correio ja barrou esta forma também, pareçe que eles querem mesmo que todos realizem contratos para poder ter acesso a isso.

Acho que dançamos.. denovo..

Comment by Rafael on 22/04/2009 5:14 pm


Dito e Feito… como o Maicon Falou, ja deu merda aqui…. meu scritp (basicamente igual o do artigo) parou de funcionar, acho que o pessoal do correio corrigiu o Bugg
Tens a solução? To ferrado pra arrumar as lojas virtuais que fiz!!!

Jonathas

Comment by Jonathas on 23/04/2009 2:10 pm


Parece que os correios mudaram o endereço…

Comment by Eder on 23/04/2009 4:38 pm


As vezes o site dos correios fica offline =[

Comment by bruno on 23/04/2009 5:31 pm


É oque o colega mencionou acabou de acontecer hoje o link http://www.correios.com.br/encomendas/precos/calculo.cfm não existe mais.
Agora meu script q pegava esse link gerou um transtorno com os meus clientes..Custa os correios deixar algum link fixo. Parecem que fazem de sacanagem

Comment by Fabian on 23/04/2009 5:45 pm


Muito bom, o melhor script que encontrei..
abraço!

Comment by wodonos on 30/04/2009 2:51 am


O serviço dos correios de calculo de frete esta cada vez pior, sai fora do ar direto, deixa todo mundo a ver navios.

Para solucionar este problema, venho compartilhar com todos vocês um serviço de calculo de frete, o CALCULADOR LIVRE. O calculo é muito simples, o
retorno é em XML, veja um exmeplo:

http://frete.w21studio.com/calFrete.xml?cep=72600000&cod=1000&peso=10&comprimento=60&largura=60&altura=5&servico=3

Note que não há cep de origem, isso porque o cep de origem esta vinculado ao parametro ‘cod’ da url. Este código você receberá ao se cadastrar no site
http://frete.w21studio.com/

No exemplo acima utilizei o “cod 1000″ de exemplo. O cep vinculado a esta conta é: 72853035

Só lembrando, o cadastro é necessário, mas é GRATUITO

Comment by Edu on 04/05/2009 11:24 pm


Quero saber como faço para colocar no orkut, pois faço vendas de artesanato pelo orkut.

Comment by Ingrid on 24/05/2009 5:59 pm


os correios sempre estão com problemas..
estou utilizando os correios e pagseguro.
quando o site dos correios estiver OFF-line automaticamente calcula com o Pagseguro.
não coloquei o pagseguro por que demora em fazer o calculo. mais é de certeza.

CLASSE DO PAGSEGURO:

http://visie.com.br/pagseguro/frete-php.php

Comment by Amixel on 13/10/2009 8:37 am


estou com problema na implementação do e-sedex para o virtuemart, ele está hospedadom fora da locaweb e pelo que estou lendo apenas eles estão com calculo online do e-sedex que precisa de empresa e senha para dar o retorno. alguém conhece alguma solução?

Comment by criacao-sites on 16/11/2009 2:48 pm


Olá Lucas,
Gostaria que me ajudasse.
O que eu preciso é de 3 baners no meu blog da bol em tres produtos diferentes que tenho lá, onde o cliente só colocasse o seu cep para que ele saiba qto irá custar o frete para cidade dele.
Tipo tenho a foto de um produto no site 1 pagina em baixo dele um banner escrito
calcule o frete
deste item aqui

a pessoa clicaria neste banner e abriria uma janela pedindo para que ela digitasse o cep dela
e ao dar ok aparecesse o valor do produto tipo R$ 40,00 frete R$ 13,00 Total R$ 53,00, logicamente o valor vai variar de acordo com o cep da pessoa, pois as medidas peso e cep origem já estarão pré estabelecida por nós.
Pode me ajudar?
visite mei site/blog e veja que fiz várias tentativas sem exito, porque nãda entendo de blog/site
agradeço
Dr Dog - silvio

Comment by dr dog on 24/11/2009 7:00 pm


Muito boa a função, principalmente a captura dos dados via expressão regular.

Só acho que o acesso a URL ficaria melhor via Curl.

Um abraço!

Comment by Leonardo Cesar Teixeira on 30/12/2009 9:29 am


Salve grande Lucas beleza.

Meu nobre amigo percebi que seu código é fantástico e muito bom “Parabéns”. Percebi que os correios realmente tirou o serviço free do frete.
Pois bem, dei uma olhada nos fretes free que tem na web e achei dois links - um que o nosso amigo Edu Colocou “frete.w21studio.com” e estou usando esse do http://www.republicavirtual.com.br/busca_de_cep/PHP/ porem esse aqui nao esta com a base atualizada de CEPs e o do EDU esta OK - testado e realmente batendo os valores de sedex e PAC.
A pergunta é como eu implemento na sua funcao o novo link frete.w21studio.com, pois ele nao acha nenhum parametro mesmo com os dados corretos e a conta ja criada no site.

Se puder me dar uma ajuda eu fico grato - Forte Abraco e otimo ano pra vc - sucesso e paz.

Comment by andre nvoaski on 06/01/2010 1:23 pm


Consegui desenvolver a solução de cálculo do esedex para o virtuemart! PENEI 1 mês mas resolvi. Desculpem a demora no post

Comment by criacao-sites montagem e otimização de websites on 24/01/2010 10:44 am


[...] Lucas Ferreira » Archive » Correios, SEDEX e o tão famigerado Cálculo de Frete [...]

Pingback by Lucas Ferreira » Archive » Correios, SEDEX e o tão famigerado Cálculo de Frete | e-commerce News on 17/06/2010 1:05 pm


Estou procurando um programador para desenvolver um modulo de frete para minha loja em wordpress, preciso de algumas coisas que não existem no modelo que consegui no pagseguro como:

- incluir valor da embalagem R$2,50
- incluir valor do seguro de 1% sobre o total da compra.

Se alguém tiver interesse em desenvolver estou em são paulo, meu email luis@roll-laden.net
Me mande um email que passo os detalhes do projeto.

Comment by luislins on 07/08/2010 1:13 pm


Ola! Pessoal,

Montei duas bases de dados, uma com todos os ceps do pais (base GPBe 2010) e outra com o valor do frete via Sedex e PAC para todos os destinos do pais, resumindo, [b]desenvolvi um módulo PHP offline para consulta de ceps e frete via PAC e Sedex[/b].

Aos interessados em participar / testar / avaliar / melhorar / usar o sistema, favor acompanhar o desenvolvimento no Forum iMasters, neste link: http://forum.imasters.uol.com.br/index.php?/topic/407875-modulo-off-line-para-calculo-de-frete-dos-correios/

Abraço a todos.

Comment by Fernando Lima on 06/09/2010 7:10 pm


Muito bem pensado ;D
Vlw!

Comment by Alex Garcia on 07/12/2010 10:08 pm

addLeave a comment