Retorno Automatico Pagseguro


(Guilhermesutto91) #1

Boa Tarde Galera,

To precisando fazer um retorno automático do pagSeguro e estou tendo problemas.

Dentro da framework, parece que o pagSeguro não consegue nem acessar meu script, porque eu deixei um simples insert na minha action e quando eu executo ela na mão, ela insere o registro no banco, e quando eu faço a transaçao no pagseguro nada acontece.

Não sei se tem alguma restrição do framework ou algo do gênero.

Se alguem puder ajudar, desde ja agradeço.


(Newerton Araujo) #2

Guilherme,

Ta usando a API 2?

Você já fez a configuração da URL dentro do PagSeguro?

Vai em Integrações >> Notificações de Transação.

Vai em Integrações >> Retorno automático dos dados.

Lá você coloca a URL completa para onde deseja receber os dados da transação.

Se tiver tudo configurado e mesmo assim não estiver funcionando, registra todos os $_POST em um log, e veja o que recebe do pagseguro.


(Newerton Araujo) #3

Dei uma enxugada no meu action.




<?php


public function actionRetorno() {


	// LOG

	Yii::log('PagSeguro: [POST] ' . serialize($_POST), CLogger::LEVEL_INFO);

	Yii::log('PagSeguro: [GET] ' . serialize($_GET), CLogger::LEVEL_INFO);


	$code = (isset($_POST['notificationCode']) && trim($_POST['notificationCode']) !== "" ? trim($_POST['notificationCode']) : null);

	$type = (isset($_POST['notificationType']) && trim($_POST['notificationType']) !== "" ? trim($_POST['notificationType']) : null);


	if ($code && $type) {


		$notificationType = new PagSeguroNotificationType($type);

		$strType = $notificationType->getTypeFromValue();


		switch ($strType) {


			case 'TRANSACTION':


				$credentials = new PagSeguroAccountCredentials(configuracao('pagseguro_email'), configuracao('pagseguro_token'));


				try {

					$transaction = PagSeguroNotificationService::checkTransaction($credentials, $code);


					$transactionStatus = $transaction->getStatus(); //Status da transação

					$paymentMethod = $transaction->getPaymentMethod(); //Dados do meio de pagamento escolhido pelo comprador

					$parcelas = $transaction->getInstallmentCount(); //Número de parcelas que o comprador escolheu no pagamento com cartão de crédito

					$pagSeguroShipping = $transaction->getShipping(); //Dados do frete

					$id_pedido = $transaction->getReference(); //Código de referência da transação


					$model = Pedido::model()->findByPk($id_pedido);


					// Obtendo o tipo de pagamento escolhido

					$payment_code = $paymentMethod->getCode();

					$comment = "Tipo de pagamento: " . $payment_code->getTypeFromValue() . " / Parcelas: " . $parcelas . "\n\n";


					// Obtendo o tipo e o valor do frete

					$pagSeguroShippingType = $pagSeguroShipping->getType();

					$valor_frete = $pagSeguroShipping->getCost();


					// Valor 1: Pac, valor 2: Sedex, valor 3: não especificado ou cálculo não realizado pelo PagSeguro

					if ($pagSeguroShippingType->getValue() != 3) {

						$comment .= "Tipo de frete escolhido no PagSeguro: " . $pagSeguroShippingType->getTypeFromValue() . " / Valor: " . $valor_frete;

					}


					switch ($transactionStatus->getTypeFromValue()) {


						case 'WAITING_PAYMENT':

							$model->pagsegurostatus_id = 1;

							break;

						case 'IN_ANALYSIS':

							$model->pagsegurostatus_id = 2;

							break;

						case 'PAID':

							$model->pagsegurostatus_id = 3;

							break;

						case 'AVAILABLE':

							$model->pagsegurostatus_id = 4;

							break;

						case 'IN_DISPUTE':

							$model->pagsegurostatus_id = 5;

							break;

						case 'REFUNDED':

							$model->pagsegurostatus_id = 6;

							break;

						case 'CANCELLED':

							$model->pagsegurostatus_id = 7;

							break;

					}


					if ($model->validate()) {

						$model->save()

					}

				} catch (PagSeguroServiceException $e) {

					Yii::log('PagSeguro: ' . $e->getMessage());

					//die($e->getMessage());

				}

				break;


			default:

				Yii::log('PagSeguro: tipo de notificação desconhecido [' . $notificationType->getValue() . ']', CLogger::LEVEL_INFO);

		}

	} else {

		Yii::log('PagSeguro: Parâmetros de notificação inválidos.', CLogger::LEVEL_INFO);

	}

}



Olha com calma cada linha.

Se deseja salvar a transação e enviar email, faça dentro do if ($model->validate()) {


(Guilhermesutto91) #4

Cara, desculpe minha ignorância, estou iniciando ainda.

Não entendi muito esse código que você postou.

A API que estou usando, acredito que seja a API antiga.

Na minha acc do PagSeguro a pagina de retorno esta configurada assim

http: // meusite. com. br/ index. php ?r=retorno/Index (coloquei os espaços pq eu nao posso postar links aqui no forum ainda)

que é o link já online, do script que eu quero executar.

Tinha feito um teste, deixando só um insert básico nesse script.

Fiz uma compra no Pagseguro nada aconteceu.

Depois eu coloquei o mesmo script dentro de outro sistema ja publicado, só que sem o framework, e fiz outra compra no pagseguro, o script rodou normalmente.

Segue o código da minha action de retorno.(Esse mesmo código peguei em um post aqui do fórum e acredito que tenha sido voce que publicou, estava tentando com outro mas achei este melhor).


class RetornoController extends Controller {


    public function actionIndex() {


        $retorno_token = '9E5B6FB5BAA645A28FA468C66F133DCF';


        $PagSeguro = 'Comando=validar';

        $PagSeguro .= '&Token=' . $retorno_token;

        $Cabecalho = "Retorno PagSeguro";


        foreach ($_POST as $key => $value) {

            $value = urlencode(stripslashes($value));

            $PagSeguro .= "&$key=$value";

        }


        if (function_exists('curl_exec')) {

            $curl = true;

        } elseif ((PHP_VERSION >= 4.3) && ($fp = @fsockopen('s sl://pags eguro. uol.com .b r', 443, $errno, $errstr, 30))) {

            $fsocket = true;

        } elseif ($fp = @fsockopen('pagseguro.uol.com.br', 80, $errno, $errstr, 30)) {

            $fsocket = true;

        }


        if ($curl == true) {


            $ch = curl_init();


            curl_setopt($ch, CURLOPT_URL, 'htt ps:/ /pagseg uro.uo l.com.br/Se curity/NP I/De fault.aspx');

            curl_setopt($ch, CURLOPT_POST, true);

            curl_setopt($ch, CURLOPT_POSTFIELDS, $PagSeguro);

            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

            curl_setopt($ch, CURLOPT_HEADER, false);

            curl_setopt($ch, CURLOPT_TIMEOUT, 30);

            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);


            curl_setopt($ch, CURLOPT_URL, 'htt ps: // pagseguro .uol. com .br/Security/ NPI /Default .aspx');

            $resp = curl_exec($ch);


            curl_close($ch);

            $confirma = (strcmp($resp, "VERIFICADO") == 0);

        } elseif ($fsocket == true) {

            $Cabecalho = "POST /Security/NPI/Default.aspx HTTP/1.0\r\n";

            $Cabecalho .= "Content-Type: application/x-www-form-urlencoded\r\n";

            $Cabecalho .= "Content-Length: " . strlen($PagSeguro) . "\r\n\r\n";


            if ($fp || $errno > 0) {

                fputs($fp, $Cabecalho . $PagSeguro);

                $confirma = false;

                $resp = '';

                while (!feof($fp)) {

                    $res = @fgets($fp, 1024);

                    $resp .= $res;

                    if (strcmp($res, "VERIFICADO") == 0) {

                        $confirma = true;

                        break;

                    }

                }

                fclose($fp);

            } else {

                echo "$errstr ($errno)<br />\n";

            }

        }




        if ($confirma) {


            // Recebendo Dados

            $TransacaoID = $_POST['TransacaoID'];

            $VendedorEmail = $_POST['VendedorEmail'];

            $Referencia = $_POST['Referencia'];

            $TipoFrete = $_POST['TipoFrete'];

            $ValorFrete = $_POST['ValorFrete'];

            $Extras = $_POST['Extras'];

            $Anotacao = $_POST['Anotacao'];

            $TipoPagamento = $_POST['TipoPagamento'];

            $StatusTransacao = $_POST['StatusTransacao'];

            $CliNome = $_POST['CliNome'];

            $CliEmail = $_POST['CliEmail'];

            $CliEndereco = $_POST['CliEndereco'];

            $CliNumero = $_POST['CliNumero'];

            $CliComplemento = $_POST['CliComplemento'];

            $CliBairro = $_POST['CliBairro'];

            $CliCidade = $_POST['CliCidade'];

            $CliEstado = $_POST['CliEstado'];

            $CliCEP = $_POST['CliCEP'];

            $CliTelefone = $_POST['CliTelefone'];

            $NumItens = $_POST['NumItens'];


            if ($TransacaoID <> '') {


                $select = "SELECT TransacaoID FROM pagsegurotransacoes WHERE TransacaoID = '{$TransacaoID}'";

                $countTransacao = Yii::app()->db->createCommand($select)->query()->getRowCount();


                if ($countTransacao == 0) {

                    $insert = "INSERT into pagsegurotransacoes SET TransacaoID='$TransacaoID',

                    VendedorEmail='$VendedorEmail', Referencia='$Referencia',TipoFrete='$TipoFrete',

                    ValorFrete='$ValorFrete', Extras='$Extras',

                    Anotacao='$Anotacao', TipoPagamento='$TipoPagamento',

                    StatusTransacao='$StatusTransacao', CliNome='$CliNome',

                    CliEmail='$CliEmail', CliEndereco='$CliEndereco',

                    CliNumero='$CliNumero', CliComplemento='$CliComplemento',

                    CliBairro='$CliBairro', CliCidade='$CliCidade',

                    CliEstado='$CliEstado', CliCEP='$CliCEP',

                    CliTelefone='$CliTelefone', NumItens='$NumItens',

                    coddoacao = '', Data=now();";


                    Yii::app()->db->createCommand($insert)->execute();

                } else if ($countTransacao >= 1) {

                    $update = "UPDATE pagsegurotransacoes SET 

                    TipoPagamento = '{$TipoPagamento}',

                    StatusTransacao = '{$StatusTransacao}'

                    WHERE TransacaoID = '{$TransacaoID}'";

                    Yii::app()->db->createCommand($update)->execute();

                }

            }

        }

    }


}


(Rmaranhao) #5

Newerton,

em primeiro lugar, parabéns pelo código. Você me salvou de um mundo de documentações conflitantes.

Em segundo lugar, você pode fazer

model()->pagsegurostatus_id = $transactionStatus->getValue();

e economizar mais algumas linhas!!!


(Newerton Araujo) #6

Boa observação.

Eu deixei com números, por que eu altero o numero do WAITING_PAYMENT para 3 (PAID), para fazer teste sem efetuar o pagamento pelo pagseguro.

Uma boa pra testar sem pagar.


(Rmaranhao) #7

Depois de muita luta com códigos de notificação e transação (e de um copy e paste do seu código), cheguei no seguinte código:




public function ProcessaNotificacao($notification_code, $type){

		// Abstrai o codigo de notificação;

		// Simplesmente busca o código da transação e chama a função que atualiza a transação.

		Yii::log('Notificacao: ' . $notification_code, CLogger::LEVEL_INFO);


	    $token = $this->mytoken;

	    $email = $this->myemail;

        $credentials = new PagSeguroAccountCredentials($email, $token);


		if ($notification_code && $type){

			$transaction = PagSeguroNotificationService::checkTransaction($credentials, $notification_code);

			$transaction_code = $transaction->getCode();

			$this->AtualizaTransacao($transaction_code);

		}

	}


	public function AtualizaTransacao($code) {

		Yii::log('Atualizando transação: ' . $code, CLogger::LEVEL_INFO);


	    $token = $this->mytoken;

	    $email = $this->myemail;

        $credentials = new PagSeguroAccountCredentials($email, $token);


        try {

                $transaction = PagSeguroTransactionSearchService::searchByCode($credentials, $code);


                $transactionStatus = $transaction->getStatus(); //Status da transação

                $codStatus = $transactionStatus->getValue();

                $strStatus = $transactionStatus->getTypeFromValue();

                $pagSeguroShipping = $transaction->getShipping(); //Dados do frete


                $idpedido = $transaction->getReference(); //Código de referência da transação

                // die("Pedido: $idpedido");

                $pessoa_id = substr($idpedido, strpos($idpedido, 'P')+1, strpos($idpedido, 'C')-(strpos($idpedido, 'P')+1)) ;

                $curso_id = substr($idpedido, strpos($idpedido, 'C')+1, <img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' />;


                Yii::log("Pedido: $idpedido; Situação: $codStatus - $strStatus;", CLogger::LEVEL_INFO);

                if ($_GET['debug'] == 'true') {

                    echo("<BR><BR>Codigo:" . $transaction->getCode());

                    echo("<BR>Status:" .$transaction->getStatus()->getTypeFromValue());

                    echo("<br>Pessoa: $pessoa_id");

                    echo("<br>Curso: $curso_id");

                }

                

                $retornoPs = RetornoPs::model()->findbypk($code);


                if ($retornoPs === null){

                    Yii::log('Nova transação. Code: ' . $code, CLogger::LEVEL_INFO);

                    if ($_GET['debug'] == 'true') echo("<BR>Nova transação. $code");

                    $retornoPs = new RetornoPS;

                    $retornoPs->id = $code;

                    $inscricao = Inscricao::model()->find('pessoa_id=:pessoa and curso_id=:curso', array(':pessoa'=>$pessoa_id, ':curso'=>$curso_id));

                    $retornoPs->inscricao_id = $inscricao->id;

					$retornoPs->referencia = $idpedido;

					$retornoPs->tipofrete = $pagSeguroShipping->getType()->getValue();

					$retornoPs->valor_frete = $pagSeguroShipping->getCost();

					$retornoPs->tipo_pagamento = $transaction->getPaymentMethod()->getType()->getValue();

					$retornoPs->status_id = $codStatus;

					$retornoPs->status = $strStatus;

					$retornoPs->data_criacao = date('d/m/Y');

                } 

                if ($transaction->getStatus()->getValue() == 3) {

                    Yii::log('Transação paga: REF ' . $code, CLogger::LEVEL_INFO);

                    if ($_GET['debug'] == 'true') echo("<BR>Transação paga: $code");

                    if (!isset($retornoPs->data_pagamento)){

                        if ($_GET['debug'] == 'true') echo('<BR>Data de pagamento setada.');

                        $retornoPs->data_pagamento=date('d/m/Y');    

                    }

                }


                if ( ($transaction->getStatus()->getValue() == 5) ||    // In Dispute

                     ($transaction->getStatus()->getValue() == 6) ||    // Refunded

                     ($transaction->getStatus()->getValue() == 7) ) {   // Cancelled

                    Yii::log('Transação cancelada: REF ' . $code, CLogger::LEVEL_INFO);

                    if ($_GET['debug'] == 'true') echo("<BR>Transação cancelada: $code");

                    if (!isset($retornoPs->data_cancelamento)){

                        if ($_GET['debug'] == 'true') echo('<BR>Data de cancelamento setada.');

                        $retornoPs->data_cancelamento=date('d/m/Y');    

                        $retornoPs->save();

                    }

                }


                $retornoPs->data_atualizacao=date('d/m/Y');    

                $retornoPs->save();


        } catch (PagSeguroServiceException $e) {

                Yii::log('PagSeguro: ' . $e->getMessage());

                //die($e->getMessage());

        }

	}




Ainda não é definitivo, mas posto aqui porque acho que pode ajudar muita gente a entender a diferença entre código de notificação e de transação.

Desculpem pela indentação do código acima. Não sei o que está acontecendo…


(Rmaranhao) #8

A vantagem das funções é que os neuróticos podem checar se perderam alguma notificação:




	public function VerificaSemana(){

        $initialDate = date('Y-m-d\Th:m', strtotime("-7 days"));

        $finalDate   = date('Y-m-d\Th:m');


        $_GET['debug'] = true;


		Yii::log('Verificando todas as transações.', CLogger::LEVEL_INFO);


	    $token = $this->mytoken;

	    $email = $this->myemail;

        $credentials = new PagSeguroAccountCredentials($email, $token);


        $result = PagSeguroTransactionSearchService::searchByDate($credentials, 1, 40, $initialDate, $finalDate);

            

        $transactions = $result->getTransactions();

		if (is_array($transactions) && count($transactions) > 0) {

		    foreach($transactions as $resumo_transacao) {

		    	$this->AtualizaTransacao($resumo_transacao->getCode()); 

		    }

		}

	}



Todas essas funções ficam no meu controller. Duas variáveis ($mytoken e $myemail) fazem parte da classe controller e não aparecem nas funções.

Essa é a estrutura que eu consegui que menos repete código, mas aceito comentários e sugestões!!!


(Rmaranhao) #9

Faltou a tabela:

CREATE TABLE IF NOT EXISTS retorno_ps (

id varchar(36) NOT NULL,

inscricao_id int(11) NOT NULL,

referencia varchar(200) NOT NULL,

tipofrete char(2) DEFAULT NULL,

valor_frete decimal(10,2) DEFAULT NULL,

tipo_pagamento varchar(50) NOT NULL,

status_id int(11) NOT NULL,

status varchar(50) NOT NULL,

data_criacao date NOT NULL,

data_atualizacao date DEFAULT NULL,

data_pagamento date DEFAULT NULL,

data_cancelamento date DEFAULT NULL,

PRIMARY KEY (id),

UNIQUE KEY id (id,referencia)

) ENGINE=InnoDB DEFAULT CHARSET=latin1;


(Havennow) #10

E ai galera ,

eu to fazendo integração

APi 2.2.4

faz a compra mas quando quero receber o POST do bot do pagseguro

para acompanhar os itens no meu sistema

ou seja Pagseguro manda post pro meu sistema e eu trato isso com a PagSeguroNotificationService

Porem… nao chega nem o POST

alguem sabe se tem algo de configurar no Yii ou até em Servidor Http ( testei em dois dominios validos Apache e NGINX ) e nada

nem os caras do pagseguro tem idea o que pode ser

Vlw


(Newerton Araujo) #11

Haven,

Usa o sandbox.

https://sandbox.pagseguro.uol.com.br/


(Havennow) #12

pois é use o sandbox 1 mes fazendo a integraçao tive dois problemas : post nao vem , e o frete nao vai

li toda documentacao da api deles , bem pequena até

e nada , ai vo comecar hoje os testes em ambiente de producao

o forum deles atualmente ta lotado de topicos com erros semelhantes , o que me leva a crer que o sandbox deles tá bixado kkk

forcei a fazer uma lib pro yii de correios , se alguem tiver um tuto de como criar extenções pro yii ("nunca criei")

eu já agradeço , fazer uma extencionzinha ai

posto aqui os resultados

abracos


(Xeviousbr) #13

Também nunca criei, mas hoje mesmo vi esse link e to te passando

Criando Extensões