Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Luiz Henrique

Como calcular o PAC (correios)?

Recommended Posts

Olá pessoas,

 

Ustilizo um code bem fácil de entender para calculo de frete, porém não funciona ou imagino que não retorne o valor correto para o PAC pois não envia para o correios as dimenssões nem o tipo de embalagem utilizada, acredito que seja necessário isto, pois se eu for utilizar o PAC no correios eles vão media o pacote, segue code:

 

define('FRETE_PAC',        '41106');
      define('FRETE_SEDEX',      '40010');
      define('FRETE_SEDEX_10',   '40215');
      define('FRETE_SEDEX_HOJE', '40290');
      define('FRETE_E_SEDEX',    '81019');
      define('FRETE_MALOTE',     '44105');
      function calcula_frete ($servico, $origem, $destino, $peso) {
        if (!$sock = fsockopen('www.correios.com.br', 80, $errornro, $error, 60)) {
          throw new Exception($error, $errornro);
        }
        $msg = "GET /encomendas/precos/calculo.cfm?"
              ."Servico={$servico}&cepOrigem={$origem}&cepDestino={$destino}"
              ."&peso={$peso}&resposta=localhost HTTP/1.1\n"
              ."Host: www.correios.com.br\nConnection: Close\n\n";
        fwrite($sock, $msg);
        while (!feof($sock)) {
          $line = fgets($sock);
          if (!preg_match('/^Location: \w+\?(.*)$/i',$line, $match)) continue;
          $data = array();
          foreach(split('&', $match[1]) as $item) {
            $t = split('=', $item);
            $data[$t[0]] = trim($t[1]);
          }
          break;
        }
        $data['Servico'] = urldecode($data['Servico']);
        $data['erro'] = urldecode($data['erro']);
        return $data;
      }
      $result = calcula_frete(FRETE_SEDEX, '20512170', '78053378', '2');
      var_dump($result);

Como podem ver eu executo a função informando apenas o serviço, cep de origem, destino e peso, como fica o resto se o serviço for PAC?

calcula_frete ($servico, $origem, $destino, $peso)

 

Alguma dica?

Obrigado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Se não me engano no site dos correios tem como você integrar isso ao seu site, vou ver se encontro aqui, mas como você envia as requisições, se é sedex ou pac.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Mas ele faz a consulta no site do correios mesmo:

 

if (!$sock = fsockopen('www.correios.com.br', 80, $errornro, $error, 60)) {
          throw new Exception($error, $errornro);
        }
        $msg = "GET /encomendas/precos/calculo.cfm?"
              ."Servico={$servico}&cepOrigem={$origem}&cepDestino={$destino}"
              ."&peso={$peso}&resposta=localhost HTTP/1.1\n"
              ."Host: www.correios.com.br\nConnection: Close\n\n";
        fwrite($sock, $msg);

Ou tem outra forma?

 

Já procurei em tudo que é lugar, e nenhum dos códigos funciona o PAC, tanto que quem está disponibilizando o mesmo, só faz o teste no SEDEX, estou tenatndo enviar as variáveis Comprimento, Largura, Altura e Diametro junto com os outros dados mas o retorno é sempre zero, ninguém tem idéia de como fazer isso funcionar, ou alguma outra solução para cálculo de PAC, criar um banco de dados próprio, mas como proceder neste caso.

 

Obrigado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Amigos tambem tive o mesmo problema que o de vocês, depois de muito quebrar a cabeça descobri que o PAC necessita definir ALTURA, LARGURA, COMPRIMENTO e o tipo se é CAIXA ou ROLO/PRISMA.

1=CAIXA.

2=ROLO OU PRISMA.

 

Porem testei varios paramentros GET:

Como $_GET['formato']:

$formato = '1';//caixa
        $msg = "GET /encomendas/precos/calculo.cfm?"
              ."Servico={$servico}&cepOrigem={$origem}&cepDestino={$destino}"
              ."&peso={$peso}&formato={$formato}&resposta=localhost HTTP/1.1\n"
              ."Host: www.correios.com.br\nConnection: Close\n\n";

Como Formato:

Como $_GET['Formato']:

$formato = '1';//caixa
        $msg = "GET /encomendas/precos/calculo.cfm?"
              ."Servico={$servico}&cepOrigem={$origem}&cepDestino={$destino}"
              ."&peso={$peso}&formato={$formato}&resposta=localhost HTTP/1.1\n"
              ."Host: www.correios.com.br\nConnection: Close\n\n";

Dentre outros a solução foi usar outro script dos correios que suporta apenas XML ou retorno (ainda nao ta 100%, mas basta acertar conforme a necessidade):

function XML2Array ( $xml , $recursive = false )
{
    if ( ! $recursive )
    {
        $array = simplexml_load_string ( $xml ) ;
    }
    else
    {
        $array = $xml ;
    }
   
    $newArray = array () ;
    $array = ( array ) $array ;
    foreach ( $array as $key => $value )
    {
        $value = ( array ) $value ;
        if ( isset ( $value [ 0 ] ) )
        {
            $newArray [ $key ] = trim ( $value [ 0 ] ) ;
        }
        else
        {
            $newArray [ $key ] = XML2Array ( $value , true ) ;
        }
    }
    return $newArray;
}

function calcula_frete($servico, $origem, $destino, $peso, $tipo='', $largura='', $altura='', $comprimento='') {
if (!$sock = @fsockopen('shopping.correios.com.br', 80, $errornro, $error, 60)) {
	return 'Erro: '.$error.' ('.$errornro.')';
}

$servico = ($servico == 'PAC') ? 41106:(($servico == 'SEDEX')? 40010:false);

if(!$servico){
	return 'Erro: Serviço selecionado invalido';
}

$msg = "GET /wbm/shopping/script/CalcPrecoPrazo.aspx?".
"sCepOrigem={$origem}&sCepDestino={$destino}&nVlPeso={$peso}".
"&nCdFormato={$tipo}&nVlComprimento={$comprimento}&nVlAltura={$altura}&nVlLargura={$largura}&".
"sCdMaoPropria=s&sCdAvisoRecebimento=n&nCdServico={$servico}&".
"nVlDiametro=0&StrRetorno=xml HTTP/1.1\n".
"Host: shopping.correios.com.br\nConnection: Close\n\n";

fwrite($sock, $msg);

$data = '';
$ler = false;
while (!feof($sock)) {
$line = fgets($sock);
	if(!$ler){
		$ler = (preg_match('/^<'.'\?xml/i',$line, $match))? true:false;
	}

	if($ler){
		$data .= $line;
	}
}

fclose($sock);
$data = XML2Array($data);
return $ler? $data['cServico']:'Erro ao retornar a informação';
}

print_r(calcula_frete('PAC', '20512170', '78053378', 2, 1, 19, 16, 26)); // 1 = caixa | 2 = rolo ou prisma
print_r(calcula_frete('SEDEX', '20512170', '78053378', 2));
?>
Estou alterando e testando ainda

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.