CDev_XPaymentsConnector - Version 1.7.1

Version Notes

What's new?

- Invoice for payment made using a saved credit card is now created automatically.

- X-Payments Connector settings page moved to admin controller. Potential 404 error fixed.

- Auto-detect of API version added. Test connection button removed, so connection between Magento store and X-Payments is tested automatically.

- Fixed issue with product attributes being reset after a product is added to the cart.

- Corrected recurring profiles creation. Fixed several issues with Recurring profiles and nominal items.

- "Allowed IP address" for X-Payments callback handling improved.

- Improved customer registration at checkout for OneStepCheckout module by Idev.

- Corrected password setting during customer registration at checkout.

- Corrected saving credit cards at customer profile.

- "My payment cards" section is now removed correctly if "Use saved card" payment method is not active.

- Compatibility with SUPEE-8788 vulnerability

- NoFraud service support added

- other minor bug-fixes and improvements in code and corrections to text labels.

Download this release

Release Info

Developer Alexander Mulin
Extension CDev_XPaymentsConnector
Version 1.7.1
Comparing to
See all releases


Code changes from version 1.7.0 to 1.7.1

Files changed (29) hide show
  1. app/code/community/Cdev/XPaymentsConnector/Block/{Control.php → Adminhtml/Settings/Xpc.php} +75 -42
  2. app/code/community/Cdev/XPaymentsConnector/Block/Checkout/Onepage/Orderdetail.php +4 -1
  3. app/code/community/Cdev/XPaymentsConnector/Block/Checkout/Onepage/Success.php +20 -0
  4. app/code/community/Cdev/XPaymentsConnector/Helper/Data.php +255 -205
  5. app/code/community/Cdev/XPaymentsConnector/Model/Fraudcheckdata.php +99 -0
  6. app/code/community/Cdev/XPaymentsConnector/{Block/Customer/Account/Navigation.php → Model/Mysql4/Fraudcheckdata.php} +14 -19
  7. app/code/community/Cdev/XPaymentsConnector/Model/Mysql4/Fraudcheckdata/Collection.php +41 -0
  8. app/code/community/Cdev/XPaymentsConnector/Model/Mysql4/Quote/Xpcdata.php +42 -0
  9. app/code/community/Cdev/XPaymentsConnector/Model/Mysql4/Quote/Xpcdata/Collection.php +37 -0
  10. app/code/community/Cdev/XPaymentsConnector/Model/Observer.php +7 -13
  11. app/code/community/Cdev/XPaymentsConnector/Model/Payment/Cc.php +147 -124
  12. app/code/community/Cdev/XPaymentsConnector/Model/Payment/Savedcards.php +1 -1
  13. app/code/community/Cdev/XPaymentsConnector/Model/Quote/Xpcdata.php +56 -0
  14. app/code/community/Cdev/XPaymentsConnector/controllers/Adminhtml/Sales/Order/FraudController.php +2 -1
  15. app/code/community/Cdev/XPaymentsConnector/controllers/{ControlController.php → Adminhtml/Settings/XpcController.php} +43 -32
  16. app/code/community/Cdev/XPaymentsConnector/controllers/ProcessingController.php +184 -103
  17. app/code/community/Cdev/XPaymentsConnector/etc/adminhtml.xml +5 -5
  18. app/code/community/Cdev/XPaymentsConnector/etc/config.xml +109 -107
  19. app/code/community/Cdev/XPaymentsConnector/etc/system.xml +9 -2
  20. app/code/community/Cdev/XPaymentsConnector/sql/xpaymentsconnector_setup/mysql4-upgrade-1.1.2-1.1.3.php +68 -0
  21. app/design/adminhtml/default/default/layout/xpaymentsconnector.xml +3 -3
  22. app/design/adminhtml/default/default/template/xpaymentsconnector/control.phtml +0 -212
  23. app/design/adminhtml/default/default/template/xpaymentsconnector/order/view/tab/xporderstate.phtml +94 -1
  24. app/design/adminhtml/default/default/template/xpaymentsconnector/settings/xpc.phtml +179 -0
  25. app/design/frontend/base/default/layout/xpaymentsconnector.xml +1 -1
  26. app/design/frontend/base/default/template/xpaymentsconnector/checkout/success.phtml +14 -4
  27. app/design/frontend/base/default/template/xpaymentsconnector/info/cc.phtml +1 -1
  28. js/xpayment/{xp-contorl.css → settings-xpc.css} +27 -1
  29. package.xml +23 -11
app/code/community/Cdev/XPaymentsConnector/Block/{Control.php → Adminhtml/Settings/Xpc.php} RENAMED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * Magento
4
  *
@@ -20,13 +21,13 @@
20
  */
21
 
22
  /**
23
- * X-Payments connector control page block
24
  *
25
  * @package Cdev_XPaymentsConnector
26
  * @see ____class_see____
27
  * @since 1.0.0
28
  */
29
- class Cdev_XPaymentsConnector_Block_Control extends Mage_Adminhtml_Block_Template
30
  {
31
  /**
32
  * @var array
@@ -37,40 +38,22 @@ class Cdev_XPaymentsConnector_Block_Control extends Mage_Adminhtml_Block_Templat
37
  * Constructor
38
  *
39
  * @return void
40
- * @access public
41
- * @see ____func_see____
42
- * @since 1.0.0
43
  */
44
  public function __construct()
45
  {
46
  parent::__construct();
47
- $this->setTemplate('xpaymentsconnector/control.phtml');
48
  }
49
 
50
  /**
51
  * Prepare layout
52
  *
53
  * @return void
54
- * @access protected
55
- * @see ____func_see____
56
- * @since 1.0.0
57
  */
58
  protected function _prepareLayout()
59
  {
60
  parent::_prepareLayout();
61
 
62
- $this->setChild(
63
- 'testButton',
64
- $this->getLayout()->createBlock('adminhtml/widget_button')
65
- ->setData(
66
- array(
67
- 'type' => 'submit',
68
- 'label' => Mage::helper('adminhtml')->__('Test module'),
69
- 'class' => 'task'
70
- )
71
- )
72
- );
73
-
74
  $this->setChild(
75
  'requestButton',
76
  $this->getLayout()->createBlock('adminhtml/widget_button')
@@ -94,17 +77,12 @@ class Cdev_XPaymentsConnector_Block_Control extends Mage_Adminhtml_Block_Templat
94
  )
95
  )
96
  );
97
-
98
-
99
  }
100
 
101
  /**
102
  * Check - payment configuration is requested or not
103
  *
104
  * @return boolean
105
- * @access public
106
- * @see ____func_see____
107
- * @since 1.0.0
108
  */
109
  public function isMethodsRequested()
110
  {
@@ -115,27 +93,22 @@ class Cdev_XPaymentsConnector_Block_Control extends Mage_Adminhtml_Block_Templat
115
  * Get requested payment configurations
116
  *
117
  * @return array
118
- * @access public
119
- * @see ____func_see____
120
- * @since 1.0.0
121
  */
122
  public function getPaymentMethods()
123
  {
124
  $list = Mage::getModel('xpaymentsconnector/paymentconfiguration')->getCollection();
125
 
126
- return ($list && count($list)) ? $list : array();
127
  }
128
 
129
  /**
130
- * Check - is payment configurations is already imported into DB or not
131
  *
132
  * @return boolean
133
- * @access public
134
- * @see ____func_see____
135
- * @since 1.0.0
136
  */
137
  public function isMethodsAlreadyImported()
138
  {
 
139
  return 0 < count($this->getPaymentMethods());
140
  }
141
 
@@ -143,9 +116,6 @@ class Cdev_XPaymentsConnector_Block_Control extends Mage_Adminhtml_Block_Templat
143
  * Get system requiremenets errors list
144
  *
145
  * @return array
146
- * @access public
147
- * @see ____func_see____
148
- * @since 1.0.0
149
  */
150
  public function getRequiremenetsErrors()
151
  {
@@ -173,13 +143,10 @@ class Cdev_XPaymentsConnector_Block_Control extends Mage_Adminhtml_Block_Templat
173
  * Get module configuration errors list
174
  *
175
  * @return array
176
- * @access public
177
- * @see ____func_see____
178
- * @since 1.0.0
179
  */
180
  public function getConfigurationErrors()
181
  {
182
- if(empty($this->_configurationErrorList)){
183
  $api = Mage::getModel('xpaymentsconnector/payment_cc');
184
 
185
  $result = $api->getConfigurationErrors();
@@ -212,5 +179,71 @@ class Cdev_XPaymentsConnector_Block_Control extends Mage_Adminhtml_Block_Templat
212
  return $this->_configurationErrorList;
213
  }
214
 
215
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
+ // vim: set ts=4 sw=4 sts=4 et:
3
  /**
4
  * Magento
5
  *
21
  */
22
 
23
  /**
24
+ * X-Payments Connector settings page block
25
  *
26
  * @package Cdev_XPaymentsConnector
27
  * @see ____class_see____
28
  * @since 1.0.0
29
  */
30
+ class Cdev_XPaymentsConnector_Block_Adminhtml_Settings_Xpc extends Mage_Adminhtml_Block_Template
31
  {
32
  /**
33
  * @var array
38
  * Constructor
39
  *
40
  * @return void
 
 
 
41
  */
42
  public function __construct()
43
  {
44
  parent::__construct();
45
+ $this->setTemplate('xpaymentsconnector/settings/xpc.phtml');
46
  }
47
 
48
  /**
49
  * Prepare layout
50
  *
51
  * @return void
 
 
 
52
  */
53
  protected function _prepareLayout()
54
  {
55
  parent::_prepareLayout();
56
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  $this->setChild(
58
  'requestButton',
59
  $this->getLayout()->createBlock('adminhtml/widget_button')
77
  )
78
  )
79
  );
 
 
80
  }
81
 
82
  /**
83
  * Check - payment configuration is requested or not
84
  *
85
  * @return boolean
 
 
 
86
  */
87
  public function isMethodsRequested()
88
  {
93
  * Get requested payment configurations
94
  *
95
  * @return array
 
 
 
96
  */
97
  public function getPaymentMethods()
98
  {
99
  $list = Mage::getModel('xpaymentsconnector/paymentconfiguration')->getCollection();
100
 
101
+ return !empty($list) ? $list : array();
102
  }
103
 
104
  /**
105
+ * Check - is payment configurations are already imported into DB or not
106
  *
107
  * @return boolean
 
 
 
108
  */
109
  public function isMethodsAlreadyImported()
110
  {
111
+ // TODO: Same as isMethodsRequested()
112
  return 0 < count($this->getPaymentMethods());
113
  }
114
 
116
  * Get system requiremenets errors list
117
  *
118
  * @return array
 
 
 
119
  */
120
  public function getRequiremenetsErrors()
121
  {
143
  * Get module configuration errors list
144
  *
145
  * @return array
 
 
 
146
  */
147
  public function getConfigurationErrors()
148
  {
149
+ if (empty($this->_configurationErrorList)) {
150
  $api = Mage::getModel('xpaymentsconnector/payment_cc');
151
 
152
  $result = $api->getConfigurationErrors();
179
  return $this->_configurationErrorList;
180
  }
181
 
182
+ /**
183
+ * Get System/X-Payments connector link
184
+ *
185
+ * @return string
186
+ */
187
+ public function getSystemConfigXpcUrl()
188
+ {
189
+ return $this->getUrl('adminhtml/system_config/edit/section/xpaymentsconnector/');
190
+ }
191
+
192
+ /**
193
+ * Get System/X-Payments connector link
194
+ *
195
+ * @return string
196
+ */
197
+ public function getTrialDemoUrl()
198
+ {
199
+ return 'http://www.x-payments.com/trial-demo.html?utm_source=mage_shop&utm_medium=link&utm_campaign=mage_shop_link';
200
+ }
201
+
202
+ /**
203
+ * Get User manual link
204
+ *
205
+ * @return string
206
+ */
207
+ public function getUserManualUrl()
208
+ {
209
+ return 'http://help.x-cart.com/index.php?title=X-Payments:User_manual#Online_Stores';
210
+ }
211
+
212
+ /**
213
+ * Get video link
214
+ *
215
+ * @return string
216
+ */
217
+ public function getVideoUrl()
218
+ {
219
+ return 'https://www.youtube.com/embed/2VRR0JW23qc';
220
+ }
221
 
222
+ /**
223
+ * Get Contact Us link
224
+ *
225
+ * @return string
226
+ */
227
+ public function getContactUsUrl()
228
+ {
229
+ return 'http://www.x-payments.com/contact-us.html?utm_source=mage_shop&utm_medium=link&utm_campaign=mage_shop_link';
230
+ }
231
+
232
+
233
+ /**
234
+ * Get description
235
+ *
236
+ * @return string
237
+ */
238
+ public function getDescription()
239
+ {
240
+ $description = 'Give your customers – and yourself – peace of mind with this payment processing module
241
+ that guarantees compliance with PCI security mandates, significantly reduces the risk of
242
+ data breaches and ensures you won’t be hit with a fine of up to $500,000 for non-compliance.
243
+ Safely and conveniently store customers credit card information to use for new orders, reorders
244
+ or recurring payments.';
245
+
246
+ return $this->__($description);
247
+ }
248
+
249
+ }
app/code/community/Cdev/XPaymentsConnector/Block/Checkout/Onepage/Orderdetail.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * Magento
4
  *
@@ -58,7 +59,9 @@ class Cdev_XPaymentsConnector_Block_Checkout_Onepage_Orderdetail extends Mage_Co
58
 
59
  $product = $recQuoteItem->getProduct();
60
  $productAdditionalInfo = unserialize($product->getCustomOption('info_buyRequest')->getValue());
61
- $deferredDateStamp = strtotime($productAdditionalInfo['recurring_profile_start_datetime']);
 
 
62
  if($deferredDateStamp){
63
  $initialFeeMessage = $this->__(" (initial fee only, 1st recurring fee will be charged on %s)",date('d-M-Y',$deferredDateStamp));
64
  $rowTotal = $recQuoteItem->getXpRecurringInitialFee() + $recQuoteItem->getInitialfeeTaxAmount();
1
  <?php
2
+ // vim: set ts=4 sw=4 sts=4 et:
3
  /**
4
  * Magento
5
  *
59
 
60
  $product = $recQuoteItem->getProduct();
61
  $productAdditionalInfo = unserialize($product->getCustomOption('info_buyRequest')->getValue());
62
+ $deferredDateStamp = isset($productAdditionalInfo['recurring_profile_start_datetime'])
63
+ ? strtotime($productAdditionalInfo['recurring_profile_start_datetime'])
64
+ : false;
65
  if($deferredDateStamp){
66
  $initialFeeMessage = $this->__(" (initial fee only, 1st recurring fee will be charged on %s)",date('d-M-Y',$deferredDateStamp));
67
  $rowTotal = $recQuoteItem->getXpRecurringInitialFee() + $recQuoteItem->getInitialfeeTaxAmount();
app/code/community/Cdev/XPaymentsConnector/Block/Checkout/Onepage/Success.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * Magento
4
  *
@@ -87,4 +88,23 @@ class Cdev_XPaymentsConnector_Block_Checkout_Onepage_Success extends Mage_Checko
87
  }
88
  }
89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  }
1
  <?php
2
+ // vim: set ts=4 sw=4 sts=4 et:
3
  /**
4
  * Magento
5
  *
88
  }
89
  }
90
 
91
+ /**
92
+ * Get recurring profiles
93
+ *
94
+ * @return array
95
+ */
96
+ public function getRecurringProfiles()
97
+ {
98
+ $order = Mage::getModel('sales/order')->load($this->getData('order_entity_id'));
99
+
100
+ $profile = Mage::helper('xpaymentsconnector')->getOrderRecurringProfile($order);
101
+
102
+ if ($profile) {
103
+ $profile = array($profile);
104
+ } else {
105
+ $profile = false;
106
+ }
107
+
108
+ return $profile;
109
+ }
110
  }
app/code/community/Cdev/XPaymentsConnector/Helper/Data.php CHANGED
@@ -34,7 +34,12 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
34
  const WEEK_TIME_STAMP = 604800;
35
  const SEMI_MONTH_TIME_STAMP = 1209600;
36
 
37
- const STATE_XPAYMENTS_PENDING_PAYMENT = 'xp_pending_payment';
 
 
 
 
 
38
 
39
  const XPAYMENTS_LOG_FILE = 'xpayments.log';
40
  const RECURRING_ORDER_TYPE = 'recurring';
@@ -323,15 +328,17 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
323
  */
324
  public function setPrepareOrderType()
325
  {
326
- $xpaymentPrepareOrder = Mage::getSingleton('checkout/session')->getData('xpayment_prepare_order');
327
- $result = $this->checkIssetRecurringOrder();
328
- if ($result['isset']) {
329
- $xpaymentPrepareOrder['type'] = self::RECURRING_ORDER_TYPE;
 
 
330
  } else {
331
- $xpaymentPrepareOrder['type'] = self::SIMPLE_ORDER_TYPE;
332
  }
333
 
334
- Mage::getSingleton('checkout/session')->setData('xpayment_prepare_order', $xpaymentPrepareOrder);
335
  }
336
 
337
  /**
@@ -701,47 +708,35 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
701
  $recurringProfile->save();
702
  }
703
 
704
- public function checkIssetRecurringOrder()
 
 
 
 
 
 
 
705
  {
706
- $checkoutSession = Mage::getSingleton('checkout/session');
707
- $quoteItems = $checkoutSession->getQuote()->getAllItems();
708
- $result = array();
709
 
710
- foreach ($quoteItems as $quoteItem) {
711
- if ($quoteItem) {
712
- $product = $quoteItem->getProduct();
713
- $issetRecurringOreder = (bool)$product->getIsRecurring();
714
- if ($issetRecurringOreder) {
715
- $result['isset'] = $issetRecurringOreder;
716
- $result['quote_item'] = $quoteItem;
717
- return $result;
718
- }
719
- }
720
  }
721
- $result['isset'] = false;
722
-
723
- return $result;
724
- }
725
 
726
- /**
727
- * @return bool
728
- */
729
- public function checkIssetSimpleOrder()
730
- {
731
- $checkoutSession = Mage::getSingleton('checkout/session');
732
- $quoteItems = $checkoutSession->getQuote()->getAllItems();
733
 
734
- foreach ($quoteItems as $quoteItem) {
735
- if ($quoteItem) {
736
- $product = $quoteItem->getProduct();
737
- $issetRecurringOreder = (bool)$product->getIsRecurring();
738
- if (!$issetRecurringOreder) {
739
- return true;
740
- }
 
741
  }
742
  }
743
 
744
- return false;
745
  }
746
 
747
  /**
@@ -754,7 +749,9 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
754
 
755
  $orderItemInfo = $recurringProfile->getData('order_item_info');
756
  $infoBuyRequest = unserialize($orderItemInfo['info_buyRequest']);
757
- $startDateTime = $infoBuyRequest['recurring_profile_start_datetime'];
 
 
758
  $xpaymentCCModel = Mage::getModel('xpaymentsconnector/payment_cc');
759
 
760
  if (!empty($startDateTime)) {
@@ -905,7 +902,9 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
905
  public function checkStartDateDataByProduct($product,$quoteItem = false)
906
  {
907
  $productAdditionalInfo = unserialize($product->getCustomOption('info_buyRequest')->getValue());
908
- $dateTimeStamp = strtotime($productAdditionalInfo['recurring_profile_start_datetime']);
 
 
909
 
910
  if ($dateTimeStamp) {
911
  $userSetTime = new Zend_Date($productAdditionalInfo['recurring_profile_start_datetime']);
@@ -963,20 +962,6 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
963
  Mage::getSingleton('checkout/session')->addNotice($this->getFailureCheckoutNoticeHelper());
964
  }
965
 
966
- public function setRecurringProductDiscount()
967
- {
968
- $quote = Mage::getSingleton('checkout/session')->getQuote();
969
- $items = $quote->getAllVisibleItems();
970
- foreach ($items as $item) {
971
- if($item->getIsNominal()){
972
- $discount = $item->getDiscountAmount();
973
- $profile = $item->getProduct()->getRecurringProfile();
974
- $profile['discount_amount'] = $discount;
975
- $item->getProduct()->setRecurringProfile($profile)->save();
976
- }
977
- }
978
- }
979
-
980
  /**
981
  * This function fixed magento bug. Magento can't create user
982
  * during checkout with recurring products.
@@ -1403,31 +1388,26 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
1403
  *
1404
  * @return void
1405
  */
1406
- protected function prepareRequringItems(Mage_Sales_Model_Quote $quote, &$result)
1407
  {
1408
- $issetRecurringProduct = $this->checkIssetRecurringOrder();
1409
-
1410
- $quoteItem = $issetRecurringProduct['quote_item'];
1411
- $product = $quoteItem->getProduct();
1412
-
1413
- $item = $quote->getItemByProduct($product);
1414
-
1415
  $recurringProfile = $product->getRecurringProfile();
1416
 
1417
  $startDateParams = $this->checkStartDateDataByProduct($product, $item);
1418
  $startDateParams = $startDateParams[$product->getId()];
1419
 
1420
- $shipping = $issetRecurringProduct['quote_item']->getData('shipping_amount');
1421
- $discount = abs($issetRecurringProduct['quote_item']->getData('discount_amount'));
1422
 
1423
- $quantity = $quoteItem->getQty();
1424
 
1425
  if ($startDateParams['success']) {
1426
 
1427
  $minimalPayment = $startDateParams['minimal_payment_amount'];
1428
 
1429
  $tax = !empty($recurringProfile['init_amount'])
1430
- ? $quoteItem->getData('initialfee_tax_amount')
1431
  : 0;
1432
 
1433
  $totalCost = $minimalPayment + $tax + $shipping - $discount;
@@ -1436,15 +1416,15 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
1436
 
1437
  $minimalPayment = 0;
1438
 
1439
- $tax = $quoteItem->getData('initialfee_tax_amount') + $quoteItem->getData('tax_amount');
1440
 
1441
- $totalCost = $quoteItem->getData('nominal_row_total');
1442
  }
1443
 
1444
  $recurringPrice = $product->getPrice();
1445
 
1446
  if (!empty($recurringProfile['init_amount'])) {
1447
- $recurringPrice += $quoteItem->getXpRecurringInitialFee() / $quantity;
1448
  }
1449
 
1450
  $price = $minimalPayment
@@ -1458,7 +1438,8 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
1458
  'quantity' => intval($quantity),
1459
  );
1460
 
1461
- $result['totalCost'] = $this->preparePrice($totalCost);
 
1462
  $result['shippingCost'] = $this->preparePrice($shipping);
1463
  $result['taxCost'] = $this->preparePrice($tax);
1464
  $result['discount'] = $this->preparePrice($discount);
@@ -1474,11 +1455,9 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
1474
  */
1475
  protected function prepareItems(Mage_Sales_Model_Quote $quote, &$result)
1476
  {
1477
- $issetSimpleProducts = $this->checkIssetSimpleOrder();
1478
- $issetRecurringProduct = $this->checkIssetRecurringOrder();
1479
-
1480
- if ($issetRecurringProduct['isset'] && !$issetSimpleProducts) {
1481
- $this->prepareRequringItems($quote, $result);
1482
  } else {
1483
  $this->prepareSimpleItems($quote, $result);
1484
  }
@@ -1633,6 +1612,40 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
1633
  return $url;
1634
  }
1635
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1636
  /**
1637
  * Get address data saved at checkout
1638
  *
@@ -1656,6 +1669,17 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
1656
 
1657
  if (isset($data[$type])) {
1658
 
 
 
 
 
 
 
 
 
 
 
 
1659
  // Addrress data from checkout
1660
  $result += array_filter($data[$type]);
1661
  }
@@ -1664,110 +1688,34 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
1664
  }
1665
 
1666
  /**
1667
- * Save checkout data
1668
- *
1669
- * @param Mage_Sales_Model_Quote $quote
1670
- * @param array $data Some checkout data
1671
- *
1672
- * @return void
1673
- */
1674
- public function saveCheckoutData($quote, $data)
1675
- {
1676
- $this->writeLog('Save checkout data for Quote #' . $quote->getEntityId(), $data);
1677
-
1678
- $data = serialize($data);
1679
- $quote->setData(self::CHECKOUT_DATA, $data);
1680
- $quote->save();
1681
- }
1682
-
1683
- /**
1684
- * Load data saved at checkou
1685
  *
1686
  * @param Mage_Sales_Model_Quote $quote
1687
- *
1688
- * @return array
1689
- */
1690
- public function loadCheckoutData(Mage_Sales_Model_Quote $quote)
1691
- {
1692
- return unserialize($quote->getData(self::CHECKOUT_DATA));
1693
- }
1694
-
1695
- /**
1696
- * Save some temporary X-Payments data to Quote
1697
- *
1698
- * @param Mage_Sales_Model_Quote $quote
1699
- * @param array $data Some data
1700
  *
1701
- * @return void
1702
  */
1703
- public function saveQuoteXpcData(Mage_Sales_Model_Quote $quote, $data = array())
1704
  {
1705
- $data = serialize($data);
1706
- $quote->setData(self::XPC_DATA, $data);
1707
- $quote->save();
1708
- }
1709
 
1710
- /**
1711
- * Clear temporary X-Payments data from Quote (just a wrapper)
1712
- *
1713
- * @param Mage_Sales_Model_Quote $quote
1714
- *
1715
- * @return void
1716
- */
1717
- public function clearQuoteXpcData(Mage_Sales_Model_Quote $quote)
1718
- {
1719
- return $this->saveQuoteXpcData($quote);
1720
- }
1721
-
1722
- /**
1723
- * Append some temporary X-Payments data to Quote
1724
- *
1725
- * @param Mage_Sales_Model_Quote $quote
1726
- * @param array $appendData Some data to append
1727
- *
1728
- * @return void
1729
- */
1730
- public function appendQuoteXpcData(Mage_Sales_Model_Quote $quote, $appendData = array())
1731
- {
1732
- $data = $this->loadQuoteXpcData($quote);
1733
-
1734
- $data += $appendData;
1735
-
1736
- $this->saveQuoteXpcData($quote, $data);
1737
- }
1738
-
1739
- /**
1740
- * Load temporary X-Payments data from Quote
1741
- *
1742
- * @param Mage_Sales_Model_Quote $quote
1743
- *
1744
- * @return array
1745
- */
1746
- public function loadQuoteXpcData(Mage_Sales_Model_Quote $quote)
1747
- {
1748
- $data = unserialize($quote->getData(self::XPC_DATA));
1749
-
1750
- if (!is_array($data)) {
1751
- $data = array();
1752
  }
1753
 
1754
- return $data;
1755
- }
 
 
 
1756
 
1757
- /**
1758
- * Get token from quote
1759
- *
1760
- * @param Mage_Sales_Model_Quote $quote
1761
- *
1762
- * @return string or false
1763
- */
1764
- public function getQuoteXpcDataToken(Mage_Sales_Model_Quote $quote)
1765
- {
1766
- $data = $this->loadQuoteXpcData($quote);
1767
 
1768
- return !empty($data['token'])
1769
- ? $data['token']
1770
- : false;
1771
  }
1772
 
1773
  /**
@@ -1780,7 +1728,7 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
1780
  protected function processCheckoutData(Mage_Sales_Model_Quote $quote)
1781
  {
1782
  // Grab data saved at checkout
1783
- $data = $this->loadCheckoutData($quote);
1784
 
1785
  // Add billing address data from checkout
1786
  $quote->getBillingAddress()->addData($this->getCheckoutAddressData($data, 'billing'));
@@ -1842,36 +1790,67 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
1842
  }
1843
 
1844
  /**
1845
- * Prepare quote for customer registration and customer order submit
 
 
1846
  *
1847
- * @return Mage_Checkout_Model_Type_Onepage
1848
  */
1849
  protected function createNewCustomer(Mage_Sales_Model_Quote $quote)
1850
  {
1851
- $billing = $quote->getBillingAddress();
1852
- $shipping = $quote->isVirtual() ? null : $quote->getShippingAddress();
 
 
 
1853
 
1854
- //$customer = Mage::getModel('customer/customer');
1855
  $customer = $quote->getCustomer();
1856
- /* @var $customer Mage_Customer_Model_Customer */
1857
  $customerBilling = $billing->exportCustomerAddress();
1858
  $customer->addAddress($customerBilling);
1859
  $billing->setCustomerAddress($customerBilling);
1860
  $customerBilling->setIsDefaultBilling(true);
1861
- if ($shipping && !$shipping->getSameAsBilling()) {
 
 
 
 
 
1862
  $customerShipping = $shipping->exportCustomerAddress();
1863
  $customer->addAddress($customerShipping);
1864
  $shipping->setCustomerAddress($customerShipping);
1865
  $customerShipping->setIsDefaultShipping(true);
 
1866
  } else {
 
1867
  $customerBilling->setIsDefaultShipping(true);
1868
  }
1869
 
1870
  Mage::helper('core')->copyFieldset('checkout_onepage_quote', 'to_customer', $quote, $customer);
1871
- $customer->setPassword($customer->decryptPassword($quote->getPasswordHash()));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1872
  $quote->setCustomer($customer)
1873
  ->setCustomerId(true);
1874
 
 
 
 
 
 
1875
  return $customer;
1876
  }
1877
 
@@ -1890,7 +1869,7 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
1890
  if ($this->checkOscModuleEnabled()) {
1891
 
1892
  // For One Step Checkout module
1893
- $data = $this->loadCheckoutData($quote);
1894
 
1895
  $result = isset($data['create_account'])
1896
  && (bool)$data['create_account'];
@@ -1898,7 +1877,7 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
1898
  } elseif ($this->checkFirecheckoutModuleEnabled()) {
1899
 
1900
  // For Firecheckout module
1901
- $data = $this->loadCheckoutData($quote);
1902
 
1903
  $result = isset($data['billing']['register_account'])
1904
  && (bool)$data['billing']['register_account'];
@@ -1933,11 +1912,12 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
1933
 
1934
  if ($this->isCreateNewCustomer($quote)) {
1935
 
1936
- // Prepare data for customer who's registered at checkout
1937
- $customer = $this->createNewCustomer($quote);
1938
- $customer->save();
1939
 
1940
- $this->appendQuoteXpcData($quote, array('address_saved' => true));
 
 
1941
  }
1942
 
1943
  // Set payment method (maybe not necessary. Just in case)
@@ -1949,37 +1929,102 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
1949
 
1950
  $order = $service->getOrder();
1951
 
1952
- $quote->setIsActive(false)->save();
1953
 
1954
- $cardData = $quote->getData(self::XPC_DATA);
1955
- $order->setData(self::XPC_DATA, $cardData);
1956
 
1957
- $cardData = unserialize($cardData);
 
 
1958
 
1959
- $order->setData('xpc_txnid', $cardData['txnId']);
1960
 
1961
- $order->save();
 
 
 
 
 
 
 
 
 
 
1962
 
1963
  $refId = $order->getIncrementId();
1964
 
1965
- $this->writeLog('Placed order #' . $refId, $cardData);
1966
 
1967
  } catch (Exception $e) {
1968
 
1969
  $this->writeLog('Unable to create order: ' . $e->getMessage(), $e->getTraceAsString());
1970
 
1971
  // Save error message in quote
1972
- $this->appendQuoteXpcData(
1973
- $quote,
1974
- array(
1975
- 'xpc_message' => $e->getMessage(),
1976
- )
1977
- );
1978
  }
1979
 
1980
  return $refId;
1981
  }
1982
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1983
  /**
1984
  * Just a wrapper to omit sid and secure params
1985
  *
@@ -2070,7 +2115,7 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
2070
  $quote = Mage::getSingleton('checkout/session')->getQuote();
2071
  }
2072
 
2073
- $this->clearQuoteXpcData($quote);
2074
  }
2075
 
2076
  /**
@@ -2091,12 +2136,13 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
2091
  /**
2092
  * Write log
2093
  *
2094
- * @param string $title Log title
2095
  * @param mixed $data Data to log
 
2096
  *
2097
  * @return void
2098
  */
2099
- public function writeLog($title, $data = '')
2100
  {
2101
  if (!is_string($data)) {
2102
  $data = var_export($data, true);
@@ -2105,9 +2151,13 @@ class Cdev_XPaymentsConnector_Helper_Data extends Mage_Payment_Helper_Data
2105
  $message = PHP_EOL . date('Y-m-d H:i:s') . PHP_EOL
2106
  . $title . PHP_EOL
2107
  . $data . PHP_EOL
2108
- . Mage::helper('core/url')->getCurrentUrl() . PHP_EOL
2109
- . '--------------------------' . PHP_EOL
2110
- . PHP_EOL;
 
 
 
 
2111
 
2112
  Mage::log($message, null, self::XPAYMENTS_LOG_FILE, true);
2113
  }
34
  const WEEK_TIME_STAMP = 604800;
35
  const SEMI_MONTH_TIME_STAMP = 1209600;
36
 
37
+ /**
38
+ * Order statuses. Constant values are left for the backwards compatibility
39
+ */
40
+ const STATUS_AUTHORIZED = 'xp_pending_payment';
41
+ const STATUS_CHARGED = 'processing';
42
+ const STATUS_FRAUD = 'fraud';
43
 
44
  const XPAYMENTS_LOG_FILE = 'xpayments.log';
45
  const RECURRING_ORDER_TYPE = 'recurring';
328
  */
329
  public function setPrepareOrderType()
330
  {
331
+ // TODO: Remove it? Or rework.
332
+
333
+ $data = Mage::getSingleton('checkout/session')->getData('xpayment_prepare_order');
334
+
335
+ if ($this->getRecurringQuoteItem()) {
336
+ $data['type'] = self::RECURRING_ORDER_TYPE;
337
  } else {
338
+ $data['type'] = self::SIMPLE_ORDER_TYPE;
339
  }
340
 
341
+ Mage::getSingleton('checkout/session')->setData('xpayment_prepare_order', $data);
342
  }
343
 
344
  /**
708
  $recurringProfile->save();
709
  }
710
 
711
+ /**
712
+ * Get quote item for the recurring product from the current checkout session. If any.
713
+ *
714
+ * @param Mage_Sales_model_Quote $quote Quote. If omitted use quote from checkout session
715
+ *
716
+ * @return Mage_Sales_Model_Quote_Item or false
717
+ */
718
+ public function getRecurringQuoteItem($quote = false)
719
  {
720
+ $result = false;
 
 
721
 
722
+ if (!$quote) {
723
+ $quote = Mage::getSingleton('checkout/session')->getQuote();
 
 
 
 
 
 
 
 
724
  }
 
 
 
 
725
 
726
+ foreach ($quote->getAllItems() as $item) {
 
 
 
 
 
 
727
 
728
+ if (
729
+ $item
730
+ && $item->getProduct()
731
+ && $item->getProduct()->getIsRecurring()
732
+ ) {
733
+
734
+ $result = $item;
735
+ break;
736
  }
737
  }
738
 
739
+ return $result;
740
  }
741
 
742
  /**
749
 
750
  $orderItemInfo = $recurringProfile->getData('order_item_info');
751
  $infoBuyRequest = unserialize($orderItemInfo['info_buyRequest']);
752
+ $startDateTime = isset($infoBuyRequest['recurring_profile_start_datetime'])
753
+ ? $infoBuyRequest['recurring_profile_start_datetime']
754
+ : false;
755
  $xpaymentCCModel = Mage::getModel('xpaymentsconnector/payment_cc');
756
 
757
  if (!empty($startDateTime)) {
902
  public function checkStartDateDataByProduct($product,$quoteItem = false)
903
  {
904
  $productAdditionalInfo = unserialize($product->getCustomOption('info_buyRequest')->getValue());
905
+ $dateTimeStamp = isset($productAdditionalInfo['recurring_profile_start_datetime'])
906
+ ? strtotime($productAdditionalInfo['recurring_profile_start_datetime'])
907
+ : false;
908
 
909
  if ($dateTimeStamp) {
910
  $userSetTime = new Zend_Date($productAdditionalInfo['recurring_profile_start_datetime']);
962
  Mage::getSingleton('checkout/session')->addNotice($this->getFailureCheckoutNoticeHelper());
963
  }
964
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
965
  /**
966
  * This function fixed magento bug. Magento can't create user
967
  * during checkout with recurring products.
1388
  *
1389
  * @return void
1390
  */
1391
+ protected function prepareRecurringItems(Mage_Sales_Model_Quote $quote, &$result)
1392
  {
1393
+ $item = $this->getRecurringQuoteItem($quote);
1394
+ $product = $item->getProduct();
 
 
 
 
 
1395
  $recurringProfile = $product->getRecurringProfile();
1396
 
1397
  $startDateParams = $this->checkStartDateDataByProduct($product, $item);
1398
  $startDateParams = $startDateParams[$product->getId()];
1399
 
1400
+ $shipping = $item->getData('shipping_amount');
1401
+ $discount = abs($item->getData('discount_amount'));
1402
 
1403
+ $quantity = $item->getQty();
1404
 
1405
  if ($startDateParams['success']) {
1406
 
1407
  $minimalPayment = $startDateParams['minimal_payment_amount'];
1408
 
1409
  $tax = !empty($recurringProfile['init_amount'])
1410
+ ? $item->getData('initialfee_tax_amount')
1411
  : 0;
1412
 
1413
  $totalCost = $minimalPayment + $tax + $shipping - $discount;
1416
 
1417
  $minimalPayment = 0;
1418
 
1419
+ $tax = $item->getData('initialfee_tax_amount') + $item->getData('tax_amount');
1420
 
1421
+ $totalCost = $item->getData('nominal_row_total');
1422
  }
1423
 
1424
  $recurringPrice = $product->getPrice();
1425
 
1426
  if (!empty($recurringProfile['init_amount'])) {
1427
+ $recurringPrice += $item->getXpRecurringInitialFee() / $quantity;
1428
  }
1429
 
1430
  $price = $minimalPayment
1438
  'quantity' => intval($quantity),
1439
  );
1440
 
1441
+
1442
+ $result['totalCost'] = $this->preparePrice($price);
1443
  $result['shippingCost'] = $this->preparePrice($shipping);
1444
  $result['taxCost'] = $this->preparePrice($tax);
1445
  $result['discount'] = $this->preparePrice($discount);
1455
  */
1456
  protected function prepareItems(Mage_Sales_Model_Quote $quote, &$result)
1457
  {
1458
+ if ($this->getRecurringQuoteItem($quote)) {
1459
+ // Actually, only one item per order
1460
+ $this->prepareRecurringItems($quote, $result);
 
 
1461
  } else {
1462
  $this->prepareSimpleItems($quote, $result);
1463
  }
1612
  return $url;
1613
  }
1614
 
1615
+ /**
1616
+ * Get error message from X-Payments callback or detailed info data
1617
+ *
1618
+ * @param array $data Callback data
1619
+ *
1620
+ * @return string
1621
+ */
1622
+ public function getResultMessage($data)
1623
+ {
1624
+ $message = array();
1625
+
1626
+ // Regular message from X-Payments
1627
+ if (!empty($data['message'])) {
1628
+ $message[] = $data['message'];
1629
+ }
1630
+
1631
+ if (isset($data['advinfo'])) {
1632
+
1633
+ // Message from payment gateway
1634
+ if (isset($data['advinfo']['message'])) {
1635
+ $message[] = $data['advinfo']['message'];
1636
+ }
1637
+
1638
+ // Message from 3-D Secure
1639
+ if (isset($data['advinfo']['s3d_message'])) {
1640
+ $message[] = $data['advinfo']['s3d_message'];
1641
+ }
1642
+ }
1643
+
1644
+ $message = array_unique($message);
1645
+
1646
+ return implode("\n", $message);
1647
+ }
1648
+
1649
  /**
1650
  * Get address data saved at checkout
1651
  *
1669
 
1670
  if (isset($data[$type])) {
1671
 
1672
+ if (
1673
+ isset($data[$type]['street'])
1674
+ && is_array($data[$type]['street'])
1675
+ ) {
1676
+
1677
+ // Prevent array to string conversion notice.
1678
+ // Necessary for:
1679
+ // - Registration at checkout for OSC module
1680
+ $data[$type]['street'] = implode(PHP_EOL, $data[$type]['street']);
1681
+ }
1682
+
1683
  // Addrress data from checkout
1684
  $result += array_filter($data[$type]);
1685
  }
1688
  }
1689
 
1690
  /**
1691
+ * Get Quote xpc data (just a wrapper)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1692
  *
1693
  * @param Mage_Sales_Model_Quote $quote
 
 
 
 
 
 
 
 
 
 
 
 
 
1694
  *
1695
+ * @return Cdev_XPaymentsConnector_Model_Quote_XpcData
1696
  */
1697
+ public function getQuoteXpcData(Mage_Sales_Model_Quote $quote, $methodCode = false)
1698
  {
1699
+ $quoteId = $quote->getEntityId();
 
 
 
1700
 
1701
+ if (!$methodCode) {
1702
+ $methodCode = 'xpaymentsconnector/payment_cc';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1703
  }
1704
 
1705
+ $model = Mage::getModel('xpaymentsconnector/quote_xpcdata')
1706
+ ->getCollection()
1707
+ ->addFieldToFilter('quote_id', $quoteId)
1708
+ ->addFieldToFilter('payment_method_code', $methodCode)
1709
+ ->getFirstItem();
1710
 
1711
+ if (!$model->getQuoteId()) {
1712
+ // Fill "primary key" for the new entity
1713
+ $model->setQuoteId($quoteId)
1714
+ ->setPaymentMethodCode($methodCode)
1715
+ ->save();
1716
+ }
 
 
 
 
1717
 
1718
+ return $model;
 
 
1719
  }
1720
 
1721
  /**
1728
  protected function processCheckoutData(Mage_Sales_Model_Quote $quote)
1729
  {
1730
  // Grab data saved at checkout
1731
+ $data = unserialize($this->getQuoteXpcData($quote)->getData('checkout_data'));
1732
 
1733
  // Add billing address data from checkout
1734
  $quote->getBillingAddress()->addData($this->getCheckoutAddressData($data, 'billing'));
1790
  }
1791
 
1792
  /**
1793
+ * Create customer and assign it to the quote
1794
+ *
1795
+ * @param Mage_Sales_Model_Quote $quote
1796
  *
1797
+ * @return Mage_Customer_Model_Customer
1798
  */
1799
  protected function createNewCustomer(Mage_Sales_Model_Quote $quote)
1800
  {
1801
+ $billing = $quote->getBillingAddress();
1802
+
1803
+ $shipping = $quote->isVirtual()
1804
+ ? null
1805
+ : $quote->getShippingAddress();
1806
 
 
1807
  $customer = $quote->getCustomer();
1808
+
1809
  $customerBilling = $billing->exportCustomerAddress();
1810
  $customer->addAddress($customerBilling);
1811
  $billing->setCustomerAddress($customerBilling);
1812
  $customerBilling->setIsDefaultBilling(true);
1813
+
1814
+ if (
1815
+ $shipping
1816
+ && !$shipping->getSameAsBilling()
1817
+ ) {
1818
+
1819
  $customerShipping = $shipping->exportCustomerAddress();
1820
  $customer->addAddress($customerShipping);
1821
  $shipping->setCustomerAddress($customerShipping);
1822
  $customerShipping->setIsDefaultShipping(true);
1823
+
1824
  } else {
1825
+
1826
  $customerBilling->setIsDefaultShipping(true);
1827
  }
1828
 
1829
  Mage::helper('core')->copyFieldset('checkout_onepage_quote', 'to_customer', $quote, $customer);
1830
+
1831
+ $password = '';
1832
+
1833
+ if ($quote->getPasswordHash()) {
1834
+ // One page checkout
1835
+ $password = $customer->decryptPassword($quote->getPasswordHash());
1836
+ } else {
1837
+ $data = unserialize($this->getQuoteXpcData($quote)->getData('checkout_data'));
1838
+ if (!empty($data['billing']['customer_password'])) {
1839
+ // One step checkout
1840
+ $password = $data['billing']['customer_password'];
1841
+ }
1842
+ }
1843
+
1844
+ $customer->setPassword($password);
1845
+
1846
  $quote->setCustomer($customer)
1847
  ->setCustomerId(true);
1848
 
1849
+ $quote->save();
1850
+ $customer->save();
1851
+
1852
+ $this->writeLog('Created new customer', $customer->getId());
1853
+
1854
  return $customer;
1855
  }
1856
 
1869
  if ($this->checkOscModuleEnabled()) {
1870
 
1871
  // For One Step Checkout module
1872
+ $data = unserialize($this->getQuoteXpcData($quote)->getData('checkout_data'));
1873
 
1874
  $result = isset($data['create_account'])
1875
  && (bool)$data['create_account'];
1877
  } elseif ($this->checkFirecheckoutModuleEnabled()) {
1878
 
1879
  // For Firecheckout module
1880
+ $data = unserialize($this->getQuoteXpcData($quote)->getData('checkout_data'));
1881
 
1882
  $result = isset($data['billing']['register_account'])
1883
  && (bool)$data['billing']['register_account'];
1912
 
1913
  if ($this->isCreateNewCustomer($quote)) {
1914
 
1915
+ // Create customer's profile who's registered at checkout
1916
+ $this->createNewCustomer($quote);
 
1917
 
1918
+ $this->getQuoteXpcData($quote)
1919
+ ->setData('address_saved', true)
1920
+ ->save();
1921
  }
1922
 
1923
  // Set payment method (maybe not necessary. Just in case)
1929
 
1930
  $order = $service->getOrder();
1931
 
1932
+ if (!$order) {
1933
 
1934
+ $orderId = $this->getQuoteXpcData($quote)->getData('recurring_order_id');
 
1935
 
1936
+ if ($orderId) {
1937
+ $order = Mage::getModel('sales/order')->load($orderId);
1938
+ }
1939
 
1940
+ if (!$order) {
1941
 
1942
+ // Cannot proceed further without an order anyway
1943
+ throw new Exception('Quote was not converted to order');
1944
+ }
1945
+ }
1946
+
1947
+ $quote->setIsActive(false)->save();
1948
+
1949
+ $xpcData = $this->getQuoteXpcData($quote)->getData();
1950
+ $order->setData(self::XPC_DATA, serialize($xpcData));
1951
+
1952
+ $order->setData('xpc_txnid', $xpcData['txn_id'])->save();
1953
 
1954
  $refId = $order->getIncrementId();
1955
 
1956
+ $this->writeLog('Placed order #' . $refId, $xpcData);
1957
 
1958
  } catch (Exception $e) {
1959
 
1960
  $this->writeLog('Unable to create order: ' . $e->getMessage(), $e->getTraceAsString());
1961
 
1962
  // Save error message in quote
1963
+ $this->getQuoteXpcData($quote)
1964
+ ->setData('xpc_message', $e->getMessage())
1965
+ ->save();
 
 
 
1966
  }
1967
 
1968
  return $refId;
1969
  }
1970
 
1971
+ /**
1972
+ * Create invoice for the charged payment
1973
+ *
1974
+ * @param Mage_Sales_Model_Order $order
1975
+ *
1976
+ * @return void
1977
+ */
1978
+ public function processCreateInvoice(Mage_Sales_Model_Order $order)
1979
+ {
1980
+ if (
1981
+ $order->getStatus() == self::STATUS_CHARGED
1982
+ && $order->canInvoice()
1983
+ ) {
1984
+
1985
+ $invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice();
1986
+ $invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE);
1987
+
1988
+ $invoice->register();
1989
+
1990
+ $transaction = Mage::getModel('core/resource_transaction')
1991
+ ->addObject($invoice)
1992
+ ->addObject($invoice->getOrder());
1993
+
1994
+ $transaction->save();
1995
+ }
1996
+ }
1997
+
1998
+ /**
1999
+ * Get recurring profile for order
2000
+ *
2001
+ * @param Mage_Sales_Model_Order $order Order
2002
+ *
2003
+ * @return Mage_Sales_Model_Recurring_Profile or false
2004
+ */
2005
+ public function getOrderRecurringProfile(Mage_Sales_Model_Order $order)
2006
+ {
2007
+ $txnId = $order->getData('xpc_txnid');
2008
+
2009
+ try {
2010
+
2011
+ $profile = Mage::getModel('sales/recurring_profile')->load($txnId, 'reference_id');
2012
+
2013
+ if (!$profile->isValid()) {
2014
+
2015
+ $profile = false;
2016
+ }
2017
+
2018
+ } catch (Exception $e) {
2019
+
2020
+ $this->writeLog('Unable to load recurring profile for reference ' . $txnId, $e->getMessage());
2021
+
2022
+ $profile = false;
2023
+ }
2024
+
2025
+ return $profile;
2026
+ }
2027
+
2028
  /**
2029
  * Just a wrapper to omit sid and secure params
2030
  *
2115
  $quote = Mage::getSingleton('checkout/session')->getQuote();
2116
  }
2117
 
2118
+ $this->getQuoteXpcData($quote)->clear();
2119
  }
2120
 
2121
  /**
2136
  /**
2137
  * Write log
2138
  *
2139
+ * @param string $title Log title
2140
  * @param mixed $data Data to log
2141
+ * @param bool $trace Include backtrace or not
2142
  *
2143
  * @return void
2144
  */
2145
+ public function writeLog($title, $data = '', $trace = false)
2146
  {
2147
  if (!is_string($data)) {
2148
  $data = var_export($data, true);
2151
  $message = PHP_EOL . date('Y-m-d H:i:s') . PHP_EOL
2152
  . $title . PHP_EOL
2153
  . $data . PHP_EOL
2154
+ . Mage::helper('core/url')->getCurrentUrl() . PHP_EOL;
2155
+
2156
+ if ($trace) {
2157
+ $message .= '--------------------------' . PHP_EOL
2158
+ . Varien_Debug::backtrace(true, false, false)
2159
+ . PHP_EOL;
2160
+ }
2161
 
2162
  Mage::log($message, null, self::XPAYMENTS_LOG_FILE, true);
2163
  }
app/code/community/Cdev/XPaymentsConnector/Model/Fraudcheckdata.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // vim: set ts=4 sw=4 sts=4 et:
3
+ /**
4
+ * Magento
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * @author Qualiteam Software info@qtmsoft.com
17
+ * @category Cdev
18
+ * @package Cdev_XPaymentsConnector
19
+ * @copyright (c) 2010-2016 Qualiteam software Ltd <info@x-cart.com>. All rights reserved
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ */
22
+
23
+ /**
24
+ * Data from the fraud-check service (Kount, NoFraud, etc)
25
+ * Class Cdev_XPaymentsConnector_Model_FraudCheckData
26
+ */
27
+
28
+ class Cdev_XPaymentsConnector_Model_Fraudcheckdata extends Mage_Core_Model_Abstract
29
+ {
30
+ /**
31
+ * Internal constructor
32
+ *
33
+ * @return void
34
+ */
35
+ protected function _construct()
36
+ {
37
+ $this->_init('xpaymentsconnector/fraudcheckdata');
38
+ }
39
+
40
+ /**
41
+ * Get and unserialize some data
42
+ *
43
+ * @param string $name Data name
44
+ *
45
+ * @return array
46
+ */
47
+ private function getUnserializedData($name)
48
+ {
49
+ $list = $this->getData($name);
50
+
51
+ $list = @unserialize($list);
52
+
53
+ if (!is_array($list)) {
54
+ $list = array();
55
+ }
56
+
57
+ return $list;
58
+ }
59
+
60
+ /**
61
+ * Get list of the triggered rules
62
+ *
63
+ * @return array
64
+ */
65
+ public function getRulesList()
66
+ {
67
+ return $this->getUnserializedData('rules');
68
+ }
69
+
70
+ /**
71
+ * Get list of the errors
72
+ *
73
+ * @return array
74
+ */
75
+ public function getErrorsList()
76
+ {
77
+ return $this->getUnserializedData('errors');
78
+ }
79
+
80
+ /**
81
+ * Get list of the warnings
82
+ *
83
+ * @return array
84
+ */
85
+ public function getWarningsList()
86
+ {
87
+ return $this->getUnserializedData('warnings');
88
+ }
89
+
90
+ /**
91
+ * Get data as list
92
+ *
93
+ * @return array
94
+ */
95
+ public function getDataList()
96
+ {
97
+ return $this->getUnserializedData('data');
98
+ }
99
+ }
app/code/community/Cdev/XPaymentsConnector/{Block/Customer/Account/Navigation.php → Model/Mysql4/Fraudcheckdata.php} RENAMED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * Magento
4
  *
@@ -20,28 +21,22 @@
20
  */
21
 
22
  /**
23
- * Remove account link "My Payment Cards"
 
 
 
 
24
  */
25
- class Cdev_XPaymentsConnector_Block__Customer_Account_Navigation extends Mage_Customer_Block_Account_Navigation
26
- {
27
- /**
28
- * @return $this
29
- */
30
- public function removeLink()
31
- {
32
- $IsSaveCardsPaymentActive = (bool)Mage::getStoreConfig('payment/savedcards/active');
33
- if (!$IsSaveCardsPaymentActive) {
34
- unset($this->_links['customer_usercards']);
35
- }
36
- return $this;
37
- }
38
 
 
 
39
  /**
40
- * @return mixed
 
 
41
  */
42
- protected function _toHtml()
43
  {
44
- $this->removeLink();
45
- return parent::_toHtml();
46
  }
47
- }
1
  <?php
2
+ // vim: set ts=4 sw=4 sts=4 et:
3
  /**
4
  * Magento
5
  *
21
  */
22
 
23
  /**
24
+ * Fraud check data RDBS-specific model
25
+ *
26
+ * @package Cdev_XPaymentsConnector
27
+ * @see ____class_see____
28
+ * @since 1.0.0
29
  */
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
+ class Cdev_XPaymentsConnector_Model_Mysql4_Fraudcheckdata extends Mage_Core_Model_Mysql4_Abstract
32
+ {
33
  /**
34
+ * Internal constructor
35
+ *
36
+ * @return void
37
  */
38
+ protected function _construct()
39
  {
40
+ $this->_init('xpaymentsconnector/fraudcheckdata', 'data_id');
 
41
  }
42
+ }
app/code/community/Cdev/XPaymentsConnector/Model/Mysql4/Fraudcheckdata/Collection.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // vim: set ts=4 sw=4 sts=4 et:
3
+ /**
4
+ * Magento
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * @author Qualiteam Software info@qtmsoft.com
17
+ * @category Cdev
18
+ * @package Cdev_XPaymentsConnector
19
+ * @copyright (c) 2010-2016 Qualiteam software Ltd <info@x-cart.com>. All rights reserved
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ */
22
+
23
+ /**
24
+ * Fraud check data RDMS-specific collection model
25
+ *
26
+ * @package Cdev_XPaymentsConnector
27
+ * @see ____class_see____
28
+ * @since 1.0.0
29
+ */
30
+
31
+ class Cdev_XPaymentsConnector_Model_Mysql4_Fraudcheckdata_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
32
+ {
33
+ /**
34
+ * Initialize collection
35
+ *
36
+ */
37
+ public function _construct()
38
+ {
39
+ $this->_init('xpaymentsconnector/fraudcheckdata');
40
+ }
41
+ }
app/code/community/Cdev/XPaymentsConnector/Model/Mysql4/Quote/Xpcdata.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // vim: set ts=4 sw=4 sts=4 et:
3
+ /**
4
+ * Magento
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * @author Qualiteam Software info@qtmsoft.com
17
+ * @category Cdev
18
+ * @package Cdev_XPaymentsConnector
19
+ * @copyright (c) 2010-2016 Qualiteam software Ltd <info@x-cart.com>. All rights reserved
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ */
22
+
23
+ /**
24
+ * X-Payments Connector Quote data RDBS-specific model
25
+ *
26
+ * @package Cdev_XPaymentsConnector
27
+ * @see ____class_see____
28
+ * @since 1.0.0
29
+ */
30
+
31
+ class Cdev_XPaymentsConnector_Model_Mysql4_Quote_Xpcdata extends Mage_Core_Model_Mysql4_Abstract
32
+ {
33
+ /**
34
+ * Internal constructor
35
+ *
36
+ * @return void
37
+ */
38
+ protected function _construct()
39
+ {
40
+ $this->_init('xpaymentsconnector/quote_xpcdata', 'data_id');
41
+ }
42
+ }
app/code/community/Cdev/XPaymentsConnector/Model/Mysql4/Quote/Xpcdata/Collection.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // vim: set ts=4 sw=4 sts=4 et:
3
+ /**
4
+ * Magento
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * @author Qualiteam Software info@qtmsoft.com
17
+ * @category Cdev
18
+ * @package Cdev_XPaymentsConnector
19
+ * @copyright (c) 2010-2016 Qualiteam software Ltd <info@x-cart.com>. All rights reserved
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ */
22
+
23
+ /**
24
+ * X-Payments Connector Data in quote
25
+ *
26
+ * @package Cdev_XPaymentsConnector
27
+ */
28
+ class Cdev_XPaymentsConnector_Model_Mysql4_Quote_Xpcdata_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
29
+ {
30
+ /**
31
+ * Initialize collection
32
+ */
33
+ public function _construct()
34
+ {
35
+ $this->_init('xpaymentsconnector/quote_xpcdata');
36
+ }
37
+ }
app/code/community/Cdev/XPaymentsConnector/Model/Observer.php CHANGED
@@ -37,12 +37,6 @@ class Cdev_XPaymentsConnector_Model_Observer extends Mage_CatalogInventory_Model
37
  $xpHelper = Mage::helper('xpaymentsconnector');
38
  $xpHelper->unsetXpaymentPrepareOrder($unsetParams);
39
 
40
- //set recurring product discount
41
- $issetRecurrnigProduct = $xpHelper->checkIssetRecurringOrder();
42
- if ($issetRecurrnigProduct['isset']) {
43
- $xpHelper->setRecurringProductDiscount();
44
- }
45
-
46
  }
47
 
48
  public function paymentMethodIsActive($observer)
@@ -112,9 +106,16 @@ class Cdev_XPaymentsConnector_Model_Observer extends Mage_CatalogInventory_Model
112
 
113
  if ($response['success']) {
114
  $result = $paymentCcModel->updateOrderByXpaymentResponse($order->getId(), $response['response']['transaction_id']);
 
 
 
 
115
  if (!$result['success']) {
116
  $checkoutSession->addError($result['error_message']);
117
  $checkoutSession->addNotice($noticeHelper);
 
 
 
118
  }
119
  } else {
120
  $checkoutSession->addError($response['error_message']);
@@ -465,9 +466,6 @@ class Cdev_XPaymentsConnector_Model_Observer extends Mage_CatalogInventory_Model
465
  $xpHelper = Mage::helper('xpaymentsconnector');
466
  $xpHelper->unsetXpaymentPrepareOrder($unsetParams);
467
 
468
- //set recurring product discount
469
- Mage::helper('xpaymentsconnector')->setRecurringProductDiscount();
470
-
471
  // update InitAmount for recurring products
472
  $cart = $observer->getCart('quote');
473
  foreach ($cart->getAllVisibleItems() as $item){
@@ -584,10 +582,6 @@ class Cdev_XPaymentsConnector_Model_Observer extends Mage_CatalogInventory_Model
584
  $unsetParams = array('token');
585
  $xpHelper->unsetXpaymentPrepareOrder($unsetParams);
586
  }
587
-
588
- //set recurring product discount
589
- $xpHelper->setRecurringProductDiscount();
590
-
591
  }
592
 
593
 
37
  $xpHelper = Mage::helper('xpaymentsconnector');
38
  $xpHelper->unsetXpaymentPrepareOrder($unsetParams);
39
 
 
 
 
 
 
 
40
  }
41
 
42
  public function paymentMethodIsActive($observer)
106
 
107
  if ($response['success']) {
108
  $result = $paymentCcModel->updateOrderByXpaymentResponse($order->getId(), $response['response']['transaction_id']);
109
+
110
+ // Reload order data, since it has been changed
111
+ $order = Mage::getModel('sales/order')->load($order->getId());
112
+
113
  if (!$result['success']) {
114
  $checkoutSession->addError($result['error_message']);
115
  $checkoutSession->addNotice($noticeHelper);
116
+ } else {
117
+ // Auto create invoice if necessary
118
+ Mage::helper('xpaymentsconnector')->processCreateInvoice($order);
119
  }
120
  } else {
121
  $checkoutSession->addError($response['error_message']);
466
  $xpHelper = Mage::helper('xpaymentsconnector');
467
  $xpHelper->unsetXpaymentPrepareOrder($unsetParams);
468
 
 
 
 
469
  // update InitAmount for recurring products
470
  $cart = $observer->getCart('quote');
471
  foreach ($cart->getAllVisibleItems() as $item){
582
  $unsetParams = array('token');
583
  $xpHelper->unsetXpaymentPrepareOrder($unsetParams);
584
  }
 
 
 
 
585
  }
586
 
587
 
app/code/community/Cdev/XPaymentsConnector/Model/Payment/Cc.php CHANGED
@@ -63,6 +63,7 @@ class Cdev_XPaymentsConnector_Model_Payment_Cc extends Mage_Payment_Model_Method
63
  const XPATH_IP_ADDRESSES = 'xpaymentsconnector/settings/xpay_allowed_ip_addresses';
64
  const XPATH_CURRENCY = 'xpaymentsconnector/settings/xpay_currency';
65
  const XPATH_CONF_BUNDLE = 'xpaymentsconnector/settings/xpay_conf_bundle';
 
66
 
67
  // Error codes
68
  const REQ_CURL = 1;
@@ -122,7 +123,6 @@ class Cdev_XPaymentsConnector_Model_Payment_Cc extends Mage_Payment_Model_Method
122
  const TRAN_TYPE_GET_INFO = 'getInfo';
123
  const TRAN_TYPE_ACCEPT = 'accept';
124
  const TRAN_TYPE_DECLINE = 'decline';
125
- const XP_API = '1.6';
126
 
127
  /**
128
  * Show or not save card checkbox statuses
@@ -131,6 +131,14 @@ class Cdev_XPaymentsConnector_Model_Payment_Cc extends Mage_Payment_Model_Method
131
  const SAVE_CARD_REQUIRED = 'Y';
132
  const SAVE_CARD_OPTIONAL = 'O';
133
 
 
 
 
 
 
 
 
 
134
  /**
135
  * unique internal payment method identifier
136
  *
@@ -377,6 +385,16 @@ class Cdev_XPaymentsConnector_Model_Payment_Cc extends Mage_Payment_Model_Method
377
 
378
  }
379
 
 
 
 
 
 
 
 
 
 
 
380
  /**
381
  * Check - module is configured
382
  *
@@ -502,7 +520,7 @@ class Cdev_XPaymentsConnector_Model_Payment_Cc extends Mage_Payment_Model_Method
502
  'callbackUrl' => Mage::getUrl('xpaymentsconnector/processing/callback',
503
  array('order_refid' => $refId,'quote_id' => $quoteId,'_secure' => true)),
504
  'saveCard' => 'Y',
505
- 'api_version' => self::XP_API
506
  );
507
 
508
  list($status, $response) = $this->request('payment', 'init', $data);
@@ -548,6 +566,8 @@ class Cdev_XPaymentsConnector_Model_Payment_Cc extends Mage_Payment_Model_Method
548
  public function requestPaymentInfo($txn_id, $refresh = false,$withAdditionalInfo = false)
549
  {
550
 
 
 
551
  if($withAdditionalInfo){
552
  $data = array(
553
  'txnId' => $txn_id,
@@ -643,19 +663,38 @@ class Cdev_XPaymentsConnector_Model_Payment_Cc extends Mage_Payment_Model_Method
643
  {
644
  srand();
645
 
646
- $hash_code = strval(rand(0, 1000000));
647
 
648
- // Make test request
649
- list($status, $response) = $this->request(
650
- 'connect',
651
- 'test',
652
- array('testCode' => $hash_code)
653
  );
654
 
655
- // Compare MD5 hashes
656
- if ($status && md5($hash_code) !== $response['hashCode']) {
657
- $this->getAPIError('Test connection data is not valid');
658
- $status = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
659
  }
660
 
661
  return $status;
@@ -715,7 +754,7 @@ class Cdev_XPaymentsConnector_Model_Payment_Cc extends Mage_Payment_Model_Method
715
  $data['target'] = $target;
716
  $data['action'] = $action;
717
  if(!isset($data['api_version'])){
718
- $data['api_version'] = self::XP_API;
719
  }
720
 
721
 
@@ -900,36 +939,46 @@ class Cdev_XPaymentsConnector_Model_Payment_Cc extends Mage_Payment_Model_Method
900
  * Check - force use authorization request or not
901
  *
902
  * @return boolean
903
- * @access protected
904
- * @see ____func_see____
905
- * @since 1.0.0
906
  */
907
  protected function isForceAuth()
908
  {
909
- $xpHelper = Mage::helper('xpaymentsconnector');
910
- $isRecurringProduct = $xpHelper->checkIssetRecurringOrder();
911
 
912
- $request = Mage::app()->getRequest()->getActionName();
913
- if($request == 'cardadd'){
914
- return true;
915
- };
916
 
917
- if ($xpHelper->checkIssetSimpleOrder()) {
918
- $useAuthorize = Mage::getStoreConfig('payment/xpayments/use_authorize');
919
- return (bool)$useAuthorize;
920
- }
 
 
 
 
 
 
921
 
922
- if ($isRecurringProduct['isset']) {
923
- $currentProduct = $isRecurringProduct['quote_item']->getProduct();
924
- $checkQuoteItemResult = $xpHelper->checkStartDateDataByProduct($currentProduct,$isRecurringProduct['quote_item']);
925
- if ($checkQuoteItemResult[$currentProduct->getId()]['success']) {
926
- if (!$isRecurringProduct['quote_item']->getXpRecurringInitialFee()) {
927
- return true;
 
 
 
 
 
 
 
 
 
 
928
  }
929
  }
930
- $useInitialFeeAuthorize = Mage::getStoreConfig('payment/xpayments/use_initialfee_authorize');
931
- return (bool)$useInitialFeeAuthorize;
932
  }
 
 
933
  }
934
 
935
  /**
@@ -1345,12 +1394,10 @@ class Cdev_XPaymentsConnector_Model_Payment_Cc extends Mage_Payment_Model_Method
1345
 
1346
  if (!$zeroAuth) {
1347
 
1348
- $xpcData = array(
1349
- 'txnId' => $response['txnId'],
1350
- 'token' => $response['token'],
1351
- );
1352
-
1353
- $helper->saveQuoteXpcData($quote, $xpcData);
1354
  }
1355
  }
1356
 
@@ -1364,17 +1411,16 @@ class Cdev_XPaymentsConnector_Model_Payment_Cc extends Mage_Payment_Model_Method
1364
  */
1365
  protected function getAllowSaveCard()
1366
  {
 
 
1367
  // Check if save card feature is available for customer
1368
- $showToUser = Mage::helper('xpaymentsconnector')->isRegisteredUser()
1369
  && Mage::getStoreConfig('payment/savedcards/active');
1370
 
1371
- // Check if recurring product is purchased
1372
- $isRecuringProduct = Mage::helper('xpaymentsconnector')->checkIssetRecurringOrder();
1373
- $isRecuringProduct = (bool)$isRecuringProduct['isset'];
1374
-
1375
  if ($showToUser) {
1376
 
1377
- $allowSaveCard = $isRecuringProduct
 
1378
  ? static::SAVE_CARD_REQUIRED
1379
  : static::SAVE_CARD_OPTIONAL;
1380
 
@@ -1397,7 +1443,7 @@ class Cdev_XPaymentsConnector_Model_Payment_Cc extends Mage_Payment_Model_Method
1397
 
1398
  $quote = Mage::getSingleton('checkout/session')->getQuote();
1399
 
1400
- if (!$helper->getQuoteXpcDataToken($quote)) {
1401
  // This saves token in the quote model
1402
  $data = $this->sendIframeHandshakeRequest();
1403
  }
@@ -1416,7 +1462,7 @@ class Cdev_XPaymentsConnector_Model_Payment_Cc extends Mage_Payment_Model_Method
1416
 
1417
  $quote = Mage::getSingleton('checkout/session')->getQuote();
1418
 
1419
- return (bool)$helper->getQuoteXpcDataToken($quote);
1420
  }
1421
 
1422
  /**
@@ -1430,7 +1476,7 @@ class Cdev_XPaymentsConnector_Model_Payment_Cc extends Mage_Payment_Model_Method
1430
 
1431
  $quote = Mage::getSingleton('checkout/session')->getQuote();
1432
 
1433
- $token = $helper->getQuoteXpcDataToken($quote);
1434
 
1435
  return array(
1436
  'target' => 'main',
@@ -1544,8 +1590,6 @@ class Cdev_XPaymentsConnector_Model_Payment_Cc extends Mage_Payment_Model_Method
1544
  $status
1545
  && in_array($response['payment']['status'], array(self::AUTH_STATUS, self::CHARGED_STATUS))
1546
  ) {
1547
- // TODO - save message - $response['message']
1548
- // TODO - process faud status
1549
 
1550
  if ($response['payment']['amount'] != number_format($order->getGrandTotal(), 2, '.','') && $checkOrderAmount) {
1551
  $order->cancel();
@@ -1582,27 +1626,30 @@ class Cdev_XPaymentsConnector_Model_Payment_Cc extends Mage_Payment_Model_Method
1582
  $order->getPayment()->setCcAvsStatus($response['payment']['advinfo']['AVS']);
1583
  }
1584
 
1585
- if ($response['payment']['status'] == self::AUTH_ACTION) {
1586
- $order->setState(
1587
- Mage_Sales_Model_Order::STATE_PROCESSING,
1588
- (bool)$order->getPayment()->getMethodInstance()->getConfigData('order_status'),
1589
- $xpaymentsHelper->__('preauthorize: Customer returned successfully')
1590
- );
1591
- $order->setStatus(Cdev_XPaymentsConnector_Helper_Data::STATE_XPAYMENTS_PENDING_PAYMENT);
1592
- }else{
1593
- $order->setState(
1594
- Mage_Sales_Model_Order::STATE_PROCESSING,
1595
- (bool)$order->getPayment()->getMethodInstance()->getConfigData('order_status'),
1596
- $xpaymentsHelper->__('preauthorize: Customer returned successfully')
1597
- );
1598
- $order->setStatus(Mage_Sales_Model_Order::STATE_PROCESSING);
1599
- }
1600
 
1601
- if(isset($response['payment']['isFraudStatus']) && $response['payment']['isFraudStatus']){
1602
- $order->setStatus('fraud');
 
 
 
 
 
 
 
1603
  }
1604
 
 
 
1605
  $order->save();
 
1606
  if(method_exists($order,'sendNewOrderEmail')){
1607
  $order->sendNewOrderEmail();
1608
  }elseif(method_exists($order,'queueNewOrderEmail')){
@@ -1767,74 +1814,45 @@ class Cdev_XPaymentsConnector_Model_Payment_Cc extends Mage_Payment_Model_Method
1767
  }
1768
 
1769
  /**
1770
- * Submit to the gateway
1771
  *
1772
  * @param Mage_Payment_Model_Recurring_Profile $profile
1773
  * @param Mage_Payment_Model_Info $paymentInfo
 
 
1774
  */
1775
  public function submitRecurringProfile(Mage_Payment_Model_Recurring_Profile $profile, Mage_Payment_Model_Info $paymentInfo)
1776
  {
1777
- $xpHelper = Mage::helper('xpaymentsconnector');
 
 
 
 
1778
  $quote = $profile->getQuote();
1779
- // registered new user and update profile
1780
- $xpHelper->addXpDefaultRecurringSettings($profile);
1781
- // end registered user
1782
- $xpHelper->setPrepareOrderType();
1783
 
1784
- //add txnid for all subscriptions
1785
- $cardData = $xpHelper->getXpCardData();
1786
 
1787
- $useIframe = Mage::helper('xpaymentsconnector')->isUseIframe();
1788
-
1789
- if (!$xpHelper->checkIssetSimpleOrder()) {
1790
- if ($useIframe) {
1791
- if (is_null($this->_currentProfileId)) {
1792
- $payDeferredSubscription = $xpHelper->payDeferredSubscription($profile);
1793
- if ($payDeferredSubscription) {
1794
- $this->_currentProfileId = $profile->getProfileId();
1795
- } else {
1796
- $this->createFirstRecurringOrder($profile);
1797
- }
1798
- if($profile->getState() == Mage_Sales_Model_Recurring_Profile::STATE_CANCELED){
1799
- $this->firstTransactionSuccess = false;
1800
- };
1801
- }else{
1802
- if (!$this->firstTransactionSuccess) {
1803
- $profile->setState(Mage_Sales_Model_Recurring_Profile::STATE_CANCELED);
1804
- }
1805
- }
1806
- $xpHelper->prepareOrderKeyByRecurringProfile($profile);
1807
- } else {
1808
- if (is_null($this->_currentProfileId)) {
1809
- $xpaymentResponse = $this->sendIframeHandshakeRequest();
1810
-
1811
- if (isset($xpaymentResponse['success']) && !$xpaymentResponse['success']) {
1812
- $this->firstTransactionSuccess = false;
1813
- $profile->setState(Mage_Sales_Model_Recurring_Profile::STATE_CANCELED);
1814
- }
1815
- $xpHelper->updateRecurringMasKeys($profile);
1816
- $this->_currentProfileId = $profile->getProfileId();
1817
- } else {
1818
- if (!$this->firstTransactionSuccess) {
1819
- $profile->setState(Mage_Sales_Model_Recurring_Profile::STATE_CANCELED);
1820
- }
1821
- }
1822
- }
1823
  }
1824
 
1825
- if($useIframe){
1826
- $profile->setReferenceId($cardData['txnId']);
1827
- if (is_null($this->_currentProfileId) && $xpHelper->checkIssetSimpleOrder()) {
1828
- //save user card
1829
- Mage::getSingleton('checkout/session')->setData('user_card_save', true);
1830
- $this->saveUserCard($cardData, $usageType = Cdev_XPaymentsConnector_Model_Usercards::RECURRING_CARD);
1831
- }
1832
- $this->_currentProfileId = $profile->getProfileId();
1833
- }else {
1834
- $orderItemInfo = $profile->getData('order_item_info');
1835
- $quote->getItemById($orderItemInfo['item_id'])->isDeleted(true);
1836
  }
1837
 
 
 
 
 
 
 
 
 
 
 
1838
  }
1839
 
1840
  /**
@@ -1894,7 +1912,12 @@ class Cdev_XPaymentsConnector_Model_Payment_Cc extends Mage_Payment_Model_Method
1894
  */
1895
  public function createFirstRecurringOrder(Mage_Payment_Model_Recurring_Profile $profile)
1896
  {
1897
- $xpHelper = Mage::helper('xpaymentsconnector');
 
 
 
 
 
1898
  $cardData = $xpHelper->getXpCardData();
1899
  $orderId = $xpHelper->createOrder($profile, $isFirstRecurringOrder = true);
1900
 
63
  const XPATH_IP_ADDRESSES = 'xpaymentsconnector/settings/xpay_allowed_ip_addresses';
64
  const XPATH_CURRENCY = 'xpaymentsconnector/settings/xpay_currency';
65
  const XPATH_CONF_BUNDLE = 'xpaymentsconnector/settings/xpay_conf_bundle';
66
+ const XPATH_API_VERSION = 'xpaymentsconnector/settings/xpay_api_version';
67
 
68
  // Error codes
69
  const REQ_CURL = 1;
123
  const TRAN_TYPE_GET_INFO = 'getInfo';
124
  const TRAN_TYPE_ACCEPT = 'accept';
125
  const TRAN_TYPE_DECLINE = 'decline';
 
126
 
127
  /**
128
  * Show or not save card checkbox statuses
131
  const SAVE_CARD_REQUIRED = 'Y';
132
  const SAVE_CARD_OPTIONAL = 'O';
133
 
134
+ /**
135
+ * List of supported API versions
136
+ */
137
+ private $apiVersions = array(
138
+ 1.7,
139
+ 1.6,
140
+ );
141
+
142
  /**
143
  * unique internal payment method identifier
144
  *
385
 
386
  }
387
 
388
+ /**
389
+ * Get API version setting
390
+ *
391
+ * @return string
392
+ */
393
+ public function getApiVersion()
394
+ {
395
+ return Mage::getStoreConfig(self::XPATH_API_VERSION);
396
+ }
397
+
398
  /**
399
  * Check - module is configured
400
  *
520
  'callbackUrl' => Mage::getUrl('xpaymentsconnector/processing/callback',
521
  array('order_refid' => $refId,'quote_id' => $quoteId,'_secure' => true)),
522
  'saveCard' => 'Y',
523
+ 'api_version' => $this->getApiVersion(),
524
  );
525
 
526
  list($status, $response) = $this->request('payment', 'init', $data);
566
  public function requestPaymentInfo($txn_id, $refresh = false,$withAdditionalInfo = false)
567
  {
568
 
569
+ Mage::helper('xpaymentsconnector')->writeLog('INFO', array($txn_id, $refresh, $withAdditionalInfo));
570
+
571
  if($withAdditionalInfo){
572
  $data = array(
573
  'txnId' => $txn_id,
663
  {
664
  srand();
665
 
666
+ $hashCode = strval(rand(0, 1000000));
667
 
668
+ $params = array(
669
+ 'testCode' => $hashCode,
 
 
 
670
  );
671
 
672
+ foreach ($this->apiVersions as $version) {
673
+
674
+ $params['api_version'] = $version;
675
+
676
+ // Make test request
677
+ list($status, $response) = $this->request(
678
+ 'connect',
679
+ 'test',
680
+ $params
681
+ );
682
+
683
+ if (
684
+ $status
685
+ && isset($response['hashCode'])
686
+ && md5($hashCode) == $response['hashCode']
687
+ ) {
688
+
689
+ // Save working API version
690
+ Mage::getConfig()->saveConfig(self::XPATH_API_VERSION, $version);
691
+ Mage::getConfig()->reinit();
692
+ break;
693
+
694
+ } else {
695
+
696
+ $status = false;
697
+ }
698
  }
699
 
700
  return $status;
754
  $data['target'] = $target;
755
  $data['action'] = $action;
756
  if(!isset($data['api_version'])){
757
+ $data['api_version'] = $this->getApiVersion();
758
  }