RicardoMartins_PagSeguro - Version 1.0.1

Version Notes

Versão estável.

Os bugs devem ser reportador na área de Issues no github do projeto em https://github.com/r-martins/PagSeguro-Magento-Transparente

Download this release

Release Info

Developer Ricardo Martins
Extension RicardoMartins_PagSeguro
Version 1.0.1
Comparing to
See all releases


Version 1.0.1

Files changed (42) hide show
  1. app/code/community/RicardoMartins/PagSeguro/Block/Form/Cc.php +70 -0
  2. app/code/community/RicardoMartins/PagSeguro/Block/Form/Cc/Dob.php +14 -0
  3. app/code/community/RicardoMartins/PagSeguro/Block/Form/Directpayment.php +20 -0
  4. app/code/community/RicardoMartins/PagSeguro/Block/Form/Info/Cc.php +38 -0
  5. app/code/community/RicardoMartins/PagSeguro/Helper/Data.php +141 -0
  6. app/code/community/RicardoMartins/PagSeguro/Helper/Internal.php +55 -0
  7. app/code/community/RicardoMartins/PagSeguro/Helper/Params.php +329 -0
  8. app/code/community/RicardoMartins/PagSeguro/Model/Abstract.php +199 -0
  9. app/code/community/RicardoMartins/PagSeguro/Model/Observer.php +22 -0
  10. app/code/community/RicardoMartins/PagSeguro/Model/Payment/Cc.php +92 -0
  11. app/code/community/RicardoMartins/PagSeguro/Model/Source/Customer/Address/Attributes.php +34 -0
  12. app/code/community/RicardoMartins/PagSeguro/Model/Source/Customer/Address/Attributes/Optional.php +36 -0
  13. app/code/community/RicardoMartins/PagSeguro/Model/Source/Customer/Attributes.php +22 -0
  14. app/code/community/RicardoMartins/PagSeguro/Model/Source/Customer/Dob.php +28 -0
  15. app/code/community/RicardoMartins/PagSeguro/Model/Source/Paymentmethods.php +46 -0
  16. app/code/community/RicardoMartins/PagSeguro/controllers/AjaxController.php +14 -0
  17. app/code/community/RicardoMartins/PagSeguro/controllers/NotificationController.php +16 -0
  18. app/code/community/RicardoMartins/PagSeguro/controllers/TestController.php +123 -0
  19. app/code/community/RicardoMartins/PagSeguro/etc/config.xml +79 -0
  20. app/code/community/RicardoMartins/PagSeguro/etc/system.xml +219 -0
  21. app/design/adminhtml/base/default/template/ricardomartins_pagseguro/form/directpayment.phtml +18 -0
  22. app/design/adminhtml/base/default/template/ricardomartins_pagseguro/form/info/cc.phtml +11 -0
  23. app/design/frontend/base/default/template/ricardomartins_pagseguro/form/cc.phtml +80 -0
  24. app/design/frontend/base/default/template/ricardomartins_pagseguro/form/cc/dob.phtml +87 -0
  25. app/design/frontend/base/default/template/ricardomartins_pagseguro/form/directpayment.phtml +20 -0
  26. app/design/frontend/base/default/template/ricardomartins_pagseguro/form/info/cc.phtml +11 -0
  27. app/etc/modules/RicardoMartins_PagSeguro.xml +9 -0
  28. app/locale/pt_BR/RicardoMartins_PagSeguro.csv +50 -0
  29. js/pagseguro/pagseguro.js +134 -0
  30. package.xml +21 -0
  31. skin/frontend/base/default/pagseguro/selo/selo01_160x90.gif +0 -0
  32. skin/frontend/base/default/pagseguro/selo/selo01_200x60.gif +0 -0
  33. skin/frontend/base/default/pagseguro/selo/selo01_300x60.gif +0 -0
  34. skin/frontend/base/default/pagseguro/selo/selo02_160x90.gif +0 -0
  35. skin/frontend/base/default/pagseguro/selo/selo02_200x60.gif +0 -0
  36. skin/frontend/base/default/pagseguro/selo/selo02_300x60.gif +0 -0
  37. skin/frontend/base/default/pagseguro/selo/selo03_160x90.gif +0 -0
  38. skin/frontend/base/default/pagseguro/selo/selo03_200x60.gif +0 -0
  39. skin/frontend/base/default/pagseguro/selo/selo03_300x60.gif +0 -0
  40. skin/frontend/base/default/pagseguro/selo/selo04_160x90.gif +0 -0
  41. skin/frontend/base/default/pagseguro/selo/selo04_200x60.gif +0 -0
  42. skin/frontend/base/default/pagseguro/selo/selo04_300x60.gif +0 -0
app/code/community/RicardoMartins/PagSeguro/Block/Form/Cc.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Paygate
23
+ * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ class RicardoMartins_PagSeguro_Block_Form_Cc extends Mage_Payment_Block_Form_Cc
28
+ {
29
+ /**
30
+ * Set block template
31
+ */
32
+ protected function _construct()
33
+ {
34
+ parent::_construct();
35
+ $this->setTemplate('ricardomartins_pagseguro/form/cc.phtml');
36
+ }
37
+
38
+ protected function _prepareLayout(){
39
+ // Mage::app()->getLayout()->getUpdate()->addHandle('pagseguro');
40
+ //adicionaremos o JS do pagseguro na tela que usará o bloco de cartao logo após o <body>
41
+ $scriptblock = Mage::app()->getLayout()->createBlock('core/text', 'js_pagseguro');
42
+ $scriptblock->setText(sprintf(
43
+ '
44
+ <script type="text/javascript">var RMPagSeguroSiteBaseURL = "%s";</script>
45
+ <script type="text/javascript" src="%s"></script>
46
+ <script type="text/javascript" src="%s"></script>
47
+ ',
48
+ Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK,true),
49
+ Mage::helper('ricardomartins_pagseguro')->getJsUrl(),
50
+ Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_JS, true) . 'pagseguro/pagseguro.js'
51
+ ));
52
+ $head = Mage::app()->getLayout()->getBlock('after_body_start');
53
+
54
+ // Mage::app()->getLayout()->getBlock('head')->addJs('pagseguro/pagseguro.js');
55
+
56
+ if($head)
57
+ {
58
+ $head->append($scriptblock);
59
+ }
60
+
61
+ return parent::_prepareLayout();
62
+ }
63
+
64
+ public function isDobVisible()
65
+ {
66
+ $owner_dob_attribute = Mage::getStoreConfig('payment/pagseguro_cc/owner_dob_attribute');
67
+ return empty($owner_dob_attribute);
68
+ }
69
+
70
+ }
app/code/community/RicardoMartins/PagSeguro/Block/Form/Cc/Dob.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class RicardoMartins_PagSeguro_Block_Form_Cc_Dob extends Mage_Customer_Block_Widget_Dob
4
+ {
5
+ public function _construct()
6
+ {
7
+ parent::_construct();
8
+
9
+ // default template location | caminho do template de data de nascimento
10
+ $this->setTemplate('ricardomartins_pagseguro/form/cc/dob.phtml');
11
+ $this->setFieldNameFormat('payment[ps_cc_owner_birthday_%s]');
12
+ $this->setFieldIdFormat('pagseguro_ps_cc_owner_birthday_%s');
13
+ }
14
+ }
app/code/community/RicardoMartins/PagSeguro/Block/Form/Directpayment.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class RicardoMartins_PagSeguro_Block_Form_Directpayment extends Mage_Core_Block_Template
3
+ {
4
+ protected function _construct()
5
+ {
6
+ parent::_construct();
7
+ $this->setTemplate('ricardomartins_pagseguro/form/directpayment.phtml');
8
+ }
9
+
10
+ protected function _toHtml()
11
+ {
12
+ // avoids block for being inserted twice
13
+ if(false == Mage::registry('directpayment_loaded')) {
14
+ Mage::register('directpayment_loaded', true);
15
+ return parent::_toHtml();
16
+ }
17
+
18
+ return '';
19
+ }
20
+ }
app/code/community/RicardoMartins/PagSeguro/Block/Form/Info/Cc.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Paygate
23
+ * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ class RicardoMartins_PagSeguro_Block_Form_Info_Cc extends Mage_Payment_Block_Info
28
+ {
29
+ /**
30
+ * Set block template
31
+ */
32
+ protected function _construct()
33
+ {
34
+ parent::_construct();
35
+ $this->setTemplate('ricardomartins_pagseguro/form/info/cc.phtml');
36
+ }
37
+
38
+ }
app/code/community/RicardoMartins/PagSeguro/Helper/Data.php ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class RicardoMartins_PagSeguro_Helper_Data extends Mage_Core_Helper_Abstract
4
+ {
5
+ const XML_PATH_PAYMENT_PAGSEGURO_EMAIL = 'payment/pagseguro/merchant_email';
6
+ const XML_PATH_PAYMENT_PAGSEGURO_TOKEN = 'payment/pagseguro/token';
7
+ const XML_PATH_PAYMENT_PAGSEGURO_DEBUG = 'payment/pagseguro/debug';
8
+ const XML_PATH_PAUMENT_PAGSEGURO_SANDBOX = 'payment/pagseguro/sandbox';
9
+ const XML_PATH_PAYMENT_PAGSEGURO_SANDBOX_EMAIL = 'payment/pagseguro/sandbox_merchant_email';
10
+ const XML_PATH_PAYMENT_PAGSEGURO_SANDBOX_TOKEN = 'payment/pagseguro/sandbox_token';
11
+ const XML_PATH_PAYMENT_PAGSEGURO_WS_URL = 'payment/pagseguro/ws_url';
12
+ const XML_PATH_PAYMENT_PAGSEGURO_JS_URL = 'payment/pagseguro/js_url';
13
+ const XML_PATH_PAYMENT_PAGSEGURO_SANDBOX_WS_URL = 'payment/pagseguro/sandbox_ws_url';
14
+ const XML_PATH_PAYMENT_PAGSEGURO_SANDBOX_JS_URL = 'payment/pagseguro/sandbox_js_url';
15
+
16
+
17
+ /**
18
+ * Retorna o ID da sessao para ser usado nas chamadas JavaScript do Checkout Transparente
19
+ * ou FALSE no caso de erro
20
+ * @return bool|string
21
+ */
22
+ public function getSessionId()
23
+ {
24
+ $client = new Zend_Http_Client($this->getWsUrl('sessions'));
25
+ $client->setMethod(Zend_Http_Client::POST);
26
+ $client->setParameterGet('email', $this->getMerchantEmail());
27
+ $client->setParameterGet('token', $this->getToken());
28
+ $client->setConfig(array('timeout'=>30));
29
+ try{
30
+ $response = $client->request();
31
+ }catch(Exception $e){
32
+ Mage::logException($e);
33
+ return false;
34
+ }
35
+
36
+ $response = $client->getLastResponse()->getBody();
37
+
38
+ libxml_use_internal_errors(true);
39
+ $xml = simplexml_load_string($response);
40
+ if(false === $xml){
41
+ $this->writeLog('Falha na autenticação com API do PagSeguro. Verifique email e token cadastrados. Retorno pagseguro: ' . $response);
42
+ return false;
43
+ }
44
+ return (string)$xml->id;
45
+ }
46
+
47
+ /**
48
+ * Retorna o email do lojista
49
+ * @return string
50
+ */
51
+ public function getMerchantEmail()
52
+ {
53
+ if($this->isSandbox())
54
+ {
55
+ return Mage::getStoreConfig(self::XML_PATH_PAYMENT_PAGSEGURO_SANDBOX_EMAIL);
56
+ }
57
+ return Mage::getStoreConfig(self::XML_PATH_PAYMENT_PAGSEGURO_EMAIL);
58
+ }
59
+
60
+ /**
61
+ * Retorna URL do Webservice do Pagseguro de acordo com o ambiente selecionado
62
+ * @param string $amend acrescenta algo no final
63
+ *
64
+ * @return string
65
+ */
66
+ public function getWsUrl($amend='')
67
+ {
68
+ if($this->isSandbox())
69
+ {
70
+ return Mage::getStoreConfig(self::XML_PATH_PAYMENT_PAGSEGURO_SANDBOX_WS_URL) . $amend;
71
+ }
72
+ return Mage::getStoreConfig(self::XML_PATH_PAYMENT_PAGSEGURO_WS_URL) . $amend;
73
+ }
74
+
75
+ /**
76
+ * Retorna o url do JavaScript da lib do Pagseguro de acordo com o ambiente selecionado
77
+ * @return string
78
+ */
79
+ public function getJsUrl()
80
+ {
81
+ if($this->isSandbox())
82
+ {
83
+ return Mage::getStoreConfig(self::XML_PATH_PAYMENT_PAGSEGURO_SANDBOX_JS_URL);
84
+ }
85
+ return Mage::getStoreConfig(self::XML_PATH_PAYMENT_PAGSEGURO_JS_URL);
86
+ }
87
+
88
+ /**
89
+ * Verifica se o debug está ativado
90
+ * @return bool
91
+ */
92
+ public function isDebugActive()
93
+ {
94
+ return Mage::getStoreConfigFlag(self::XML_PATH_PAYMENT_PAGSEGURO_DEBUG);
95
+ }
96
+
97
+ /**
98
+ * Está no modo SandBox?
99
+ * @return bool
100
+ */
101
+ public function isSandbox()
102
+ {
103
+ return Mage::getStoreConfigFlag(self::XML_PATH_PAUMENT_PAGSEGURO_SANDBOX);
104
+ }
105
+
106
+ /**
107
+ * Grava algo no pagseguro.log
108
+ * @param $obj mixed|string
109
+ */
110
+ public function writeLog($obj)
111
+ {
112
+ if ($this->isDebugActive()) {
113
+ if(is_string($obj)){
114
+ Mage::log($obj, Zend_Log::DEBUG, 'pagseguro.log', true);
115
+ }else{
116
+ Mage::log(var_export($obj, true), Zend_Log::DEBUG, 'pagseguro.log', true);
117
+ }
118
+ }else{
119
+ Mage::log(var_export('debug inativo', true), null, 'martins.log', true);
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Retorna o TOKEN configurado pro ambiente selecionado. Retorna false caso não tenha sido preenchido.
125
+ * @return string | false
126
+ */
127
+ public function getToken()
128
+ {
129
+ $token = Mage::getStoreConfig(self::XML_PATH_PAYMENT_PAGSEGURO_TOKEN);
130
+ if($this->isSandbox())
131
+ {
132
+ $token = Mage::getStoreConfig(self::XML_PATH_PAYMENT_PAGSEGURO_SANDBOX_TOKEN);
133
+ }
134
+ if(empty($token))
135
+ {
136
+ return false;
137
+ }
138
+
139
+ return Mage::helper('core')->decrypt($token);
140
+ }
141
+ }
app/code/community/RicardoMartins/PagSeguro/Helper/Internal.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class RicardoMartins_PagSeguro_Helper_Internal
4
+ * Trata chamadas internas da API
5
+ *
6
+ * @author Ricardo Martins <ricardo@ricardomartins.net.br>
7
+ */
8
+ class RicardoMartins_PagSeguro_Helper_Internal extends Mage_Core_Helper_Abstract
9
+ {
10
+ /*
11
+ * Retorna campos de uma dada entidade
12
+ * @author Gabriela D'Ávila (http://davila.blog.br)
13
+ */
14
+ public static function getFields($type = 'customer_address') {
15
+ $entityType = Mage::getModel('eav/config')->getEntityType($type);
16
+ $entityTypeId = $entityType->getEntityTypeId();
17
+ $attributes = Mage::getResourceModel('eav/entity_attribute_collection')->setEntityTypeFilter($entityTypeId);
18
+
19
+ return $attributes->getData();
20
+ }
21
+
22
+ /*
23
+ * Retorna array associativo com parametros necessarios pra uma chamada de API para pagamento com Cartao
24
+ * @return array
25
+ */
26
+ public function getCreditCardApiCallParams(Mage_Sales_Model_Order $order, $payment)
27
+ {
28
+ $helper = Mage::helper('ricardomartins_pagseguro');
29
+ $phelper = Mage::helper('ricardomartins_pagseguro/params'); //params helper - helper auxiliar de parametrização
30
+ $params = array(
31
+ 'email' => $helper->getMerchantEmail(),
32
+ 'token' => $helper->getToken(),
33
+ 'paymentMode' => 'default',
34
+ 'paymentMethod' => 'creditCard',
35
+ 'receiverEmail' => $helper->getMerchantEmail(),
36
+ 'currency' => 'BRL',
37
+ 'creditCardToken' => $payment['additional_information']['credit_card_token'],
38
+ 'reference' => $order->getIncrementId(),
39
+ 'extraAmount'=> $phelper->getExtraAmount($order),
40
+ 'notificationURL' => Mage::getUrl('ricardomartins_pagseguro/notification'),
41
+ );
42
+ $items = $phelper->getItemsParams($order);
43
+ $params = array_merge($params, $phelper->getItemsParams($order));
44
+ $params = array_merge($params, $phelper->getSenderParams($order,$payment));
45
+ $params = array_merge($params, $phelper->getAddressParams($order,'shipping'));
46
+ $params = array_merge($params, $phelper->getAddressParams($order,'billing'));
47
+ $params = array_merge($params, $phelper->getCreditCardHolderParams($order,$payment));
48
+ $params = array_merge($params, $phelper->getCreditCardInstallmentsParams($order,$payment));
49
+
50
+ // Mage::log(var_export($params, true), null, 'pagseguro.log', true);
51
+
52
+ return $params;
53
+ }
54
+
55
+ }
app/code/community/RicardoMartins/PagSeguro/Helper/Params.php ADDED
@@ -0,0 +1,329 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class RicardoMartins_PagSeguro_Helper_Params
4
+ * Classe para auxiliar na montagem dos parametros de chamadas da api. Trata telefones, itens, dados do cliente e afins.
5
+ *
6
+ * @author Ricardo Martins <ricardo@ricardomartins.net.br>
7
+ */
8
+ class RicardoMartins_PagSeguro_Helper_Params extends Mage_Core_Helper_Abstract
9
+ {
10
+
11
+ /**
12
+ * Retorna um array com informações dos itens para ser enviado pra API
13
+ * @param Mage_Sales_Model_Order $order
14
+ * @return array
15
+ */
16
+ public function getItemsParams(Mage_Sales_Model_Order $order)
17
+ {
18
+ $retorno = array();
19
+ if($items = $order->getAllVisibleItems())
20
+ {
21
+ for($x=1, $y=0, $c=count($items); $x <= $c; $x++, $y++)
22
+ {
23
+ $retorno['itemId'.$x] = $items[$y]->getId();
24
+ $retorno['itemDescription'.$x] = $this->normalizeChars($items[$y]->getName());
25
+ $retorno['itemAmount'.$x] = number_format($items[$y]->getPrice(),2,'.','');
26
+ $retorno['itemQuantity'.$x] = $items[$y]->getQtyOrdered();
27
+ }
28
+ }
29
+ return $retorno;
30
+ }
31
+
32
+ /**
33
+ * Retorna um array com informações do Sender(Cliente) para ser enviado pra API
34
+ * @param Mage_Sales_Model_Order $order
35
+ * @param $payment
36
+ * @return array
37
+ */
38
+ public function getSenderParams(Mage_Sales_Model_Order $order, $payment)
39
+ {
40
+ $digits = new Zend_Filter_Digits();
41
+
42
+ /** @var Mage_Customer_Model_Customer $customer */
43
+ $customer = Mage::getModel('customer/customer')->load($order->getCustomerId());
44
+ $customer_cpf_attribute = Mage::getStoreConfig('payment/pagseguro/customer_cpf_attribute');
45
+ $cpf = $customer->getResource()->getAttribute($customer_cpf_attribute)->getFrontend()->getValue($customer);
46
+
47
+ //telefone
48
+ $phone = $this->_extractPhone($order->getBillingAddress()->getTelephone());
49
+
50
+
51
+ $retorno = array(
52
+ 'senderName' => sprintf('%s %s',$order->getCustomerFirstname(), $order->getCustomerLastname()),
53
+ 'senderEmail' => $order->getCustomerEmail(),
54
+ 'senderHash' => $payment['additional_information']['sender_hash'],
55
+ 'senderCPF' => $digits->filter($cpf),
56
+ 'senderAreaCode'=> $phone['area'],
57
+ 'senderPhone' => $phone['number'],
58
+ );
59
+
60
+ return $retorno;
61
+ }
62
+
63
+ /**
64
+ * Retorna um array com informações do dono do Cartao(Cliente) para ser enviado pra API
65
+ * @param Mage_Sales_Model_Order $order
66
+ * @param $payment
67
+ * @return array
68
+ */
69
+ public function getCreditCardHolderParams(Mage_Sales_Model_Order $order, $payment)
70
+ {
71
+ $digits = new Zend_Filter_Digits();
72
+
73
+ /** @var Mage_Customer_Model_Customer $customer */
74
+ $customer = Mage::getModel('customer/customer')->load($order->getCustomerId());
75
+ $customer_cpf_attribute = Mage::getStoreConfig('payment/pagseguro/customer_cpf_attribute');
76
+ $cpf = $customer->getResource()->getAttribute($customer_cpf_attribute)->getFrontend()->getValue($customer);
77
+
78
+
79
+ $cpf = $customer->getResource()->getAttribute($customer_cpf_attribute)->getFrontend()->getValue($customer);
80
+
81
+ //dados
82
+ $creditCardHolderBirthDate = $this->_getCustomerCcDobValue($customer,$payment);
83
+ $phone = $this->_extractPhone($order->getBillingAddress()->getTelephone());
84
+
85
+
86
+ $retorno = array(
87
+ 'creditCardHolderName' => $payment['additional_information']['credit_card_owner'],
88
+ 'creditCardHolderBirthDate' => $creditCardHolderBirthDate,
89
+ 'creditCardHolderCPF' => $digits->filter($cpf),
90
+ 'creditCardHolderAreaCode' => $phone['area'],
91
+ 'creditCardHolderPhone' => $phone['number'],
92
+ );
93
+
94
+ return $retorno;
95
+ }
96
+
97
+ /**
98
+ * Retorna um array com informações de parcelamento (Cartao) para ser enviado pra API
99
+ * @param Mage_Sales_Model_Order $order
100
+ * @param $payment Mage_Sales_Model_Order_Payment
101
+ * @return array
102
+ */
103
+ public function getCreditCardInstallmentsParams(Mage_Sales_Model_Order $order, $payment)
104
+ {
105
+ $retorno = array();
106
+ if($payment->getAdditionalInformation('installment_quantity') && $payment->getAdditionalInformation('installment_value'))
107
+ {
108
+ $retorno = array(
109
+ 'installmentQuantity' => $payment->getAdditionalInformation('installment_quantity'),
110
+ 'installmentValue' => number_format($payment->getAdditionalInformation('installment_value'),2,'.',''),
111
+ );
112
+ }else{
113
+ $retorno = array(
114
+ 'installmentQuantity' => '1',
115
+ 'installmentValue' => number_format($order->getGrandTotal(),2,'.',''),
116
+ );
117
+ }
118
+ return $retorno;
119
+ }
120
+
121
+
122
+ /**
123
+ * Retorna um array com informações do endereço de entrega/cobranca para ser enviado pra API
124
+ * @param Mage_Sales_Model_Order $order
125
+ * @param string (billing|shipping) $type
126
+ * @return array
127
+ */
128
+ public function getAddressParams(Mage_Sales_Model_Order $order, $type)
129
+ {
130
+ $digits = new Zend_Filter_Digits();
131
+
132
+ //atributos de endereço
133
+ /** @var Mage_Sales_Model_Order_Address $address */
134
+ $address = ($type=='shipping' && !$order->getIsVirtual()) ? $order->getShippingAddress() : $order->getBillingAddress();
135
+ $address_street_attribute = Mage::getStoreConfig('payment/pagseguro/address_street_attribute');
136
+ $address_number_attribute = Mage::getStoreConfig('payment/pagseguro/address_number_attribute');
137
+ $address_complement_attribute = Mage::getStoreConfig('payment/pagseguro/address_complement_attribute');
138
+ $address_neighborhood_attribute = Mage::getStoreConfig('payment/pagseguro/address_neighborhood_attribute');
139
+
140
+ //obtendo dados de endereço
141
+ $addressStreet = $this->_getAddressAttributeValue($address,$address_street_attribute);
142
+ $addressNumber = $this->_getAddressAttributeValue($address,$address_number_attribute);
143
+ $addressComplement = $this->_getAddressAttributeValue($address,$address_complement_attribute);
144
+ $addressDistrict = $this->_getAddressAttributeValue($address,$address_neighborhood_attribute);
145
+ $addressPostalCode = $address->getPostcode();
146
+ $addressCity = $address->getCity();
147
+ $addressState = $this->getStateCode( $address->getRegion() );
148
+
149
+
150
+ $retorno = array(
151
+ $type.'AddressStreet' => $this->normalizeChars($addressStreet),
152
+ $type.'AddressNumber' => $addressNumber,
153
+ $type.'AddressComplement' => $this->normalizeChars($addressComplement),
154
+ $type.'AddressDistrict' => $this->normalizeChars($addressDistrict),
155
+ $type.'AddressPostalCode' => $addressPostalCode,
156
+ $type.'AddressCity' => $this->normalizeChars($addressCity),
157
+ $type.'AddressState' => $addressState,
158
+ $type.'AddressCountry' => 'BRA',
159
+ );
160
+
161
+ //específico pra shipping
162
+ if($type == 'shipping')
163
+ {
164
+ $shippingType = $this->_getShippingType($order);
165
+ $shippingCost = $order->getShippingAmount();
166
+ $retorno['shippingType'] = $shippingType;
167
+ if($shippingCost > 0)
168
+ {
169
+ $retorno['shippingCost'] = number_format($shippingCost,2,'.','');
170
+ }
171
+ }
172
+ return $retorno;
173
+ }
174
+
175
+ public function getStateCode($state)
176
+ {
177
+ if(strlen($state) == 2 && is_string($state))
178
+ {
179
+ return mb_convert_case($state,MB_CASE_UPPER);
180
+ }
181
+ else if(strlen($state) > 2 && is_string($state))
182
+ {
183
+ $state = $this->normalizeChars($state);
184
+ $state = trim($state);
185
+ $state = mb_convert_case($state, MB_CASE_UPPER);
186
+ $codes = array("AC"=>"ACRE", "AL"=>"ALAGOAS", "AM"=>"AMAZONAS", "AP"=>"AMAPA","BA"=>"BAHIA","CE"=>"CEARA","DF"=>"DISTRITO FEDERAL","ES"=>"ESPIRITO SANTO","GO"=>"GOIAS","MA"=>"MARANHAO","MT"=>"MATO GROSSO","MS"=>"MATO GROSSO DO SUL","MG"=>"MINAS GERAIS","PA"=>"PARA","PB"=>"PARAIBA","PR"=>"PARANA","PE"=>"PERNAMBUCO","PI"=>"PIAUI","RJ"=>"RIO DE JANEIRO","RN"=>"RIO GRANDE DO NORTE","RO"=>"RONDONIA","RS"=>"RIO GRANDE DO SUL","RR"=>"RORAIMA","SC"=>"SANTA CATARINA","SE"=>"SERGIPE","SP"=>"SAO PAULO","TO"=>"TOCANTINS");
187
+ if($code = array_search($state,$codes))
188
+ {
189
+ return $code;
190
+ }
191
+ }
192
+ return $state;
193
+ }
194
+
195
+ /**
196
+ * Replace language-specific characters by ASCII-equivalents.
197
+ * @see http://stackoverflow.com/a/16427125/529403
198
+ * @param string $s
199
+ * @return string
200
+ */
201
+ public static function normalizeChars($s) {
202
+ $replace = array(
203
+ 'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'Ae', 'Å'=>'A', 'Æ'=>'A', 'Ă'=>'A',
204
+ 'à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'ae', 'å'=>'a', 'ă'=>'a', 'æ'=>'ae',
205
+ 'þ'=>'b', 'Þ'=>'B',
206
+ 'Ç'=>'C', 'ç'=>'c',
207
+ 'È'=>'E', 'É'=>'E', 'Ê'=>'E', 'Ë'=>'E',
208
+ 'è'=>'e', 'é'=>'e', 'ê'=>'e', 'ë'=>'e',
209
+ 'Ğ'=>'G', 'ğ'=>'g',
210
+ 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I', 'İ'=>'I', 'ı'=>'i', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i',
211
+ 'Ñ'=>'N',
212
+ 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O', 'Õ'=>'O', 'Ö'=>'Oe', 'Ø'=>'O', 'ö'=>'oe', 'ø'=>'o',
213
+ 'ð'=>'o', 'ñ'=>'n', 'ò'=>'o', 'ó'=>'o', 'ô'=>'o', 'õ'=>'o',
214
+ 'Š'=>'S', 'š'=>'s', 'Ş'=>'S', 'ș'=>'s', 'Ș'=>'S', 'ş'=>'s', 'ß'=>'ss',
215
+ 'ț'=>'t', 'Ț'=>'T',
216
+ 'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'Ue',
217
+ 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ü'=>'ue',
218
+ 'Ý'=>'Y',
219
+ 'ý'=>'y', 'ý'=>'y', 'ÿ'=>'y',
220
+ 'Ž'=>'Z', 'ž'=>'z'
221
+ );
222
+ return strtr($s, $replace);
223
+ }
224
+
225
+ /**
226
+ * Calcula o valor "Extra", que será o valor das Taxas subtraído do valor dos impostos
227
+ * @param Mage_Sales_Model_Order $order
228
+ *
229
+ * @return string
230
+ */
231
+ public function getExtraAmount($order)
232
+ {
233
+ $discount = $order->getDiscountAmount();
234
+ $tax_amount = $order->getTaxAmount();
235
+ $extra = $discount+$tax_amount;
236
+ return number_format($extra,2, '.','');
237
+ }
238
+
239
+ /**
240
+ * Extraí codigo de area e telefone e devolve array com area e number como chave
241
+ * @author Ricardo Martins <ricardo@ricardomartins.net.br>
242
+ * @param string $phone
243
+ * @return array
244
+ */
245
+ private function _extractPhone($phone)
246
+ {
247
+ $digits = new Zend_Filter_Digits();
248
+ $phone = $digits->filter($phone);
249
+ $original_phone = $phone;
250
+
251
+ $phone = preg_replace('/^(\d{2})(\d{7,9})$/','$1-$2',$phone);
252
+ if(is_array($phone) && count($phone) == 2)
253
+ {
254
+ list($area,$number) = explode('-',$phone);
255
+ return array(
256
+ 'area' => $area,
257
+ 'number'=>$number
258
+ );
259
+ }
260
+
261
+ return array(
262
+ 'area' => (string)substr($original_phone,0,2),
263
+ 'number'=> (string)substr($original_phone,2,9),
264
+ );
265
+ }
266
+
267
+ /**
268
+ * Retorna a forma de envio do produto
269
+ * 1 – PAC, 2 – SEDEX, 3 - Desconhecido
270
+ * @param Mage_Sales_Model_Order $order
271
+ *
272
+ * @return string
273
+ */
274
+ private function _getShippingType(Mage_Sales_Model_Order $order)
275
+ {
276
+ $method = strtolower($order->getShippingMethod());
277
+ if(strstr($method,'pac') !== false){
278
+ return '1';
279
+ }else if(strstr($method,'sedex') !== false)
280
+ {
281
+ return '2';
282
+ }
283
+ return '3';
284
+ }
285
+
286
+ /**
287
+ * Pega um atributo de endereço baseado em um dos Id's vindos de RicardoMartins_PagSeguro_Model_Source_Customer_Address_*
288
+ * @param Mage_Sales_Model_Order_Address $address
289
+ * @param string $attribute_id
290
+ */
291
+ private function _getAddressAttributeValue($address, $attribute_id)
292
+ {
293
+ $is_streetline = preg_match('/^street_(\d{1})$/', $attribute_id, $matches);
294
+
295
+ if($is_streetline !== false && isset($matches[1])) //usa Streetlines
296
+ {
297
+ return $address->getStreet(intval($matches[1]));
298
+ }
299
+ else if($attribute_id == '') //Nao informar ao pagseguro
300
+ {
301
+ return '';
302
+ }
303
+ return (string)$address->getData($attribute_id);
304
+ }
305
+
306
+ /**
307
+ * Retorna a Data de Nascimento do cliente baseado na selecao realizada na configuração do Cartao de credito do modulo
308
+ * @param Mage_Customer_Model_Customer $customer
309
+ * @param $payment
310
+ *
311
+ * @return mixed
312
+ */
313
+ private function _getCustomerCcDobValue(Mage_Customer_Model_Customer $customer, $payment)
314
+ {
315
+ $cc_dob_attribute = Mage::getStoreConfig('payment/pagseguro_cc/owner_dob_attribute');
316
+
317
+ if(empty($cc_dob_attribute)) //Soliciado ao cliente junto com os dados do cartao
318
+ {
319
+ if(isset($payment['additional_information']['credit_card_owner_birthdate'])){
320
+ return $payment['additional_information']['credit_card_owner_birthdate'];
321
+ }
322
+ }
323
+
324
+ $dob = $customer->getResource()->getAttribute($cc_dob_attribute)->getFrontend()->getValue($customer);
325
+
326
+
327
+ return date('d/m/Y', strtotime($dob));
328
+ }
329
+ }
app/code/community/RicardoMartins/PagSeguro/Model/Abstract.php ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class RicardoMartins_PagSeguro_Model_Abstract extends Mage_Payment_Model_Method_Abstract
3
+ {
4
+ /**
5
+ * Processa o XML de retorno da notificação. O XML é enviado no ato do pedido, e depois nas consultas de atualizacao de pedido.
6
+ * @see https://pagseguro.uol.com.br/v2/guia-de-integracao/api-de-notificacoes.html#v2-item-servico-de-notificacoes
7
+ * @param SimpleXMLElement $resultXML
8
+ */
9
+ public function proccessNotificatonResult(SimpleXMLElement $resultXML)
10
+ {
11
+ if(isset($resultXML->error)){
12
+ $errMsg = Mage::helper('ricardomartins_pagseguro')->__((string)$resultXML->error->message);
13
+ Mage::throwException($this->_getHelper()->__('Problemas ao processar seu pagamento. %s(%s)', $errMsg, (string)$resultXML->error->code));
14
+ }
15
+ if(isset($resultXML->reference))
16
+ {
17
+ /** @var Mage_Sales_Model_Order $order */
18
+ $order = Mage::getModel('sales/order')->loadByIncrementId((string)$resultXML->reference);
19
+ $payment = $order->getPayment();
20
+ $processedState = $this->processStatus((int)$resultXML->status);
21
+ $message = $processedState->getMessage();
22
+
23
+ if((int)$resultXML->status == 6) //valor devolvido (gera credit memo e tenta cancelar o pedido)
24
+ {
25
+ if ($order->canUnhold()) {
26
+ $order->unhold();
27
+ }
28
+ if($order->canCancel())
29
+ {
30
+ $payment->registerRefundNotification(floatval($resultXML->grossAmount));
31
+ $order->cancel();
32
+ $order->save();
33
+ }else{
34
+ $order->addStatusHistoryComment('Devolvido: o valor foi devolvido ao comprador, mas o pedido encontra-se em um estado que não pode ser cancelado.')
35
+ ->save();
36
+ }
37
+ }
38
+
39
+ if($processedState->getStateChanged())
40
+ {
41
+ $order->setState($processedState->getState(),true,$processedState->getIsCustomerNotified())->save();
42
+ }
43
+
44
+ if((int)$resultXML->status == 3) //Quando o pedido foi dado como Pago
45
+ {
46
+ $payment->registerCaptureNotification(floatval($resultXML->grossAmount));
47
+ }
48
+
49
+ if((int)$resultXML->status == 7 && isset($resultXML->cancellationSource)) //Especificamos a fonte do cancelamento do pedido
50
+ {
51
+ switch((string)$resultXML->cancellationSource)
52
+ {
53
+ case 'INTERNAL':
54
+ $message .= ' O próprio PagSeguro negou ou cancelou a transação.';
55
+ break;
56
+ case 'EXTERNAL':
57
+ $message .= ' A transação foi negada ou cancelada pela instituição bancária.';
58
+ break;
59
+ }
60
+ }
61
+
62
+ $order->addStatusHistoryComment($message);
63
+ $payment->save();
64
+ $order->save();
65
+ Mage::dispatchEvent('pagseguro_proccess_notification_after',array(
66
+ 'order' => $order,
67
+ 'payment'=> $payment,
68
+ 'result_xml' => $resultXML,
69
+ ));
70
+ }else{
71
+ Mage::throwException('Retorno inválido. Referência do pedido não encontrada.');
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Pega um codigo de notificacao (enviado pelo pagseguro quando algo acontece com o pedido) e consulta o que mudou no status
77
+ * @param $notificationCode
78
+ *
79
+ * @return SimpleXMLElement
80
+ */
81
+ public function getNotificationStatus($notificationCode)
82
+ {
83
+ $helper = Mage::helper('ricardomartins_pagseguro');
84
+ $url = $helper->getWsUrl('transactions/notifications/' . $notificationCode);
85
+ $client = new Zend_Http_Client($url);
86
+ $client->setParameterGet(array(
87
+ 'token'=>$helper->getToken(),
88
+ 'email'=> $helper->getMerchantEmail(),
89
+ ));
90
+ $client->request();
91
+ $helper->writeLog(sprintf('Retorno do Pagseguro para notificationCode %s: %s', $notificationCode, $client->getLastResponse()->getBody()));
92
+ return simplexml_load_string($client->getLastResponse()->getBody());
93
+ }
94
+
95
+ /**
96
+ * Processa o status do pedido devolvendo informacoes como status e state do pedido
97
+ * @param $statusCode
98
+ * @return Varien_Object
99
+ */
100
+ public function processStatus($statusCode)
101
+ {
102
+ $return = new Varien_Object();
103
+ $return->setStateChanged(true);
104
+ $return->setIsTransactionPending(true); //payment is pending?
105
+ switch($statusCode)
106
+ {
107
+ case '1':
108
+ $return->setState(Mage_Sales_Model_Order::STATE_PENDING_PAYMENT);
109
+ $return->setIsCustomerNotified(true);
110
+ $return->setMessage('Aguardando pagamento: o comprador iniciou a transação, mas até o momento o PagSeguro não recebeu nenhuma informação sobre o pagamento.');
111
+ break;
112
+ case '2':
113
+ $return->setState(Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW);
114
+ $return->setIsCustomerNotified(true);
115
+ $return->setMessage('Em análise: o comprador optou por pagar com um cartão de crédito e o PagSeguro está analisando o risco da transação.');
116
+ break;
117
+ case '3':
118
+ $return->setState(Mage_Sales_Model_Order::STATE_PROCESSING);
119
+ $return->setIsCustomerNotified(true);
120
+ $return->setMessage('Paga: a transação foi paga pelo comprador e o PagSeguro já recebeu uma confirmação da instituição financeira responsável pelo processamento.');
121
+ $return->setIsTransactionPending(false);
122
+ break;
123
+ case '4':
124
+ $return->setMessage('Disponível: a transação foi paga e chegou ao final de seu prazo de liberação sem ter sido retornada e sem que haja nenhuma disputa aberta.');
125
+ $return->setIsCustomerNotified(false);
126
+ $return->setStateChanged(false);
127
+ $return->setIsTransactionPending(false);
128
+ break;
129
+ case '5':
130
+ $return->setState(Mage_Sales_Model_Order::STATE_PROCESSING);
131
+ $return->setIsCustomerNotified(false);
132
+ $return->setIsTransactionPending(false);
133
+ $return->setMessage('Em disputa: o comprador, dentro do prazo de liberação da transação, abriu uma disputa.');
134
+ break;
135
+ case '6':
136
+ $return->setState(Mage_Sales_Model_Order::STATE_CLOSED);
137
+ $return->setIsCustomerNotified(false);
138
+ $return->setIsTransactionPending(false);
139
+ $return->setMessage('Devolvida: o valor da transação foi devolvido para o comprador.');
140
+ break;
141
+ case '7':
142
+ $return->setState(Mage_Sales_Model_Order::STATE_CANCELED);
143
+ $return->setIsCustomerNotified(true);
144
+ $return->setMessage('Cancelada: a transação foi cancelada sem ter sido finalizada.');
145
+ break;
146
+ default:
147
+ $return->setIsCustomerNotified(false);
148
+ $return->setStateChanged(false);
149
+ $return->setMessage('Codigo de status inválido retornado pelo PagSeguro. (' . $statusCode . ')');
150
+ }
151
+ return $return;
152
+ }
153
+
154
+ /**
155
+ * Chama API pra realizar um pagamento
156
+ * @param $params
157
+ * @param $payment
158
+ *
159
+ * @return SimpleXMLElement
160
+ */
161
+ public function callApi($params, $payment)
162
+ {
163
+ $helper = Mage::helper('ricardomartins_pagseguro');
164
+ $client = new Zend_Http_Client($helper->getWsUrl('transactions'));
165
+ $client->setMethod(Zend_Http_Client::POST);
166
+ $client->setConfig(array('timeout'=>30));
167
+
168
+ $client->setParameterPost($params); //parametros enviados via POST
169
+
170
+ $helper->writeLog('Parametros sendo enviados para API (/transactions): '. var_export($params,true));
171
+ try{
172
+ $response = $client->request(); //faz o request
173
+ }catch(Exception $e){
174
+ Mage::throwException('Falha na comunicação com Pagseguro (' . $e->getMessage() . ')');
175
+ }
176
+
177
+ $response = $client->getLastResponse()->getBody();
178
+ $helper->writeLog('Retorno PagSeguro (/transactions): ' . var_export($response,true));
179
+
180
+ libxml_use_internal_errors(true);
181
+ $xml = simplexml_load_string($response);
182
+ if(false === $xml){
183
+ switch($response){
184
+ case 'Unauthorized':
185
+ $helper->writeLog('Token/email não autorizado pelo PagSeguro. Verifique suas configurações no painel.');
186
+ break;
187
+ case 'Forbidden':
188
+ $helper->writeLog('Acesso não autorizado à Api Pagseguro. Verifique se você tem permissão para usar este serviço. Retorno: ' . var_export($response,true));
189
+ break;
190
+ default:
191
+ $helper->writeLog('Retorno inesperado do PagSeguro. Retorno: ' . var_export($response,true));
192
+ }
193
+ Mage::throwException('Houve uma falha ao processar seu pedido/pagamento. Por favor entre em contato conosco.');
194
+ }
195
+
196
+
197
+ return $xml;
198
+ }
199
+ }
app/code/community/RicardoMartins/PagSeguro/Model/Observer.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class RicardoMartins_PagSeguro_Model_Observer
3
+ {
4
+ /**
5
+ * Adiciona o bloco do direct payment logo após um dos forms do pagseguro ter sido inserido.
6
+ * @param $observer
7
+ *
8
+ * @return $this
9
+ */
10
+ public function addDirectPaymentBlock($observer)
11
+ {
12
+ $pagseguroBlocks = array('ricardomartins_pagseguropro/form_boleto','ricardomartins_pagseguro/form_cc');
13
+ $blockType = $observer->getBlock()->getType();
14
+ if(in_array($blockType,$pagseguroBlocks)){
15
+ $output = $observer->getTransport()->getHtml();
16
+ $directpayment = Mage::app()->getLayout()->createBlock('ricardomartins_pagseguro/form_directpayment')->toHtml();
17
+ $observer->getTransport()->setHtml($output . $directpayment);
18
+
19
+ }
20
+ return $this;
21
+ }
22
+ }
app/code/community/RicardoMartins/PagSeguro/Model/Payment/Cc.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class RicardoMartins_PagSeguro_Model_Payment_Cc extends RicardoMartins_PagSeguro_Model_Abstract
3
+ {
4
+ protected $_code = 'pagseguro_cc';
5
+ protected $_formBlockType = 'ricardomartins_pagseguro/form_cc';
6
+ protected $_infoBlockType = 'ricardomartins_pagseguro/form_info_cc';
7
+ protected $_isGateway = true;
8
+ protected $_canAuthorize = true;
9
+ protected $_canCapture = true;
10
+ protected $_canRefund = false;
11
+ protected $_canVoid = true;
12
+ protected $_canUseInternal = true;
13
+ protected $_canUseCheckout = true;
14
+ protected $_canUseForMultishipping = true;
15
+ protected $_canSaveCc = false;
16
+
17
+ public function assignData($data)
18
+ {
19
+ if(!($data instanceof Varien_Object)){
20
+ $data = new Varien_Object($data);
21
+ }
22
+
23
+ $info = $this->getInfoInstance();
24
+ $info->setAdditionalInformation('sender_hash',$data->getSenderHash())
25
+ ->setAdditionalInformation('credit_card_token',$data->getCreditCardToken())
26
+ ->setAdditionalInformation('credit_card_owner', $data->getPsCcOwner())
27
+ ->setCcType($data->getPsCardType())
28
+ ->setCcLast4(substr($data->getPsCcNumber(), -4));
29
+
30
+ //data de nascimento
31
+ $owner_dob_attribute = Mage::getStoreConfig('payment/pagseguro_cc/owner_dob_attribute');
32
+ if(empty($owner_dob_attribute)){// pegar o dob e salvar aí
33
+ $info->setAdditionalInformation('credit_card_owner_birthdate', date('d/m/Y',strtotime(
34
+ $data->getPsCcOwnerBirthdayYear().'/'.$data->getPsCcOwnerBirthdayMonth().'/'.$data->getPsCcOwnerBirthdayDay()
35
+ )));
36
+ }
37
+
38
+ //parcelas
39
+ if($data->getPsCcInstallments())
40
+ {
41
+ $installments = explode('|', $data->getPsCcInstallments());
42
+ if(false !== $installments && count($installments)==2){
43
+ $info->setAdditionalInformation('installment_quantity', (int)$installments[0]);
44
+ $info->setAdditionalInformation('installment_value', $installments[1]);
45
+ }
46
+ }
47
+
48
+ return $this;
49
+ }
50
+
51
+ public function validate()
52
+ {
53
+ parent::validate();
54
+ $info = $this->getInfoInstance();
55
+
56
+ $sender_hash = $info->getAdditionalInformation('sender_hash');
57
+ $credit_card_token = $info->getAdditionalInformation('credit_card_token');
58
+
59
+ if(empty($credit_card_token) || empty($sender_hash))
60
+ {
61
+ Mage::helper('ricardomartins_pagseguro')->writeLog('Falha ao obter o token do cartao ou sender_hash. Veja se os dados "sender_hash" e "credit_card_token" foram enviados no formulário. Um problema de JavaScript pode ter ocorrido.');
62
+ Mage::throwException('Falha ao processar pagamento junto ao PagSeguro. Por favor, entre em contato com nossa equipe.');
63
+ }
64
+ return $this;
65
+ }
66
+
67
+ public function order(Varien_Object $payment, $amount)
68
+ {
69
+ $order = $payment->getOrder();
70
+
71
+ //montaremos os dados a ser enviados via POST pra api em $params
72
+ $params = Mage::helper('ricardomartins_pagseguro/internal')->getCreditCardApiCallParams($order, $payment);
73
+
74
+ //chamamos a API
75
+ $xmlRetorno = $this->callApi($params,$payment);
76
+ $this->proccessNotificatonResult($xmlRetorno);
77
+
78
+ if(isset($xmlRetorno->errors)){
79
+ $errMsg = array();
80
+ foreach($xmlRetorno->errors as $error){
81
+ $errMsg[] = (string)$error->message . '(' . $error->code . ')';
82
+ }
83
+ Mage::throwException('Um ou mais erros ocorreram no seu pagamento.' . PHP_EOL . implode(PHP_EOL,$errMsg));
84
+ }
85
+
86
+ if(isset($xmlRetorno->code)){
87
+ $payment->setAdditionalInformation(array('transaction_id'=>(string)$xmlRetorno->code));
88
+ }
89
+ return $this;
90
+ }
91
+
92
+ }
app/code/community/RicardoMartins/PagSeguro/Model/Source/Customer/Address/Attributes.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Payment Method Codes
5
+ *
6
+ * @author Ricardo Martins <ricardo@ricardomartins.net.br>
7
+ */
8
+ class RicardoMartins_PagSeguro_Model_Source_Customer_Address_Attributes
9
+ {
10
+ /**
11
+ * Retorna os atributos de endereco
12
+ * @author Gabriela D'Ávila (http://davila.blog.br)
13
+ * @return array
14
+ */
15
+ public function toOptionArray() {
16
+ $fields = Mage::helper('ricardomartins_pagseguro/internal')->getFields('customer_address');
17
+ $options = array();
18
+
19
+ foreach($fields as $key => $value) {
20
+ if(!is_null($value['frontend_label'])) {
21
+ //caso esteja sendo usado a propriedade multilinha do endereco, ele aceita indicar o que cada linha faz
22
+ if($value['attribute_code'] == 'street') {
23
+ $street_lines = Mage::getStoreConfig('customer/address/street_lines');
24
+ for($i = 1; $i <= $street_lines; $i++){
25
+ $options[] = array('value' => 'street_'.$i, 'label' => 'Street Line '.$i);
26
+ }
27
+ } else {
28
+ $options[] = array('value' => $value['attribute_code'], 'label' => $value['frontend_label']);
29
+ }
30
+ }
31
+ }
32
+ return $options;
33
+ }
34
+ }
app/code/community/RicardoMartins/PagSeguro/Model/Source/Customer/Address/Attributes/Optional.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Payment Method Codes
5
+ *
6
+ * @author Ricardo Martins <ricardo@ricardomartins.net.br>
7
+ */
8
+ class RicardoMartins_PagSeguro_Model_Source_Customer_Address_Attributes_Optional
9
+ {
10
+ /**
11
+ * Retorna os atributos de endereco
12
+ * @author Gabriela D'Ávila (http://davila.blog.br)
13
+ * @return array
14
+ */
15
+ public function toOptionArray() {
16
+ $fields = Mage::helper('ricardomartins_pagseguro/internal')->getFields('customer_address');
17
+ $options = array();
18
+ $options[] = array('value'=>'','label'=>'Não Informar ao PagSeguro');
19
+
20
+ foreach($fields as $key => $value) {
21
+ if(!is_null($value['frontend_label'])) {
22
+ //caso esteja sendo usado a propriedade multilinha do endereco, ele aceita indicar o que cada linha faz
23
+ if($value['attribute_code'] == 'street') {
24
+ $street_lines = Mage::getStoreConfig('customer/address/street_lines');
25
+ for($i = 1; $i <= $street_lines; $i++){
26
+ $options[] = array('value' => 'street_'.$i, 'label' => 'Street Line '.$i);
27
+ }
28
+ } else {
29
+ $options[] = array('value' => $value['attribute_code'], 'label' => $value['frontend_label']);
30
+ }
31
+ }
32
+ }
33
+
34
+ return $options;
35
+ }
36
+ }
app/code/community/RicardoMartins/PagSeguro/Model/Source/Customer/Attributes.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Payment Method Codes
5
+ *
6
+ * @author Ricardo Martins <ricardo@ricardomartins.net.br>
7
+ */
8
+ class RicardoMartins_PagSeguro_Model_Source_Customer_Attributes
9
+ {
10
+ public function toOptionArray() {
11
+ $fields = Mage::helper('ricardomartins_pagseguro/internal')->getFields('customer');
12
+ $options = array();
13
+
14
+ foreach($fields as $key => $value) {
15
+ if(!is_null($value['frontend_label'])) {
16
+ $options[$value['frontend_label']] = array('value' => $value['attribute_code'], 'label' => $value['frontend_label']);
17
+ }
18
+ }
19
+
20
+ return $options;
21
+ }
22
+ }
app/code/community/RicardoMartins/PagSeguro/Model/Source/Customer/Dob.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Payment Method Codes
5
+ *
6
+ * @author Ricardo Martins <ricardo@ricardomartins.net.br>
7
+ */
8
+ class RicardoMartins_PagSeguro_Model_Source_Customer_Dob
9
+ {
10
+ /**
11
+ * Retorna os atributos de endereco
12
+ * @author Gabriela D'Ávila (http://davila.blog.br)
13
+ * @return array
14
+ */
15
+ public function toOptionArray() {
16
+ $fields = Mage::helper('ricardomartins_pagseguro/internal')->getFields('customer');
17
+ $options = array();
18
+ $options[] = array('value'=>'','label'=>'Solicitar ao cliente junto com dados do cartão');
19
+
20
+ foreach($fields as $key => $value) {
21
+ if(!is_null($value['frontend_label'])) {
22
+ $options[] = array('value' => $value['attribute_code'], 'label' => $value['frontend_label']);
23
+ }
24
+ }
25
+
26
+ return $options;
27
+ }
28
+ }
app/code/community/RicardoMartins/PagSeguro/Model/Source/Paymentmethods.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Payment Method Codes
4
+ *
5
+ * @author Ricardo Martins <ricardo@ricardomartins.net.br>
6
+ */
7
+ class RicardoMartins_PagSeguro_Model_Source_Paymentmethods
8
+ {
9
+ public function toOptionArray()
10
+ {
11
+ $options = array();
12
+ $options[] = array('value'=>'101','label'=>'Cartão de crédito Visa');
13
+ $options[] = array('value'=>'102','label'=>'Cartão de crédito MasterCard');
14
+ $options[] = array('value'=>'103','label'=>'Cartão de crédito American Express');
15
+ $options[] = array('value'=>'104','label'=>'Cartão de crédito Diners');
16
+ $options[] = array('value'=>'105','label'=>'Cartão de crédito Hipercard');
17
+ $options[] = array('value'=>'106','label'=>'Cartão de crédito Aura');
18
+ $options[] = array('value'=>'107','label'=>'Cartão de crédito Elo');
19
+ $options[] = array('value'=>'108','label'=>'Cartão de crédito PLENOCard');
20
+ $options[] = array('value'=>'109','label'=>'Cartão de crédito PersonalCard');
21
+ $options[] = array('value'=>'110','label'=>'Cartão de crédito JCB');
22
+ $options[] = array('value'=>'111','label'=>'Cartão de crédito Discover');
23
+ $options[] = array('value'=>'112','label'=>'Cartão de crédito BrasilCard');
24
+ $options[] = array('value'=>'113','label'=>'Cartão de crédito FORTBRASIL');
25
+ $options[] = array('value'=>'114','label'=>'Cartão de crédito CARDBAN');
26
+ $options[] = array('value'=>'115','label'=>'Cartão de crédito VALECARD');
27
+ $options[] = array('value'=>'116','label'=>'Cartão de crédito Cabal');
28
+ $options[] = array('value'=>'117','label'=>'Cartão de crédito Mais!');
29
+ $options[] = array('value'=>'118','label'=>'Cartão de crédito Avista');
30
+ $options[] = array('value'=>'119','label'=>'Cartão de crédito GRANDCARD');
31
+ $options[] = array('value'=>'201','label'=>'Boleto Bradesco');
32
+ $options[] = array('value'=>'202','label'=>'Boleto Santander');
33
+ $options[] = array('value'=>'301','label'=>'Débito online Bradesco');
34
+ $options[] = array('value'=>'302','label'=>'Débito online Itaú');
35
+ $options[] = array('value'=>'303','label'=>'Débito online Unibanco');
36
+ $options[] = array('value'=>'304','label'=>'Débito online Banco do Brasil');
37
+ $options[] = array('value'=>'305','label'=>'Débito online Banco Real');
38
+ $options[] = array('value'=>'306','label'=>'Débito online Banrisul');
39
+ $options[] = array('value'=>'307','label'=>'Débito online HSBC');
40
+ $options[] = array('value'=>'401','label'=>'Saldo PagSeguro');
41
+ $options[] = array('value'=>'501','label'=>'Oi Paggo');
42
+ $options[] = array('value'=>'701','label'=>'Depósito em conta - Banco do Brasil');
43
+
44
+ return $options;
45
+ }
46
+ }
app/code/community/RicardoMartins/PagSeguro/controllers/AjaxController.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class RicardoMartins_PagSeguro_AjaxController extends Mage_Core_Controller_Front_Action
3
+ {
4
+ /**
5
+ * Metodo auxiliar para obter o total do pedido
6
+ */
7
+ public function getGrandTotalAction()
8
+ {
9
+ $total = Mage::helper('checkout/cart')->getQuote()->getGrandTotal();
10
+
11
+ $this->getResponse()->setHeader('Content-type','application/json');
12
+ $this->getResponse()->setBody(json_encode(array('total'=>$total)));
13
+ }
14
+ }
app/code/community/RicardoMartins/PagSeguro/controllers/NotificationController.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class RicardoMartins_PagSeguro_NotificationController extends Mage_Core_Controller_Front_Action
3
+ {
4
+ /**
5
+ * Recebe e processa as notificações do pagseguro quando há alguma notificacao.
6
+ * Não esqueça de configurar a url de retorno como http://sualoja.com.br/pagseguro/notification
7
+ */
8
+ public function indexAction()
9
+ {
10
+ /** @var RicardoMartins_PagSeguro_Model_Abstract $model */
11
+ Mage::helper('ricardomartins_pagseguro')->writeLog('Recebido notificacao do pagseguro com os parametros:'. var_export($this->getRequest()->getParams(),true));
12
+ $model = Mage::getModel('ricardomartins_pagseguro/abstract');
13
+ $response = $model->getNotificationStatus($this->getRequest()->getPost('notificationCode'));
14
+ $model->proccessNotificatonResult($response);
15
+ }
16
+ }
app/code/community/RicardoMartins/PagSeguro/controllers/TestController.php ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class RicardoMartins_PagSeguro_TestController extends Mage_Core_Controller_Front_Action
3
+ {
4
+ public function indexAction(){
5
+
6
+ $client = new Zend_Http_Client('https://ws.pagseguro.uol.com.br/v2/sessions/');
7
+ $client->setMethod(Zend_Http_Client::POST);
8
+ $client->setParameterGet('email','ricardo@ricardomartins.info');
9
+ $client->setParameterGet('token','9F79900A9B454CE6B18613D7224C0621');
10
+ $client->request();
11
+
12
+ var_dump($client->getLastResponse()->getBody());
13
+ }
14
+
15
+ public function xmlAction()
16
+ {
17
+ echo Mage::helper('ricardomartins_pagseguro')->_getToken();
18
+ }
19
+
20
+
21
+ public function formAction()
22
+ {
23
+ $this->loadLayout();
24
+
25
+ $scriptblock = Mage::app()->getLayout()->createBlock('core/text', 'js_pagseguro');
26
+ $scriptblock->setText(sprintf(
27
+ '<script type="text/javascript" src="%s"></script>
28
+ <script type="text/javascript" src="/js/pagseguro/pagseguro.js"/>
29
+ ',
30
+ Mage::helper('ricardomartins_pagseguro')->getJsUrl()
31
+ ));
32
+ $head = Mage::app()->getLayout()->getBlock('after_body_start');
33
+ $head->append($scriptblock);
34
+
35
+ $_helper = Mage::helper('ricardomartins_pagseguro');
36
+
37
+
38
+ $html =<<<EOF
39
+
40
+ <form id="meu_form" action="#">
41
+ <li>
42
+ <label for="pagseguro_cc_cc_number" class="required"><em>*</em>Credit Card Number</label>
43
+ <div class="input-box">
44
+ <input autocomplete="off" id="pagseguro_cc_cc_number" name="payment[ps_cc_number]" title="Credit Card Number" class="input-text validate-cc-number validate-cc-type" value="" type="text">
45
+ <span id="card-brand"></span>
46
+ </div>
47
+ </li>
48
+ <li id="pagseguro_cc_cc_type_exp_div">
49
+ <label for="pagseguro_cc_expiration" class="required"><em>*</em>Expiration Date</label>
50
+ <div class="input-box">
51
+ <div class="v-fix">
52
+ <select autocomplete="off" id="pagseguro_cc_expiration" name="payment[ps_cc_exp_month]" class="month validate-cc-exp required-entry">
53
+ <option value="" selected="selected">Month</option>
54
+ <option value="1">01 - janeiro</option>
55
+ <option value="2">02 - fevereiro</option>
56
+ <option value="3">03 - março</option>
57
+ <option value="4">04 - abril</option>
58
+ <option value="5">05 - maio</option>
59
+ <option value="6">06 - junho</option>
60
+ <option value="7">07 - julho</option>
61
+ <option value="8">08 - agosto</option>
62
+ <option value="9">09 - setembro</option>
63
+ <option value="10">10 - outubro</option>
64
+ <option value="11">11 - novembro</option>
65
+ <option value="12">12 - dezembro</option>
66
+ </select>
67
+ </div>
68
+ <div class="v-fix">
69
+ <select autocomplete="off" id="pagseguro_cc_expiration_yr" name="payment[ps_cc_exp_year]" class="year required-entry">
70
+ <option value="" selected="selected">Year</option>
71
+ <option value="2014">2014</option>
72
+ <option value="2015">2015</option>
73
+ <option value="2016">2016</option>
74
+ <option value="2017">2017</option>
75
+ <option value="2018">2018</option>
76
+ <option value="2019">2019</option>
77
+ <option value="2020">2020</option>
78
+ <option value="2021">2021</option>
79
+ <option value="2022">2022</option>
80
+ <option value="2023">2023</option>
81
+ <option value="2024">2024</option>
82
+ </select>
83
+ </div>
84
+ </div>
85
+ </li>
86
+ <li id="pagseguro_cc_cc_type_cvv_div">
87
+ <label for="pagseguro_cc_cc_cid" class="required"><em>*</em>Card Verification Number</label>
88
+ <div class="input-box">
89
+ <div class="v-fix">
90
+ <input autocomplete="off" title="Card Verification Number" class="input-text cvv required-entry validate-cc-cvn" id="ps_cc_cid" name="payment[ps_cc_cid]" value="" type="text">
91
+ </div>
92
+ <a href="#" class="cvv-what-is-this">What is this?</a>
93
+ </div>
94
+
95
+ <?php #nao remover/alterar ?>
96
+ <input type="hidden" name="payment[sender_hash]"/>
97
+ <input type="hidden" name="payment[credit_card_token]"/>
98
+
99
+
100
+ <input type="submit"/>
101
+
102
+
103
+
104
+ </li>
105
+ </form>
106
+ <script type="text/javascript">
107
+ //<![CDATA[
108
+
109
+
110
+ PagSeguroDirectPayment.setSessionId('{$_helper->getSessionId()}');
111
+
112
+
113
+ //]]>
114
+ </script>
115
+
116
+ EOF;
117
+
118
+ $block = Mage::app()->getLayout()->createBlock('core/text')->setText($html);
119
+
120
+ Mage::app()->getLayout()->getBlock('content')->append($block, 'teste');
121
+ $this->renderLayout();
122
+ }
123
+ }
app/code/community/RicardoMartins/PagSeguro/etc/config.xml ADDED
<
@@ -0,0 +1,79 @@