PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/php/retorno.php

https://github.com/visie/PagSeguro
PHP | 319 lines | 169 code | 15 blank | 135 comment | 32 complexity | 5995b7637f0f3110f2086d433eef452a MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /**
  3. * Retorno automático do PagSeguro
  4. *
  5. * Faz a requisição e verificação do POST recebido pelo PagSeguro
  6. *
  7. * PHP Version 5
  8. *
  9. * @category PagSeguro
  10. * @package PagSeguro
  11. * @author Michael Castillo Granados <mike@visie.com.br>
  12. * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
  13. * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
  14. * @link http://visie.com.br/pagseguro
  15. */
  16. if (!defined('TOKEN')) {
  17. define('TOKEN', '');
  18. }
  19. /**
  20. * RetornoPagSeguro
  21. *
  22. * Classe de manipulação para o retorno do post do pagseguro
  23. *
  24. * @category PagSeguro
  25. * @package PagSeguro
  26. * @author dgmike <mike@visie.com.br>
  27. * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
  28. * @link http://visie.com.br/pagseguro
  29. */
  30. class RetornoPagSeguro
  31. {
  32. /**
  33. * _preparaDados
  34. *
  35. * Prepara os dados vindos do post e converte-os para url, adicionando
  36. * o token do usuario quando necessario.
  37. *
  38. * @param array $post Array contendo os posts do pagseguro
  39. * @param bool $confirmacao Controlando a adicao do token no post
  40. *
  41. * @return string
  42. *
  43. * @access private
  44. *
  45. * @internal é usado pela {@see RetornoPagSeguro::verifica} para gerar os,
  46. * dados que serão enviados pelo PagSeguro
  47. */
  48. function _preparaDados($post, $confirmacao=true)
  49. {
  50. if ('array' !== gettype($post)) {
  51. $post = array();
  52. }
  53. if ($confirmacao) {
  54. $post['Comando'] = 'validar';
  55. $post['Token'] = TOKEN;
  56. }
  57. $retorno = array();
  58. foreach ($post as $key => $value) {
  59. if ('string' !== gettype($value)) {
  60. $post[$key] = '';
  61. }
  62. $value = urlencode(stripslashes($value));
  63. $retorno[] = "{$key}={$value}";
  64. }
  65. return implode('&', $retorno);
  66. }
  67. /**
  68. * _tipoEnvio
  69. *
  70. * Checa qual será a conexao de acordo com a versao do PHP
  71. * preferencialmente em CURL ou via socket
  72. *
  73. * em CURL o retorno será:
  74. * <code>
  75. * array ('curl','https://pagseguro.uol.com.br/Security/NPI/Default.aspx')
  76. * </code>
  77. * já em socket o retorno será:
  78. *
  79. * <code>
  80. * array ('fsocket', '/Security/NPI/Default.aspx', $objeto_de_conexao)
  81. * </code>
  82. *
  83. * se não encontrar nenhum nem outro:
  84. *
  85. * <code>
  86. * array ('','')
  87. * </code>
  88. *
  89. * @access private
  90. * @global string $_retPagSeguroErrNo Numero de erro do pagseguro
  91. * @global string $_retPagSeguroErrStr Texto descritivo do erro do pagseguro
  92. * @return array Array com as configurações
  93. *
  94. */
  95. function _tipoEnvio()
  96. {
  97. // Prefira utilizar a função CURL do PHP
  98. // Leia mais sobre CURL em: http://us3.php.net/curl
  99. global $_retPagSeguroErrNo, $_retPagSeguroErrStr;
  100. if (function_exists('curl_exec')) {
  101. return array(
  102. 'curl',
  103. 'https://pagseguro.uol.com.br/Security/NPI/Default.aspx'
  104. );
  105. } elseif ((PHP_VERSION >= 4.3) &&
  106. ($fp = @fsockopen('ssl://pagseguro.uol.com.br',
  107. 443, $_retPagSeguroErrNo, $_retPagSeguroErrStr, 30))
  108. ) {
  109. return array('fsocket', '/Security/NPI/Default.aspx', $fp);
  110. } elseif ($fp = @fsockopen('pagseguro.uol.com.br', 80,
  111. $_retPagSeguroErrNo, $_retPagSeguroErrStr, 30)
  112. ) {
  113. return array('fsocket', '/Security/NPI/Default.aspx', $fp);
  114. }
  115. return array ('', '');
  116. }
  117. /**
  118. * _confirma
  119. *
  120. * Faz a parte Server-Side, verificando os dados junto ao PagSeguro
  121. *
  122. * @param array $tipoEnvio Array com a configuração gerada
  123. * por {@see Retorno::_tipoEnvio()}
  124. * @param array $post Dados vindos no POST do PagSeguro para serem
  125. * verificados
  126. *
  127. * @return bool
  128. * @global string $_retPagSeguroErrNo Numero de erro do pagseguro
  129. * @global string $_retPagSeguroErrStr Texto descritivo do erro do pagseguro
  130. */
  131. function _confirma($tipoEnvio, $post)
  132. {
  133. global $_retPagSeguroErrNo, $_retPagSeguroErrStr;
  134. $spost = RetornoPagSeguro::_preparaDados($post);
  135. $confirma = false;
  136. // Usando a biblioteca cURL
  137. if ($tipoEnvio[0] === 'curl') {
  138. $ch = curl_init();
  139. curl_setopt($ch, CURLOPT_URL, $tipoEnvio[1]);
  140. curl_setopt($ch, CURLOPT_POST, true);
  141. curl_setopt($ch, CURLOPT_POSTFIELDS, $spost);
  142. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  143. curl_setopt($ch, CURLOPT_HEADER, false);
  144. curl_setopt($ch, CURLOPT_TIMEOUT, 30);
  145. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  146. // Deve funcionar apenas em teste
  147. if (defined('PAGSEGURO_AMBIENTE_DE_TESTE')) {
  148. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  149. }
  150. $resp = curl_exec($ch);
  151. if (!RetornoPagSeguro::notNull($resp)) {
  152. curl_setopt($ch, CURLOPT_URL, $tipoEnvio[1]);
  153. $resp = curl_exec($ch);
  154. }
  155. curl_close($ch);
  156. $confirma = (strcmp($resp, 'VERIFICADO') == 0);
  157. // Usando fsocket
  158. } elseif ($tipoEnvio[0] === 'fsocket') {
  159. if (!$tipoEnvio[2]) {
  160. die ("{$_retPagSeguroErrStr} ($_retPagSeguroErrNo)");
  161. } else {
  162. $cabecalho = "POST {$tipoEnvio[1]} HTTP/1.0\r\n";
  163. $cabecalho .= "Content-Type: application/x-www-form-urlencoded\r\n";
  164. $cabecalho .= "Content-Length: " . strlen($spost) . "\r\n\r\n";
  165. $resp = '';
  166. fwrite($tipoEnvio[2], "{$cabecalho}{$spost}");
  167. while (!feof($tipoEnvio[2])) {
  168. $resp = fgets($tipoEnvio[2], 1024);
  169. if (strcmp($resp, 'VERIFICADO') == 0) {
  170. $confirma = true;
  171. break;
  172. }
  173. }
  174. fclose($tipoEnvio[2]);
  175. }
  176. }
  177. return $confirma;
  178. }
  179. /**
  180. * notNull
  181. *
  182. * Extraido de OScommerce 2.2 com base no original do pagseguro,
  183. * Checa se o valor e nulo
  184. *
  185. * @param mixed $value Variável a ser checada se é nula
  186. *
  187. * @return bool
  188. * @access public
  189. */
  190. function notNull($value)
  191. {
  192. if (is_array($value)) {
  193. if (sizeof($value) > 0) {
  194. return true;
  195. } else {
  196. return false;
  197. }
  198. } else {
  199. if (($value != '') && (strtolower($value) != 'null') &&
  200. (strlen(trim($value)) > 0)
  201. ) {
  202. return true;
  203. } else {
  204. return false;
  205. }
  206. }
  207. }
  208. /**
  209. * verifica
  210. *
  211. * Verifica o tipo de conexão aberta e envia os dados vindos
  212. * do post
  213. *
  214. * @param array $post Array contendo os posts do pagseguro
  215. * @param bool $tipoEnvio (opcional) Verifica o tipo de envio do post
  216. *
  217. * @access public
  218. * @use RetornoPagSeguro::_tipoenvio()
  219. * @use RetornoPagSeguro::_confirma()
  220. * @return bool
  221. */
  222. function verifica($post, $tipoEnvio=false)
  223. {
  224. if ('array' !== gettype($tipoEnvio)) {
  225. $tipoEnvio = RetornoPagSeguro::_tipoEnvio();
  226. }
  227. if (!in_array($tipoEnvio[0], array('curl', 'fsocket'))) {
  228. return false;
  229. }
  230. $confirma = RetornoPagSeguro::_confirma($tipoEnvio, $post);
  231. if ($confirma && function_exists('retorno_automatico')) {
  232. $itens = array (
  233. 'VendedorEmail', 'TransacaoID', 'Referencia', 'TipoFrete',
  234. 'ValorFrete', 'Anotacao', 'DataTransacao', 'TipoPagamento',
  235. 'StatusTransacao', 'CliNome', 'CliEmail', 'CliEndereco',
  236. 'CliNumero', 'CliComplemento', 'CliBairro', 'CliCidade',
  237. 'CliEstado', 'CliCEP', 'CliTelefone', 'NumItens',
  238. );
  239. foreach ($itens as $item) {
  240. if (!isset($post[$item])) {
  241. $post[$item] = '';
  242. }
  243. if ($item=='ValorFrete') {
  244. $post[$item] = str_replace(',', '.', $post[$item]);
  245. }
  246. }
  247. $produtos = array ();
  248. for ($i=1;isset($post["ProdID_{$i}"]);$i++) {
  249. $produtos[] = self::makeProd($post, $i);
  250. }
  251. retorno_automatico($post['Referencia'],
  252. $post['StatusTransacao'],
  253. (object) $post);
  254. }
  255. return $confirma;
  256. }
  257. /**
  258. * Gera o produto baseado no post e no id enviados
  259. *
  260. * @param array $post O post enviado pelo PagSeguro
  261. * @param int $i ID do produto que deseja gerar
  262. *
  263. * @return array
  264. */
  265. public function makeProd ($post, $i)
  266. {
  267. $post += array ("ProdFrete_{$i}"=>0, "ProdExtras_{$i}" => 0);
  268. return array (
  269. 'ProdID' => $post["ProdID_{$i}"],
  270. 'ProdDescricao' => $post["ProdDescricao_{$i}"],
  271. 'ProdValor' => self::convertNumber($post["ProdValor_{$i}"]),
  272. 'ProdQuantidade' => $post["ProdQuantidade_{$i}"],
  273. 'ProdFrete' => self::convertNumber($post["ProdFrete_{$i}"]),
  274. 'ProdExtras' => self::convertNumber($post["ProdExtras_{$i}"]),
  275. );
  276. }
  277. /**
  278. * Converte o numero enviado para padrão numerico
  279. *
  280. * @param string|int|double $number Numero que deseja converter
  281. *
  282. * @return double
  283. */
  284. function convertNumber ($number)
  285. {
  286. return (double) (str_replace(',', '.', $number));
  287. }
  288. /**
  289. * Grava histórias no arquivo de log do sistema
  290. *
  291. * @param mixed $message Mensagem que gostaria de gravar no log
  292. *
  293. * @return void
  294. */
  295. public function keepLog($message)
  296. {
  297. file_put_contents(dirname(__FILE__) . "/" . __FILE__ . ".log",
  298. var_export($message, true), FILE_APPEND);
  299. }
  300. }
  301. if ($_POST) {
  302. RetornoPagSeguro::verifica($_POST);
  303. die();
  304. }