Classe php para integrar com correios e recuperar informações de frete

Olá galera! O post de hoje é dedicado aos developers voltados para a área de e-commerce ou mesmo para aqueles que interessam entrar nela.

Trata-se de uma pequena classe que implementei e que é voltada para a integração de uma aplicação php com o web service dos Correios. Através dessa classe você passa o serviço, o cep de origem e de destino o peso da encomenda e ele te retorna via XML informações relevantes como valor do frete e prazo de entrega.

Então vamos ao código da classe e exemplo de como utilizá-la.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<?php
/**
 * Description of Frete.class.php
 *
 * @author Rafael Wendel Pinheiro
 */
class Frete {
 
    private $cod_servico;
    private $cep_origem;
    private $cep_destino;
    private $peso;
    private $altura = '4';
    private $largura = '12';
    private $comprimento = '16';
    private $valor = '10.00';
    private $erro;
 
    public function getCep_origem() {
        return $this->cep_origem;
    }
 
    public function setCep_origem($cep_origem) {
        $this->cep_origem = $cep_origem;
    }
 
    public function getCep_destino() {
        return $this->cep_destino;
    }
 
    public function setCep_destino($cep_destino) {
        $this->cep_destino = $cep_destino;
    }
 
    public function getPeso() {
        return $this->peso;
    }
 
    public function setPeso($peso) {
        $this->peso = $peso;
    }
 
    public function getAltura() {
        return $this->altura;
    }
 
    public function setAltura($altura) {
        $this->altura = $altura;
    }
 
    public function getLargura() {
        return $this->largura;
    }
 
    public function setLargura($largura) {
        $this->largura = $largura;
    }
 
    public function getComprimento() {
        return $this->comprimento;
    }
 
    public function setComprimento($comprimento) {
        $this->comprimento = $comprimento;
    }
 
    public function getValor() {
        return $this->valor;
    }
 
    public function setValor($valor) {
        $this->valor = $valor;
    }
 
    public function getErro() {
        return $this->erro;
    }
 
    public function setErro($erro) {
        $this->erro = $erro;
    }
 
    public function defineServico($servico){
        $servico = strtolower($servico);
        if($servico == 'pac'){
            $this->cod_servico = '41106';
        }
        elseif($servico == 'sedex'){
            $this->cod_servico = '40010';
        }
        elseif($servico == 'sedex a cobrar'){
            $this->cod_servico = '40045';
        }
        elseif($servico == 'sedex 10'){
            $this->cod_servico = '40215';
        }
        else{
            return false;
        }
    }
 
    public function calcular(){
        $ws_correios = "http://ws.correios.com.br/calculador/CalcPrecoPrazo.aspx?nCdEmpresa=&sDsSenha=&sCepOrigem=".$this->cep_origem."&sCepDestino=".$this->cep_destino."&nVlPeso=".$this->peso."&nCdFormato=1&nVlComprimento=".$this->comprimento."&nVlAltura=".$this->altura."&nVlLargura=".$this->largura."&sCdMaoPropria=n&nVlValorDeclarado=".$this->valor."&sCdAvisoRecebimento=n&nCdServico=".$this->cod_servico."&nVlDiametro=0&StrRetorno=xml";
        $xml = simplexml_load_file($ws_correios);
        if($xml->cServico->Erro == '0'){
            return $xml->cServico;
        }else{
            $this->setErro($xml->cServico->MsgErro);
            return false;
        }
    }
}

Tirando os métodos get e set dos aributos privados da classe, ela se resume a 2 funções básicas: a definição do serviço (se é PAC, SEDEX, SEDEX 10 ou SEDEX A COBRAR) e o método de execução que faz a requisição no WS dos correios e captura os resultados.

O WS exige que passamos uma série de parâmetros referentes ao envio. Alguns desses parâmetros já vem com valores padrão como a altura, largura, comprimento e valor(valor declarado: É o serviço adicional pelo qual o cliente declara o valor de um objeto postado sob registro, para fins de ressarcimento, em caso de extravio ou espoliação). Devemos ainda passar o cep de origem, cep de destino, o serviço e o peso da encomenda.

No exemplo abaixo faço uma simulação de envio de uma encomenda de um CEP de SP com destino ao RJ. Veja:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
 
require_once('Frete.class.php');
 
$frete = new Frete();
 
$frete->setCep_origem('07500000');
$frete->setCep_destino('20000000');
/*
 * TIPO DE SERVIÇO
 * VALORES VÁLIDOS:
 *  pac
 *  sedex
 *  sedex 10
 *  sedex a cobrar
 */
$frete->defineServico('sedex');
 
/*PESO EM KG (EX: SE FOR 500gr INFORME 0.5)*/
$frete->setPeso('1');
 
$retorno = $frete->calcular();
 
if($frete->getErro()){
    die("Ocorreu um erro: " . $frete->getErro());
}
 
echo "Informacoes do frete com origem ". $frete->getCep_origem() ." e destino ". $frete->getCep_destino() ." <br />";
echo "Valor do frete: $retorno->Valor reais <br />";
echo "Prazo para entrega: $retorno->PrazoEntrega dias <br />";
echo "Entrega domiciliar? $retorno->EntregaDomiciliar <br />";
echo "Entrega sabado? $retorno->EntregaSabado";
?>

A execução desse código me retorna algo semelhante ao print à seguir:

Utlização muito fácil da classe e você pode melhorá-la se desejar. E qualquer dúvida estou à disposição. É só deixar o seu comentário.

Abs.

Siga-me no twitter: @rafaelwendel

É formado em Sistemas de Informação, pós-graduado em Sistemas de Banco de Dados e mestre em Educação com foco em Tecnologias Sociocomunitárias. Trabalha como professor de ensino técnico e tecnológico no Instituto Federal de Educação, Ciência e Tecnologia de São Paulo ministrando disciplinas nas áreas de programação, banco de dados, desenvolvimento de projetos e engenharia de software.

Posts relacionados

Comentários

  1. O meu esta dando erro 500 na classe por causa do fopen teria como fazer um paleativo que nao ulilize o fopen?
    o curl talvez ?
    Agradeço des de ja !

  2. blz Rafael, cara tem como eu calcular e retorna todos os tipos de frete por exemplo

    eu digito o cep e ao clicar para calcular ele aparece SEDEX e o valor PAC e o valor

    fico no aguardo abraço

  3. O Rafael, mais uma vez encontrei a solução em seu site, parabéns pelo post, não usei a classe, mas através da sua comparei com o meu codigo mais simples e indentifiquei o meu erro, no meu ele faz um laço e traz somente os nodes ‘Valor’ e ‘PrazoEntrega’ pois e um algoritmo que faz o calculo do frete de todos os produtos do carrinho, depois soma e joga o resultado. ^^

  4. Olá! Muito bom… Só queria saber se realmente posso confiar nos valores dos fretes, pois estou desenvolvendo uma loja virtual para uma cliente então preciso realmente dos valores corretos. Obrigado.

  5. Olá, muito bom seu post.
    Estou desenvolvendo uma loja virtual e, fazendo uns testes antes de publicar, percebi que ao comprar 3 produtos, ao invés de calcular os 3 e me gerar um valor mais em conta, está somando os valores dos 3 produtos, e o frete com valor muito alto. Sabes o que pode estar acontecendo?

  6. Ola o meu ta funcionando em localhost mas o servidor online que roda em php7 ta dando erro
    : Trying to get property of non-object acho que é a parte do $retorno = $frete->calcular(); tem alguma alternativa pra resolver isso?

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *