Datacash - Version 1.2.9

Version Notes

Version 1.2.9

Download this release

Release Info

Developer DataCash
Extension Datacash
Version 1.2.9
Comparing to
See all releases


Code changes from version 1.2.5 to 1.2.9

Files changed (28) hide show
  1. app/code/community/DataCash/Dpg/Block/Adminhtml/Sales/Order/Risk.php +49 -0
  2. app/code/community/DataCash/Dpg/Controller/Abstract.php +39 -0
  3. app/code/community/DataCash/Dpg/Helper/Data.php +22 -0
  4. app/code/community/DataCash/Dpg/Model/Api/Abstract.php +52 -2
  5. app/code/community/DataCash/Dpg/Model/Api/Direct.php +3 -1
  6. app/code/community/DataCash/Dpg/Model/Api/Hcc.php +27 -1
  7. app/code/community/DataCash/Dpg/Model/Config.php +330 -311
  8. app/code/community/DataCash/Dpg/Model/Datacash/Request.php +30 -3
  9. app/code/community/DataCash/Dpg/Model/Datacash/Response.php +18 -1
  10. app/code/community/DataCash/Dpg/Model/Method/Abstract.php +750 -678
  11. app/code/community/DataCash/Dpg/Model/Method/Api.php +489 -530
  12. app/code/community/DataCash/Dpg/Model/Method/Hcc.php +60 -22
  13. app/code/community/DataCash/Dpg/Model/Method/Hosted/Abstract.php +0 -1
  14. app/code/community/DataCash/Dpg/Model/Observer.php +107 -45
  15. app/code/community/DataCash/Dpg/Model/Resource/Risk.php +14 -0
  16. app/code/community/DataCash/Dpg/Model/Resource/Risk/Collection.php +14 -0
  17. app/code/community/DataCash/Dpg/Model/Risk.php +81 -0
  18. app/code/community/DataCash/Dpg/Model/Risk/Abstract.php +75 -0
  19. app/code/community/DataCash/Dpg/Model/Risk/Bankresult.php +38 -0
  20. app/code/community/DataCash/Dpg/Model/Risk/Score.php +103 -0
  21. app/code/community/DataCash/Dpg/Model/Risk/Screening.php +59 -0
  22. app/code/community/DataCash/Dpg/Model/Source/RsgServiceTypes.php +14 -8
  23. app/code/community/DataCash/Dpg/controllers/RsgController.php +76 -0
  24. app/code/community/DataCash/Dpg/controllers/T3mController.php +16 -27
  25. app/code/community/DataCash/Dpg/etc/config.xml +42 -6
  26. app/code/community/DataCash/Dpg/etc/system.xml +99 -1
  27. app/code/community/DataCash/Dpg/sql/datacash_dpg_setup/mysql4-upgrade-1.2.5-1.2.6.php +35 -0
  28. package.xml +5 -5
app/code/community/DataCash/Dpg/Block/Adminhtml/Sales/Order/Risk.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class DataCash_Dpg_Block_Adminhtml_Sales_Order_Risk extends Mage_Adminhtml_Block_Template
3
+ {
4
+ protected $_instanceCollection = null;
5
+
6
+ /**
7
+ * _construct function.
8
+ *
9
+ * @access public
10
+ * @return void
11
+ */
12
+ public function _construct()
13
+ {
14
+ parent::_construct();
15
+ $this->setTemplate('datacash/sales/order/risk.phtml');
16
+ }
17
+
18
+ /**
19
+ * getRiskData function.
20
+ *
21
+ * @access public
22
+ * @return collection
23
+ */
24
+ public function getRiskData()
25
+ {
26
+ if ($this->_instanceCollection === null) {
27
+ $orderId = $this->getOrder()->getId();
28
+ $collection = Mage::getResourceModel('dpg/risk_collection')
29
+ ->addFieldToFilter('order_id', $orderId);
30
+
31
+ $this->_instanceCollection = array();
32
+ foreach($collection as $item) {
33
+ $this->_instanceCollection[] = Mage::getModel('dpg/risk')->getTypeInstanceFromItem($item);
34
+ }
35
+ }
36
+ return $this->_instanceCollection;
37
+ }
38
+
39
+ /**
40
+ * hasRiskData function.
41
+ *
42
+ * @access public
43
+ * @return boolean
44
+ */
45
+ public function hasRiskData()
46
+ {
47
+ return count($this->getRiskData()) > 0;
48
+ }
49
+ }
app/code/community/DataCash/Dpg/Controller/Abstract.php CHANGED
@@ -47,4 +47,43 @@ abstract class DataCash_Dpg_Controller_Abstract extends Mage_Core_Controller_Fro
47
  {
48
  return Mage::getSingleton('dpg/config');
49
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  }
47
  {
48
  return Mage::getSingleton('dpg/config');
49
  }
50
+
51
+ /**
52
+ * mapCallback function.
53
+ *
54
+ * @access protected
55
+ * @param array $request
56
+ * @param array $indices
57
+ * @return array
58
+ */
59
+ protected function mapCallback($request, $indices)
60
+ {
61
+ $mapped = array();
62
+ foreach ($indices as $i => $j) {
63
+ if ($request[$j] !== null) {
64
+ $mapped[$i] = $request[$j];
65
+ }
66
+ }
67
+ return $mapped;
68
+ }
69
+
70
+ /**
71
+ * getInputStreamAsArray function.
72
+ *
73
+ * @access protected
74
+ * @return array
75
+ */
76
+ protected function getInputStreamAsArray()
77
+ {
78
+ $rawInput = file_get_contents('php://input');
79
+ $keyValues = explode('&', $rawInput);
80
+
81
+ $values = array();
82
+ foreach($keyValues as $keyValue) {
83
+ list($key, $value) = explode('=', $keyValue);
84
+ $values[$key] = $value;
85
+ }
86
+
87
+ return $values;
88
+ }
89
  }
app/code/community/DataCash/Dpg/Helper/Data.php CHANGED
@@ -39,6 +39,28 @@ class DataCash_Dpg_Helper_Data extends Mage_Core_Helper_Abstract
39
  {
40
  protected $_status_prefix = "status_";
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  /**
43
  * Tries to get a user-friently version from translartion by status code
44
  * returns False when it does not find it.
39
  {
40
  protected $_status_prefix = "status_";
41
 
42
+ /**
43
+ * isIpAllowed function.
44
+ *
45
+ * @access public
46
+ * @param string $paymentMethodCode
47
+ * @return bool
48
+ */
49
+ public function isIpAllowed($paymentMethodCode)
50
+ {
51
+ $storeId = Mage::app()->getStore()->getId();
52
+
53
+ if (!Mage::getStoreConfigFlag("payment/{$paymentMethodCode}/rsg_callbacks_security", $storeId)) {
54
+ return true;
55
+ }
56
+
57
+ $ipsRaw = Mage::getStoreConfig("payment/{$paymentMethodCode}/rsg_callbacks_ips", $storeId);
58
+ $allowedIps = array_map('trim', explode("\n", $ipsRaw));
59
+
60
+ $clientIp = Mage::helper('core/http')->getRemoteAddr();
61
+ return in_array($clientIp, $allowedIps);
62
+ }
63
+
64
  /**
65
  * Tries to get a user-friently version from translartion by status code
66
  * returns False when it does not find it.
app/code/community/DataCash/Dpg/Model/Api/Abstract.php CHANGED
@@ -28,6 +28,9 @@
28
 
29
  abstract class DataCash_Dpg_Model_Api_Abstract extends Varien_Object
30
  {
 
 
 
31
  /**
32
  * The internal member variable that will hold the client
33
  *
@@ -90,7 +93,7 @@ abstract class DataCash_Dpg_Model_Api_Abstract extends Varien_Object
90
  */
91
  public function getUniqueOrderNumber()
92
  {
93
- return $this->getOrderNumber().' - '.time();
94
  }
95
 
96
  /**
@@ -310,7 +313,7 @@ abstract class DataCash_Dpg_Model_Api_Abstract extends Varien_Object
310
 
311
  public function addFraudScreening()
312
  {
313
- if (!$this->getUseFraudScreening()) {
314
  return;
315
  }
316
 
@@ -325,6 +328,14 @@ abstract class DataCash_Dpg_Model_Api_Abstract extends Varien_Object
325
  $this->paymentRsgDataToRequest($policy['payment'], $req);
326
  $this->orderRsgDataToRequest($policy['order'], $req);
327
  $this->itemRsgDataToRequest($policy['item'], $req);
 
 
 
 
 
 
 
 
328
  }
329
 
330
  /* @return void */
@@ -745,4 +756,43 @@ abstract class DataCash_Dpg_Model_Api_Abstract extends Varien_Object
745
  ->log($debugData);
746
  }
747
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
748
  }
28
 
29
  abstract class DataCash_Dpg_Model_Api_Abstract extends Varien_Object
30
  {
31
+ const DEFAULT_CB_FORMAT = 'HTTP';
32
+ const DEFAULT_CB_OPTIONS = '02';
33
+
34
  /**
35
  * The internal member variable that will hold the client
36
  *
93
  */
94
  public function getUniqueOrderNumber()
95
  {
96
+ return $this->getOrderNumber();
97
  }
98
 
99
  /**
313
 
314
  public function addFraudScreening()
315
  {
316
+ if (!$this->getUseFraudScreening() || $this->getConfig()->getIsAllowedT3m($this->getMethod())) {
317
  return;
318
  }
319
 
328
  $this->paymentRsgDataToRequest($policy['payment'], $req);
329
  $this->orderRsgDataToRequest($policy['order'], $req);
330
  $this->itemRsgDataToRequest($policy['item'], $req);
331
+
332
+ if ($this->getConfig()->getAllowRsgCallback($this->getMethod())) {
333
+ $this->getRequest()->addCallbackResponse(array(
334
+ 'callback_url' => $this->getConfig()->getRsgCallBackUrl($this->getMethod()),
335
+ 'callback_format' => self::DEFAULT_CB_FORMAT,
336
+ //'callback_options' => self::DEFAULT_CB_OPTIONS,
337
+ ));
338
+ }
339
  }
340
 
341
  /* @return void */
756
  ->log($debugData);
757
  }
758
  }
759
+
760
+ public function call3DLookup()
761
+ {
762
+ if (!$this->getConfig()->getIsAllowedT3m($this->getMethod())) {
763
+ return;
764
+ }
765
+
766
+ if (Mage::getSingleton('customer/session')->isLoggedIn()) {
767
+ $customer = Mage::getSingleton('customer/session')->getCustomer();
768
+ $orders = Mage::getModel('sales/order')
769
+ ->getCollection()
770
+ ->addAttributeToSelect('*')
771
+ ->addFieldToFilter('customer_id', $customer->getId())
772
+ ->setOrder('created_at', 'asc');
773
+
774
+ $previousOrderTotal = 0;
775
+ foreach ($orders as $order) {
776
+ $previousOrderTotal += $order->getData('grand_total');
777
+ }
778
+
779
+ $previousOrders = array(
780
+ 'count' => count($orders),
781
+ 'total' => $previousOrderTotal,
782
+ 'first' => $orders->getSize() > 0 ?
783
+ substr($orders->getFirstItem()->getCreatedAt(), 0, 10) : NULL
784
+ );
785
+ } else {
786
+ $previousOrders = array(
787
+ 'count' => 0,
788
+ 'total' => 0,
789
+ 'first' => null,
790
+ );
791
+ }
792
+
793
+ $quote = Mage::getSingleton('checkout/session')->getQuote();
794
+ $this->setOrderItems($quote->getAllVisibleItems());
795
+ $this->setPreviousOrders($previousOrders);
796
+ $this->setRemoteIp(Mage::helper('core/http')->getRemoteAddr());
797
+ }
798
  }
app/code/community/DataCash/Dpg/Model/Api/Direct.php CHANGED
@@ -136,7 +136,9 @@ class DataCash_Dpg_Model_Api_Direct extends DataCash_Dpg_Model_Api_Abstract
136
  **/
137
  public function call3DLookup()
138
  {
139
- $mpiMerchantReference = $this->getOrderNumber() . '-' . time();
 
 
140
  $request = $this->getRequest()
141
  ->addTransaction()
142
  ->addTxnDetails($mpiMerchantReference, $this->getAmount(), $this->getCurrency(), 'ecomm')
136
  **/
137
  public function call3DLookup()
138
  {
139
+ parent::call3DLookup();
140
+
141
+ $mpiMerchantReference = $this->getOrderNumber();
142
  $request = $this->getRequest()
143
  ->addTransaction()
144
  ->addTxnDetails($mpiMerchantReference, $this->getAmount(), $this->getCurrency(), 'ecomm')
app/code/community/DataCash/Dpg/Model/Api/Hcc.php CHANGED
@@ -134,6 +134,18 @@ class DataCash_Dpg_Model_Api_Hcc extends DataCash_Dpg_Model_Api_Abstract
134
  $this->_addLineItems();
135
  $this->_addCv2Avs();
136
  // $this->_addRed();
 
 
 
 
 
 
 
 
 
 
 
 
137
  $this->addFraudScreening();
138
 
139
  $this->call($request);
@@ -170,8 +182,20 @@ class DataCash_Dpg_Model_Api_Hcc extends DataCash_Dpg_Model_Api_Abstract
170
  $this->_addLineItems();
171
  $this->_addCv2Avs();
172
  // $this->_addRed();
 
 
 
 
 
 
 
 
 
 
 
 
173
  $this->addFraudScreening();
174
-
175
  $this->call($request);
176
  }
177
 
@@ -209,6 +233,8 @@ class DataCash_Dpg_Model_Api_Hcc extends DataCash_Dpg_Model_Api_Abstract
209
  **/
210
  public function call3DLookup()
211
  {
 
 
212
  $paymentAction = $this->getConfig()->getPaymentAction($this->getMethod());
213
  if ($paymentAction == Mage_Payment_Model_Method_Abstract::ACTION_AUTHORIZE) {
214
  $this->callPre(self::ADD_THREED_SECURE_SECTION);
134
  $this->_addLineItems();
135
  $this->_addCv2Avs();
136
  // $this->_addRed();
137
+ $this->_addT3m(array(
138
+ 'previousOrders' => $this->getPreviousOrders(),
139
+ 'orderNumber' => $this->getUniqueOrderNumber(),
140
+ 'orderItems' => $this->getOrderItems(),
141
+ 'forename' => $this->getForename(),
142
+ 'surname' => $this->getSurname(),
143
+ 'email' => $this->getCustomerEmail(),
144
+ 'remoteIp' => $this->getRemoteIp(),
145
+ 'orderItems' => $this->getOrderItems(),
146
+ 'billingAddress' => $this->getBillingAddress(),
147
+ 'shippingAddress' => $this->getShippingAddress()
148
+ ));
149
  $this->addFraudScreening();
150
 
151
  $this->call($request);
182
  $this->_addLineItems();
183
  $this->_addCv2Avs();
184
  // $this->_addRed();
185
+ $this->_addT3m(array(
186
+ 'previousOrders' => $this->getPreviousOrders(),
187
+ 'orderNumber' => $this->getUniqueOrderNumber(),
188
+ 'orderItems' => $this->getOrderItems(),
189
+ 'forename' => $this->getForename(),
190
+ 'surname' => $this->getSurname(),
191
+ 'email' => $this->getCustomerEmail(),
192
+ 'remoteIp' => $this->getRemoteIp(),
193
+ 'orderItems' => $this->getOrderItems(),
194
+ 'billingAddress' => $this->getBillingAddress(),
195
+ 'shippingAddress' => $this->getShippingAddress()
196
+ ));
197
  $this->addFraudScreening();
198
+
199
  $this->call($request);
200
  }
201
 
233
  **/
234
  public function call3DLookup()
235
  {
236
+ parent::call3DLookup();
237
+
238
  $paymentAction = $this->getConfig()->getPaymentAction($this->getMethod());
239
  if ($paymentAction == Mage_Payment_Model_Method_Abstract::ACTION_AUTHORIZE) {
240
  $this->callPre(self::ADD_THREED_SECURE_SECTION);
app/code/community/DataCash/Dpg/Model/Config.php CHANGED
@@ -1,311 +1,330 @@
1
- <?php
2
- /**
3
- * DataCash
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.
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 info@datacash.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 this module to newer
18
- * versions in the future. If you wish to customize this module for your
19
- * needs please refer to http://testserver.datacash.com/software/download.cgi
20
- * for more information.
21
- *
22
- * @author Alistair Stead
23
- * @version $Id$
24
- * @copyright DataCash, 11 April, 2011
25
- * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
26
- * @package DataCash
27
- **/
28
-
29
- class DataCash_Dpg_Model_Config extends Varien_Object
30
- {
31
- const TRANSACTION_TYPES = 'global/datacash/transaction/types';
32
-
33
- /**
34
- * Return the internal storeId
35
- *
36
- * @return int
37
- * @author Alistair Stead
38
- **/
39
- public function getStoreId()
40
- {
41
- if (is_null($this->getStorId())) {
42
- $this->setStoreId(Mage::app()->getStore()->getId());
43
- }
44
-
45
- return $this->getStorId();
46
- }
47
-
48
- protected function _getStoreFlag($method, $setting)
49
- {
50
- return Mage::getStoreConfigFlag("payment/{$method}/{$setting}", $this->getStoreId());
51
- }
52
-
53
- protected function _getStoreSetting($method, $setting)
54
- {
55
- return Mage::getStoreConfig("payment/{$method}/{$setting}", $this->getStoreId());
56
- }
57
-
58
- /**
59
- * Retrieve array of credit card types
60
- *
61
- * @return array
62
- */
63
- public function getTansactionTypes()
64
- {
65
- $_types = Mage::getConfig()->getNode(self::TRANSACTION_TYPES)->asArray();
66
-
67
- $types = array();
68
- foreach ($_types as $data) {
69
- if (isset($data['code']) && isset($data['name'])) {
70
- $types[$data['code']] = $data['name'];
71
- }
72
- }
73
-
74
- return $types;
75
- }
76
-
77
- /**
78
- * Check whether method active in configuration and supported for merchant country or not
79
- *
80
- * @param string $method Method code
81
- * @author Alistair Stead
82
- */
83
- public function isMethodActive($method)
84
- {
85
- if (Mage::getStoreConfigFlag("payment/{$method}/active", $this->getStoreId()))
86
- {
87
- return true;
88
- }
89
- return false;
90
- }
91
-
92
- /**
93
- * Is the payment method configured to run in sandbox mode
94
- *
95
- * @param string $method Method code
96
- * @return bool
97
- * @author Alistair Stead
98
- **/
99
- public function isMethodSandboxed($method)
100
- {
101
- $option = (int)Mage::getStoreConfig("payment/{$method}/sandbox", $this->getStoreId());
102
- return in_array($option, array(1, 2));
103
- }
104
-
105
- /**
106
- * Is the payment method configured to run in sandbox mode
107
- *
108
- * @param string $method Method code
109
- * @return bool
110
- * @author Alistair Stead
111
- **/
112
- public function getEndpoint($method)
113
- {
114
- $option = (int)Mage::getStoreConfig("payment/{$method}/sandbox", $this->getStoreId());
115
- $endpoints = array(
116
- $this->_getStoreSetting($method, 'live_endpoint'),
117
- $this->_getStoreSetting($method, 'testing_endpoint'), // test mode 1
118
- $this->_getStoreSetting($method, 'accreditation_cnp_endpoint'), // test mode 2
119
- $this->_getStoreSetting($method, 'accreditation_acq_endpoint'), // test mode 3
120
- );
121
- return $endpoints[$option];
122
- }
123
-
124
- /**
125
- * Is the debugging enabled
126
- *
127
- * @param string $method Method code
128
- * @return bool
129
- * @author Alistair Stead
130
- **/
131
- public function isMethodDebug($method)
132
- {
133
- if (Mage::getStoreConfigFlag("payment/{$method}/debug", $this->getStoreId()))
134
- {
135
- return true;
136
- }
137
- return false;
138
- }
139
-
140
- /**
141
- * Should order line items be transmitted
142
- *
143
- * @param string $method Method code
144
- * @return bool
145
- * @author Alistair Stead
146
- **/
147
- public function isLineItemsEnabled($method)
148
- {
149
- if ($method == "datacash_api") { // XXX: make it more elegant
150
- return false;
151
- }
152
- if (Mage::getStoreConfigFlag("payment/{$method}/line_items_enabled", $this->getStoreId()))
153
- {
154
- return true;
155
- }
156
- return false;
157
- }
158
-
159
- /**
160
- * Should CV2 information be transmitted
161
- *
162
- * @param string $method Method code
163
- * @return bool
164
- * @author Alistair Stead
165
- **/
166
- public function isUseCcv($method)
167
- {
168
- if (Mage::getStoreConfigFlag("payment/{$method}/useccv", $this->getStoreId()) == '1')
169
- {
170
- return true;
171
- }
172
- return false;
173
- }
174
-
175
- /**
176
- * Should CV2 Extended Policy information be transmitted
177
- *
178
- * @param string $method Method code
179
- * @return bool
180
- * @author Alistair Stead
181
- **/
182
- public function isUseAdvancedCcv($method)
183
- {
184
- if (Mage::getStoreConfigFlag("payment/{$method}/useccv_advanced", $this->getStoreId()) == '1')
185
- {
186
- return true;
187
- }
188
- return false;
189
- }
190
-
191
- /**
192
- * Should 3D Secure inormation be transmitted
193
- *
194
- * @param string $method Method code
195
- * @return bool
196
- * @author Alistair Stead
197
- **/
198
- public function getIsCentinelValidationEnabled($method)
199
- {
200
- if (Mage::getStoreConfigFlag("payment/{$method}/centinel", $this->getStoreId()) == '1')
201
- {
202
- return true;
203
- }
204
- return false;
205
- }
206
-
207
- /**
208
- * Decrypt and return the Merchant password for the DataCash gateway
209
- *
210
- * @return string
211
- * @author Alistair Stead
212
- **/
213
- public function getApiPassword($method)
214
- {
215
- $password = Mage::getStoreConfig("payment/{$method}/merchant_password", $this->getStoreId());
216
- // Decrypt the marchant password in order to transmit it as part of the request
217
- return Mage::helper('core')->decrypt($password);
218
- }
219
-
220
- /**
221
- * Return the Merchant ID for the DataCash gateway
222
- *
223
- * @return string
224
- * @author Alistair Stead
225
- **/
226
- public function getApiMerchantId($method)
227
- {
228
- return Mage::getStoreConfig("payment/{$method}/merchant_id", $this->getStoreId());
229
- }
230
-
231
- /**
232
- * Return the configured payment action
233
- *
234
- * @return string
235
- * @author Alistair Stead
236
- **/
237
- public function getPaymentAction($method)
238
- {
239
- return Mage::getStoreConfig("payment/{$method}/payment_action", $this->getStoreId());
240
- }
241
-
242
- /**
243
- * Should processing continue for 3DSecure response code
244
- *
245
- * @param string $method Method code
246
- * $param string $code DRG response code
247
- * @return bool
248
- * @author Hilary Boyce
249
- **/
250
- public function continueBehaviour($method, $code)
251
- {
252
- if (Mage::getStoreConfigFlag("payment/{$method}/threedsecure_behaviour_{$code}", $this->getStoreId()) == '1')
253
- {
254
- return true;
255
- }
256
- return false;
257
- }
258
-
259
- public function getIsAllowedFraudScreening($method = 'datacash_api')
260
- {
261
- if (Mage::getStoreConfigFlag("payment/{$method}/allow_fraud_screening", $this->getStoreId()))
262
- {
263
- return true;
264
- }
265
- return false;
266
- }
267
-
268
- public function getFraudScreeningMode($method = 'datacash_api')
269
- {
270
- return Mage::getStoreConfig("payment/{$method}/rsg_service_mode", $this->getStoreId());
271
- }
272
-
273
- public function getIsAllowedTokenizer($method = 'datacash_api')
274
- {
275
- if (Mage::getStoreConfigFlag("payment/{$method}/allow_tokenizer", $this->getStoreId()))
276
- {
277
- return true;
278
- }
279
- return false;
280
- }
281
-
282
- public function getIsAllowedT3m($method = 'datacash_api')
283
- {
284
- if (Mage::getStoreConfigFlag("payment/{$method}/allow_t3m", $this->getStoreId()))
285
- {
286
- return true;
287
- }
288
- return false;
289
- }
290
-
291
- public function getT3mUseSslCallback($method = 'datacash_api')
292
- {
293
- if (Mage::getStoreConfigFlag("payment/{$method}/t3m_use_ssl_callback", $this->getStoreId()))
294
- {
295
- return true;
296
- }
297
- return false;
298
- }
299
-
300
- public function getT3mCallBackUrl($method = 'datacash_api')
301
- {
302
- $defaultStore = Mage::getModel('core/store')->load('default', 'code');
303
- $uri = 'index.php/datacash/t3m';
304
-
305
- if ($this->getT3mUseSslCallback($method)) {
306
- return Mage::getStoreConfig('web/secure/base_url', $defaultStore->getStoreId()) . $uri;
307
- } else {
308
- return Mage::getStoreConfig('web/unsecure/base_url', $defaultStore->getStoreId()) . $uri;
309
- }
310
- }
311
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * DataCash
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.
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 info@datacash.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 this module to newer
18
+ * versions in the future. If you wish to customize this module for your
19
+ * needs please refer to http://testserver.datacash.com/software/download.cgi
20
+ * for more information.
21
+ *
22
+ * @author Alistair Stead
23
+ * @version $Id$
24
+ * @copyright DataCash, 11 April, 2011
25
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
26
+ * @package DataCash
27
+ **/
28
+
29
+ class DataCash_Dpg_Model_Config extends Varien_Object
30
+ {
31
+ const TRANSACTION_TYPES = 'global/datacash/transaction/types';
32
+
33
+ const RSG_REJECT = 2;
34
+ const RSG_RELEASE = 0;
35
+ const RSG_HOLD = 1;
36
+ const RSG_INV = 9;
37
+
38
+ public $_t3mPaymentInfo = array(
39
+ 0 => 'Release',
40
+ 1 => 'Hold',
41
+ 2 => 'Reject',
42
+ 9 => 'Under Investigation',
43
+ );
44
+
45
+ public $_t3mResponseMap = array(
46
+ 't3m_score' => 'score',
47
+ 't3m_recommendation' => 'recommendation',
48
+ );
49
+
50
+ /**
51
+ * Return the internal storeId
52
+ *
53
+ * @return int
54
+ * @author Alistair Stead
55
+ **/
56
+ public function getStoreId()
57
+ {
58
+ if (is_null($this->getStorId())) {
59
+ $this->setStoreId(Mage::app()->getStore()->getId());
60
+ }
61
+
62
+ return $this->getStorId();
63
+ }
64
+
65
+ protected function _getStoreFlag($method, $setting)
66
+ {
67
+ return Mage::getStoreConfigFlag("payment/{$method}/{$setting}", $this->getStoreId());
68
+ }
69
+
70
+ protected function _getStoreSetting($method, $setting)
71
+ {
72
+ return Mage::getStoreConfig("payment/{$method}/{$setting}", $this->getStoreId());
73
+ }
74
+
75
+ /**
76
+ * Retrieve array of credit card types
77
+ *
78
+ * @return array
79
+ */
80
+ public function getTansactionTypes()
81
+ {
82
+ $_types = Mage::getConfig()->getNode(self::TRANSACTION_TYPES)->asArray();
83
+
84
+ $types = array();
85
+ foreach ($_types as $data) {
86
+ if (isset($data['code']) && isset($data['name'])) {
87
+ $types[$data['code']] = $data['name'];
88
+ }
89
+ }
90
+
91
+ return $types;
92
+ }
93
+
94
+ /**
95
+ * Check whether method active in configuration and supported for merchant country or not
96
+ *
97
+ * @param string $method Method code
98
+ * @author Alistair Stead
99
+ */
100
+ public function isMethodActive($method)
101
+ {
102
+ if (Mage::getStoreConfigFlag("payment/{$method}/active", $this->getStoreId()))
103
+ {
104
+ return true;
105
+ }
106
+ return false;
107
+ }
108
+
109
+ /**
110
+ * Is the payment method configured to run in sandbox mode
111
+ *
112
+ * @param string $method Method code
113
+ * @return bool
114
+ * @author Alistair Stead
115
+ **/
116
+ public function isMethodSandboxed($method)
117
+ {
118
+ $option = (int)Mage::getStoreConfig("payment/{$method}/sandbox", $this->getStoreId());
119
+ return in_array($option, array(1, 2));
120
+ }
121
+
122
+ /**
123
+ * Is the payment method configured to run in sandbox mode
124
+ *
125
+ * @param string $method Method code
126
+ * @return bool
127
+ * @author Alistair Stead
128
+ **/
129
+ public function getEndpoint($method)
130
+ {
131
+ $option = (int)Mage::getStoreConfig("payment/{$method}/sandbox", $this->getStoreId());
132
+ $endpoints = array(
133
+ $this->_getStoreSetting($method, 'live_endpoint'),
134
+ $this->_getStoreSetting($method, 'testing_endpoint'), // test mode 1
135
+ $this->_getStoreSetting($method, 'accreditation_cnp_endpoint'), // test mode 2
136
+ $this->_getStoreSetting($method, 'accreditation_acq_endpoint'), // test mode 3
137
+ );
138
+ return $endpoints[$option];
139
+ }
140
+
141
+ /**
142
+ * Is the debugging enabled
143
+ *
144
+ * @param string $method Method code
145
+ * @return bool
146
+ * @author Alistair Stead
147
+ **/
148
+ public function isMethodDebug($method)
149
+ {
150
+ if (Mage::getStoreConfigFlag("payment/{$method}/debug", $this->getStoreId()))
151
+ {
152
+ return true;
153
+ }
154
+ return false;
155
+ }
156
+
157
+ /**
158
+ * Should order line items be transmitted
159
+ *
160
+ * @param string $method Method code
161
+ * @return bool
162
+ * @author Alistair Stead
163
+ **/
164
+ public function isLineItemsEnabled($method)
165
+ {
166
+ if ($method == "datacash_api") { // XXX: make it more elegant
167
+ return false;
168
+ }
169
+ if (Mage::getStoreConfigFlag("payment/{$method}/line_items_enabled", $this->getStoreId()))
170
+ {
171
+ return true;
172
+ }
173
+ return false;
174
+ }
175
+
176
+ /**
177
+ * Should CV2 information be transmitted
178
+ *
179
+ * @param string $method Method code
180
+ * @return bool
181
+ * @author Alistair Stead
182
+ **/
183
+ public function isUseCcv($method)
184
+ {
185
+ if (Mage::getStoreConfigFlag("payment/{$method}/useccv", $this->getStoreId()) == '1')
186
+ {
187
+ return true;
188
+ }
189
+ return false;
190
+ }
191
+
192
+ /**
193
+ * Should CV2 Extended Policy information be transmitted
194
+ *
195
+ * @param string $method Method code
196
+ * @return bool
197
+ * @author Alistair Stead
198
+ **/
199
+ public function isUseAdvancedCcv($method)
200
+ {
201
+ if (Mage::getStoreConfigFlag("payment/{$method}/useccv_advanced", $this->getStoreId()) == '1')
202
+ {
203
+ return true;
204
+ }
205
+ return false;
206
+ }
207
+
208
+ /**
209
+ * Should 3D Secure inormation be transmitted
210
+ *
211
+ * @param string $method Method code
212
+ * @return bool
213
+ * @author Alistair Stead
214
+ **/
215
+ public function getIsCentinelValidationEnabled($method)
216
+ {
217
+ if (Mage::getStoreConfigFlag("payment/{$method}/centinel", $this->getStoreId()) == '1')
218
+ {
219
+ return true;
220
+ }
221
+ return false;
222
+ }
223
+
224
+ /**
225
+ * Decrypt and return the Merchant password for the DataCash gateway
226
+ *
227
+ * @return string
228
+ * @author Alistair Stead
229
+ **/
230
+ public function getApiPassword($method)
231
+ {
232
+ $password = Mage::getStoreConfig("payment/{$method}/merchant_password", $this->getStoreId());
233
+ // Decrypt the marchant password in order to transmit it as part of the request
234
+ return Mage::helper('core')->decrypt($password);
235
+ }
236
+
237
+ /**
238
+ * Return the Merchant ID for the DataCash gateway
239
+ *
240
+ * @return string
241
+ * @author Alistair Stead
242
+ **/
243
+ public function getApiMerchantId($method)
244
+ {
245
+ return Mage::getStoreConfig("payment/{$method}/merchant_id", $this->getStoreId());
246
+ }
247
+
248
+ /**
249
+ * Return the configured payment action
250
+ *
251
+ * @return string
252
+ * @author Alistair Stead
253
+ **/
254
+ public function getPaymentAction($method)
255
+ {
256
+ return Mage::getStoreConfig("payment/{$method}/payment_action", $this->getStoreId());
257
+ }
258
+
259
+ /**
260
+ * Should processing continue for 3DSecure response code
261
+ *
262
+ * @param string $method Method code
263
+ * $param string $code DRG response code
264
+ * @return bool
265
+ * @author Hilary Boyce
266
+ **/
267
+ public function continueBehaviour($method, $code)
268
+ {
269
+ if (Mage::getStoreConfigFlag("payment/{$method}/threedsecure_behaviour_{$code}", $this->getStoreId()) == '1')
270
+ {
271
+ return true;
272
+ }
273
+ return false;
274
+ }
275
+
276
+ public function getIsAllowedFraudScreening($method = 'datacash_api')
277
+ {
278
+ if (Mage::getStoreConfigFlag("payment/{$method}/allow_fraud_screening", $this->getStoreId()))
279
+ {
280
+ return true;
281
+ }
282
+ return false;
283
+ }
284
+
285
+ public function getFraudScreeningMode($method = 'datacash_api')
286
+ {
287
+ return Mage::getStoreConfig("payment/{$method}/rsg_service_mode", $this->getStoreId());
288
+ }
289
+
290
+ public function getIsAllowedTokenizer($method = 'datacash_api')
291
+ {
292
+ if (Mage::getStoreConfigFlag("payment/{$method}/allow_tokenizer", $this->getStoreId()))
293
+ {
294
+ return true;
295
+ }
296
+ return false;
297
+ }
298
+
299
+ public function getIsAllowedT3m($method = 'datacash_api')
300
+ {
301
+ $mode = Mage::getStoreConfig("payment/{$method}/rsg_service_mode", $this->getStoreId());
302
+ return $mode == 't3m';
303
+ }
304
+
305
+ public function getT3mCallBackUrl($method = 'datacash_api')
306
+ {
307
+ return Mage::getUrl('datacash/t3m/index', array('_secure' => true));
308
+ }
309
+
310
+ public function getAllowRsgCallback($method = 'datacash_api')
311
+ {
312
+ if (Mage::getStoreConfigFlag("payment/{$method}/rsg_callbacks", $this->getStoreId())) {
313
+ return true;
314
+ }
315
+ return false;
316
+ }
317
+
318
+ public function getRsgCallBackUrl($method = 'datacash_api')
319
+ {
320
+ return Mage::getUrl('datacash/rsg/index', array('_secure' => true));
321
+ }
322
+
323
+ public function isRsgAutoUpdateEnabled($method = 'datacash_api')
324
+ {
325
+ if (Mage::getStoreConfigFlag("payment/{$method}/rsg_callbacks_autoupdate", $this->getStoreId())) {
326
+ return true;
327
+ }
328
+ return false;
329
+ }
330
+ }
app/code/community/DataCash/Dpg/Model/Datacash/Request.php CHANGED
@@ -818,6 +818,31 @@ class DataCash_Dpg_Model_Datacash_Request extends Varien_Object
818
  return $this;
819
  }
820
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
821
  /**
822
  * addThe3rdMan
823
  * @author David Marrs
@@ -845,10 +870,11 @@ class DataCash_Dpg_Model_Datacash_Request extends Varien_Object
845
  $customer->addChild('customer_dob', NULL);
846
  $customer->addChild('first_purchase_date', $previousOrders['first']);
847
  $customer->addChild('ip_address', $remoteIp);
 
848
  $prevPurchases = $customer->addChild('previous_purchases');
849
  $prevPurchases->addAttribute('count', $previousOrders['count']);
850
  $prevPurchases->addAttribute('value', $previousOrders['total']);
851
-
852
  if ($shippingAddress) {
853
  $this->addT3mAddress($t3m, 'DeliveryAddress', $shippingAddress);
854
  }
@@ -858,6 +884,7 @@ class DataCash_Dpg_Model_Datacash_Request extends Varien_Object
858
  $rt = $t3m->addChild('Realtime');
859
  $rt->addChild('real_time_callback', $callbackUrl);
860
  $rt->addChild('real_time_callback_format', 'HTTP');
 
861
  // XXX Field 'distribution_channel' is not specified as required so I'm
862
  // leaving it out.
863
  $order->addChild('distribution_channel', NULL); // XXX Where is this set in mage?
@@ -866,8 +893,8 @@ class DataCash_Dpg_Model_Datacash_Request extends Varien_Object
866
  foreach ($orderItems as $item) {
867
  $product = $products->addChild('Product');
868
  $product->addChild('code', $item->getSku());
869
- $product->addChild('quantity', $item->getQtyOrdered());
870
- $product->addChild('price', $item->getPrice());
871
  }
872
  }
873
 
818
  return $this;
819
  }
820
 
821
+ /**
822
+ * addCallbackResponse function.
823
+ *
824
+ * @access public
825
+ * @param mixed $vars
826
+ * @return void
827
+ */
828
+ public function addCallbackResponse($vars)
829
+ {
830
+ $txn = $this->getRequest()->Transaction->TxnDetails;
831
+ if (!$txn) {
832
+ throw new Exception('Parent node (Transaction->TxnDetails) does not exist');
833
+ }
834
+
835
+ $merchConf = $txn->Risk->Action->MerchantConfiguration;
836
+ if (!$merchConf) {
837
+ throw new Exception('Parent node (Risk->Action->MerchantConfiguration) does not exist');
838
+ }
839
+
840
+ $callbackConf = $merchConf->addChild('CallbackConfiguration');
841
+ $callbackConf->addChild('callback_url', $vars['callback_url']);
842
+ $callbackConf->addChild('callback_format', $vars['callback_format']);
843
+ //$callbackConf->addChild('callback_options', $vars['callback_options']);
844
+ }
845
+
846
  /**
847
  * addThe3rdMan
848
  * @author David Marrs
870
  $customer->addChild('customer_dob', NULL);
871
  $customer->addChild('first_purchase_date', $previousOrders['first']);
872
  $customer->addChild('ip_address', $remoteIp);
873
+
874
  $prevPurchases = $customer->addChild('previous_purchases');
875
  $prevPurchases->addAttribute('count', $previousOrders['count']);
876
  $prevPurchases->addAttribute('value', $previousOrders['total']);
877
+
878
  if ($shippingAddress) {
879
  $this->addT3mAddress($t3m, 'DeliveryAddress', $shippingAddress);
880
  }
884
  $rt = $t3m->addChild('Realtime');
885
  $rt->addChild('real_time_callback', $callbackUrl);
886
  $rt->addChild('real_time_callback_format', 'HTTP');
887
+ //$rt->addChild('real_time_callback_options', '2');
888
  // XXX Field 'distribution_channel' is not specified as required so I'm
889
  // leaving it out.
890
  $order->addChild('distribution_channel', NULL); // XXX Where is this set in mage?
893
  foreach ($orderItems as $item) {
894
  $product = $products->addChild('Product');
895
  $product->addChild('code', $item->getSku());
896
+ $product->addChild('quantity', $item->getQty());
897
+ $product->addChild('price', $item->getProduct()->getPrice());
898
  }
899
  }
900
 
app/code/community/DataCash/Dpg/Model/Datacash/Response.php CHANGED
@@ -43,6 +43,12 @@ class DataCash_Dpg_Model_Datacash_Response extends Varien_Object
43
  return false;
44
  }
45
 
 
 
 
 
 
 
46
  public function isMarkedForReview()
47
  {
48
  return (string)$this->getData('Risk/action_response/screening_response/response_code') == DataCash_Dpg_Model_Code::REVIEW;
@@ -51,7 +57,7 @@ class DataCash_Dpg_Model_Datacash_Response extends Varien_Object
51
  /**
52
  * Was the transaction judged to be fraudulent
53
  *
54
- * @return bool
55
  * @author Alistair Stead
56
  **/
57
  public function isFraud()
@@ -59,6 +65,17 @@ class DataCash_Dpg_Model_Datacash_Response extends Varien_Object
59
  return (string)$this->getData('Risk/action_response/screening_response/response_code') == DataCash_Dpg_Model_Code::FRAUD;
60
  }
61
 
 
 
 
 
 
 
 
 
 
 
 
62
  /**
63
  * Does the payment transaction require review
64
  *
43
  return false;
44
  }
45
 
46
+ /**
47
+ * isMarkedForReview function.
48
+ *
49
+ * @access public
50
+ * @return string
51
+ */
52
  public function isMarkedForReview()
53
  {
54
  return (string)$this->getData('Risk/action_response/screening_response/response_code') == DataCash_Dpg_Model_Code::REVIEW;
57
  /**
58
  * Was the transaction judged to be fraudulent
59
  *
60
+ * @return string
61
  * @author Alistair Stead
62
  **/
63
  public function isFraud()
65
  return (string)$this->getData('Risk/action_response/screening_response/response_code') == DataCash_Dpg_Model_Code::FRAUD;
66
  }
67
 
68
+ /**
69
+ * getRiskResponse function.
70
+ *
71
+ * @access public
72
+ * @return array
73
+ */
74
+ public function getRiskResponse()
75
+ {
76
+ return $this->getData('Risk/action_response');
77
+ }
78
+
79
  /**
80
  * Does the payment transaction require review
81
  *
app/code/community/DataCash/Dpg/Model/Method/Abstract.php CHANGED
@@ -1,678 +1,750 @@
1
- <?php
2
- /**
3
- * DataCash
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.
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 info@datacash.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 this module to newer
18
- * versions in the future. If you wish to customize this module for your
19
- * needs please refer to http://testserver.datacash.com/software/download.cgi
20
- * for more information.
21
- *
22
- * @author Alistair Stead
23
- * @version $Id$
24
- * @copyright DataCash, 11 April, 2011
25
- * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
26
- * @package DataCash
27
- **/
28
-
29
- abstract class DataCash_Dpg_Model_Method_Abstract extends Mage_Payment_Model_Method_Cc
30
- {
31
- /**
32
- * Member variable that will hold reference to the API broker.
33
- *
34
- * The broker class will handle all the external calls
35
- *
36
- * @var string
37
- **/
38
- protected $_api;
39
-
40
- protected $_config;
41
- protected $_token = null;
42
-
43
- /**
44
- *
45
- * @return DataCash_Dpg_Model_Method_Hcc
46
- */
47
- public function __construct($params = array())
48
- {
49
- parent::__construct($params);
50
-
51
- return $this;
52
- }
53
-
54
- /**
55
- * Add token to instance variable
56
- * @param $token DataCash_Dpg_Model_Tokencard
57
- */
58
- public function setToken(DataCash_Dpg_Model_Tokencard $token)
59
- {
60
- $this->_token = $token;
61
- return $this;
62
- }
63
-
64
- public function getToken()
65
- {
66
- return $this->_token;
67
- }
68
-
69
- /**
70
- * getMethodAuthoriseStartUrl
71
- * @return string url for placeform action for redirection to Datacash
72
- */
73
- public function getMethodAuthoriseStartUrl()
74
- {
75
- return Mage::getUrl('checkout/hosted/start', array('_secure' => true));
76
- }
77
-
78
- /**
79
- * Check if current quote is multishipping
80
- */
81
- protected function _isMultishippingCheckout() {
82
- if (Mage::getSingleton('admin/session')->isLoggedIn()) {
83
- return false;
84
- }
85
-
86
- return (bool) Mage::getSingleton('checkout/session')->getQuote()->getIsMultiShipping();
87
- }
88
-
89
- public function hasAdvancedVerification()
90
- {
91
- $configData = $this->getConfigData('useccv_advanced');
92
- if(is_null($configData)){
93
- return false;
94
- }
95
- return (bool) $configData;
96
- }
97
-
98
- public function hasFraudScreening()
99
- {
100
- $configData = $this->getConfigData('allow_fraud_screening');
101
- if(is_null($configData) || $configData=='0'){
102
- return false;
103
- }
104
- return (bool) $configData;
105
- }
106
-
107
- /**
108
- *
109
- * Gets Extended policy from config.
110
- * @returns array $extendedPolicy
111
- * @author Hilary Boyce
112
- */
113
- protected function _extendedPolicy()
114
- {
115
- $extendedPolicy = array(
116
- 'cv2_policy' => array(
117
- 'notprovided' => $this->getConfigData('extpol_cv2policy_notprovided'),
118
- 'notchecked' => $this->getConfigData('extpol_cv2policy_notchecked'),
119
- 'matched' => $this->getConfigData('extpol_cv2policy_matched'),
120
- 'notmatched' => $this->getConfigData('extpol_cv2policy_notmatched'),
121
- 'partialmatch' => $this->getConfigData('extpol_cv2policy_partialmatch')
122
- ),
123
- 'postcode_policy' => array(
124
- 'notprovided' => $this->getConfigData('extpol_postcode_notprovided'),
125
- 'notchecked' => $this->getConfigData('extpol_postcode_notchecked'),
126
- 'matched' => $this->getConfigData('extpol_postcode_matched'),
127
- 'notmatched' => $this->getConfigData('extpol_postcode_notmatched'),
128
- 'partialmatch' => $this->getConfigData('extpol_postcode_partialmatch')
129
- ),
130
- 'address_policy' => array(
131
- 'notprovided' => $this->getConfigData('extpol_address_notprovided'),
132
- 'notchecked' => $this->getConfigData('extpol_address_notchecked'),
133
- 'matched' => $this->getConfigData('extpol_address_matched'),
134
- 'notmatched' => $this->getConfigData('extpol_address_notmatched'),
135
- 'partialmatch' => $this->getConfigData('extpol_address_partialmatch')
136
- )
137
- );
138
- return $extendedPolicy;
139
- }
140
-
141
- protected function _fraudPolicy()
142
- {
143
- $fraudPolicy = array(
144
- 'customer' => array(
145
- 'first_name' => true, // XXX: this field is always included
146
- 'surname' => true, // XXX: same as above because one field controls both
147
- 'ip_address' => $this->getConfigData('rsg_data_customer_ip_address'),
148
- 'email_address' => $this->getConfigData('rsg_data_customer_email_address'),
149
- 'user_id' => $this->getConfigData('rsg_data_customer_user_id'),
150
- 'telephone' => $this->getConfigData('rsg_data_customer_telephone'),
151
- 'address_line1' => $this->getConfigData('rsg_data_customer_address_line1'),
152
- 'address_line2' => $this->getConfigData('rsg_data_customer_address_line2'),
153
- 'city' => $this->getConfigData('rsg_data_customer_city'),
154
- 'state_province'=> $this->getConfigData('rsg_data_customer_state_province'),
155
- 'country' => $this->getConfigData('rsg_data_customer_country'),
156
- 'zip_code' => $this->getConfigData('rsg_data_customer_zip_code'),
157
- ),
158
- 'shipping' => array(
159
- 'first_name' => $this->getConfigData('rsg_data_shipping_first_name'),
160
- 'surname' => $this->getConfigData('rsg_data_shipping_surname'),
161
- 'address_line1' => $this->getConfigData('rsg_data_shipping_address_line1'),
162
- 'address_line2' => $this->getConfigData('rsg_data_shipping_address_line2'),
163
- 'city' => $this->getConfigData('rsg_data_shipping_city'),
164
- 'state_province'=> $this->getConfigData('rsg_data_shipping_state_province'),
165
- 'country' => $this->getConfigData('rsg_data_shipping_country'),
166
- 'zip_code' => $this->getConfigData('rsg_data_shipping_zip_code'),
167
- ),
168
- 'payment' => array(
169
- 'payment_method'=> $this->getConfigData('rsg_data_payment_payment_method'),
170
- ),
171
- 'order' => array(
172
- 'time_zone' => $this->getConfigData('rsg_data_order_time_zone'),
173
- 'discount_value'=> $this->getConfigData('rsg_data_order_discount_value'),
174
- ),
175
- 'item' => array(
176
- 'product_code' => $this->getConfigData('rsg_data_item_product_code'),
177
- 'product_description'=> $this->getConfigData('rsg_data_item_product_description'),
178
- 'product_category'=> $this->getConfigData('rsg_data_item_product_category'),
179
- 'order_quantity'=> $this->getConfigData('rsg_data_item_order_quantity'),
180
- 'unit_price' => $this->getConfigData('rsg_data_item_unit_price'),
181
- ),
182
- 'billing' => array(
183
- 'name' => $this->getConfigData('rsg_data_billing_name'),
184
- 'address_line1' => $this->getConfigData('rsg_data_billing_address_line1'),
185
- 'address_line2' => $this->getConfigData('rsg_data_billing_address_line2'),
186
- 'city' => $this->getConfigData('rsg_data_billing_city'),
187
- 'state_province'=> $this->getConfigData('rsg_data_billing_state_province'),
188
- 'country' => $this->getConfigData('rsg_data_billing_country'),
189
- 'zip_code' => $this->getConfigData('rsg_data_billing_zip_code'),
190
- ),
191
- );
192
- return $fraudPolicy;
193
- }
194
-
195
- public function setApi($value)
196
- {
197
- $this->_api = $value;
198
- }
199
-
200
- /**
201
- * Void the payment
202
- *
203
- * @param Varien_Object $payment
204
- * @return DataCash_Dpg_Model_Method_Api
205
- * @author Alistair Stead
206
- */
207
- public function void(Varien_Object $payment)
208
- {
209
- parent::void($payment);
210
- $this->cancel($payment);
211
-
212
- return $this;
213
- }
214
-
215
- /**
216
- * Refund the payment
217
- *
218
- * @param Varien_Object $payment
219
- * @param string $amount
220
- * @return void
221
- * @author Alistair Stead
222
- */
223
- public function refund(Varien_Object $payment, $amount)
224
- {
225
- parent::refund($payment, $amount);
226
- $this->_initApi();
227
- $this->_mapRequestDataToApi($payment, $amount);
228
- try {
229
- $this->_api->callTxnRefund();
230
- } catch (Exception $e) {
231
- Mage::throwException($e->getMessage());
232
- }
233
- // Process the response
234
- $response = $this->_api->getResponse();
235
- if ($response->isSuccessful()) {
236
- $payment->setTransactionId($response->getDatacashReference())
237
- ->setShouldCloseParentTransaction(false)
238
- ->setIsTransactionClosed(false);
239
- } else {
240
- Mage::throwException($response->getReason());
241
- }
242
-
243
- return $this;
244
- }
245
-
246
- /**
247
- * Cancel payment
248
- *
249
- * @param Mage_Sales_Model_Order_Payment $payment
250
- * @return Mage_Paypal_Model_Direct
251
- * @author Alistair Stead
252
- */
253
- public function cancel(Varien_Object $payment)
254
- {
255
- parent::cancel($payment);
256
- $this->_initApi();
257
- $this->_mapRequestDataToApi($payment, null);
258
- try {
259
- $this->_api->callCancel();
260
- } catch (Exception $e) {
261
- Mage::throwException($e->getMessage());
262
- }
263
- // Process the response
264
- $response = $this->_api->getResponse();
265
- if ($response->isSuccessful()) {
266
- $payment->setTransactionId($response->getDatacashReference())
267
- ->setShouldCloseParentTransaction(true)
268
- ->setIsTransactionClosed(true);
269
- } else {
270
- Mage::throwException($response->getReason());
271
- }
272
-
273
- return $this;
274
- }
275
-
276
- /**
277
- * Attempt to accept a pending payment
278
- *
279
- * @param Mage_Sales_Model_Order_Payment $payment
280
- * @return bool
281
- * @author Alistair Stead & Kristjan Heinaste
282
- */
283
- public function acceptPayment(Mage_Payment_Model_Info $payment)
284
- {
285
- parent::acceptPayment($payment);
286
- return $this->_reviewPayment($payment, DataCash_Dpg_Model_Code::PAYMENT_REVIEW_ACCEPT);
287
- }
288
-
289
- /**
290
- * Attempt to deny a pending payment
291
- *
292
- * @param Mage_Sales_Model_Order_Payment $payment
293
- * @return bool
294
- * @author Alistair Stead & Kristjan Heinaste
295
- */
296
- public function denyPayment(Mage_Payment_Model_Info $payment)
297
- {
298
- parent::denyPayment($payment);
299
- return $this->_reviewPayment($payment, DataCash_Dpg_Model_Code::PAYMENT_REVIEW_DENY);
300
- }
301
-
302
- /**
303
- * Generic payment review processor
304
- *
305
- * @author Kristjan Heinaste <kristjan@ontapgroup.com>
306
- */
307
- public function _reviewPayment(Mage_Payment_Model_Info $payment, $action)
308
- {
309
- //
310
- // XXX: When denied we leave it as is - no DC API support
311
- //
312
- if ($action == DataCash_Dpg_Model_Code::PAYMENT_REVIEW_DENY) {
313
- return true;
314
- }
315
-
316
- $this->_initApi();
317
-
318
- $this->_mapRequestDataToApi($payment, null);
319
-
320
- try {
321
- $this->_api->callReview($action);
322
- } catch (Exception $e) {
323
- Mage::throwException($e->getMessage());
324
- }
325
- // Process the response
326
- $response = $this->_api->getResponse();
327
- if ($response->isSuccessful()) {
328
- $responseMap = array(
329
- 'cc_approval' => 'HistoricTxn/authcode',
330
- 'cc_trans_id' => 'datacash_reference',
331
- 'cc_status' => 'status',
332
- 'cc_status_description' => 'reason',
333
- );
334
- foreach ($responseMap as $paymentKey => $responseKey) {
335
- if ($value = $response->getData($responseKey)) {
336
- $payment->setData($paymentKey, $value);
337
- }
338
- }
339
- $responseTransactionInfoMap = array(
340
- 'CardTxn' => 'CardTxn',
341
- 'datacash_reference' => 'datacash_refrence',
342
- 'mode' => 'mode',
343
- 'reason' => 'reason',
344
- 'status' => 'status',
345
- 'time' => 'time',
346
- 'authcode' => 'HistoricTxn/authcode',
347
- );
348
- foreach ($responseTransactionInfoMap as $paymentKey => $responseKey) {
349
- if ($value = $response->getData($responseKey)) {
350
- $payment->setTransactionAdditionalInfo($paymentKey, $value);
351
- }
352
- }
353
-
354
- //
355
- // XXX: This section depends on $action
356
- // but because DC does not support deny action yet, we leave this as is.
357
- //
358
- $payment->setTransactionId($response->getDatacashReference())
359
- ->setShouldCloseParentTransaction(true)
360
- ->setIsTransactionClosed(true)
361
- ->setIsTransactionApproved(true);
362
- } else {
363
- Mage::throwException($response->getReason());
364
- }
365
-
366
- return true;
367
- }
368
-
369
- /**
370
- * Fetch transaction details info
371
- *
372
- * @param Mage_Payment_Model_Info $payment
373
- * @param string $transactionId
374
- * @return array
375
- * @author Alistair Stead
376
- */
377
- public function fetchTransactionInfo(Mage_Payment_Model_Info $payment, $transactionId)
378
- {
379
- // Add method body (Phase 2 requirement)
380
- parent::fetchTransactionInfo($payment, $transactionId);
381
-
382
- return $this;
383
- }
384
-
385
- /**
386
- * Return datacash config instance
387
- *
388
- * @return DataCash_Dpg_Model_Config
389
- */
390
- public function getConfig()
391
- {
392
- return Mage::getSingleton('dpg/config');
393
- }
394
-
395
- /**
396
- * Decrypt and return the Merchant password for the DataCash gateway
397
- *
398
- * @return string
399
- * @author Alistair Stead
400
- **/
401
- protected function _getApiPassword()
402
- {
403
- // Decrypt the marchant password in order to transmit it as part of the request
404
- return Mage::helper('core')->decrypt($this->getConfigData('merchant_password'));
405
- }
406
-
407
- /**
408
- * Return the Merchant ID for the DataCash gateway
409
- *
410
- * @return string
411
- * @author Alistair Stead
412
- **/
413
- protected function _getApiMerchantId()
414
- {
415
- return $this->getConfigData('merchant_id');
416
- }
417
-
418
- /**
419
- * Initialize the data required be the API across all methods
420
- *
421
- * @return void
422
- * @author Alistair Stead
423
- **/
424
- protected function _initApi()
425
- {
426
- if (is_null($this->_api)) {
427
- $this->_api = Mage::getModel('dpg/api_direct');
428
- }
429
- $this->_api->setMerchantId($this->_getApiMerchantId());
430
- $this->_api->setMerchantPassword($this->_getApiPassword());
431
- }
432
-
433
- /**
434
- * Get an order number within different cart contexts
435
- *
436
- * @return int
437
- * @author Alistair Stead
438
- **/
439
- protected function _getOrderNumber($object = null)
440
- {
441
- if ($this->_isPlaceOrder($object)) {
442
- if ($object === NULL) {
443
- $object = $this->getInfoInstance()->getOrder();
444
- }
445
- return $object->getIncrementId();
446
- } else {
447
- if ($object === NULL) {
448
- $object = $this->getInfoInstance()->getQuote();
449
- }
450
- if (!$object->getReservedOrderId()) {
451
- $object->reserveOrderId();
452
- }
453
- return $object->getReservedOrderId();
454
- }
455
- }
456
-
457
- /**
458
- * Grand total getter
459
- *
460
- * @return string
461
- */
462
- protected function _getAmount()
463
- {
464
- $info = $this->getInfoInstance();
465
- if ($this->_isPlaceOrder()) {
466
- return (double)$info->getOrder()->getQuoteBaseGrandTotal();
467
- } else {
468
- return (double)$info->getQuote()->getBaseGrandTotal();
469
- }
470
- }
471
-
472
- /**
473
- * Currency code getter
474
- *
475
- * @return string
476
- */
477
- protected function _getCurrencyCode()
478
- {
479
- $info = $this->getInfoInstance();
480
-
481
- if ($this->_isPlaceOrder()) {
482
- return $info->getOrder()->getBaseCurrencyCode();
483
- } else {
484
- return $info->getQuote()->getBaseCurrencyCode();
485
- }
486
- }
487
-
488
- /**
489
- * Whether current operation is order placement
490
- *
491
- * @return bool
492
- */
493
- protected function _isPlaceOrder($object = null)
494
- {
495
- if ($object !== null) {
496
- if ($object instanceof Mage_Sales_Model_Quote) {
497
- return false;
498
- } elseif ($object instanceof Mage_Sales_Model_Order) {
499
- return true;
500
- }
501
- } else {
502
- $info = $this->getInfoInstance();
503
- if ($info instanceof Mage_Sales_Model_Quote_Payment) {
504
- return false;
505
- } elseif ($info instanceof Mage_Sales_Model_Order_Payment) {
506
- return true;
507
- }
508
- }
509
- }
510
-
511
- /**
512
- * Map data supplied by the request to the API
513
- *
514
- * This method will set all possible data no exceptions will be thrown even if data is missing
515
- * If the data is not supplied the error will be thrown by the API
516
- *
517
- * @return void
518
- * @author Alistair Stead
519
- **/
520
- protected function _mapRequestDataToApi($payment, $amount)
521
- {
522
- $order = $payment->getOrder();
523
- $orderId = $this->_getOrderNumber();
524
- $customer = Mage::getModel('customer/customer')->load($order->getCustomerId());
525
-
526
- $this->_api->setCustomerForename($customer->getFirstname());
527
- $this->_api->setCustomerSurname($customer->getLastname());
528
- $this->_api->setCustomerEmail($customer->getEmail());
529
- // Set the object properties required to make the API call
530
- $this->_api->setOrderNumber($orderId);
531
- $this->_api->setAmount($amount);
532
- $this->_api->setCurrency($order->getBaseCurrencyCode());
533
- $this->_api->setAddress($order->getShippingAddress());
534
- $this->_api->setBillingAddress($order->getBillingAddress());
535
- $this->_api->setShippingAddress($order->getShippingAddress());
536
- $this->_api->setShippingAmount($order->getShippingAmount());
537
- $this->_api->setShippingVatRate($order->getShippingVatPercent());
538
- if ($order->getCustomerIsGuest()) {
539
- $customerId = 'guest';
540
- } else {
541
- $customerId = $order->getCustomerId();
542
- }
543
- $this->_api->setCustomerCode($customerId);
544
- // add order line items
545
- $this->_api->setCartItems($order->getAllVisibleItems());
546
- // Add historic details
547
- if ($auth = $payment->getAuthorizationTransaction()) {
548
- $txnDetails = explode('-',$auth->getTxnId());
549
- $this->_api->setDataCashReference(array_shift($txnDetails));
550
- } else {
551
- $this->_api->setDataCashReference($payment->getCcTransId());
552
- }
553
- $this->_api->setAuthCode($payment->getCcApproval());
554
- $centinel = $this->getCentinelValidator();
555
- if ($centinel) {
556
- $state = $centinel->getValidationState();
557
- if ($state) {
558
- $bypass3DSecure = $state->getLookupBypass3dsecure();
559
- $this->_api->setBypass3dsecure($bypass3DSecure);
560
- if (!$bypass3DSecure) {
561
- $this->_api->setMpiReference($state->getAuthenticateTransactionId());
562
- }
563
- }
564
- }
565
-
566
- }
567
-
568
- /**
569
- * Protected method that will manage the transfer of data between the to objects
570
- *
571
- * @return void
572
- * @author Alistair Stead
573
- **/
574
- protected function _mapResponseToPayment($response, $payment)
575
- {
576
- $additionalInformationMap = array(
577
- 'cc_avs_address_result' => 'CardTxn/Cv2Avs/address_result/0',
578
- 'cc_avs_cv2_result' => 'CardTxn/Cv2Avs/cv2_result/0',
579
- 'cc_avs_postcode_result' => 'CardTxn/Cv2Avs/postcode_result/0',
580
- 'acs_url' => 'CardTxn/ThreeDSecure/acs_url',
581
- 'pareq_message' => 'CardTxn/ThreeDSecure/pareq_message',
582
- 'mode' => 'mode'
583
- );
584
- foreach ($additionalInformationMap as $paymentKey => $responseKey) {
585
- if ($value = $response->getData($responseKey)) {
586
- $payment->setAdditionalInformation($paymentKey, $value);
587
- }
588
- }
589
- $responseMap = array(
590
- 'cc_avs_status' => 'CardTxn/Cv2Avs/cv2avs_status',
591
- 'cc_approval' => 'CardTxn/authcode',
592
- 'cc_trans_id' => 'datacash_reference',
593
- 'cc_status' => 'status',
594
- 'cc_status_description' => 'reason',
595
- );
596
- foreach ($responseMap as $paymentKey => $responseKey) {
597
- if ($value = $response->getData($responseKey)) {
598
- $payment->setData($paymentKey, $value);
599
- }
600
- }
601
- $responseTransactionInfoMap = array(
602
- 'CardTxn' => 'CardTxn',
603
- 'datacash_reference' => 'datacash_refrence',
604
- 'mode' => 'mode',
605
- 'reason' => 'reason',
606
- 'status' => 'status',
607
- 'time' => 'time',
608
- 'authcode' => 'CardTxn/authcode',
609
- );
610
- foreach ($responseTransactionInfoMap as $paymentKey => $responseKey) {
611
- if ($value = $response->getData($responseKey)) {
612
- $payment->setTransactionAdditionalInfo($paymentKey, $value);
613
- }
614
- }
615
- if ($response->isFraud()) {
616
- $payment->setIsTransactionPending(true);
617
- $payment->setIsFraudDetected(true);
618
- }
619
- if ($response->isMarkedForReview()) {
620
- $payment->setIsTransactionPending(true);
621
- }
622
- $datacashReferenceMap = array(
623
- 'datacash_reference',
624
- 'QueryTxnResult/datacash_reference'
625
- );
626
- foreach ($datacashReferenceMap as $responseKey) {
627
- if ($value = $response->getData($responseKey)) {
628
- $payment->setTransactionId($value.'-'.time())
629
- ->setShouldCloseParentTransaction(false)
630
- ->setIsTransactionClosed(false);
631
- }
632
- }
633
-
634
- $session = $this->_getDataCashSession();
635
- $saveToken = $session->getData($this->getCode().'_save_token');
636
- if ($saveToken) {
637
- Mage::getModel('dpg/tokencard')->tokenizeResponse($payment, $response);
638
- }
639
- }
640
-
641
- protected function _getCentinelValidator($service)
642
- {
643
- $validator = Mage::getSingleton($service);
644
- $validator
645
- ->setIsModeStrict($this->getConfigData('centinel_is_mode_strict'))
646
- ->setCustomApiEndpointUrl($this->getConfigData('centinel_api_url'))
647
- ->setCode($this->getCode())
648
- ->setStore($this->getStore())
649
- ->setIsPlaceOrder($this->_isPlaceOrder());
650
-
651
- return $validator;
652
- }
653
-
654
- /**
655
- * Set the data cash session storage
656
- *
657
- * @param Varien_Object $value
658
- */
659
- public function setDataCashSession($value)
660
- {
661
- $this->_dataCashSession = $value;
662
-
663
- return $this;
664
- }
665
-
666
- /**
667
- * Get the DataCash session storage.
668
- *
669
- * @return Varien_Object
670
- */
671
- protected function _getDataCashSession()
672
- {
673
- if ($this->_dataCashSession === null) {
674
- $this->_dataCashSession = Mage::getSingleton('checkout/session');
675
- }
676
- return $this->_dataCashSession;
677
- }
678
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * DataCash
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.
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 info@datacash.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 this module to newer
18
+ * versions in the future. If you wish to customize this module for your
19
+ * needs please refer to http://testserver.datacash.com/software/download.cgi
20
+ * for more information.
21
+ *
22
+ * @author Alistair Stead
23
+ * @version $Id$
24
+ * @copyright DataCash, 11 April, 2011
25
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
26
+ * @package DataCash
27
+ **/
28
+
29
+ abstract class DataCash_Dpg_Model_Method_Abstract extends Mage_Payment_Model_Method_Cc
30
+ {
31
+ /**
32
+ * Member variable that will hold reference to the API broker.
33
+ *
34
+ * The broker class will handle all the external calls
35
+ *
36
+ * @var string
37
+ **/
38
+ protected $_api;
39
+
40
+ protected $_config;
41
+ protected $_token = null;
42
+ protected $_t3mRecommendation = null;
43
+
44
+ /**
45
+ *
46
+ * @return DataCash_Dpg_Model_Method_Hcc
47
+ */
48
+ public function __construct($params = array())
49
+ {
50
+ parent::__construct($params);
51
+ return $this;
52
+ }
53
+
54
+ /**
55
+ * updateT3mInfo function.
56
+ *
57
+ * @access protected
58
+ * @param mixed $t3mResponse
59
+ * @param Varien_Object $payment
60
+ * @return void
61
+ */
62
+ protected function mapT3mInfoToPayment($t3mResponse, Varien_Object $payment)
63
+ {
64
+ if ($this->getConfig()->getIsAllowedT3m($this->getCode())) {
65
+ $risk = Mage::getModel('dpg/risk_score');
66
+ $risk = $risk->storeDataToOrder($payment->getOrder(), $t3mResponse);
67
+
68
+ $t3mPaymentResponse = $t3mResponse;
69
+ $payInfo = $this->getConfig()->_t3mPaymentInfo;
70
+ $t3mPaymentResponse['t3m_recommendation'] = $payInfo[$t3mResponse['t3m_recommendation']];
71
+ $this->_t3mRecommendation = $t3mPaymentResponse['t3m_recommendation'];
72
+
73
+ if ($this->_t3mRecommendation != 'Release') {
74
+ $payment->setIsTransactionPending(true);
75
+ if ('Reject' == $this->_t3mRecommendation) { // TODO: refactor to use DataCash_Dpg_Model_Config::RSG_***
76
+ $payment->setIsFraudDetected(true);
77
+ }
78
+ }
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Add token to instance variable
84
+ * @param $token DataCash_Dpg_Model_Tokencard
85
+ */
86
+ public function setToken(DataCash_Dpg_Model_Tokencard $token)
87
+ {
88
+ $this->_token = $token;
89
+ return $this;
90
+ }
91
+
92
+ public function getToken()
93
+ {
94
+ return $this->_token;
95
+ }
96
+
97
+ /**
98
+ * getMethodAuthoriseStartUrl
99
+ * @return string url for placeform action for redirection to Datacash
100
+ */
101
+ public function getMethodAuthoriseStartUrl()
102
+ {
103
+ return Mage::getUrl('checkout/hosted/start', array('_secure' => true));
104
+ }
105
+
106
+ /**
107
+ * Check if current quote is multishipping
108
+ */
109
+ protected function _isMultishippingCheckout() {
110
+ if (Mage::getSingleton('admin/session')->isLoggedIn()) {
111
+ return false;
112
+ }
113
+
114
+ return (bool) Mage::getSingleton('checkout/session')->getQuote()->getIsMultiShipping();
115
+ }
116
+
117
+ public function hasAdvancedVerification()
118
+ {
119
+ $configData = $this->getConfigData('useccv_advanced');
120
+ if(is_null($configData)){
121
+ return false;
122
+ }
123
+ return (bool) $configData;
124
+ }
125
+
126
+ public function hasFraudScreening()
127
+ {
128
+ $configData = $this->getConfigData('allow_fraud_screening');
129
+ if (is_null($configData) || $configData=='0'){
130
+ return false;
131
+ }
132
+ return (bool) $configData;
133
+ }
134
+
135
+ /**
136
+ *
137
+ * Gets Extended policy from config.
138
+ * @returns array $extendedPolicy
139
+ * @author Hilary Boyce
140
+ */
141
+ protected function _extendedPolicy()
142
+ {
143
+ $extendedPolicy = array(
144
+ 'cv2_policy' => array(
145
+ 'notprovided' => $this->getConfigData('extpol_cv2policy_notprovided'),
146
+ 'notchecked' => $this->getConfigData('extpol_cv2policy_notchecked'),
147
+ 'matched' => $this->getConfigData('extpol_cv2policy_matched'),
148
+ 'notmatched' => $this->getConfigData('extpol_cv2policy_notmatched'),
149
+ 'partialmatch' => $this->getConfigData('extpol_cv2policy_partialmatch')
150
+ ),
151
+ 'postcode_policy' => array(
152
+ 'notprovided' => $this->getConfigData('extpol_postcode_notprovided'),
153
+ 'notchecked' => $this->getConfigData('extpol_postcode_notchecked'),
154
+ 'matched' => $this->getConfigData('extpol_postcode_matched'),
155
+ 'notmatched' => $this->getConfigData('extpol_postcode_notmatched'),
156
+ 'partialmatch' => $this->getConfigData('extpol_postcode_partialmatch')
157
+ ),
158
+ 'address_policy' => array(
159
+ 'notprovided' => $this->getConfigData('extpol_address_notprovided'),
160
+ 'notchecked' => $this->getConfigData('extpol_address_notchecked'),
161
+ 'matched' => $this->getConfigData('extpol_address_matched'),
162
+ 'notmatched' => $this->getConfigData('extpol_address_notmatched'),
163
+ 'partialmatch' => $this->getConfigData('extpol_address_partialmatch')
164
+ )
165
+ );
166
+ return $extendedPolicy;
167
+ }
168
+
169
+ protected function _fraudPolicy()
170
+ {
171
+ $fraudPolicy = array(
172
+ 'customer' => array(
173
+ 'first_name' => true, // XXX: this field is always included
174
+ 'surname' => true, // XXX: same as above because one field controls both
175
+ 'ip_address' => $this->getConfigData('rsg_data_customer_ip_address'),
176
+ 'email_address' => $this->getConfigData('rsg_data_customer_email_address'),
177
+ 'user_id' => $this->getConfigData('rsg_data_customer_user_id'),
178
+ 'telephone' => $this->getConfigData('rsg_data_customer_telephone'),
179
+ 'address_line1' => $this->getConfigData('rsg_data_customer_address_line1'),
180
+ 'address_line2' => $this->getConfigData('rsg_data_customer_address_line2'),
181
+ 'city' => $this->getConfigData('rsg_data_customer_city'),
182
+ 'state_province'=> $this->getConfigData('rsg_data_customer_state_province'),
183
+ 'country' => $this->getConfigData('rsg_data_customer_country'),
184
+ 'zip_code' => $this->getConfigData('rsg_data_customer_zip_code'),
185
+ ),
186
+ 'shipping' => array(
187
+ 'first_name' => $this->getConfigData('rsg_data_shipping_first_name'),
188
+ 'surname' => $this->getConfigData('rsg_data_shipping_surname'),
189
+ 'address_line1' => $this->getConfigData('rsg_data_shipping_address_line1'),
190
+ 'address_line2' => $this->getConfigData('rsg_data_shipping_address_line2'),
191
+ 'city' => $this->getConfigData('rsg_data_shipping_city'),
192
+ 'state_province'=> $this->getConfigData('rsg_data_shipping_state_province'),
193
+ 'country' => $this->getConfigData('rsg_data_shipping_country'),
194
+ 'zip_code' => $this->getConfigData('rsg_data_shipping_zip_code'),
195
+ ),
196
+ 'payment' => array(
197
+ 'payment_method'=> $this->getConfigData('rsg_data_payment_payment_method'),
198
+ ),
199
+ 'order' => array(
200
+ 'time_zone' => $this->getConfigData('rsg_data_order_time_zone'),
201
+ 'discount_value'=> $this->getConfigData('rsg_data_order_discount_value'),
202
+ ),
203
+ 'item' => array(
204
+ 'product_code' => $this->getConfigData('rsg_data_item_product_code'),
205
+ 'product_description'=> $this->getConfigData('rsg_data_item_product_description'),
206
+ 'product_category'=> $this->getConfigData('rsg_data_item_product_category'),
207
+ 'order_quantity'=> $this->getConfigData('rsg_data_item_order_quantity'),
208
+ 'unit_price' => $this->getConfigData('rsg_data_item_unit_price'),
209
+ ),
210
+ 'billing' => array(
211
+ 'name' => $this->getConfigData('rsg_data_billing_name'),
212
+ 'address_line1' => $this->getConfigData('rsg_data_billing_address_line1'),
213
+ 'address_line2' => $this->getConfigData('rsg_data_billing_address_line2'),
214
+ 'city' => $this->getConfigData('rsg_data_billing_city'),
215
+ 'state_province'=> $this->getConfigData('rsg_data_billing_state_province'),
216
+ 'country' => $this->getConfigData('rsg_data_billing_country'),
217
+ 'zip_code' => $this->getConfigData('rsg_data_billing_zip_code'),
218
+ ),
219
+ );
220
+ return $fraudPolicy;
221
+ }
222
+
223
+ public function setApi($value)
224
+ {
225
+ $this->_api = $value;
226
+ }
227
+
228
+ /**
229
+ * Void the payment
230
+ *
231
+ * @param Varien_Object $payment
232
+ * @return DataCash_Dpg_Model_Method_Api
233
+ * @author Alistair Stead
234
+ */
235
+ public function void(Varien_Object $payment)
236
+ {
237
+ parent::void($payment);
238
+ $this->cancel($payment);
239
+
240
+ return $this;
241
+ }
242
+
243
+ /**
244
+ * Refund the payment
245
+ *
246
+ * @param Varien_Object $payment
247
+ * @param string $amount
248
+ * @return void
249
+ * @author Alistair Stead
250
+ */
251
+ public function refund(Varien_Object $payment, $amount)
252
+ {
253
+ parent::refund($payment, $amount);
254
+ $this->_initApi();
255
+ $this->_mapRequestDataToApi($payment, $amount);
256
+ try {
257
+ $this->_api->callTxnRefund();
258
+ } catch (Exception $e) {
259
+ Mage::throwException($e->getMessage());
260
+ }
261
+ // Process the response
262
+ $response = $this->_api->getResponse();
263
+ if ($response->isSuccessful()) {
264
+ $payment->setTransactionId($response->getDatacashReference())
265
+ ->setShouldCloseParentTransaction(false)
266
+ ->setIsTransactionClosed(false);
267
+ } else {
268
+ Mage::throwException($response->getReason());
269
+ }
270
+
271
+ return $this;
272
+ }
273
+
274
+ /**
275
+ * Cancel payment
276
+ *
277
+ * @param Mage_Sales_Model_Order_Payment $payment
278
+ * @return Mage_Paypal_Model_Direct
279
+ * @author Alistair Stead
280
+ */
281
+ public function cancel(Varien_Object $payment)
282
+ {
283
+ parent::cancel($payment);
284
+ $this->_initApi();
285
+ $this->_mapRequestDataToApi($payment, null);
286
+ try {
287
+ $this->_api->callCancel();
288
+ } catch (Exception $e) {
289
+ Mage::throwException($e->getMessage());
290
+ }
291
+ // Process the response
292
+ $response = $this->_api->getResponse();
293
+ if ($response->isSuccessful()) {
294
+ $payment->setTransactionId($response->getDatacashReference())
295
+ ->setShouldCloseParentTransaction(true)
296
+ ->setIsTransactionClosed(true);
297
+ } else {
298
+ Mage::throwException($response->getReason());
299
+ }
300
+
301
+ return $this;
302
+ }
303
+
304
+ /**
305
+ * Attempt to accept a pending payment
306
+ *
307
+ * @param Mage_Sales_Model_Order_Payment $payment
308
+ * @return bool
309
+ * @author Alistair Stead & Kristjan Heinaste
310
+ */
311
+ public function acceptPayment(Mage_Payment_Model_Info $payment)
312
+ {
313
+ parent::acceptPayment($payment);
314
+ return $this->_reviewPayment($payment, DataCash_Dpg_Model_Code::PAYMENT_REVIEW_ACCEPT);
315
+ }
316
+
317
+ /**
318
+ * Attempt to deny a pending payment
319
+ *
320
+ * @param Mage_Sales_Model_Order_Payment $payment
321
+ * @return bool
322
+ * @author Alistair Stead & Kristjan Heinaste
323
+ */
324
+ public function denyPayment(Mage_Payment_Model_Info $payment)
325
+ {
326
+ parent::denyPayment($payment);
327
+ return $this->_reviewPayment($payment, DataCash_Dpg_Model_Code::PAYMENT_REVIEW_DENY);
328
+ }
329
+
330
+ /**
331
+ * Generic payment review processor
332
+ *
333
+ * @author Kristjan Heinaste <kristjan@ontapgroup.com>
334
+ */
335
+ public function _reviewPayment(Mage_Payment_Model_Info $payment, $action)
336
+ {
337
+ //
338
+ // XXX: When denied we leave it as is - no DC API support
339
+ //
340
+ if ($action == DataCash_Dpg_Model_Code::PAYMENT_REVIEW_DENY) {
341
+ return true;
342
+ }
343
+
344
+ if ($action == DataCash_Dpg_Model_Code::PAYMENT_REVIEW_ACCEPT) {
345
+ $this->_initApi();
346
+ $this->_mapRequestDataToApi($payment, null);
347
+
348
+ // Handle old legacy route
349
+ if ($this->getConfig()->getIsAllowedT3m($this->getCode())) {
350
+ $this->_initApi();
351
+ $this->_mapRequestDataToApi($payment, null);
352
+ try {
353
+ $this->_api->callFulfill();
354
+ } catch (Exception $e) {
355
+ throw new Mage_Payment_Model_Info_Exception($e->getMessage());
356
+ }
357
+ return true;
358
+ }
359
+
360
+ try {
361
+ $this->_api->callReview($action);
362
+ } catch (Exception $e) {
363
+ Mage::throwException($e->getMessage());
364
+ }
365
+ // Process the response
366
+ $response = $this->_api->getResponse();
367
+ if ($response->isSuccessful()) {
368
+ $responseMap = array(
369
+ 'cc_approval' => 'HistoricTxn/authcode',
370
+ 'cc_trans_id' => 'datacash_reference',
371
+ 'cc_status' => 'status',
372
+ 'cc_status_description' => 'reason',
373
+ );
374
+ foreach ($responseMap as $paymentKey => $responseKey) {
375
+ if ($value = $response->getData($responseKey)) {
376
+ $payment->setData($paymentKey, $value);
377
+ }
378
+ }
379
+ $responseTransactionInfoMap = array(
380
+ 'CardTxn' => 'CardTxn',
381
+ 'datacash_reference' => 'datacash_refrence',
382
+ 'mode' => 'mode',
383
+ 'reason' => 'reason',
384
+ 'status' => 'status',
385
+ 'time' => 'time',
386
+ 'authcode' => 'HistoricTxn/authcode',
387
+ );
388
+ foreach ($responseTransactionInfoMap as $paymentKey => $responseKey) {
389
+ if ($value = $response->getData($responseKey)) {
390
+ $payment->setTransactionAdditionalInfo($paymentKey, $value);
391
+ }
392
+ }
393
+
394
+ //
395
+ // XXX: This section depends on $action
396
+ // but because DC does not support deny action yet, we leave this as is.
397
+ //
398
+ $payment->setTransactionId($response->getDatacashReference())
399
+ ->setShouldCloseParentTransaction(true)
400
+ ->setIsTransactionClosed(true)
401
+ ->setIsTransactionApproved(true);
402
+ } else {
403
+ Mage::throwException($response->getReason());
404
+ }
405
+ return true;
406
+ }
407
+
408
+ Mage::throwException("Payment action '{$action}' was not understood");
409
+ }
410
+
411
+ /**
412
+ * Fetch transaction details info
413
+ *
414
+ * @param Mage_Payment_Model_Info $payment
415
+ * @param string $transactionId
416
+ * @return array
417
+ * @author Alistair Stead
418
+ */
419
+ public function fetchTransactionInfo(Mage_Payment_Model_Info $payment, $transactionId)
420
+ {
421
+ // Add method body (Phase 2 requirement)
422
+ parent::fetchTransactionInfo($payment, $transactionId);
423
+
424
+ return $this;
425
+ }
426
+
427
+ /**
428
+ * Return datacash config instance
429
+ *
430
+ * @return DataCash_Dpg_Model_Config
431
+ */
432
+ public function getConfig()
433
+ {
434
+ return Mage::getSingleton('dpg/config');
435
+ }
436
+
437
+ /**
438
+ * Decrypt and return the Merchant password for the DataCash gateway
439
+ *
440
+ * @return string
441
+ * @author Alistair Stead
442
+ **/
443
+ protected function _getApiPassword()
444
+ {
445
+ // Decrypt the marchant password in order to transmit it as part of the request
446
+ return Mage::helper('core')->decrypt($this->getConfigData('merchant_password'));
447
+ }
448
+
449
+ /**
450
+ * Return the Merchant ID for the DataCash gateway
451
+ *
452
+ * @return string
453
+ * @author Alistair Stead
454
+ **/
455
+ protected function _getApiMerchantId()
456
+ {
457
+ return $this->getConfigData('merchant_id');
458
+ }
459
+
460
+ /**
461
+ * Initialize the data required be the API across all methods
462
+ *
463
+ * @return void
464
+ * @author Alistair Stead
465
+ **/
466
+ protected function _initApi()
467
+ {
468
+ if (is_null($this->_api)) {
469
+ $this->_api = Mage::getModel('dpg/api_direct');
470
+ }
471
+ $this->_api->setMerchantId($this->_getApiMerchantId());
472
+ $this->_api->setMerchantPassword($this->_getApiPassword());
473
+ }
474
+
475
+ /**
476
+ * Get an order number within different cart contexts
477
+ *
478
+ * @return int
479
+ * @author Alistair Stead
480
+ **/
481
+ protected function _getOrderNumber($object = null)
482
+ {
483
+ if ($this->_isPlaceOrder($object)) {
484
+ if ($object === NULL) {
485
+ $object = $this->getInfoInstance()->getOrder();
486
+ }
487
+ return $object->getIncrementId();
488
+ } else {
489
+ if ($object === NULL) {
490
+ $object = $this->getInfoInstance()->getQuote();
491
+ }
492
+ if (!$object->getReservedOrderId()) {
493
+ $object->reserveOrderId();
494
+ }
495
+ return $object->getReservedOrderId();
496
+ }
497
+ }
498
+
499
+ /**
500
+ * Grand total getter
501
+ *
502
+ * @return string
503
+ */
504
+ protected function _getAmount()
505
+ {
506
+ $info = $this->getInfoInstance();
507
+ if ($this->_isPlaceOrder()) {
508
+ return (double)$info->getOrder()->getQuoteBaseGrandTotal();
509
+ } else {
510
+ return (double)$info->getQuote()->getBaseGrandTotal();
511
+ }
512
+ }
513
+
514
+ /**
515
+ * Currency code getter
516
+ *
517
+ * @return string
518
+ */
519
+ protected function _getCurrencyCode()
520
+ {
521
+ $info = $this->getInfoInstance();
522
+
523
+ if ($this->_isPlaceOrder()) {
524
+ return $info->getOrder()->getBaseCurrencyCode();
525
+ } else {
526
+ return $info->getQuote()->getBaseCurrencyCode();
527
+ }
528
+ }
529
+
530
+ /**
531
+ * Whether current operation is order placement
532
+ *
533
+ * @return bool
534
+ */
535
+ protected function _isPlaceOrder($object = null)
536
+ {
537
+ if ($object !== null) {
538
+ if ($object instanceof Mage_Sales_Model_Quote) {
539
+ return false;
540
+ } elseif ($object instanceof Mage_Sales_Model_Order) {
541
+ return true;
542
+ }
543
+ } else {
544
+ $info = $this->getInfoInstance();
545
+ if ($info instanceof Mage_Sales_Model_Quote_Payment) {
546
+ return false;
547
+ } elseif ($info instanceof Mage_Sales_Model_Order_Payment) {
548
+ return true;
549
+ }
550
+ }
551
+ }
552
+
553
+ /**
554
+ * Map data supplied by the request to the API
555
+ *
556
+ * This method will set all possible data no exceptions will be thrown even if data is missing
557
+ * If the data is not supplied the error will be thrown by the API
558
+ *
559
+ * @return void
560
+ * @author Alistair Stead
561
+ **/
562
+ protected function _mapRequestDataToApi($payment, $amount)
563
+ {
564
+ $order = $payment->getOrder();
565
+ $orderId = $this->_getOrderNumber();
566
+ $customer = Mage::getModel('customer/customer')->load($order->getCustomerId());
567
+
568
+ $this->_api->setCustomerForename($customer->getFirstname());
569
+ $this->_api->setCustomerSurname($customer->getLastname());
570
+ $this->_api->setCustomerEmail($customer->getEmail());
571
+ // Set the object properties required to make the API call
572
+ $this->_api->setOrderNumber($orderId);
573
+ $this->_api->setAmount($amount);
574
+ $this->_api->setCurrency($order->getBaseCurrencyCode());
575
+ $this->_api->setAddress($order->getShippingAddress());
576
+ $this->_api->setBillingAddress($order->getBillingAddress());
577
+ $this->_api->setShippingAddress($order->getShippingAddress());
578
+ $this->_api->setShippingAmount($order->getShippingAmount());
579
+ $this->_api->setShippingVatRate($order->getShippingVatPercent());
580
+ if ($order->getCustomerIsGuest()) {
581
+ $customerId = 'guest';
582
+ } else {
583
+ $customerId = $order->getCustomerId();
584
+ }
585
+ $this->_api->setCustomerCode($customerId);
586
+ // add order line items
587
+ $this->_api->setCartItems($order->getAllVisibleItems());
588
+ // Add historic details
589
+ if ($auth = $payment->getAuthorizationTransaction()) {
590
+ $txnDetails = explode('-',$auth->getTxnId());
591
+ $this->_api->setDataCashReference(array_shift($txnDetails));
592
+ } else {
593
+ $this->_api->setDataCashReference($payment->getCcTransId());
594
+ }
595
+ $this->_api->setAuthCode($payment->getCcApproval());
596
+ $centinel = $this->getCentinelValidator();
597
+ if ($centinel) {
598
+ $state = $centinel->getValidationState();
599
+ if ($state) {
600
+ $bypass3DSecure = $state->getLookupBypass3dsecure();
601
+ $this->_api->setBypass3dsecure($bypass3DSecure);
602
+ if (!$bypass3DSecure) {
603
+ $this->_api->setMpiReference($state->getAuthenticateTransactionId());
604
+ }
605
+ }
606
+ }
607
+ if ($this->getConfig()->getIsAllowedT3m($this->getCode())) {
608
+ $this->mapT3mToApi($order, $customer);
609
+ }
610
+ }
611
+
612
+ /**
613
+ * Protected method that will manage the transfer of data between the to objects
614
+ *
615
+ * @return void
616
+ * @author Alistair Stead
617
+ **/
618
+ protected function _mapResponseToPayment($response, $payment)
619
+ {
620
+ $additionalInformationMap = array(
621
+ 'cc_avs_address_result' => 'CardTxn/Cv2Avs/address_result/0',
622
+ 'cc_avs_cv2_result' => 'CardTxn/Cv2Avs/cv2_result/0',
623
+ 'cc_avs_postcode_result' => 'CardTxn/Cv2Avs/postcode_result/0',
624
+ 'acs_url' => 'CardTxn/ThreeDSecure/acs_url',
625
+ 'pareq_message' => 'CardTxn/ThreeDSecure/pareq_message',
626
+ 'mode' => 'mode'
627
+ );
628
+ foreach ($additionalInformationMap as $paymentKey => $responseKey) {
629
+ if ($value = $response->getData($responseKey)) {
630
+ $payment->setAdditionalInformation($paymentKey, $value);
631
+ }
632
+ }
633
+ $responseMap = array(
634
+ 'cc_avs_status' => 'CardTxn/Cv2Avs/cv2avs_status',
635
+ 'cc_approval' => 'CardTxn/authcode',
636
+ 'cc_trans_id' => 'datacash_reference',
637
+ 'cc_status' => 'status',
638
+ 'cc_status_description' => 'reason',
639
+ );
640
+ foreach ($responseMap as $paymentKey => $responseKey) {
641
+ if ($value = $response->getData($responseKey)) {
642
+ $payment->setData($paymentKey, $value);
643
+ }
644
+ }
645
+ $responseTransactionInfoMap = array(
646
+ 'CardTxn' => 'CardTxn',
647
+ 'datacash_reference' => 'datacash_refrence',
648
+ 'mode' => 'mode',
649
+ 'reason' => 'reason',
650
+ 'status' => 'status',
651
+ 'time' => 'time',
652
+ 'authcode' => 'CardTxn/authcode',
653
+ );
654
+ foreach ($responseTransactionInfoMap as $paymentKey => $responseKey) {
655
+ if ($value = $response->getData($responseKey)) {
656
+ $payment->setTransactionAdditionalInfo($paymentKey, $value);
657
+ }
658
+ }
659
+ if ($response->isFraud()) {
660
+ $payment->setIsTransactionPending(true);
661
+ $payment->setIsFraudDetected(true);
662
+ }
663
+ if ($response->isMarkedForReview()) {
664
+ $payment->setIsTransactionPending(true);
665
+ }
666
+ Mage::getModel('dpg/risk')->storeRiskResponse($payment, $response);
667
+
668
+ $datacashReferenceMap = array(
669
+ 'datacash_reference',
670
+ 'QueryTxnResult/datacash_reference'
671
+ );
672
+ foreach ($datacashReferenceMap as $responseKey) {
673
+ if ($value = $response->getData($responseKey)) {
674
+ $payment->setTransactionId($value.'-'.time())
675
+ ->setShouldCloseParentTransaction(false)
676
+ ->setIsTransactionClosed(false);
677
+ }
678
+ }
679
+
680
+ $session = $this->_getDataCashSession();
681
+ $saveToken = $session->getData($this->getCode().'_save_token');
682
+ if ($saveToken) {
683
+ Mage::getModel('dpg/tokencard')->tokenizeResponse($payment, $response);
684
+ }
685
+ }
686
+
687
+ protected function _getCentinelValidator($service)
688
+ {
689
+ $validator = Mage::getSingleton($service);
690
+ $validator
691
+ ->setIsModeStrict($this->getConfigData('centinel_is_mode_strict'))
692
+ ->setCustomApiEndpointUrl($this->getConfigData('centinel_api_url'))
693
+ ->setCode($this->getCode())
694
+ ->setStore($this->getStore())
695
+ ->setIsPlaceOrder($this->_isPlaceOrder());
696
+
697
+ return $validator;
698
+ }
699
+
700
+ /**
701
+ * Set the data cash session storage
702
+ *
703
+ * @param Varien_Object $value
704
+ */
705
+ public function setDataCashSession($value)
706
+ {
707
+ $this->_dataCashSession = $value;
708
+
709
+ return $this;
710
+ }
711
+
712
+ /**
713
+ * Get the DataCash session storage.
714
+ *
715
+ * @return Varien_Object
716
+ */
717
+ protected function _getDataCashSession()
718
+ {
719
+ if ($this->_dataCashSession === null) {
720
+ $this->_dataCashSession = Mage::getSingleton('checkout/session');
721
+ }
722
+ return $this->_dataCashSession;
723
+ }
724
+
725
+ protected function mapT3mToApi($order, $customer)
726
+ {
727
+ $remoteIp = $order->getRemoteIp()? $order->getRemoteIp(): $order->getQuote()->getRemoteIp();
728
+ $this->_api->setRemoteIp($remoteIp);
729
+ $this->_api->setOrderItems($order->getAllVisibleItems());
730
+
731
+ $orders = Mage::getModel('sales/order')
732
+ ->getCollection()
733
+ ->addAttributeToSelect('*')
734
+ ->addFieldToFilter('customer_id', $customer->getId())
735
+ ->setOrder('created_at', 'asc');
736
+
737
+ $previousOrderTotal = 0;
738
+ foreach ($orders as $order) {
739
+ $previousOrderTotal += $order->getData('grand_total');
740
+ }
741
+
742
+ $this->_api->setPreviousOrders(array(
743
+ 'count' => count($orders),
744
+ 'total' => $previousOrderTotal,
745
+ 'first' => $orders->getSize() > 0?
746
+ substr($orders->getFirstItem()->getCreatedAt(), 0, 10) : NULL
747
+ ));
748
+ }
749
+
750
+ }
app/code/community/DataCash/Dpg/Model/Method/Api.php CHANGED
@@ -1,530 +1,489 @@
1
- <?php
2
- /**
3
- * DataCash
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.
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 info@datacash.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 this module to newer
18
- * versions in the future. If you wish to customize this module for your
19
- * needs please refer to http://testserver.datacash.com/software/download.cgi
20
- * for more information.
21
- *
22
- * @author Alistair Stead
23
- * @version $Id$
24
- * @copyright DataCash, 11 April, 2011
25
- * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
26
- * @package DataCash
27
- **/
28
-
29
- class DataCash_Dpg_Model_Method_Api extends DataCash_Dpg_Model_Method_Abstract
30
- {
31
- protected $_code = 'datacash_api';
32
- protected $_formBlockType = 'dpg/form_api';
33
- protected $_infoBlockType = 'payment/info_cc';
34
-
35
- /**
36
- * Payment Method features
37
- * @var bool
38
- */
39
- protected $_isGateway = true;
40
- protected $_canOrder = true;
41
- protected $_canAuthorize = true;
42
- protected $_canCapture = true;
43
- protected $_canCapturePartial = true;
44
- protected $_canRefund = true;
45
- protected $_canRefundInvoicePartial = true;
46
- protected $_canVoid = true;
47
- protected $_canUseInternal = true;
48
- protected $_canUseCheckout = true;
49
- protected $_canUseForMultishipping = true;
50
- protected $_isInitializeNeeded = false;
51
- protected $_canFetchTransactionInfo = true;
52
- protected $_canReviewPayment = true;
53
- protected $_canCreateBillingAgreement = true;
54
- protected $_canManageRecurringProfiles = true;
55
- protected $_canCancelInvoice = false;
56
-
57
- public function getVerificationRegEx()
58
- {
59
- $verificationExpList = parent::getVerificationRegEx();
60
- $verificationExpList['DIN'] = '/^[0-9]{3}$/'; //Diners Club
61
- return $verificationExpList;
62
- }
63
-
64
- public function assignData($data)
65
- {
66
- parent::assignData($data);
67
- $info = $this->getInfoInstance();
68
- $info->setAdditionalData($data->getCcTransId());
69
- $info->setCcTransId($data->getCcTransId());
70
- $info->setData('additional_information', array(
71
- 'tokencard' => $data->getCcTokencard(),
72
- 'remember_card' => $data->getCcRememberCard() == "1",
73
- ));
74
-
75
- return $this;
76
- }
77
-
78
- // TODO: refactor to generic
79
- public function getTxnData($txn_id)
80
- {
81
- $this->_api = Mage::getModel('dpg/api_direct');
82
-
83
- $this->_api->setMerchantId($this->_getApiMerchantId());
84
- $this->_api->setMerchantPassword($this->_getApiPassword());
85
-
86
- $this->_api->setIsSandboxed($this->getConfig()->isMethodSandboxed($this->getCode()));
87
-
88
- $this->_api->queryTxn($txn_id);
89
-
90
- $response = $this->_api->getResponse();
91
-
92
- if ($response->isSuccessful()) {
93
- return $response;
94
- } else {
95
- $message = Mage::helper('dpg')->getUserFriendlyStatus($response->getStatus());
96
- throw new Mage_Payment_Model_Info_Exception($message ? $message : $response->getReason());
97
- }
98
- }
99
-
100
- protected $_t3mRecommendation = null;
101
-
102
- /**
103
- * Authorise the payment
104
- *
105
- * @param Varien_Object $payment
106
- * @param string $amount
107
- * @return DataCash_Dpg_Model_Method_Api
108
- * @author Alistair Stead
109
- */
110
- public function authorize(Varien_Object $payment, $amount)
111
- {
112
- parent::authorize($payment, $amount);
113
- $this->_initApi();
114
- $this->_mapRequestDataToApi($payment, $amount);
115
- $order = $payment->getOrder();
116
- try {
117
- if ($this->hasFraudScreening()) {
118
- $this->_api->setUseFraudScreening(true);
119
- $this->_api->setFraudScreeningPolicy($this->_fraudPolicy());
120
- }
121
- $this->_api->callPre();
122
- $t3mResponse = $this->_api->getResponse()->t3MToMappedArray(array(
123
- 't3m_score' => 'score',
124
- 't3m_recommendation' => 'recommendation'));
125
- Mage::dispatchEvent('datacash_dpg_t3m_response', $t3mResponse);
126
- } catch (Exception $e) {
127
- Mage::throwException($e->getMessage());
128
- }
129
-
130
- // Process the response
131
- $response = $this->_api->getResponse();
132
- if ($response->isSuccessful()) {
133
- // Map data to the payment
134
- $this->_mapResponseToPayment($response, $payment);
135
- } else {
136
- $message = Mage::helper('dpg')->getUserFriendlyStatus($response->getStatus());
137
- throw new Mage_Payment_Model_Info_Exception($message ? $message : $response->getReason());
138
- }
139
-
140
- if ($this->getConfig()->getIsAllowedT3m()) {
141
- $t3mPaymentInfo = array('Release', 'Hold', 'Reject', 9 => 'Under Investigation');
142
- $t3mPaymentResponse = $t3mResponse;
143
- $t3mPaymentResponse['t3m_recommendation'] = $t3mPaymentInfo[$t3mResponse['t3m_recommendation']];
144
- $this->_t3mRecommendation = $t3mPaymentResponse['t3m_recommendation'];
145
- $oldInfo = $payment->getAdditionalInformation();
146
- $newInfo = array_merge($oldInfo, $t3mPaymentResponse);
147
- $payment->setAdditionalInformation($newInfo);
148
-
149
- if ($this->_t3mRecommendation != 'Release') {
150
- $payment->setIsTransactionPending(true);
151
- if ('Reject' == $this->_t3mRecommendation) {
152
- $payment->setIsFraudDetected(true);
153
- }
154
- }
155
- }
156
-
157
-
158
- return $this;
159
- }
160
-
161
- /**
162
- * Capture the payment
163
- *
164
- * @param Varien_Object $payment
165
- * @param string $amount
166
- * @return DataCash_Dpg_Model_Method_Api
167
- * @author Alistair Stead
168
- */
169
- public function capture(Varien_Object $payment, $amount)
170
- {
171
- $authTransaction = $payment->getAuthorizationTransaction();
172
- $fulfill = (bool) $authTransaction;
173
- if (!$fulfill && $payment->getId()) {
174
- $collection = Mage::getModel('sales/order_payment_transaction')->getCollection()
175
- ->setOrderFilter($payment->getOrder())
176
- ->addPaymentIdFilter($payment->getId())
177
- ->addTxnTypeFilter(Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE);
178
- $fulfill = $collection->count();
179
- }
180
-
181
- if ($this->getConfig()->getIsAllowedT3m()) {
182
- // Must preauth card first (if not already done so) to make third
183
- // man realtime check.
184
- if (!array_intersect_key($payment->getAdditionalInformation(), array('t3m_score'=>1, 't3m_recommendation'=>1))) {
185
- $this->authorize($payment, $amount);
186
-
187
- if ($this->_t3mRecommendation != 'Release') {
188
- return $this;
189
- }
190
-
191
- $fulfill = true;
192
- }
193
- if ($this->_t3mRecommendation == 'Release') {
194
- $this->_api->setRequest(Mage::getModel('dpg/datacash_request'));
195
- $this->_api->getRequest()->addAuthentication($this->_api->getMerchantId(), $this->_api->getMerchantPassword());
196
-
197
- $payment->setAmountAuthorized($amount);
198
- }
199
- }
200
- parent::capture($payment, $amount);
201
- $this->_initApi();
202
- $this->_mapRequestDataToApi($payment, $amount);
203
-
204
- // If the payment has already been authorized we need to only call fulfill
205
- if ($fulfill && $payment->getAmountAuthorized() > 0 && $payment->getAmountAuthorized() >= $amount) {
206
- try {
207
- $this->_api->callFulfill();
208
- } catch (Exception $e) {
209
- Mage::throwException($e->getMessage());
210
- }
211
- } else if ($fulfill && $payment->getAmountAuthorized() > 0 && $payment->getAmountAuthorized() < $amount) {
212
- throw new Exception('This card has not been authorized for this amount');
213
- } else {
214
- try {
215
- if ($this->hasFraudScreening()) {
216
- $this->_api->setUseFraudScreening(true);
217
- $this->_api->setFraudScreeningPolicy($this->_fraudPolicy());
218
- }
219
- $this->_api->callAuth();
220
- } catch (Exception $e) {
221
- Mage::throwException($e->getMessage());
222
- }
223
- }
224
-
225
- // Process the response
226
- $response = $this->_api->getResponse();
227
- if ($response->isSuccessful()) {
228
- // Map data to the payment
229
- $this->_mapResponseToPayment($response, $payment);
230
- } else {
231
- $message = Mage::helper('dpg')->getUserFriendlyStatus($response->getStatus());
232
- throw new Mage_Payment_Model_Info_Exception($message ? $message : $response->getReason());
233
- }
234
-
235
- return $this;
236
- }
237
-
238
- /**
239
- * Overload the parent validation method
240
- *
241
- * This method is overloaded to allow the validation to be turned
242
- * off during testing as the DataCash magic numbers do not pass the validation
243
- *
244
- * @return Mage_Payment_Model_Abstract
245
- **/
246
- public function validate()
247
- {
248
- // Mage-Test is being used to test this module. It is not required in the production
249
- // environment. This variable is only set during testing
250
- if (isset($_SERVER['MAGE_TEST'])) {
251
- return $this;
252
- }
253
-
254
- // pass the validation when token is used
255
- if ($this->getConfig()->getIsAllowedTokenizer($this->getCode())) {
256
- $info = $this->getInfoInstance();
257
- $additionalInfo = $info->getAdditionalInformation();
258
- if (isset($additionalInfo['tokencard']) && $additionalInfo['tokencard'] != "0") {
259
- return $this;
260
- }
261
- }
262
-
263
- $info = $this->getInfoInstance();
264
- $errorMsg = false;
265
- $availableTypes = explode(',',$this->getConfigData('cctypes'));
266
-
267
- $ccNumber = $info->getCcNumber();
268
-
269
- // remove credit card number delimiters such as "-" and space
270
- $ccNumber = preg_replace('/[\-\s]+/', '', $ccNumber);
271
- $info->setCcNumber($ccNumber);
272
-
273
- $ccType = '';
274
-
275
- if (in_array($info->getCcType(), $availableTypes)){
276
- if ($this->validateCcNum($ccNumber)
277
- // Other credit card type number validation
278
- || ($this->OtherCcType($info->getCcType()) && $this->validateCcNumOther($ccNumber))) {
279
-
280
- $ccType = 'OT';
281
- $ccTypeRegExpList = array(
282
- //Solo, Switch or Maestro. International safe
283
- /*
284
- // Maestro / Solo
285
- 'SS' => '/^((6759[0-9]{12})|(6334|6767[0-9]{12})|(6334|6767[0-9]{14,15})'
286
- . '|(5018|5020|5038|6304|6759|6761|6763[0-9]{12,19})|(49[013][1356][0-9]{12})'
287
- . '|(633[34][0-9]{12})|(633110[0-9]{10})|(564182[0-9]{10}))([0-9]{2,3})?$/',
288
- */
289
- // Solo only
290
- 'SO' => '/(^(6334)[5-9](\d{11}$|\d{13,14}$))|(^(6767)(\d{12}$|\d{14,15}$))/',
291
- 'SM' => '/(^(5[0678])\d{11,18}$)|(^(6[^05])\d{11,18}$)|(^(601)[^1]\d{9,16}$)|(^(6011)\d{9,11}$)'
292
- . '|(^(6011)\d{13,16}$)|(^(65)\d{11,13}$)|(^(65)\d{15,18}$)'
293
- . '|(^(49030)[2-9](\d{10}$|\d{12,13}$))|(^(49033)[5-9](\d{10}$|\d{12,13}$))'
294
- . '|(^(49110)[1-2](\d{10}$|\d{12,13}$))|(^(49117)[4-9](\d{10}$|\d{12,13}$))'
295
- . '|(^(49118)[0-2](\d{10}$|\d{12,13}$))|(^(4936)(\d{12}$|\d{14,15}$))/',
296
- // Visa
297
- 'VI' => '/^4[0-9]{12}([0-9]{3})?$/',
298
- // Master Card
299
- 'MC' => '/^5[1-5][0-9]{14}$/',
300
- // American Express
301
- 'AE' => '/^3[47][0-9]{13}$/',
302
- // Discovery
303
- 'DI' => '/^6011[0-9]{12}$/',
304
- // JCB
305
- 'JCB' => '/^(3[0-9]{15}|(2131|1800)[0-9]{11})$/',
306
- 'DIN' => '/^3(?:0[0-5]|[68][0-9])[0-9]{11}$/', //Diners Club
307
- );
308
-
309
- foreach ($ccTypeRegExpList as $ccTypeMatch=>$ccTypeRegExp) {
310
- if (preg_match($ccTypeRegExp, $ccNumber)) {
311
- $ccType = $ccTypeMatch;
312
- break;
313
- }
314
- }
315
-
316
- if (!$this->OtherCcType($info->getCcType()) && $ccType!=$info->getCcType()) {
317
- $errorMsg = Mage::helper('payment')->__('Credit card number mismatch with credit card type.');
318
- }
319
- }
320
- else {
321
- $errorMsg = Mage::helper('payment')->__('Invalid Credit Card Number');
322
- }
323
-
324
- }
325
- else {
326
- $errorMsg = Mage::helper('payment')->__('Credit card type is not allowed for this payment method.');
327
- }
328
-
329
- //validate credit card verification number
330
- if ($errorMsg === false && $this->hasVerification()) {
331
- $verifcationRegEx = $this->getVerificationRegEx();
332
- $regExp = isset($verifcationRegEx[$info->getCcType()]) ? $verifcationRegEx[$info->getCcType()] : '';
333
- if (!$info->getCcCid() || !$regExp || !preg_match($regExp ,$info->getCcCid())){
334
- $errorMsg = Mage::helper('payment')->__('Please enter a valid credit card verification number.');
335
- }
336
- }
337
-
338
- if ($ccType != 'SS' && !$this->_validateExpDate($info->getCcExpYear(), $info->getCcExpMonth())) {
339
- $errorMsg = Mage::helper('payment')->__('Incorrect credit card expiration date.');
340
- }
341
-
342
- if($errorMsg){
343
- Mage::throwException($errorMsg);
344
- }
345
-
346
- //This must be after all validation conditions
347
- if ($this->getIsCentinelValidationEnabled()) {
348
- $this->getCentinelValidator()->validate($this->getCentinelValidationData());
349
- }
350
-
351
- return $this;
352
- }
353
-
354
- /**
355
- * Overload the parent method getCanCapturePartial
356
- *
357
- * If the basket items have been sent you must capture the full amount
358
- *
359
- * @return bool
360
- * @author Alistair Stead
361
- **/
362
- public function getCanCapturePartial()
363
- {
364
- if (parent::getCanCapturePartial() && !$this->getConfigData('line_items_enabled')) {
365
- return true;
366
- }
367
-
368
- return false;
369
- }
370
-
371
- /**
372
- * Overload the parent method getCanRefundInvoicePartial
373
- *
374
- * If the basket items have been sent you must refund the full amount
375
- *
376
- * @return bool
377
- * @author Alistair Stead
378
- **/
379
- public function getCanRefundInvoicePartial()
380
- {
381
- return true;
382
- if (parent::getCanRefundInvoicePartial() && !$this->getConfigData('line_items_enabled')) {
383
- return true;
384
- }
385
-
386
- return false;
387
- }
388
-
389
-
390
- /**
391
- * Format the supplied dates to be sent to the API
392
- *
393
- * @return string 00/00
394
- * @author Alistair Stead
395
- **/
396
- protected function _formatDate($month, $year)
397
- {
398
- return sprintf(
399
- '%02d/%02d',
400
- substr($month, -2, 2),
401
- substr($year, -2, 2)
402
- );
403
- }
404
-
405
- /**
406
- * undocumented function
407
- *
408
- * @return void
409
- * @author Alistair Stead
410
- **/
411
- protected function _initApi()
412
- {
413
- parent::_initApi();
414
- // Set the sandboxed state
415
- $this->_api->setIsSandboxed($this->getConfig()->isMethodSandboxed($this->getCode()));
416
- $this->_api->setEndpoint($this->getConfig()->getEndpoint($this->getCode()));
417
-
418
- // Set if CV2 data should be transmitted
419
- $this->_api->setIsUseCcv($this->getConfig()->isUseCcv($this->getCode()));
420
- // If extended policy required, set it up.
421
- if ($this->getConfig()->isUseAdvancedCcv($this->getCode())){
422
- $this->_api->setIsUseExtendedCv2(true);
423
- $this->_api->setCv2ExtendedPolicy($this->_extendedPolicy());
424
- }
425
- $this->_api->setIsUse3d($this->getIsCentinelValidationEnabled());
426
- // Set if line items should be transmitted
427
- $this->_api->setIsLineItemsEnabled($this->getConfig()->isLineItemsEnabled($this->getCode()));
428
- }
429
-
430
- /**
431
- * Map data supplied by the request to the API
432
- *
433
- * This method will set all possible data no exceptions will be thrown even if data is missing
434
- * If the data is not supplied the error will be thrown by the API
435
- *
436
- * @return void
437
- * @author Alistair Stead
438
- **/
439
- protected function _mapRequestDataToApi($payment, $amount)
440
- {
441
- parent::_mapRequestDataToApi($payment, $amount);
442
- $order = $payment->getOrder();
443
- $customer = Mage::getModel('customer/customer')->load($order->getCustomerId());
444
-
445
- // When using tokens, get the token object
446
- $tokencard = null;
447
- $additionalInfo = $payment->getMethodInstance()->getInfoInstance()->getData('additional_information');
448
- $tokencardId = $additionalInfo['tokencard'];
449
- if ($customer && $tokencardId && is_numeric($tokencardId)) {
450
- $tokencard = Mage::getModel('dpg/tokencard')
451
- ->getCollection()
452
- ->addCustomerFilter($customer)
453
- ->addIdFilter($tokencardId)
454
- ->getFirstItem();
455
- }
456
-
457
- // Save the UI state to session for later use
458
- $session = $this->_getDataCashSession();
459
- $session->setData($this->_code . '_save_token', $additionalInfo['remember_card']);
460
-
461
- // Set the object properties required to make the API call
462
- $this->_api
463
- ->setCreditCardNumber($payment->getCcNumber())
464
- ->setCreditCardExpirationDate(
465
- $this->_formatDate(
466
- $payment->getCcExpMonth(),
467
- $payment->getCcExpYear()
468
- )
469
- )
470
- ->setCreditCardCvv2($payment->getCcCid())
471
- ->setMaestroSoloIssueNumber($payment->getCcSsIssue())
472
- ->setToken($tokencard);
473
-
474
- // Add the additional SM card details
475
- if ($payment->getCcSsStartMonth() && $payment->getCcSsStartYear()) {
476
- $this->_api->setMaestroSoloIssueDate(
477
- $this->_formatDate(
478
- $payment->getCcSsStartMonth(),
479
- $payment->getCcSsStartYear()
480
- )
481
- );
482
- }
483
-
484
- if ($this->getConfig()->getIsAllowedT3m()) {
485
- $this->_api->setForename($customer->getFirstName());
486
- $this->_api->setSurname($customer->getLastName());
487
- $this->_api->setCustomerEmail($customer->getEmail());
488
- $remoteIp = $order->getRemoteIp()? $order->getRemoteIp(): $order->getQuote()->getRemoteIp();
489
- $this->_api->setRemoteIp($remoteIp);
490
- $this->_api->setOrderItems($order->getAllItems());
491
-
492
- $orders = Mage::getModel('sales/order')
493
- ->getCollection()
494
- ->addAttributeToSelect('*')
495
- ->addFieldToFilter('customer_id', $customer->getId())
496
- ->setOrder('created_at', 'asc');
497
- $previousOrderTotal = 0;
498
- foreach ($orders as $order) {
499
- $previousOrderTotal += $order->getData('grand_total');
500
- }
501
-
502
- $this->_api->setPreviousOrders(array(
503
- 'count' => count($orders->getData()),
504
- 'total' => $previousOrderTotal,
505
- 'first' => $orders->getSize() > 0?
506
- substr($orders->getFirstItem()->getCreatedAt(), 0, 10) : NULL
507
- ));
508
- }
509
- }
510
-
511
- /**
512
- * Instantiate centinel validator model
513
- *
514
- * @return Mage_Centinel_Model_Service
515
- */
516
- public function getCentinelValidator()
517
- {
518
- return $this->_getCentinelValidator('dpg/service_direct');
519
- }
520
-
521
- /**
522
- * Whether centinel service is enabled
523
- *
524
- * @return bool
525
- */
526
- public function getIsCentinelValidationEnabled()
527
- {
528
- return false !== Mage::getConfig()->getNode('modules/Mage_Centinel') && 1 == $this->getConfigData('centinel');
529
- }
530
- }
1
+ <?php
2
+ /**
3
+ * DataCash
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.
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 info@datacash.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 this module to newer
18
+ * versions in the future. If you wish to customize this module for your
19
+ * needs please refer to http://testserver.datacash.com/software/download.cgi
20
+ * for more information.
21
+ *
22
+ * @author Alistair Stead
23
+ * @version $Id$
24
+ * @copyright DataCash, 11 April, 2011
25
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
26
+ * @package DataCash
27
+ **/
28
+
29
+ class DataCash_Dpg_Model_Method_Api extends DataCash_Dpg_Model_Method_Abstract
30
+ {
31
+ protected $_code = 'datacash_api';
32
+ protected $_formBlockType = 'dpg/form_api';
33
+ protected $_infoBlockType = 'payment/info_cc';
34
+
35
+ /**
36
+ * Payment Method features
37
+ * @var bool
38
+ */
39
+ protected $_isGateway = true;
40
+ protected $_canOrder = true;
41
+ protected $_canAuthorize = true;
42
+ protected $_canCapture = true;
43
+ protected $_canCapturePartial = true;
44
+ protected $_canRefund = true;
45
+ protected $_canRefundInvoicePartial = true;
46
+ protected $_canVoid = true;
47
+ protected $_canUseInternal = true;
48
+ protected $_canUseCheckout = true;
49
+ protected $_canUseForMultishipping = true;
50
+ protected $_isInitializeNeeded = false;
51
+ protected $_canFetchTransactionInfo = true;
52
+ protected $_canReviewPayment = true;
53
+ protected $_canCreateBillingAgreement = true;
54
+ protected $_canManageRecurringProfiles = true;
55
+ protected $_canCancelInvoice = false;
56
+
57
+ public function getVerificationRegEx()
58
+ {
59
+ $verificationExpList = parent::getVerificationRegEx();
60
+ $verificationExpList['DIN'] = '/^[0-9]{3}$/'; //Diners Club
61
+ return $verificationExpList;
62
+ }
63
+
64
+ public function assignData($data)
65
+ {
66
+ parent::assignData($data);
67
+ $info = $this->getInfoInstance();
68
+ $info->setAdditionalData($data->getCcTransId());
69
+ $info->setCcTransId($data->getCcTransId());
70
+ $info->setData('additional_information', array(
71
+ 'tokencard' => $data->getCcTokencard(),
72
+ 'remember_card' => $data->getCcRememberCard() == "1",
73
+ ));
74
+
75
+ return $this;
76
+ }
77
+
78
+ // TODO: refactor to generic
79
+ public function getTxnData($txn_id)
80
+ {
81
+ $this->_api = Mage::getModel('dpg/api_direct');
82
+
83
+ $this->_api->setMerchantId($this->_getApiMerchantId());
84
+ $this->_api->setMerchantPassword($this->_getApiPassword());
85
+
86
+ $this->_api->setIsSandboxed($this->getConfig()->isMethodSandboxed($this->getCode()));
87
+
88
+ $this->_api->queryTxn($txn_id);
89
+
90
+ $response = $this->_api->getResponse();
91
+
92
+ if ($response->isSuccessful()) {
93
+ return $response;
94
+ } else {
95
+ $message = Mage::helper('dpg')->getUserFriendlyStatus($response->getStatus());
96
+ throw new Mage_Payment_Model_Info_Exception($message ? $message : $response->getReason());
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Authorise the payment
102
+ *
103
+ * @param Varien_Object $payment
104
+ * @param string $amount
105
+ * @return DataCash_Dpg_Model_Method_Api
106
+ * @author Alistair Stead
107
+ */
108
+ public function authorize(Varien_Object $payment, $amount)
109
+ {
110
+ parent::authorize($payment, $amount);
111
+ $this->_initApi();
112
+ $this->_mapRequestDataToApi($payment, $amount);
113
+ $order = $payment->getOrder();
114
+ try {
115
+ if ($this->hasFraudScreening()) {
116
+ $this->_api->setUseFraudScreening(true);
117
+ $this->_api->setFraudScreeningPolicy($this->_fraudPolicy());
118
+ }
119
+ $this->_api->callPre();
120
+ $t3mResponse = $this->_api->getResponse()->t3MToMappedArray($this->getConfig()->_t3mResponseMap);
121
+ Mage::dispatchEvent('datacash_dpg_t3m_response', $t3mResponse);
122
+ } catch (Exception $e) {
123
+ Mage::throwException($e->getMessage());
124
+ }
125
+
126
+ // Process the response
127
+ $response = $this->_api->getResponse();
128
+ if ($response->isSuccessful() || $response->isMarkedForReview()) {
129
+ // Map data to the payment
130
+ $this->mapT3mInfoToPayment($t3mResponse, $payment);
131
+ $this->_mapResponseToPayment($response, $payment);
132
+ } else {
133
+ $message = Mage::helper('dpg')->getUserFriendlyStatus($response->getStatus());
134
+ throw new Mage_Payment_Model_Info_Exception($message ? $message : $response->getReason());
135
+ }
136
+
137
+ return $this;
138
+ }
139
+
140
+ /**
141
+ * Capture the payment
142
+ *
143
+ * @param Varien_Object $payment
144
+ * @param string $amount
145
+ * @return DataCash_Dpg_Model_Method_Api
146
+ * @author Alistair Stead
147
+ */
148
+ public function capture(Varien_Object $payment, $amount)
149
+ {
150
+ $authTransaction = $payment->getAuthorizationTransaction();
151
+ $fulfill = (bool) $authTransaction;
152
+ if (!$fulfill && $payment->getId()) {
153
+ $collection = Mage::getModel('sales/order_payment_transaction')->getCollection()
154
+ ->setOrderFilter($payment->getOrder())
155
+ ->addPaymentIdFilter($payment->getId())
156
+ ->addTxnTypeFilter(Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE);
157
+ $fulfill = $collection->count();
158
+ }
159
+
160
+ // Old T3M auth
161
+ if ($this->getConfig()->getIsAllowedT3m($this->getCode())) {
162
+ if ($this->getIsCallbackRequest() == 1) { // In case of callbacks, the order is already fulfilled by invoice->capture see Observer.php
163
+ return $this;
164
+ }
165
+ // Must preauth card first (if not already done so) to make third
166
+ // man realtime check.
167
+ if (!$authTransaction) {
168
+ if (!array_intersect_key($payment->getAdditionalInformation(), array('t3m_score'=>1, 't3m_recommendation'=>1))) {
169
+ $this->authorize($payment, $amount);
170
+
171
+ if ($this->_t3mRecommendation != 'Release') {
172
+ return $this;
173
+ }
174
+
175
+ $fulfill = true;
176
+ }
177
+ if ($this->_t3mRecommendation == 'Release') {
178
+ $this->_api->setRequest(Mage::getModel('dpg/datacash_request'));
179
+ $this->_api->getRequest()->addAuthentication($this->_api->getMerchantId(), $this->_api->getMerchantPassword());
180
+
181
+ $payment->setAmountAuthorized($amount);
182
+ }
183
+ }
184
+ }
185
+ parent::capture($payment, $amount);
186
+ $this->_initApi();
187
+ $this->_mapRequestDataToApi($payment, $amount);
188
+
189
+ // If the payment has already been authorized we need to only call fulfill
190
+ if ($fulfill && $payment->getAmountAuthorized() > 0 && $payment->getAmountAuthorized() >= $amount) {
191
+ try {
192
+ $this->_api->callFulfill();
193
+ } catch (Exception $e) {
194
+ Mage::throwException($e->getMessage());
195
+ }
196
+ } else if ($fulfill && $payment->getAmountAuthorized() > 0 && $payment->getAmountAuthorized() < $amount) {
197
+ throw new Exception('This card has not been authorized for this amount');
198
+ } else {
199
+ try {
200
+ if ($this->hasFraudScreening()) {
201
+ $this->_api->setUseFraudScreening(true);
202
+ $this->_api->setFraudScreeningPolicy($this->_fraudPolicy());
203
+ }
204
+ $this->_api->callAuth();
205
+ } catch (Exception $e) {
206
+ Mage::throwException($e->getMessage());
207
+ }
208
+ }
209
+
210
+ // Process the response
211
+ $response = $this->_api->getResponse();
212
+ if ($response->isSuccessful() || $response->isMarkedForReview()) {
213
+ // Map data to the payment
214
+ $this->_mapResponseToPayment($response, $payment);
215
+ } else {
216
+ $message = Mage::helper('dpg')->getUserFriendlyStatus($response->getStatus());
217
+ throw new Mage_Payment_Model_Info_Exception($message ? $message : $response->getReason());
218
+ }
219
+
220
+ return $this;
221
+ }
222
+
223
+ /**
224
+ * Overload the parent validation method
225
+ *
226
+ * This method is overloaded to allow the validation to be turned
227
+ * off during testing as the DataCash magic numbers do not pass the validation
228
+ *
229
+ * @return Mage_Payment_Model_Abstract
230
+ **/
231
+ public function validate()
232
+ {
233
+ // Mage-Test is being used to test this module. It is not required in the production
234
+ // environment. This variable is only set during testing
235
+ if (isset($_SERVER['MAGE_TEST'])) {
236
+ return $this;
237
+ }
238
+
239
+ // pass the validation when token is used
240
+ if ($this->getConfig()->getIsAllowedTokenizer($this->getCode())) {
241
+ $info = $this->getInfoInstance();
242
+ $additionalInfo = $info->getAdditionalInformation();
243
+ if (isset($additionalInfo['tokencard']) && $additionalInfo['tokencard'] != "0") {
244
+ return $this;
245
+ }
246
+ }
247
+
248
+ $info = $this->getInfoInstance();
249
+ $errorMsg = false;
250
+ $availableTypes = explode(',',$this->getConfigData('cctypes'));
251
+
252
+ $ccNumber = $info->getCcNumber();
253
+
254
+ // remove credit card number delimiters such as "-" and space
255
+ $ccNumber = preg_replace('/[\-\s]+/', '', $ccNumber);
256
+ $info->setCcNumber($ccNumber);
257
+
258
+ $ccType = '';
259
+
260
+ if (in_array($info->getCcType(), $availableTypes)){
261
+ if ($this->validateCcNum($ccNumber)
262
+ // Other credit card type number validation
263
+ || ($this->OtherCcType($info->getCcType()) && $this->validateCcNumOther($ccNumber))) {
264
+
265
+ $ccType = 'OT';
266
+ $ccTypeRegExpList = array(
267
+ //Solo, Switch or Maestro. International safe
268
+ /*
269
+ // Maestro / Solo
270
+ 'SS' => '/^((6759[0-9]{12})|(6334|6767[0-9]{12})|(6334|6767[0-9]{14,15})'
271
+ . '|(5018|5020|5038|6304|6759|6761|6763[0-9]{12,19})|(49[013][1356][0-9]{12})'
272
+ . '|(633[34][0-9]{12})|(633110[0-9]{10})|(564182[0-9]{10}))([0-9]{2,3})?$/',
273
+ */
274
+ // Solo only
275
+ 'SO' => '/(^(6334)[5-9](\d{11}$|\d{13,14}$))|(^(6767)(\d{12}$|\d{14,15}$))/',
276
+ 'SM' => '/(^(5[0678])\d{11,18}$)|(^(6[^05])\d{11,18}$)|(^(601)[^1]\d{9,16}$)|(^(6011)\d{9,11}$)'
277
+ . '|(^(6011)\d{13,16}$)|(^(65)\d{11,13}$)|(^(65)\d{15,18}$)'
278
+ . '|(^(49030)[2-9](\d{10}$|\d{12,13}$))|(^(49033)[5-9](\d{10}$|\d{12,13}$))'
279
+ . '|(^(49110)[1-2](\d{10}$|\d{12,13}$))|(^(49117)[4-9](\d{10}$|\d{12,13}$))'
280
+ . '|(^(49118)[0-2](\d{10}$|\d{12,13}$))|(^(4936)(\d{12}$|\d{14,15}$))/',
281
+ // Visa
282
+ 'VI' => '/^4[0-9]{12}([0-9]{3})?$/',
283
+ // Master Card
284
+ 'MC' => '/^5[1-5][0-9]{14}$/',
285
+ // American Express
286
+ 'AE' => '/^3[47][0-9]{13}$/',
287
+ // Discovery
288
+ 'DI' => '/^6011[0-9]{12}$/',
289
+ // JCB
290
+ 'JCB' => '/^(3[0-9]{15}|(2131|1800)[0-9]{11})$/',
291
+ 'DIN' => '/^3(?:0[0-5]|[68][0-9])[0-9]{11}$/', //Diners Club
292
+ );
293
+
294
+ foreach ($ccTypeRegExpList as $ccTypeMatch=>$ccTypeRegExp) {
295
+ if (preg_match($ccTypeRegExp, $ccNumber)) {
296
+ $ccType = $ccTypeMatch;
297
+ break;
298
+ }
299
+ }
300
+
301
+ if (!$this->OtherCcType($info->getCcType()) && $ccType!=$info->getCcType()) {
302
+ $errorMsg = Mage::helper('payment')->__('Credit card number mismatch with credit card type.');
303
+ }
304
+ }
305
+ else {
306
+ $errorMsg = Mage::helper('payment')->__('Invalid Credit Card Number');
307
+ }
308
+
309
+ }
310
+ else {
311
+ $errorMsg = Mage::helper('payment')->__('Credit card type is not allowed for this payment method.');
312
+ }
313
+
314
+ //validate credit card verification number
315
+ if ($errorMsg === false && $this->hasVerification()) {
316
+ $verifcationRegEx = $this->getVerificationRegEx();
317
+ $regExp = isset($verifcationRegEx[$info->getCcType()]) ? $verifcationRegEx[$info->getCcType()] : '';
318
+ if (!$info->getCcCid() || !$regExp || !preg_match($regExp ,$info->getCcCid())){
319
+ $errorMsg = Mage::helper('payment')->__('Please enter a valid credit card verification number.');
320
+ }
321
+ }
322
+
323
+ if ($ccType != 'SS' && !$this->_validateExpDate($info->getCcExpYear(), $info->getCcExpMonth())) {
324
+ $errorMsg = Mage::helper('payment')->__('Incorrect credit card expiration date.');
325
+ }
326
+
327
+ if($errorMsg){
328
+ Mage::throwException($errorMsg);
329
+ }
330
+
331
+ //This must be after all validation conditions
332
+ if ($this->getIsCentinelValidationEnabled()) {
333
+ $this->getCentinelValidator()->validate($this->getCentinelValidationData());
334
+ }
335
+
336
+ return $this;
337
+ }
338
+
339
+ /**
340
+ * Overload the parent method getCanCapturePartial
341
+ *
342
+ * If the basket items have been sent you must capture the full amount
343
+ *
344
+ * @return bool
345
+ * @author Alistair Stead
346
+ **/
347
+ public function getCanCapturePartial()
348
+ {
349
+ if (parent::getCanCapturePartial() && !$this->getConfigData('line_items_enabled')) {
350
+ return true;
351
+ }
352
+
353
+ return false;
354
+ }
355
+
356
+ /**
357
+ * Overload the parent method getCanRefundInvoicePartial
358
+ *
359
+ * If the basket items have been sent you must refund the full amount
360
+ *
361
+ * @return bool
362
+ * @author Alistair Stead
363
+ **/
364
+ public function getCanRefundInvoicePartial()
365
+ {
366
+ return true;
367
+ if (parent::getCanRefundInvoicePartial() && !$this->getConfigData('line_items_enabled')) {
368
+ return true;
369
+ }
370
+
371
+ return false;
372
+ }
373
+
374
+
375
+ /**
376
+ * Format the supplied dates to be sent to the API
377
+ *
378
+ * @return string 00/00
379
+ * @author Alistair Stead
380
+ **/
381
+ protected function _formatDate($month, $year)
382
+ {
383
+ return sprintf(
384
+ '%02d/%02d',
385
+ substr($month, -2, 2),
386
+ substr($year, -2, 2)
387
+ );
388
+ }
389
+
390
+ /**
391
+ * undocumented function
392
+ *
393
+ * @return void
394
+ * @author Alistair Stead
395
+ **/
396
+ protected function _initApi()
397
+ {
398
+ parent::_initApi();
399
+ // Set the sandboxed state
400
+ $this->_api->setIsSandboxed($this->getConfig()->isMethodSandboxed($this->getCode()));
401
+ $this->_api->setEndpoint($this->getConfig()->getEndpoint($this->getCode()));
402
+
403
+ // Set if CV2 data should be transmitted
404
+ $this->_api->setIsUseCcv($this->getConfig()->isUseCcv($this->getCode()));
405
+ // If extended policy required, set it up.
406
+ if ($this->getConfig()->isUseAdvancedCcv($this->getCode())){
407
+ $this->_api->setIsUseExtendedCv2(true);
408
+ $this->_api->setCv2ExtendedPolicy($this->_extendedPolicy());
409
+ }
410
+ $this->_api->setIsUse3d($this->getIsCentinelValidationEnabled());
411
+ // Set if line items should be transmitted
412
+ $this->_api->setIsLineItemsEnabled($this->getConfig()->isLineItemsEnabled($this->getCode()));
413
+ }
414
+
415
+ /**
416
+ * Map data supplied by the request to the API
417
+ *
418
+ * This method will set all possible data no exceptions will be thrown even if data is missing
419
+ * If the data is not supplied the error will be thrown by the API
420
+ *
421
+ * @return void
422
+ * @author Alistair Stead
423
+ **/
424
+ protected function _mapRequestDataToApi($payment, $amount)
425
+ {
426
+ parent::_mapRequestDataToApi($payment, $amount);
427
+ $order = $payment->getOrder();
428
+ $customer = Mage::getModel('customer/customer')->load($order->getCustomerId());
429
+
430
+ // When using tokens, get the token object
431
+ $tokencard = null;
432
+ $additionalInfo = $payment->getMethodInstance()->getInfoInstance()->getData('additional_information');
433
+ $tokencardId = $additionalInfo['tokencard'];
434
+ if ($customer && $tokencardId && is_numeric($tokencardId)) {
435
+ $tokencard = Mage::getModel('dpg/tokencard')
436
+ ->getCollection()
437
+ ->addCustomerFilter($customer)
438
+ ->addIdFilter($tokencardId)
439
+ ->getFirstItem();
440
+ }
441
+
442
+ // Save the UI state to session for later use
443
+ $session = $this->_getDataCashSession();
444
+ $session->setData($this->_code . '_save_token', $additionalInfo['remember_card']);
445
+
446
+ // Set the object properties required to make the API call
447
+ $this->_api
448
+ ->setCreditCardNumber($payment->getCcNumber())
449
+ ->setCreditCardExpirationDate(
450
+ $this->_formatDate(
451
+ $payment->getCcExpMonth(),
452
+ $payment->getCcExpYear()
453
+ )
454
+ )
455
+ ->setCreditCardCvv2($payment->getCcCid())
456
+ ->setMaestroSoloIssueNumber($payment->getCcSsIssue())
457
+ ->setToken($tokencard);
458
+
459
+ // Add the additional SM card details
460
+ if ($payment->getCcSsStartMonth() && $payment->getCcSsStartYear()) {
461
+ $this->_api->setMaestroSoloIssueDate(
462
+ $this->_formatDate(
463
+ $payment->getCcSsStartMonth(),
464
+ $payment->getCcSsStartYear()
465
+ )
466
+ );
467
+ }
468
+ }
469
+
470
+ /**
471
+ * Instantiate centinel validator model
472
+ *
473
+ * @return Mage_Centinel_Model_Service
474
+ */
475
+ public function getCentinelValidator()
476
+ {
477
+ return $this->_getCentinelValidator('dpg/service_direct');
478
+ }
479
+
480
+ /**
481
+ * Whether centinel service is enabled
482
+ *
483
+ * @return bool
484
+ */
485
+ public function getIsCentinelValidationEnabled()
486
+ {
487
+ return false !== Mage::getConfig()->getNode('modules/Mage_Centinel') && 1 == $this->getConfigData('centinel');
488
+ }
489
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/DataCash/Dpg/Model/Method/Hcc.php CHANGED
@@ -71,7 +71,7 @@ class DataCash_Dpg_Model_Method_Hcc
71
  $this->_api->setMerchantPassword($this->_getApiPassword());
72
 
73
  $this->_api->setIsSandboxed($this->getConfig()->isMethodSandboxed($this->getCode()));
74
-
75
  if ($this->hasAdvancedVerification()) {
76
  $this->_api->setIsUseExtendedCv2(true);
77
  $this->_api->setCv2ExtendedPolicy($this->_extendedPolicy());
@@ -80,21 +80,21 @@ class DataCash_Dpg_Model_Method_Hcc
80
  // Set if line items should be transmitted
81
  $this->_api->setIsLineItemsEnabled($this->getConfig()->isLineItemsEnabled($this->getCode()));
82
  }
83
-
84
- // TODO: refactor to generic
85
  public function getTxnData($txn_id)
86
  {
87
  $this->_api = Mage::getModel('dpg/api_hcc');
88
-
89
  $this->_api->setMerchantId($this->_getApiMerchantId());
90
  $this->_api->setMerchantPassword($this->_getApiPassword());
91
-
92
  $this->_api->setIsSandboxed($this->getConfig()->isMethodSandboxed($this->getCode()));
93
-
94
  $this->_api->queryTxn($txn_id);
95
-
96
  $response = $this->_api->getResponse();
97
-
98
  if ($response->isSuccessful()) {
99
  return $response;
100
  } else {
@@ -102,7 +102,7 @@ class DataCash_Dpg_Model_Method_Hcc
102
  throw new Mage_Payment_Model_Info_Exception($message ? $message : $response->getReason());
103
  }
104
  }
105
-
106
  /**
107
  * initSession
108
  * Initialise session with DataCash for HCC
@@ -117,12 +117,12 @@ class DataCash_Dpg_Model_Method_Hcc
117
  $returnUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB).'checkout/hosted/complete/';
118
 
119
  $this->_initApi();
120
-
121
  $amount = $quote->getBaseGrandTotal();
122
  if ($amount == 0) {
123
  $amount = 1;
124
  }
125
-
126
  // Set the object properties required to make the API call
127
  $this->_api->setOrderNumber($orderId)
128
  ->setAmount($amount)
@@ -168,7 +168,7 @@ class DataCash_Dpg_Model_Method_Hcc
168
  parent::authorize($payment, $amount);
169
  $this->_initApi();
170
  $this->_mapRequestDataToApi($payment, $amount);
171
-
172
  try {
173
  if ($this->hasFraudScreening()) {
174
  $this->_api->setUseFraudScreening(true);
@@ -180,14 +180,17 @@ class DataCash_Dpg_Model_Method_Hcc
180
  } else {
181
  $this->_api->callPre();
182
  }
 
 
183
  } catch (Exception $e) {
184
- throw new Mage_Payment_Model_Info_Exception($e->getMessage());
185
  }
186
-
187
  // Process the response
188
  $response = $this->_api->getResponse();
189
- if ($response->isSuccessful()) {
190
  // Map data to the payment
 
191
  $this->_mapResponseToPayment($response, $payment);
192
  } else {
193
  $message = Mage::helper('dpg')->getUserFriendlyStatus($response->getStatus());
@@ -207,20 +210,55 @@ class DataCash_Dpg_Model_Method_Hcc
207
  */
208
  public function capture(Varien_Object $payment, $amount)
209
  {
210
- parent::capture($payment, $amount);
211
- $order = $payment->getOrder();
212
  $authTransaction = $payment->getAuthorizationTransaction();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  $this->_initApi();
214
  $this->_mapRequestDataToApi($payment, $amount);
215
-
216
  // If the payment has already been authorized we need to only call fullfill
217
- if ($authTransaction && $payment->getAmountAuthorized() > 0 && $payment->getAmountAuthorized() >= $amount) {
218
  try {
219
  $this->_api->callFulfill();
220
  } catch (Exception $e) {
221
  throw new Mage_Payment_Model_Info_Exception($e->getMessage());
222
  }
223
- } else if ($authTransaction && $payment->getAmountAuthorized() > 0 && $payment->getAmountAuthorized() < $amount) {
224
  throw new Exception('This card has not been authorized for this amount');
225
  } else {
226
  try {
@@ -228,7 +266,7 @@ class DataCash_Dpg_Model_Method_Hcc
228
  $this->_api->setUseFraudScreening(true);
229
  $this->_api->setFraudScreeningPolicy($this->_fraudPolicy());
230
  }
231
-
232
  if ($this->getIsCentinelValidationEnabled()) {
233
  // if 3D secure check is turned on, we just have to authorize the previous calls
234
  $validator = $this->getCentinelValidator();
@@ -243,7 +281,7 @@ class DataCash_Dpg_Model_Method_Hcc
243
 
244
  // Process the response
245
  $response = $this->_api->getResponse();
246
- if ($response->isSuccessful()) {
247
  // Map data to the payment
248
  $this->_mapResponseToPayment($response, $payment);
249
  } else {
71
  $this->_api->setMerchantPassword($this->_getApiPassword());
72
 
73
  $this->_api->setIsSandboxed($this->getConfig()->isMethodSandboxed($this->getCode()));
74
+
75
  if ($this->hasAdvancedVerification()) {
76
  $this->_api->setIsUseExtendedCv2(true);
77
  $this->_api->setCv2ExtendedPolicy($this->_extendedPolicy());
80
  // Set if line items should be transmitted
81
  $this->_api->setIsLineItemsEnabled($this->getConfig()->isLineItemsEnabled($this->getCode()));
82
  }
83
+
84
+ // TODO: refactor to generic
85
  public function getTxnData($txn_id)
86
  {
87
  $this->_api = Mage::getModel('dpg/api_hcc');
88
+
89
  $this->_api->setMerchantId($this->_getApiMerchantId());
90
  $this->_api->setMerchantPassword($this->_getApiPassword());
91
+
92
  $this->_api->setIsSandboxed($this->getConfig()->isMethodSandboxed($this->getCode()));
93
+
94
  $this->_api->queryTxn($txn_id);
95
+
96
  $response = $this->_api->getResponse();
97
+
98
  if ($response->isSuccessful()) {
99
  return $response;
100
  } else {
102
  throw new Mage_Payment_Model_Info_Exception($message ? $message : $response->getReason());
103
  }
104
  }
105
+
106
  /**
107
  * initSession
108
  * Initialise session with DataCash for HCC
117
  $returnUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB).'checkout/hosted/complete/';
118
 
119
  $this->_initApi();
120
+
121
  $amount = $quote->getBaseGrandTotal();
122
  if ($amount == 0) {
123
  $amount = 1;
124
  }
125
+
126
  // Set the object properties required to make the API call
127
  $this->_api->setOrderNumber($orderId)
128
  ->setAmount($amount)
168
  parent::authorize($payment, $amount);
169
  $this->_initApi();
170
  $this->_mapRequestDataToApi($payment, $amount);
171
+
172
  try {
173
  if ($this->hasFraudScreening()) {
174
  $this->_api->setUseFraudScreening(true);
180
  } else {
181
  $this->_api->callPre();
182
  }
183
+ $t3mResponse = $this->_api->getResponse()->t3MToMappedArray($this->getConfig()->_t3mResponseMap);
184
+ Mage::dispatchEvent('datacash_dpg_t3m_response', $t3mResponse);
185
  } catch (Exception $e) {
186
+ throw new Mage_Payment_Model_Info_Exception($e->getMessage());
187
  }
188
+
189
  // Process the response
190
  $response = $this->_api->getResponse();
191
+ if ($response->isSuccessful() || $response->isMarkedForReview()) {
192
  // Map data to the payment
193
+ $this->mapT3mInfoToPayment($t3mResponse, $payment);
194
  $this->_mapResponseToPayment($response, $payment);
195
  } else {
196
  $message = Mage::helper('dpg')->getUserFriendlyStatus($response->getStatus());
210
  */
211
  public function capture(Varien_Object $payment, $amount)
212
  {
 
 
213
  $authTransaction = $payment->getAuthorizationTransaction();
214
+ $order = $payment->getOrder();
215
+
216
+ $fulfill = (bool)$authTransaction;
217
+ if (!$fulfill && $payment->getId()) {
218
+ $collection = Mage::getModel('sales/order_payment_transaction')->getCollection()
219
+ ->setOrderFilter($payment->getOrder())
220
+ ->addPaymentIdFilter($payment->getId())
221
+ ->addTxnTypeFilter(Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE);
222
+ $fulfill = $collection->count();
223
+ }
224
+
225
+ // Old T3M auth
226
+ if ($this->getConfig()->getIsAllowedT3m($this->getCode())) {
227
+ if ($this->getIsCallbackRequest() == 1) { // In case of callbacks, the order is already fulfilled by invoice->capture see Observer.php
228
+ return $this;
229
+ }
230
+ // Must preauth card first (if not already done so) to make third
231
+ // man realtime check.
232
+ if (!$authTransaction) {
233
+ if (!array_intersect_key($payment->getAdditionalInformation(), array('t3m_score'=>1, 't3m_recommendation'=>1))) {
234
+ $this->authorize($payment, $amount);
235
+
236
+ if ($this->_t3mRecommendation != 'Release') {
237
+ return $this;
238
+ }
239
+
240
+ $fulfill = true;
241
+ }
242
+ if ($this->_t3mRecommendation == 'Release') {
243
+ $this->_api->setRequest(Mage::getModel('dpg/datacash_request'));
244
+ $this->_api->getRequest()->addAuthentication($this->_api->getMerchantId(), $this->_api->getMerchantPassword());
245
+
246
+ $payment->setAmountAuthorized($amount);
247
+ }
248
+ }
249
+ }
250
+ parent::capture($payment, $amount);
251
  $this->_initApi();
252
  $this->_mapRequestDataToApi($payment, $amount);
253
+
254
  // If the payment has already been authorized we need to only call fullfill
255
+ if ($fulfill && $payment->getAmountAuthorized() > 0 && $payment->getAmountAuthorized() >= $amount) {
256
  try {
257
  $this->_api->callFulfill();
258
  } catch (Exception $e) {
259
  throw new Mage_Payment_Model_Info_Exception($e->getMessage());
260
  }
261
+ } else if ($fulfill && $payment->getAmountAuthorized() > 0 && $payment->getAmountAuthorized() < $amount) {
262
  throw new Exception('This card has not been authorized for this amount');
263
  } else {
264
  try {
266
  $this->_api->setUseFraudScreening(true);
267
  $this->_api->setFraudScreeningPolicy($this->_fraudPolicy());
268
  }
269
+
270
  if ($this->getIsCentinelValidationEnabled()) {
271
  // if 3D secure check is turned on, we just have to authorize the previous calls
272
  $validator = $this->getCentinelValidator();
281
 
282
  // Process the response
283
  $response = $this->_api->getResponse();
284
+ if ($response->isSuccessful() || $response->isMarkedForReview()) {
285
  // Map data to the payment
286
  $this->_mapResponseToPayment($response, $payment);
287
  } else {
app/code/community/DataCash/Dpg/Model/Method/Hosted/Abstract.php CHANGED
@@ -59,7 +59,6 @@ abstract class DataCash_Dpg_Model_Method_Hosted_Abstract
59
  * If the data is not supplied the error will be thrown by the API
60
  *
61
  * @return void
62
- * @author Andy Thompson
63
  **/
64
  protected function _mapRequestDataToApi($payment, $amount)
65
  {
59
  * If the data is not supplied the error will be thrown by the API
60
  *
61
  * @return void
 
62
  **/
63
  protected function _mapRequestDataToApi($payment, $amount)
64
  {
app/code/community/DataCash/Dpg/Model/Observer.php CHANGED
@@ -29,6 +29,24 @@
29
  class DataCash_Dpg_Model_Observer
30
  {
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  /**
33
  * Add DataCash data to info block
34
  *
@@ -64,8 +82,6 @@ class DataCash_Dpg_Model_Observer
64
  'cc_avs_postcode_result',
65
  'cc_avs_cv2_result',
66
  'mode',
67
- 't3m_score',
68
- 't3m_recommendation'
69
  );
70
  foreach ($info as $key) {
71
  if ($value = $payment->getAdditionalInformation($key)) {
@@ -90,59 +106,104 @@ class DataCash_Dpg_Model_Observer
90
  return count($arr) === count(array_intersect_key($arr, array_flip($list)));
91
  }
92
 
93
- public function saveT3mRecommendationToOrder($data)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  {
 
 
95
  $t3mKeys = array('merchant_identifier', 'order_id', 't3m_id', 't3m_score', 't3m_recommendation');
96
- $t3mPaymentInfo = array('Release', 'Hold', 'Reject', 9 => 'Under Investigation');
97
- if ( ! $this->_arrayKeysInList((array)$data['response'], $t3mKeys)) {
98
  Mage::throwException('Observer' . __METHOD__ . ' was expecting different data.');
99
  }
100
- $rsp = (array)$data['response'];
 
 
101
  $orders = Mage::getModel('sales/order')->getCollection();
102
- $orders->addFieldToFilter('increment_id', $rsp['order_id']);
103
  $order = $orders->getFirstItem();
104
  if (!$order->getId()) {
105
- Mage::throwException(__METHOD__ . ' could not find order ' . $rsp['order_id']);
 
 
 
 
 
 
 
 
 
106
  }
107
 
108
  if (Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW != $order->getState()) {
109
  throw new Exception(
110
  'order state was not expected (while expecting it to be payment_review), order id: '
111
- .$rsp['order_id'].'; '
112
  .'suggested new recommendation: '.$t3mPaymentInfo[$rsp['t3m_recommendation']]
113
  );
114
  }
115
 
116
- $payment = $order->getPayment();
117
-
118
- $oldInfo = $payment->getAdditionalInformation();
119
- $newInfo = array_merge($oldInfo, array(
120
- 't3m_id' => $rsp['t3m_id'],
121
- 't3m_score' => $rsp['t3m_score'],
122
- 't3m_recommendation' => $t3mPaymentInfo[$rsp['t3m_recommendation']],
123
  ));
124
- $payment->setAdditionalInformation($newInfo);
125
-
126
- $order->save();
127
-
128
- switch($newInfo['t3m_recommendation']) {
129
- case 'Release':
130
- $payment->accept();
131
- $order->save();
132
- break;
133
- case 'Reject':
134
- $payment->setIsFraudDetected(true);
135
- $payment->deny();
136
- $order->setState(Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW, Mage_Sales_Model_Order::STATUS_FRAUD);
137
- $order->save();
138
- break;
139
- case 'Hold':
140
- $order->setState(Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW, true);
141
- $order->save();
142
- break;
143
- default:
144
- throw new Exception('Unknown response recommendation: '.$rsp['t3m_recommendation']);
145
- }
146
  }
147
 
148
  /**
@@ -155,16 +216,17 @@ class DataCash_Dpg_Model_Observer
155
  */
156
  public function afterOrderSubmit(Varien_Event_Observer $observer)
157
  {
158
- if (!Mage::getSingleton('dpg/config')->getIsAllowedT3m()) {
159
- return;
160
- }
161
-
162
  $order = $observer->getEvent()->getOrder();
163
  $payment = $order->getPayment();
164
-
 
 
 
 
165
  if (Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW == $order->getState() && $payment->getIsTransactionPending()) {
166
- $info = $payment->getAdditionalInformation();
167
- if (isset($info['t3m_recommendation']) && ('Reject' == $info['t3m_recommendation'])) {
 
168
  // load new payment to avoid payment::$_transactionsLookup caching of value 'false'
169
  $loadedPayment = Mage::getModel('sales/order_payment')->load($payment->getId());
170
  if ($loadedPayment->getId()) {
29
  class DataCash_Dpg_Model_Observer
30
  {
31
 
32
+ /**
33
+ * addRiskDataToPayment function.
34
+ *
35
+ * @access public
36
+ * @param mixed $observer
37
+ * @return void
38
+ */
39
+ public function addRiskDataToPayment($observer)
40
+ {
41
+ $block = $observer->getEvent()->getBlock();
42
+ if (get_class($block) == "Mage_Adminhtml_Block_Sales_Order_View_Info") {
43
+ $riskBlock = Mage::app()->getLayout()->createBlock('dpg/adminhtml_sales_order_risk');
44
+ $riskBlock->setOrder($block->getOrder());
45
+ $out = $observer->getTransport()->getHtml();
46
+ $observer->getTransport()->setHtml($out . $riskBlock->toHtml());
47
+ }
48
+ }
49
+
50
  /**
51
  * Add DataCash data to info block
52
  *
82
  'cc_avs_postcode_result',
83
  'cc_avs_cv2_result',
84
  'mode',
 
 
85
  );
86
  foreach ($info as $key) {
87
  if ($value = $payment->getAdditionalInformation($key)) {
106
  return count($arr) === count(array_intersect_key($arr, array_flip($list)));
107
  }
108
 
109
+ /**
110
+ * afterRiskCallbackUpdate function.
111
+ *
112
+ * @access public
113
+ * @param mixed $observer
114
+ * @return void
115
+ */
116
+ public function afterRiskCallbackUpdate($observer)
117
+ {
118
+ $event = $observer->getEvent();
119
+ $order = $event->getOrder();
120
+ $risk = $event->getRisk();
121
+ $payment = $order->getPayment();
122
+
123
+ $autoUpdate = Mage::getSingleton('dpg/config')->isRsgAutoUpdateEnabled($payment->getMethod());
124
+ if ($autoUpdate) {
125
+ $t3mPaymentInfo = Mage::getSingleton('dpg/config')->_t3mPaymentInfo;
126
+ switch($t3mPaymentInfo[$risk->getRecommendation()]) { // TODO: refactor to use DataCash_Dpg_Model_Config::RSG_***
127
+ case 'Release':
128
+ $payment->accept();
129
+ $order->save();
130
+
131
+ // XXX: "auto accept" overrides the Payment Action in a way that it will create an invoice and issue a fulfill request
132
+ // not just authorise the payment
133
+ $paymentAction = Mage::getSingleton('dpg/config')->getPaymentAction($payment->getMethod());
134
+ if ($paymentAction == Mage_Payment_Model_Method_Abstract::ACTION_AUTHORIZE) {
135
+ $order = Mage::getModel('sales/order')->load($order->getId()); // XXX: order needs to be reloaded
136
+ $order->getPayment()->getMethodInstance()->setIsCallbackRequest(1);
137
+ $order->getPayment()->capture();
138
+ $order->save();
139
+ }
140
+ break;
141
+ case 'Reject':
142
+ $payment->setIsFraudDetected(true);
143
+ $payment->deny();
144
+ $order->setState(Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW, Mage_Sales_Model_Order::STATUS_FRAUD);
145
+ $order->save();
146
+ break;
147
+ case 'Hold':
148
+ $order->setState(Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW, true);
149
+ $order->save();
150
+ break;
151
+ default:
152
+ throw new Exception('Unknown response recommendation: '.$risk->getRecommendation());
153
+ }
154
+ }
155
+ }
156
+
157
+ /**
158
+ * saveRiskRecommendationToOrder function.
159
+ *
160
+ * @access public
161
+ * @param mixed $observer
162
+ * @return void
163
+ */
164
+ public function saveRiskRecommendationToOrder($observer)
165
  {
166
+ $data = $observer->getEvent()->getResponse();
167
+
168
  $t3mKeys = array('merchant_identifier', 'order_id', 't3m_id', 't3m_score', 't3m_recommendation');
169
+ $t3mPaymentInfo = Mage::getSingleton('dpg/config')->_t3mPaymentInfo;
170
+ if ( ! $this->_arrayKeysInList((array)$data, $t3mKeys)) {
171
  Mage::throwException('Observer' . __METHOD__ . ' was expecting different data.');
172
  }
173
+ $rsp = (array)$data;
174
+
175
+ $order_id = $rsp['order_id'];
176
  $orders = Mage::getModel('sales/order')->getCollection();
177
+ $orders->addFieldToFilter('increment_id', $order_id);
178
  $order = $orders->getFirstItem();
179
  if (!$order->getId()) {
180
+ Mage::throwException(__METHOD__ . ' could not find order ' . $order_id);
181
+ }
182
+
183
+ if (!Mage::helper('dpg')->isIpAllowed($order->getPayment()->getMethod())) {
184
+ Mage::throwException('IP_restricted');
185
+ }
186
+
187
+ $config = Mage::getSingleton('dpg/config');
188
+ if ($config->isMethodDebug($order->getPayment()->getMethod())) {
189
+ Mage::log(var_export($data, 1), null, $order->getPayment()->getMethod().'.log');
190
  }
191
 
192
  if (Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW != $order->getState()) {
193
  throw new Exception(
194
  'order state was not expected (while expecting it to be payment_review), order id: '
195
+ .$order_id.'; '
196
  .'suggested new recommendation: '.$t3mPaymentInfo[$rsp['t3m_recommendation']]
197
  );
198
  }
199
 
200
+ $risk = Mage::getModel('dpg/risk_score');
201
+ $risk = $risk->storeDataToOrder($order, $rsp);
202
+
203
+ Mage::dispatchEvent('datacash_dpg_risk_callback_update', array(
204
+ 'order' => $order,
205
+ 'risk' => $risk
 
206
  ));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
  }
208
 
209
  /**
216
  */
217
  public function afterOrderSubmit(Varien_Event_Observer $observer)
218
  {
 
 
 
 
219
  $order = $observer->getEvent()->getOrder();
220
  $payment = $order->getPayment();
221
+
222
+ if (!Mage::getSingleton('dpg/config')->getIsAllowedT3m($payment->getMethod())) {
223
+ return;
224
+ }
225
+
226
  if (Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW == $order->getState() && $payment->getIsTransactionPending()) {
227
+ $item = Mage::getModel('dpg/risk_score')->loadByOrderId($order->getId());
228
+ $instance = $item->getTypeInstanceFromItem($item);
229
+ if ($instance->getRecommendationDisplay() == 'Reject') { // TODO: refactor to use DataCash_Dpg_Model_Config::RSG_REJECT
230
  // load new payment to avoid payment::$_transactionsLookup caching of value 'false'
231
  $loadedPayment = Mage::getModel('sales/order_payment')->load($payment->getId());
232
  if ($loadedPayment->getId()) {
app/code/community/DataCash/Dpg/Model/Resource/Risk.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class DataCash_Dpg_Model_Resource_Risk extends Mage_Core_Model_Resource_Db_Abstract
3
+ {
4
+ /**
5
+ * _construct function.
6
+ *
7
+ * @access protected
8
+ * @return void
9
+ */
10
+ protected function _construct()
11
+ {
12
+ $this->_init('dpg/risk', 'id');
13
+ }
14
+ }
app/code/community/DataCash/Dpg/Model/Resource/Risk/Collection.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class DataCash_Dpg_Model_Resource_Risk_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
3
+ {
4
+ /**
5
+ * _construct function.
6
+ *
7
+ * @access protected
8
+ * @return void
9
+ */
10
+ protected function _construct()
11
+ {
12
+ $this->_init('dpg/risk');
13
+ }
14
+ }
app/code/community/DataCash/Dpg/Model/Risk.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class DataCash_Dpg_Model_Risk extends DataCash_Dpg_Model_Risk_Abstract
3
+ {
4
+ const TYPE_SCREENING = 'dpg/risk_screening';
5
+ const TYPE_BANK = 'dpg/risk_bankresult';
6
+ const TYPE_SCORE = 'dpg/risk_score';
7
+
8
+ /**
9
+ * responseToInstanceMap
10
+ *
11
+ * @var mixed
12
+ * @access private
13
+ */
14
+ private $responseToInstanceMap = array(
15
+ 'screening_response' => self::TYPE_SCREENING,
16
+ 'bankresult_response' => self::TYPE_BANK,
17
+ 'score_response' => self::TYPE_SCORE,
18
+ );
19
+
20
+ /**
21
+ * typeToInstanceMap
22
+ *
23
+ * @var mixed
24
+ * @access private
25
+ */
26
+ private $typeToInstanceMap = array(
27
+ '0' => self::TYPE_SCREENING,
28
+ '1' => self::TYPE_BANK,
29
+ '2' => self::TYPE_SCORE,
30
+ );
31
+
32
+ /**
33
+ * storeRiskResponse function.
34
+ *
35
+ * @access public
36
+ * @param Mage_Sales_Model_Order_Payment $payment
37
+ * @param DataCash_Dpg_Model_Datacash_Response $response
38
+ * @return void
39
+ */
40
+ public function storeRiskResponse(Mage_Sales_Model_Order_Payment $payment, DataCash_Dpg_Model_Datacash_Response $response)
41
+ {
42
+ $riskResponse = $response->getRiskResponse();
43
+ if (!$riskResponse) {
44
+ return;
45
+ }
46
+ foreach($riskResponse as $typeStr => $riskData) {
47
+ $this->getTypeInstance($typeStr)->storeDataToOrder($payment->getOrder(), $riskData);
48
+ }
49
+
50
+ }
51
+
52
+ /**
53
+ * getTypeInstance function.
54
+ *
55
+ * @access protected
56
+ * @param string $typeId
57
+ * @return void
58
+ */
59
+ protected function getTypeInstance($typeId)
60
+ {
61
+ if (!isset($this->responseToInstanceMap[$typeId]) || !$this->responseToInstanceMap[$typeId]) {
62
+ throw new Exception("Could not find matching response model for type string '{$typeId}'");
63
+ }
64
+ return Mage::getModel($this->responseToInstanceMap[$typeId]);
65
+ }
66
+
67
+ /**
68
+ * getTypeInstanceFromItem function.
69
+ *
70
+ * @access public
71
+ * @param DataCash_Dpg_Model_Risk $item
72
+ * @return DataCash_Dpg_Model_Risk_Abstract instance
73
+ */
74
+ public function getTypeInstanceFromItem(DataCash_Dpg_Model_Risk $item)
75
+ {
76
+ if (!isset($this->typeToInstanceMap[$item->getData('txn_type')]) || !$this->typeToInstanceMap[$item->getData('txn_type')]) {
77
+ throw new Exception("Could not find matching type model for item '{$item->getId()}'");
78
+ }
79
+ return Mage::getModel($this->typeToInstanceMap[$item->getData('txn_type')])->setData('item', $item);
80
+ }
81
+ }
app/code/community/DataCash/Dpg/Model/Risk/Abstract.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class DataCash_Dpg_Model_Risk_Abstract extends Mage_Core_Model_Abstract
3
+ {
4
+ /**
5
+ * _construct function.
6
+ *
7
+ * @access protected
8
+ * @return void
9
+ */
10
+ protected function _construct()
11
+ {
12
+ $this->_init('dpg/risk');
13
+ }
14
+
15
+ /**
16
+ * getAdditionalMessages function.
17
+ *
18
+ * @access public
19
+ * @return array
20
+ */
21
+ public function getAdditionalMessages()
22
+ {
23
+ $messages = (array)json_decode($this->getData('messages'));
24
+ if (count($messages) == 1) {
25
+ $messages = array($messages);
26
+ }
27
+ return $messages;
28
+ }
29
+
30
+ /**
31
+ * storeDataToOrder function.
32
+ *
33
+ * @access public
34
+ * @param Mage_Sales_Model_Order $order
35
+ * @param array $riskData
36
+ * @return object
37
+ */
38
+ public function storeDataToOrder(Mage_Sales_Model_Order $order, array $riskData)
39
+ {
40
+ $map = $this->getMappedFields();
41
+
42
+ $this->setId(null);
43
+ $this->setData('txn_type', $this->_typeId);
44
+ $this->setData('order_id', $order->getId());
45
+
46
+ foreach($map as $responseField => $toField) {
47
+ if ($riskData[$responseField] !== null) {
48
+ $value = $riskData[$responseField];
49
+ $this->setData($toField, $value);
50
+ }
51
+ }
52
+
53
+ $this->validateRiskData();
54
+ $this->save();
55
+
56
+ return $this;
57
+ }
58
+
59
+ /**
60
+ * validateRiskData function.
61
+ *
62
+ * @access protected
63
+ * @return void
64
+ */
65
+ protected function validateRiskData()
66
+ {
67
+ if (!$this->getData('order_id')) {
68
+ throw new Exception("order_id not supplied");
69
+ }
70
+
71
+ if ($this->getData('txn_type') === null) {
72
+ throw new Exception("txn_type not supplied");
73
+ }
74
+ }
75
+ }
app/code/community/DataCash/Dpg/Model/Risk/Bankresult.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class DataCash_Dpg_Model_Risk_Bankresult extends DataCash_Dpg_Model_Risk_Abstract
3
+ {
4
+ // Example data
5
+ /*[bankresult_response] => Array
6
+ (
7
+ [cpi_value] =>
8
+ [response_code] => 00
9
+ [response_message] => Successful
10
+ [transaction_id] => 3800900036209415
11
+ )*/
12
+
13
+ /**
14
+ * _typeId
15
+ *
16
+ * (default value: 1)
17
+ *
18
+ * @var int
19
+ * @access protected
20
+ */
21
+ protected $_typeId = 1;
22
+
23
+ /**
24
+ * getMappedData function.
25
+ *
26
+ * @access protected
27
+ * @return array
28
+ */
29
+ protected function getMappedFields()
30
+ {
31
+ return array(
32
+ 'cpi_value' => 'cpi_value',
33
+ 'response_code' => 'response_code',
34
+ 'response_message' => 'response_message',
35
+ 'transaction_id' => 'transaction_id',
36
+ );
37
+ }
38
+ }
app/code/community/DataCash/Dpg/Model/Risk/Score.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class DataCash_Dpg_Model_Risk_Score extends DataCash_Dpg_Model_Risk_Abstract
3
+ {
4
+ //Example data
5
+ /*<RealTimeResponse xmlns="T3MCallback">
6
+ <aggregator_identifier/>
7
+ <merchant_identifier>5567</merchant_identifier>
8
+ <merchant_order_ref>12345</merchant_order_ref>
9
+ <t3m_id>333333333</t3m_id>
10
+ <score>0</score>
11
+ <recommendation>1</recommendation>
12
+ <message_digest></message_digest>*/
13
+
14
+ /**
15
+ * _typeId
16
+ *
17
+ * (default value: 2)
18
+ *
19
+ * @var int
20
+ * @access protected
21
+ */
22
+ protected $_typeId = 2;
23
+
24
+ /**
25
+ * getMappedData function.
26
+ *
27
+ * @access protected
28
+ * @return void
29
+ */
30
+ protected function getMappedFields()
31
+ {
32
+ return array(
33
+ 't3m_score' => 'score',
34
+ 't3m_recommendation' => 'recommendation',
35
+ );
36
+ }
37
+
38
+ /**
39
+ * getRecommendationDisplay function.
40
+ *
41
+ * @access public
42
+ * @return array
43
+ */
44
+ public function getRecommendationDisplay()
45
+ {
46
+ $t3mPaymentInfo = Mage::getSingleton('dpg/config')->_t3mPaymentInfo;
47
+ return $t3mPaymentInfo[$this->getData('item')->getData('recommendation')];
48
+ }
49
+
50
+ /**
51
+ * loadByOrderId function.
52
+ *
53
+ * @access public
54
+ * @param string $orderId
55
+ * @return risk object
56
+ */
57
+ public function loadByOrderId($orderId)
58
+ {
59
+ $risk = $this->getCollection()
60
+ ->addFieldToFilter('order_id', $orderId)
61
+ ->addFieldToFilter('txn_type', $this->_typeId)
62
+ ->getFirstItem();
63
+
64
+ return $risk;
65
+ }
66
+
67
+ /**
68
+ * storeDataToOrder function.
69
+ *
70
+ * @access public
71
+ * @param Mage_Sales_Model_Order $order
72
+ * @param array $riskData
73
+ * @return object
74
+ */
75
+ public function storeDataToOrder(Mage_Sales_Model_Order $order, array $riskData)
76
+ {
77
+ $map = $this->getMappedFields();
78
+ $txn = $this->getCollection()
79
+ ->addFieldToFilter('order_id', $order->getId())
80
+ ->addFieldToFilter('txn_type', $this->_typeId)
81
+ ->getFirstItem();
82
+
83
+ if (!$txn->getId()) {
84
+ $txn = $this;
85
+ $txn->setId(null);
86
+ }
87
+
88
+ $txn->setData('txn_type', $this->_typeId);
89
+ $txn->setData('order_id', $order->getId());
90
+
91
+ foreach($map as $responseField => $toField) {
92
+ if ($riskData[$responseField] !== null) {
93
+ $value = $riskData[$responseField];
94
+ $txn->setData($toField, $value);
95
+ }
96
+ }
97
+
98
+ $txn->validateRiskData();
99
+ $txn->save();
100
+
101
+ return $txn;
102
+ }
103
+ }
app/code/community/DataCash/Dpg/Model/Risk/Screening.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class DataCash_Dpg_Model_Risk_Screening extends DataCash_Dpg_Model_Risk_Abstract
3
+ {
4
+ // Example data
5
+ /*[screening_response] => Array
6
+ (
7
+ [additional_messages] => Array
8
+ (
9
+ [message] =>
10
+ )
11
+
12
+ [cpi_value] =>
13
+ [response_code] => 00
14
+ [response_message] => Transaction Approved
15
+ [transaction_id] => 3800900036209415
16
+ )*/
17
+
18
+ /**
19
+ * _typeId
20
+ *
21
+ * (default value: 0)
22
+ *
23
+ * @var int
24
+ * @access protected
25
+ */
26
+ protected $_typeId = 0;
27
+
28
+ /**
29
+ * getMappedData function.
30
+ *
31
+ * @access protected
32
+ * @return void
33
+ */
34
+ protected function getMappedFields()
35
+ {
36
+ return array(
37
+ 'cpi_value' => 'cpi_value',
38
+ 'response_code' => 'response_code',
39
+ 'response_message' => 'response_message',
40
+ 'transaction_id' => 'transaction_id',
41
+ 'additional_messages' => 'messages',
42
+ );
43
+ }
44
+
45
+ /**
46
+ * _beforeSave function.
47
+ *
48
+ * @access protected
49
+ * @return this
50
+ */
51
+ protected function _beforeSave()
52
+ {
53
+ parent::_beforeSave();
54
+ if ($this->getData('messages')) {
55
+ $this->setData('messages', json_encode($this->getData('messages')));
56
+ }
57
+ return $this;
58
+ }
59
+ }
app/code/community/DataCash/Dpg/Model/Source/RsgServiceTypes.php CHANGED
@@ -22,7 +22,6 @@
22
  * @author Kristjan Heinaste <kristjan@ontapgroup.com>
23
  * @package DataCash
24
  **/
25
-
26
  class DataCash_Dpg_Model_Source_RsgServiceTypes
27
  {
28
  /**
@@ -33,13 +32,20 @@ class DataCash_Dpg_Model_Source_RsgServiceTypes
33
  **/
34
  public function toOptionArray()
35
  {
36
- $options = array(array('value' => 1,
37
- 'label' => 'Pre-Auth Fraud Checking'),
38
- array('value' => 2,
39
- 'label' => 'Post-Auth Fraud Checking')
40
- );
41
-
42
-
 
 
 
 
 
 
 
43
  return $options;
44
  }
45
  }
22
  * @author Kristjan Heinaste <kristjan@ontapgroup.com>
23
  * @package DataCash
24
  **/
 
25
  class DataCash_Dpg_Model_Source_RsgServiceTypes
26
  {
27
  /**
32
  **/
33
  public function toOptionArray()
34
  {
35
+ $options = array(
36
+ array(
37
+ 'value' => 1,
38
+ 'label' => 'Pre-Auth Fraud Checking'
39
+ ),
40
+ array(
41
+ 'value' => 2,
42
+ 'label' => 'Post-Auth Fraud Checking'
43
+ ),
44
+ array(
45
+ 'value' => 't3m',
46
+ 'label' => 'Legacy T3M'
47
+ ),
48
+ );
49
  return $options;
50
  }
51
  }
app/code/community/DataCash/Dpg/controllers/RsgController.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * DataCash
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.
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 info@datacash.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 this module to newer
18
+ * versions in the future. If you wish to customize this module for your
19
+ * needs please refer to http://testserver.datacash.com/software/download.cgi
20
+ * for more information.
21
+ *
22
+ * @author Alistair Stead
23
+ * @version $Id$
24
+ * @copyright DataCash, 11 April, 2011
25
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
26
+ * @package DataCash
27
+ **/
28
+
29
+ /**
30
+ * DataCash_Dpg_RsgController
31
+ *
32
+ * Controller that handles all of the hosted payment processes
33
+ *
34
+ * @package DataCash
35
+ * @subpackage Controller
36
+ * @author OnTap Group
37
+ */
38
+ class DataCash_Dpg_RsgController extends DataCash_Dpg_Controller_Abstract
39
+ {
40
+ /**
41
+ * indexAction function.
42
+ *
43
+ * @access public
44
+ * @return void
45
+ */
46
+ public function indexAction()
47
+ {
48
+ $values = $this->getInputStreamAsArray();
49
+ if (count(array_keys($values))) {
50
+ $response = $this->mapCallback(
51
+ $values,
52
+ array(
53
+ 'merchant_identifier' => 'merchant_identifier',
54
+ 'order_id' => 'merchant_order_ref',
55
+ 't3m_id' => 't3m_id',
56
+ 't3m_score' => 'score',
57
+ 't3m_recommendation' => 'recommendation',
58
+ )
59
+ );
60
+ try {
61
+ Mage::dispatchEvent('datacash_dpg_rsg_callback', array(
62
+ 'response' => $response
63
+ ));
64
+ die('ok');
65
+ } catch (Exception $e) {
66
+ Mage::logException($e);
67
+ if ($e->getMessage() == 'IP_restricted') {
68
+ $this->getResponse()->setHeader('HTTP/1.1','403 Forbidden');
69
+ $this->getResponse()->setBody('');
70
+ return;
71
+ }
72
+ }
73
+ }
74
+ die('FAIL');
75
+ }
76
+ }
app/code/community/DataCash/Dpg/controllers/T3mController.php CHANGED
@@ -37,14 +37,18 @@
37
  */
38
  class DataCash_Dpg_T3mController extends DataCash_Dpg_Controller_Abstract
39
  {
40
-
 
 
 
 
 
41
  public function indexAction()
42
  {
43
  $request = $this->getRequest();
44
  if ($request->isPost()) {
45
- $config = Mage::getSingleton('dpg/config');
46
- $response = $this->_map(
47
- $request,
48
  array(
49
  'merchant_identifier' => 'merchant_identifier',
50
  'order_id' => 'merchant_order_ref',
@@ -53,35 +57,20 @@ class DataCash_Dpg_T3mController extends DataCash_Dpg_Controller_Abstract
53
  't3m_recommendation' => 'recommendation',
54
  )
55
  );
56
-
57
- if ($config->isMethodDebug('datacash_api')) {
58
- Mage::getModel('core/log_adapter', 'datacash_api.log')
59
- ->log($response);
60
- }
61
-
62
  try {
63
- Mage::dispatchEvent(
64
- 'datacash_dpg_t3m_callback',
65
- array(
66
- 'response' => $response
67
- )
68
- );
69
  die('ok');
70
  } catch (Exception $e) {
71
  Mage::logException($e);
 
 
 
 
 
72
  }
73
  }
74
  die('FAIL');
75
  }
76
-
77
- private function _map($request, $indices)
78
- {
79
- $t3m = array();
80
- foreach ($indices as $i => $j) {
81
- if ($request->getPost($j) !== null) {
82
- $t3m[$i] = $request->getPost($j);
83
- }
84
- }
85
- return $t3m;
86
- }
87
  }
37
  */
38
  class DataCash_Dpg_T3mController extends DataCash_Dpg_Controller_Abstract
39
  {
40
+ /**
41
+ * indexAction function.
42
+ *
43
+ * @access public
44
+ * @return void
45
+ */
46
  public function indexAction()
47
  {
48
  $request = $this->getRequest();
49
  if ($request->isPost()) {
50
+ $response = $this->mapCallback(
51
+ $request->getPost(),
 
52
  array(
53
  'merchant_identifier' => 'merchant_identifier',
54
  'order_id' => 'merchant_order_ref',
57
  't3m_recommendation' => 'recommendation',
58
  )
59
  );
 
 
 
 
 
 
60
  try {
61
+ Mage::dispatchEvent('datacash_dpg_t3m_callback', array(
62
+ 'response' => $response
63
+ ));
 
 
 
64
  die('ok');
65
  } catch (Exception $e) {
66
  Mage::logException($e);
67
+ if ($e->getMessage() == 'IP_restricted') {
68
+ $this->getResponse()->setHeader('HTTP/1.1','403 Forbidden');
69
+ $this->getResponse()->setBody('');
70
+ return;
71
+ }
72
  }
73
  }
74
  die('FAIL');
75
  }
 
 
 
 
 
 
 
 
 
 
 
76
  }
app/code/community/DataCash/Dpg/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <DataCash_Dpg>
5
- <version>1.2.5</version>
6
  </DataCash_Dpg>
7
  </modules>
8
  <global>
@@ -18,13 +18,31 @@
18
  </cc>
19
  </payment>
20
  <events>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  <datacash_dpg_t3m_callback>
22
  <observers>
23
- <Datacash_dpg_model_api_observer>
24
  <type>singleton</type>
25
  <class>DataCash_Dpg_Model_Observer</class>
26
- <method>saveT3mRecommendationToOrder</method>
27
- </Datacash_dpg_model_api_observer>
28
  </observers>
29
  </datacash_dpg_t3m_callback>
30
  <checkout_submit_all_after>
@@ -48,6 +66,9 @@
48
  <tokencard>
49
  <table>dpg_tokencard</table>
50
  </tokencard>
 
 
 
51
  </entities>
52
  </dpg_resource>
53
  </models>
@@ -73,12 +94,12 @@
73
  <types>
74
  <auth>
75
  <code>authorize</code>
76
- <name>Authorise</name>
77
  <order>0</order>
78
  </auth>
79
  <pre>
80
  <code>authorize_capture</code>
81
- <name>Authorise and Capture</name>
82
  <order>10</order>
83
  </pre>
84
  </types>
@@ -130,6 +151,15 @@
130
  </dpg>
131
  </observers>
132
  </payment_info_block_prepare_specific_information>
 
 
 
 
 
 
 
 
 
133
  </events>
134
  </adminhtml>
135
  <default>
@@ -149,6 +179,9 @@
149
  <sandbox>0</sandbox>
150
  <allow_fraud_screening>0</allow_fraud_screening>
151
  <rsg_service_mode>1</rsg_service_mode>
 
 
 
152
  <rsg_data_customer_first_name>1</rsg_data_customer_first_name>
153
  <rsg_data_customer_ip_address>1</rsg_data_customer_ip_address>
154
  <rsg_data_customer_email_address>1</rsg_data_customer_email_address>
@@ -201,6 +234,9 @@
201
  <sandbox>0</sandbox>
202
  <allow_fraud_screening>0</allow_fraud_screening>
203
  <rsg_service_mode>1</rsg_service_mode>
 
 
 
204
  <rsg_data_customer_first_name>1</rsg_data_customer_first_name>
205
  <rsg_data_customer_ip_address>1</rsg_data_customer_ip_address>
206
  <rsg_data_customer_email_address>1</rsg_data_customer_email_address>
2
  <config>
3
  <modules>
4
  <DataCash_Dpg>
5
+ <version>1.2.9</version>
6
  </DataCash_Dpg>
7
  </modules>
8
  <global>
18
  </cc>
19
  </payment>
20
  <events>
21
+ <datacash_dpg_risk_callback_update>
22
+ <observers>
23
+ <Datacash_dpg_model_risk_observer>
24
+ <type>singleton</type>
25
+ <class>DataCash_Dpg_Model_Observer</class>
26
+ <method>afterRiskCallbackUpdate</method>
27
+ </Datacash_dpg_model_risk_observer>
28
+ </observers>
29
+ </datacash_dpg_risk_callback_update>
30
+ <datacash_dpg_rsg_callback>
31
+ <observers>
32
+ <Datacash_dpg_model_rsgcallback_observer>
33
+ <type>singleton</type>
34
+ <class>DataCash_Dpg_Model_Observer</class>
35
+ <method>saveRiskRecommendationToOrder</method>
36
+ </Datacash_dpg_model_rsgcallback_observer>
37
+ </observers>
38
+ </datacash_dpg_rsg_callback>
39
  <datacash_dpg_t3m_callback>
40
  <observers>
41
+ <Datacash_dpg_model_t3mcallback_observer>
42
  <type>singleton</type>
43
  <class>DataCash_Dpg_Model_Observer</class>
44
+ <method>saveRiskRecommendationToOrder</method>
45
+ </Datacash_dpg_model_t3mcallback_observer>
46
  </observers>
47
  </datacash_dpg_t3m_callback>
48
  <checkout_submit_all_after>
66
  <tokencard>
67
  <table>dpg_tokencard</table>
68
  </tokencard>
69
+ <risk>
70
+ <table>dpg_risk</table>
71
+ </risk>
72
  </entities>
73
  </dpg_resource>
74
  </models>
94
  <types>
95
  <auth>
96
  <code>authorize</code>
97
+ <name>Authorise (PRE/FULFIL)</name>
98
  <order>0</order>
99
  </auth>
100
  <pre>
101
  <code>authorize_capture</code>
102
+ <name>Authorise and Capture (AUTH)</name>
103
  <order>10</order>
104
  </pre>
105
  </types>
151
  </dpg>
152
  </observers>
153
  </payment_info_block_prepare_specific_information>
154
+ <core_block_abstract_to_html_after>
155
+ <observers>
156
+ <dpg_risk_block>
157
+ <type>model</type>
158
+ <class>dpg/observer</class>
159
+ <method>addRiskDataToPayment</method>
160
+ </dpg_risk_block>
161
+ </observers>
162
+ </core_block_abstract_to_html_after>
163
  </events>
164
  </adminhtml>
165
  <default>
179
  <sandbox>0</sandbox>
180
  <allow_fraud_screening>0</allow_fraud_screening>
181
  <rsg_service_mode>1</rsg_service_mode>
182
+ <rsg_callbacks>0</rsg_callbacks>
183
+ <rsg_callbacks_autoupdate>0</rsg_callbacks_autoupdate>
184
+ <rsg_callbacks_security>0</rsg_callbacks_security>
185
  <rsg_data_customer_first_name>1</rsg_data_customer_first_name>
186
  <rsg_data_customer_ip_address>1</rsg_data_customer_ip_address>
187
  <rsg_data_customer_email_address>1</rsg_data_customer_email_address>
234
  <sandbox>0</sandbox>
235
  <allow_fraud_screening>0</allow_fraud_screening>
236
  <rsg_service_mode>1</rsg_service_mode>
237
+ <rsg_callbacks>0</rsg_callbacks>
238
+ <rsg_callbacks_autoupdate>0</rsg_callbacks_autoupdate>
239
+ <rsg_callbacks_security>0</rsg_callbacks_security>
240
  <rsg_data_customer_first_name>1</rsg_data_customer_first_name>
241
  <rsg_data_customer_ip_address>1</rsg_data_customer_ip_address>
242
  <rsg_data_customer_email_address>1</rsg_data_customer_email_address>
app/code/community/DataCash/Dpg/etc/system.xml CHANGED
@@ -521,6 +521,55 @@
521
  <allow_fraud_screening>1</allow_fraud_screening>
522
  </depends>
523
  </rsg_service_mode>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
524
 
525
  <!-- CUSTOMER -->
526
  <rsg_data_customer_heading translate="label">
@@ -1524,7 +1573,56 @@
1524
  <allow_fraud_screening>1</allow_fraud_screening>
1525
  </depends>
1526
  </rsg_service_mode>
1527
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1528
  <!-- CUSTOMER -->
1529
  <rsg_data_customer_heading translate="label">
1530
  <label>Customer data to screening</label>
521
  <allow_fraud_screening>1</allow_fraud_screening>
522
  </depends>
523
  </rsg_service_mode>
524
+ <rsg_callbacks translate="label">
525
+ <label>Enable callback services</label>
526
+ <frontend_type>select</frontend_type>
527
+ <source_model>adminhtml/system_config_source_yesno</source_model>
528
+ <sort_order>511</sort_order>
529
+ <show_in_default>1</show_in_default>
530
+ <show_in_website>1</show_in_website>
531
+ <show_in_store>0</show_in_store>
532
+ <depends>
533
+ <allow_fraud_screening>1</allow_fraud_screening>
534
+ </depends>
535
+ </rsg_callbacks>
536
+ <rsg_callbacks_autoupdate translate="label">
537
+ <label>Automatically accept/deny payments based on recommendation</label>
538
+ <frontend_type>select</frontend_type>
539
+ <source_model>adminhtml/system_config_source_yesno</source_model>
540
+ <sort_order>512</sort_order>
541
+ <show_in_default>1</show_in_default>
542
+ <show_in_website>1</show_in_website>
543
+ <show_in_store>0</show_in_store>
544
+ <depends>
545
+ <rsg_callbacks>1</rsg_callbacks>
546
+ </depends>
547
+ </rsg_callbacks_autoupdate>
548
+ <rsg_callbacks_security translate="label">
549
+ <label>Enable IP filtering</label>
550
+ <frontend_type>select</frontend_type>
551
+ <source_model>adminhtml/system_config_source_yesno</source_model>
552
+ <sort_order>513</sort_order>
553
+ <show_in_default>1</show_in_default>
554
+ <show_in_website>1</show_in_website>
555
+ <show_in_store>0</show_in_store>
556
+ <depends>
557
+ <rsg_callbacks>1</rsg_callbacks>
558
+ </depends>
559
+ <comment>Only certain IPs are allowed to send callback</comment>
560
+ </rsg_callbacks_security>
561
+ <rsg_callbacks_ips translate="label">
562
+ <label>List of IPs</label>
563
+ <frontend_type>textarea</frontend_type>
564
+ <sort_order>514</sort_order>
565
+ <show_in_default>1</show_in_default>
566
+ <show_in_website>1</show_in_website>
567
+ <show_in_store>0</show_in_store>
568
+ <depends>
569
+ <rsg_callbacks_security>1</rsg_callbacks_security>
570
+ </depends>
571
+ <comment>Separate IP's with a line-break</comment>
572
+ </rsg_callbacks_ips>
573
 
574
  <!-- CUSTOMER -->
575
  <rsg_data_customer_heading translate="label">
1573
  <allow_fraud_screening>1</allow_fraud_screening>
1574
  </depends>
1575
  </rsg_service_mode>
1576
+ <rsg_callbacks translate="label">
1577
+ <label>Enable callback services</label>
1578
+ <frontend_type>select</frontend_type>
1579
+ <source_model>adminhtml/system_config_source_yesno</source_model>
1580
+ <sort_order>511</sort_order>
1581
+ <show_in_default>1</show_in_default>
1582
+ <show_in_website>1</show_in_website>
1583
+ <show_in_store>0</show_in_store>
1584
+ <depends>
1585
+ <allow_fraud_screening>1</allow_fraud_screening>
1586
+ </depends>
1587
+ </rsg_callbacks>
1588
+ <rsg_callbacks_autoupdate translate="label">
1589
+ <label>Automatically accept/deny payments based on recommendation</label>
1590
+ <frontend_type>select</frontend_type>
1591
+ <source_model>adminhtml/system_config_source_yesno</source_model>
1592
+ <sort_order>512</sort_order>
1593
+ <show_in_default>1</show_in_default>
1594
+ <show_in_website>1</show_in_website>
1595
+ <show_in_store>0</show_in_store>
1596
+ <depends>
1597
+ <rsg_callbacks>1</rsg_callbacks>
1598
+ </depends>
1599
+ </rsg_callbacks_autoupdate>
1600
+ <rsg_callbacks_security translate="label">
1601
+ <label>Enable IP filtering</label>
1602
+ <frontend_type>select</frontend_type>
1603
+ <source_model>adminhtml/system_config_source_yesno</source_model>
1604
+ <sort_order>513</sort_order>
1605
+ <show_in_default>1</show_in_default>
1606
+ <show_in_website>1</show_in_website>
1607
+ <show_in_store>0</show_in_store>
1608
+ <depends>
1609
+ <rsg_callbacks>1</rsg_callbacks>
1610
+ </depends>
1611
+ <comment>Only certain IPs are allowed to send callback</comment>
1612
+ </rsg_callbacks_security>
1613
+ <rsg_callbacks_ips translate="label">
1614
+ <label>List of IPs</label>
1615
+ <frontend_type>textarea</frontend_type>
1616
+ <sort_order>514</sort_order>
1617
+ <show_in_default>1</show_in_default>
1618
+ <show_in_website>1</show_in_website>
1619
+ <show_in_store>0</show_in_store>
1620
+ <depends>
1621
+ <rsg_callbacks_security>1</rsg_callbacks_security>
1622
+ </depends>
1623
+ <comment>Separate IP's with a line-break</comment>
1624
+ </rsg_callbacks_ips>
1625
+
1626
  <!-- CUSTOMER -->
1627
  <rsg_data_customer_heading translate="label">
1628
  <label>Customer data to screening</label>
app/code/community/DataCash/Dpg/sql/datacash_dpg_setup/mysql4-upgrade-1.2.5-1.2.6.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $installer = $this;
3
+ $installer->startSetup();
4
+
5
+ //Changing tables storage engine to avoid table locking, with InnoDB we get row locking.
6
+ $installer->run("
7
+ ALTER TABLE `{$this->getTable('dpg_tokencard')}` ENGINE='InnoDB';
8
+ ");
9
+
10
+ // txn_type definition
11
+ // 0 - screening_response
12
+ // 1 - bankresult_response
13
+ // 2 - score_response
14
+ $installer->run("
15
+ CREATE TABLE IF NOT EXISTS `{$this->getTable('dpg_risk')}` (
16
+ `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
17
+ `txn_type` TINYINT(2) NOT NULL,
18
+ `order_id` INT(11) UNSIGNED NOT NULL,
19
+ `transaction_id` INT(11) UNSIGNED NULL,
20
+ `response_code` VARCHAR(4) NULL,
21
+ `response_message` VARCHAR(255) NULL,
22
+ `cpi_value` TINYINT(2) NULL,
23
+ `messages` TEXT NULL,
24
+ `score` TINYINT(2) NULL,
25
+ `recommendation` TINYINT(2) NULL,
26
+ `created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
27
+ PRIMARY KEY (`id`) )
28
+ ENGINE=InnoDB DEFAULT CHARSET=utf8;
29
+ ");
30
+
31
+ $installer->run("
32
+ ALTER TABLE `{$this->getTable('dpg_risk')}` ADD INDEX `IDX_DATACASH_RISK_ORDER_ID` (`order_id`);
33
+ ");
34
+
35
+ $installer->endSetup();
package.xml CHANGED
@@ -1,18 +1,18 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Datacash</name>
4
- <version>1.2.5</version>
5
  <stability>stable</stability>
6
  <license>OSL 3.0</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>DataCash payment gateway integration</summary>
10
  <description>DataCash payment gateway integration. System requirements as for Magento http://www.magentocommerce.com/system-requirements. cURL with the FOLLOWLOCATION option is used for service calls to DataCash. FOLLOWLOCATION requires safe_mode to be off and open_basedir to be disabled in the php.ini</description>
11
- <notes>Version 1.2.5</notes>
12
  <authors><author><name>DataCash</name><user>datacash</user><email>support@datacash.com</email></author></authors>
13
- <date>2014-10-20</date>
14
- <time>08:43:55</time>
15
- <contents><target name="magecommunity"><dir name="DataCash"><dir name="Dpg"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Fieldset"><file name="Hint.php" hash="c65030837e1ce97a063b9146f3bb983d"/></dir></dir></dir></dir><dir name="Form"><file name="Api.php" hash="033a34c52dc6dc03fa802c78e05fff9c"/><file name="Apiprereg.php" hash="bf28b55b476562ff459012c9fc21bc6d"/><file name="Hcc.php" hash="b3406a87a800b9182a0e4e259cf75754"/><file name="Hps.php" hash="47a732ebb397a14a145851cdb00ceb0b"/><file name="Iframe.php" hash="d0aad3633894b90f64112a962c8e3161"/><file name="Placeform.php" hash="19bafec3229f6f35382d9b725d41f620"/></dir><dir name="Iframe"><file name="Complete.php" hash="adbf0cb0a89aee5704cebf62dd63b4a9"/><file name="Start.php" hash="ef6527a85117c67a52291932339a25a1"/></dir><dir name="Info"><file name="Api.php" hash="a2893e155ba8c92776e12ed7d4472284"/><file name="Hcc.php" hash="7a2c713640e7fcee5d5c2150d1baff40"/><file name="Hps.php" hash="8b06d32980842db5274897d3bfba9df1"/></dir></dir><dir name="Controller"><file name="Abstract.php" hash="3082d6a39d67762df16eed690823aab3"/></dir><dir name="Helper"><file name="Cdata.php" hash="8e73bf53fd94e3b3af31bf3d42c42d72"/><file name="Data.php" hash="5ed8bc718e0fe451c28e9292fff73e97"/></dir><dir name="Model"><dir name="Api"><file name="Abstract.php" hash="55c06a742eff55fa47be8a6251ecac44"/><file name="Direct.php" hash="bb6e10495f1a5f50feb0766dea293684"/><file name="Directprereg.php" hash="1ba0633478037b367bf3f15f091dcdb4"/><file name="Hcc.php" hash="5f54b2c9c23472f49ea61f4ba3041c94"/><file name="Hps.php" hash="40616c129c29acb6978b4bf543b4187c"/></dir><file name="Code.php" hash="43d2b25050901ebd6f6e82ed264de783"/><file name="Config.php" hash="612bce5a820094cdc809f6c3689d62b8"/><dir name="Datacash"><file name="Request.php" hash="8fc13fb3b8b38b2bf26167305d34e58b"/><file name="Response.php" hash="aa56436c93b2ededbec0f9e75f5e96d3"/><dir name="Simplexml"><file name="Element.php" hash="ac1b66c652eb1843a36dcbf1b94a40fa"/></dir></dir><file name="Dpg.php" hash="5ded0f39a06d12f538fbdf8fe7553c7c"/><dir name="Entity"><file name="Setup.php" hash="d74a82e89fe2213034f6558956ad9633"/></dir><dir name="Method"><file name="Abstract.php" hash="838a8a09927ba7768dd90757bc754d3d"/><file name="Api.php" hash="57f1f0db3c75d50f2977693b6b771b3c"/><file name="Apiprereg.php" hash="7af51159fa691a4593ca34754fa7490d"/><file name="Hcc.php" hash="4157135984275a240880dd657ba8a837"/><dir name="Hosted"><file name="Abstract.php" hash="32100702f8e7dbf2e3faafa1b541a981"/><file name="Interface.php" hash="926072fcd7d864e1f98da8b59b164eb7"/></dir><file name="Hps.php" hash="ce07c9a04d19558a052678e3df28c1f2"/></dir><file name="Observer.php" hash="8b1bb83efec831a079d8a248a5aa1f9c"/><dir name="Resource"><file name="Setup.php" hash="8c8dfa376d518c3b1122ecdeceec7683"/><dir name="Tokencard"><file name="Collection.php" hash="8f12f4c957db4c60542f345c909d7918"/></dir><file name="Tokencard.php" hash="4f1098828b12460edf828342fe88e559"/></dir><dir name="Service"><file name="Abstract.php" hash="8815585398e87b8bcb6d4c282b954f95"/><file name="Direct.php" hash="2dc35bf8f06de86cbdcb2975ea08ef9d"/><file name="Directprereg.php" hash="342849147fb97872192d800a2457c917"/><file name="Hcc.php" hash="090324b893a844715e3c06384bd456fe"/><dir name="State"><file name="Datacash.php" hash="79df9d849f4d23e154c1075b776ca888"/></dir></dir><file name="Service.php" hash="3c5374cf5d2f3d802fe032dce47c1c64"/><dir name="Source"><file name="Acceptreject.php" hash="a3142c294701177d85aab3a6f214e9b2"/><file name="Authtypes.php" hash="a7923edddb42f8ea86b2abb07546d62a"/><file name="GatewayMode.php" hash="c449151400da02fd3eff28cd799d4b46"/><file name="RsgBillingShipping.php" hash="03055dbd794ddef88e4c89d9f690e470"/><file name="RsgServiceTypes.php" hash="2a756b7341413ae462f3ad7f83c8ada6"/><file name="Threedstypes.php" hash="5f404d5d676a3baf0e0e71f1331decc2"/></dir><file name="Tokencard.php" hash="a83e3a6c6bfd86377727e5fab0b1020b"/></dir><dir name="controllers"><file name="HccController.php" hash="4257caa14117e23565568855abe307a9"/><file name="HostedController.php" hash="d08cef939ce21212e30150354f86f6fc"/><file name="HpsController.php" hash="7c94d6d858f20f810cfd6df61a3238f3"/><file name="T3mController.php" hash="bf54d16c48e5fc9fec96dad1e6e0f0fc"/></dir><dir name="etc"><file name="config.xml" hash="f2dca001e7d89f952e65b056f1934e39"/><file name="system.xml" hash="bdb039f715fb9b2190c524e5d0e85051"/></dir><dir name="sql"><dir name="datacash_dpg_setup"><file name="mysql4-install-0.1.0.php" hash="00a5d0be2b14d26ed85ed891b811abfc"/><file name="mysql4-upgrade-1.0.1-1.1.0.php" hash="a793557ab661f8d8a8535ae3a0683151"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="datacash"><dir><dir name="form"><file name="cc.phtml" hash="b798c2c2c0729bef424d1be5f64ca024"/><file name="cc.phtml.backup" hash="4930cc189ac48efe55694e5aec89939f"/><file name="cc_prereg.phtml" hash="5b33eaca19e25153a7bcedee02a6f0a6"/></dir><dir name="hcc"><file name="form.phtml" hash="81ed0746ffbd96d8000b95db7c281d03"/><file name="info.phtml" hash="eb512a6dab0d1396742cddf5c5db1598"/><file name="placeform.phtml" hash="b79869ff4346c230c6214b2bffdbc46c"/></dir><dir name="hps"><file name="form.phtml" hash="81ed0746ffbd96d8000b95db7c281d03"/><file name="info.phtml" hash="4bd99be8a9e08b77618fc2f596d2856a"/></dir><dir name="iframe"><file name="complete.phtml" hash="9190056410f552cb802a85b582127065"/><file name="form.phtml" hash="74abd537d1256778a19dd580d236224f"/><file name="start.phtml" hash="3493cd85bf3b3ca604990bd3d810d14d"/></dir></dir></dir></dir><dir name="layout"><file name="datacash.xml" hash="5f2531bbff2d8a5d2a20ea3ec91ea91e"/></dir></dir></dir></dir></target><target name="magelocale"><dir><dir name="en_GB"><file name="DataCash_Dpg.csv" hash="f5d24ae44a0d5f3ac76e74430059152d"/></dir></dir></target><target name="mageetc"><dir name="modules"><file name="DataCash_Payment.xml" hash="7f1d393c458e2287f492fc01dd2f1265"/></dir></target></contents>
16
  <compatible/>
17
  <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
18
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Datacash</name>
4
+ <version>1.2.9</version>
5
  <stability>stable</stability>
6
  <license>OSL 3.0</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>DataCash payment gateway integration</summary>
10
  <description>DataCash payment gateway integration. System requirements as for Magento http://www.magentocommerce.com/system-requirements. cURL with the FOLLOWLOCATION option is used for service calls to DataCash. FOLLOWLOCATION requires safe_mode to be off and open_basedir to be disabled in the php.ini</description>
11
+ <notes>Version 1.2.9</notes>
12
  <authors><author><name>DataCash</name><user>datacash</user><email>support@datacash.com</email></author></authors>
13
+ <date>2015-02-13</date>
14
+ <time>14:13:35</time>
15
+ <contents><target name="magecommunity"><dir name="DataCash"><dir name="Dpg"><dir name="Block"><dir name="Adminhtml"><dir name="Sales"><dir name="Order"><file name="Risk.php" hash="087e512ca652eccffd905c154f699b0b"/></dir></dir><dir name="System"><dir name="Config"><dir name="Fieldset"><file name="Hint.php" hash="c65030837e1ce97a063b9146f3bb983d"/></dir></dir></dir></dir><dir name="Form"><file name="Api.php" hash="033a34c52dc6dc03fa802c78e05fff9c"/><file name="Apiprereg.php" hash="bf28b55b476562ff459012c9fc21bc6d"/><file name="Hcc.php" hash="b3406a87a800b9182a0e4e259cf75754"/><file name="Hps.php" hash="47a732ebb397a14a145851cdb00ceb0b"/><file name="Iframe.php" hash="d0aad3633894b90f64112a962c8e3161"/><file name="Placeform.php" hash="19bafec3229f6f35382d9b725d41f620"/></dir><dir name="Iframe"><file name="Complete.php" hash="adbf0cb0a89aee5704cebf62dd63b4a9"/><file name="Start.php" hash="ef6527a85117c67a52291932339a25a1"/></dir><dir name="Info"><file name="Api.php" hash="a2893e155ba8c92776e12ed7d4472284"/><file name="Hcc.php" hash="7a2c713640e7fcee5d5c2150d1baff40"/><file name="Hps.php" hash="8b06d32980842db5274897d3bfba9df1"/></dir></dir><dir name="Controller"><file name="Abstract.php" hash="8be5810fc25d1d1aecb0df3b18b0e536"/></dir><dir name="Helper"><file name="Cdata.php" hash="8e73bf53fd94e3b3af31bf3d42c42d72"/><file name="Data.php" hash="d0432d33a8705ca3a34f192e1659699f"/></dir><dir name="Model"><dir name="Api"><file name="Abstract.php" hash="f64fb44b5e4d21cf5789be5fb404739a"/><file name="Direct.php" hash="71cca949b9d97a9947bff8a2f0b024a7"/><file name="Directprereg.php" hash="1ba0633478037b367bf3f15f091dcdb4"/><file name="Hcc.php" hash="5f0bfa147b92755cddb0243a49e0b6b9"/><file name="Hps.php" hash="40616c129c29acb6978b4bf543b4187c"/></dir><file name="Code.php" hash="43d2b25050901ebd6f6e82ed264de783"/><file name="Config.php" hash="6bc17df54e9692d696b84c16626f28fb"/><dir name="Datacash"><file name="Request.php" hash="06fa2fdf10c89d7b9934e723965255af"/><file name="Response.php" hash="5507d072f231eebcb3d7bff05da27ecb"/><dir name="Simplexml"><file name="Element.php" hash="ac1b66c652eb1843a36dcbf1b94a40fa"/></dir></dir><file name="Dpg.php" hash="5ded0f39a06d12f538fbdf8fe7553c7c"/><dir name="Entity"><file name="Setup.php" hash="d74a82e89fe2213034f6558956ad9633"/></dir><dir name="Method"><file name="Abstract.php" hash="56d0d20c9b81dbf437b8528cd61279fd"/><file name="Api.php" hash="8880dfa3dda98381eacec8ef2c9af040"/><file name="Apiprereg.php" hash="7af51159fa691a4593ca34754fa7490d"/><file name="Hcc.php" hash="eab5f28256dcc7948c07a45a18727bfd"/><dir name="Hosted"><file name="Abstract.php" hash="f52b0d48cc87e885359e43373dc37c13"/><file name="Interface.php" hash="926072fcd7d864e1f98da8b59b164eb7"/></dir><file name="Hps.php" hash="ce07c9a04d19558a052678e3df28c1f2"/></dir><file name="Observer.php" hash="bf6744f8b7ef6cd7acd430928ffa561c"/><dir name="Resource"><dir name="Risk"><file name="Collection.php" hash="b40b9dfa1942fb977518b0f139837b9b"/></dir><file name="Risk.php" hash="a2c777f8447d7302228201426295be0b"/><file name="Setup.php" hash="8c8dfa376d518c3b1122ecdeceec7683"/><dir name="Tokencard"><file name="Collection.php" hash="8f12f4c957db4c60542f345c909d7918"/></dir><file name="Tokencard.php" hash="4f1098828b12460edf828342fe88e559"/></dir><dir name="Risk"><file name="Abstract.php" hash="0f5506868fe68480d6c8b9049ae2d57d"/><file name="Bankresult.php" hash="3bdf045047881195a20bfec39e5c5f3a"/><file name="Score.php" hash="e564950b8da436b1369b240d094b4213"/><file name="Screening.php" hash="b28d2db8daab751830d737553617851d"/></dir><file name="Risk.php" hash="944331f5e7b96a29ba4940bbbb8739aa"/><dir name="Service"><file name="Abstract.php" hash="8815585398e87b8bcb6d4c282b954f95"/><file name="Direct.php" hash="2dc35bf8f06de86cbdcb2975ea08ef9d"/><file name="Directprereg.php" hash="342849147fb97872192d800a2457c917"/><file name="Hcc.php" hash="090324b893a844715e3c06384bd456fe"/><dir name="State"><file name="Datacash.php" hash="79df9d849f4d23e154c1075b776ca888"/></dir></dir><file name="Service.php" hash="3c5374cf5d2f3d802fe032dce47c1c64"/><dir name="Source"><file name="Acceptreject.php" hash="a3142c294701177d85aab3a6f214e9b2"/><file name="Authtypes.php" hash="a7923edddb42f8ea86b2abb07546d62a"/><file name="GatewayMode.php" hash="c449151400da02fd3eff28cd799d4b46"/><file name="RsgBillingShipping.php" hash="03055dbd794ddef88e4c89d9f690e470"/><file name="RsgServiceTypes.php" hash="0560250f3db9da1d187d4e1d55b5b52e"/><file name="Threedstypes.php" hash="5f404d5d676a3baf0e0e71f1331decc2"/></dir><file name="Tokencard.php" hash="a83e3a6c6bfd86377727e5fab0b1020b"/></dir><dir name="controllers"><file name="HccController.php" hash="4257caa14117e23565568855abe307a9"/><file name="HostedController.php" hash="d08cef939ce21212e30150354f86f6fc"/><file name="HpsController.php" hash="7c94d6d858f20f810cfd6df61a3238f3"/><file name="RsgController.php" hash="631c247eb35e325b268a6996baa0b39b"/><file name="T3mController.php" hash="8d7888657be282bafd75f2802a818556"/></dir><dir name="etc"><file name="config.xml" hash="33995d349cdac0fff096cfd54ad9a33a"/><file name="system.xml" hash="ddc40b2cf948a52f4e098eca518f84d1"/></dir><dir name="sql"><dir name="datacash_dpg_setup"><file name="mysql4-install-0.1.0.php" hash="00a5d0be2b14d26ed85ed891b811abfc"/><file name="mysql4-upgrade-1.0.1-1.1.0.php" hash="a793557ab661f8d8a8535ae3a0683151"/><file name="mysql4-upgrade-1.2.5-1.2.6.php" hash="0a8b673a9e4c5f66ccf209ade90f370a"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="datacash"><dir><dir name="form"><file name="cc.phtml" hash="b798c2c2c0729bef424d1be5f64ca024"/><file name="cc.phtml.backup" hash="4930cc189ac48efe55694e5aec89939f"/><file name="cc_prereg.phtml" hash="5b33eaca19e25153a7bcedee02a6f0a6"/></dir><dir name="hcc"><file name="form.phtml" hash="81ed0746ffbd96d8000b95db7c281d03"/><file name="info.phtml" hash="eb512a6dab0d1396742cddf5c5db1598"/><file name="placeform.phtml" hash="b79869ff4346c230c6214b2bffdbc46c"/></dir><dir name="hps"><file name="form.phtml" hash="81ed0746ffbd96d8000b95db7c281d03"/><file name="info.phtml" hash="4bd99be8a9e08b77618fc2f596d2856a"/></dir><dir name="iframe"><file name="complete.phtml" hash="9190056410f552cb802a85b582127065"/><file name="form.phtml" hash="74abd537d1256778a19dd580d236224f"/><file name="start.phtml" hash="3493cd85bf3b3ca604990bd3d810d14d"/></dir></dir></dir></dir><dir name="layout"><file name="datacash.xml" hash="5f2531bbff2d8a5d2a20ea3ec91ea91e"/></dir></dir></dir></dir></target><target name="magelocale"><dir><dir name="en_GB"><file name="DataCash_Dpg.csv" hash="f5d24ae44a0d5f3ac76e74430059152d"/></dir></dir></target><target name="mageetc"><dir name="modules"><file name="DataCash_Payment.xml" hash="7f1d393c458e2287f492fc01dd2f1265"/></dir></target></contents>
16
  <compatible/>
17
  <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
18
  </package>