Fontis_Masterpass - Version 1.0.2

Version Notes

Initial release.

Download this release

Release Info

Developer Fontis
Extension Fontis_Masterpass
Version 1.0.2
Comparing to
See all releases


Version 1.0.2

Files changed (35) hide show
  1. app/code/community/Fontis/Masterpass/Block/Abstract.php +36 -0
  2. app/code/community/Fontis/Masterpass/Block/Adminhtml/Sales/Orderpayment.php +40 -0
  3. app/code/community/Fontis/Masterpass/Block/Checkout/Review.php +244 -0
  4. app/code/community/Fontis/Masterpass/Block/Checkout/Review/Details.php +45 -0
  5. app/code/community/Fontis/Masterpass/Block/Checkoutlink.php +122 -0
  6. app/code/community/Fontis/Masterpass/Block/Payment/Form.php +90 -0
  7. app/code/community/Fontis/Masterpass/Helper/Config.php +146 -0
  8. app/code/community/Fontis/Masterpass/Helper/Data.php +272 -0
  9. app/code/community/Fontis/Masterpass/Model/Checkout.php +206 -0
  10. app/code/community/Fontis/Masterpass/Model/Directory/Region.php +62 -0
  11. app/code/community/Fontis/Masterpass/Model/Masterpass/Oauth.php +280 -0
  12. app/code/community/Fontis/Masterpass/Model/Masterpass/Order.php +75 -0
  13. app/code/community/Fontis/Masterpass/Model/Masterpass/Payment.php +346 -0
  14. app/code/community/Fontis/Masterpass/Model/Observer.php +59 -0
  15. app/code/community/Fontis/Masterpass/Model/Payment.php +57 -0
  16. app/code/community/Fontis/Masterpass/Model/System/Cards.php +134 -0
  17. app/code/community/Fontis/Masterpass/Model/System/CheckoutButton.php +48 -0
  18. app/code/community/Fontis/Masterpass/Model/System/Environment.php +40 -0
  19. app/code/community/Fontis/Masterpass/Model/System/LearnmoreLanguage.php +47 -0
  20. app/code/community/Fontis/Masterpass/Model/System/PaymentGateways.php +64 -0
  21. app/code/community/Fontis/Masterpass/Model/Zend/OauthAccessToken.php +39 -0
  22. app/code/community/Fontis/Masterpass/Model/Zend/OauthConfig.php +66 -0
  23. app/code/community/Fontis/Masterpass/Model/Zend/OauthConsumer.php +40 -0
  24. app/code/community/Fontis/Masterpass/Model/Zend/OauthRequestToken.php +39 -0
  25. app/code/community/Fontis/Masterpass/PaymentException.php +21 -0
  26. app/code/community/Fontis/Masterpass/controllers/CheckoutController.php +639 -0
  27. app/code/community/Fontis/Masterpass/etc/config.xml +128 -0
  28. app/code/community/Fontis/Masterpass/etc/system.xml +199 -0
  29. app/design/frontend/base/default/layout/fontis/masterpass.xml +69 -0
  30. app/design/frontend/base/default/template/fontis/masterpass/checkoutlink.phtml +21 -0
  31. app/design/frontend/base/default/template/fontis/masterpass/payment/form.phtml +22 -0
  32. app/design/frontend/base/default/template/fontis/masterpass/review.phtml +135 -0
  33. app/design/frontend/base/default/template/fontis/masterpass/review/details.phtml +64 -0
  34. app/etc/modules/Fontis_Masterpass.xml +27 -0
  35. package.xml +18 -0
app/code/community/Fontis/Masterpass/Block/Abstract.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Block_Abstract extends Mage_Core_Block_Template
20
+ {
21
+ /**
22
+ * @var Fontis_Masterpass_Helper_Data
23
+ */
24
+ protected $_helper = null;
25
+
26
+ /**
27
+ * @return Fontis_Masterpass_Helper_Data
28
+ */
29
+ protected function getMasterpassHelper()
30
+ {
31
+ if (!$this->_helper) {
32
+ $this->_helper = Mage::helper("fontis_masterpass");
33
+ }
34
+ return $this->_helper;
35
+ }
36
+ }
app/code/community/Fontis/Masterpass/Block/Adminhtml/Sales/Orderpayment.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Block_Adminhtml_Sales_Orderpayment extends Mage_Adminhtml_Block_Sales_Order_Payment
20
+ {
21
+ /**
22
+ * Intercepts the rendering of the "Payment Information" box on the order view page in the admin panel.
23
+ * Checks to see if there is MasterPass data on the quote object, and if so, display an appropriate message.
24
+ *
25
+ * @return string
26
+ */
27
+ protected function _toHtml()
28
+ {
29
+ $html = parent::_toHtml();
30
+ $payment = $this->getData("payment");
31
+ $info = $payment->getAdditionalInformation();
32
+ if (!empty($info["cc_from"]) && $info["cc_from"] === "masterpass") {
33
+ $html .= "<br />" . $this->__("The details for this order came from %s.", Mage::helper("fontis_masterpass/config")->getFrontendTitle()) . "<br />";
34
+ if (!empty($info[Fontis_Masterpass_Helper_Data::MPASS_TXNID_LABEL])) {
35
+ $html .= "MasterPass transaction ID: " . $info[Fontis_Masterpass_Helper_Data::MPASS_TXNID_LABEL] . "<br />";
36
+ }
37
+ }
38
+ return $html;
39
+ }
40
+ }
app/code/community/Fontis/Masterpass/Block/Checkout/Review.php ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Block_Checkout_Review extends Fontis_Masterpass_Block_Abstract
20
+ {
21
+ const ACCEPTANCE_MARK_URL = "http://www.mastercard.com/mc_us/wallet/img/en/AU/mp_acc_068px_gif.gif";
22
+
23
+ /**
24
+ * @var Mage_Sales_Model_Quote
25
+ */
26
+ protected $_quote = null;
27
+
28
+ /**
29
+ * @var Mage_Sales_Model_Quote_Address
30
+ */
31
+ protected $_shippingAddress = null;
32
+
33
+ /**
34
+ * Currently selected shipping rate.
35
+ *
36
+ * @var Mage_Sales_Model_Quote_Address_Rate
37
+ */
38
+ protected $_currentShippingRate = null;
39
+
40
+ /**
41
+ * @return string
42
+ */
43
+ public function getMasterpassAcceptanceMarkUrl()
44
+ {
45
+ return self::ACCEPTANCE_MARK_URL;
46
+ }
47
+
48
+ /**
49
+ * Quote object setter.
50
+ *
51
+ * @param Mage_Sales_Model_Quote $quote
52
+ * @return Fontis_Masterpass_Block_Checkout_Review
53
+ */
54
+ public function setQuote(Mage_Sales_Model_Quote $quote)
55
+ {
56
+ $this->_quote = $quote;
57
+ return $this;
58
+ }
59
+
60
+ /**
61
+ * Get checkout quote object.
62
+ *
63
+ * @return Mage_Sales_Model_Quote
64
+ */
65
+ public function getQuote()
66
+ {
67
+ if ($this->_quote === null) {
68
+ $this->_quote = Mage::getSingleton("checkout/session")->getQuote();
69
+ }
70
+ return $this->_quote;
71
+ }
72
+
73
+ /**
74
+ * Get billing address from quote.
75
+ *
76
+ * @return Mage_Sales_Model_Quote_Address
77
+ */
78
+ public function getBillingAddress()
79
+ {
80
+ return $this->getQuote()->getBillingAddress();
81
+ }
82
+
83
+ /**
84
+ * Get shipping address from quote.
85
+ * Returns null if the quote only contains virtual products.
86
+ *
87
+ * @return Mage_Sales_Model_Quote_Address
88
+ */
89
+ public function getShippingAddress()
90
+ {
91
+ if ($this->getQuote()->isVirtual()) {
92
+ return null;
93
+ }
94
+ return $this->getQuote()->getShippingAddress();
95
+ }
96
+
97
+ /**
98
+ * Get payment details from quote.
99
+ *
100
+ * @return Mage_Sales_Model_Quote_Payment
101
+ */
102
+ public function getQuotePayment()
103
+ {
104
+ return $this->getQuote()->getPayment();
105
+ }
106
+
107
+ /**
108
+ * Get HTML output for supplied address object.
109
+ *
110
+ * @param Mage_Sales_Model_Quote_Address $address
111
+ * @return string
112
+ */
113
+ public function renderAddress(Mage_Sales_Model_Quote_Address $address)
114
+ {
115
+ return $address->getFormated(true);
116
+ }
117
+
118
+ /**
119
+ * Return carrier name from config, base on carrier code
120
+ *
121
+ * @param string $carrierCode
122
+ * @return string
123
+ */
124
+ public function getCarrierName($carrierCode)
125
+ {
126
+ if ($name = Mage::getStoreConfig("carriers/{$carrierCode}/title")) {
127
+ return $name;
128
+ }
129
+ return $carrierCode;
130
+ }
131
+
132
+ /**
133
+ * Get either shipping rate code or empty value on error
134
+ *
135
+ * @param Varien_Object $rate
136
+ * @return string
137
+ */
138
+ public function renderShippingRateValue(Varien_Object $rate)
139
+ {
140
+ if ($rate->getErrorMessage()) {
141
+ return '';
142
+ }
143
+ return $rate->getCode();
144
+ }
145
+
146
+ /**
147
+ * Get shipping rate code title and its price or error message
148
+ *
149
+ * @param Varien_Object $rate
150
+ * @param string $format
151
+ * @param string $inclTaxFormat
152
+ * @return string
153
+ */
154
+ public function renderShippingRateOption($rate, $format = '%s - %s%s', $inclTaxFormat = ' (%s %s)')
155
+ {
156
+ $renderedInclTax = '';
157
+ if ($rate->getErrorMessage()) {
158
+ $price = $rate->getErrorMessage();
159
+ } else {
160
+ $price = $this->_getShippingPrice($rate->getPrice(), $this->helper('tax')->displayShippingPriceIncludingTax());
161
+ $incl = $this->_getShippingPrice($rate->getPrice(), true);
162
+ if (($incl != $price) && $this->helper('tax')->displayShippingBothPrices()) {
163
+ $renderedInclTax = sprintf($inclTaxFormat, Mage::helper('tax')->__('Incl. Tax'), $incl);
164
+ }
165
+ }
166
+ return sprintf($format, $rate->getMethodTitle(), $price, $renderedInclTax);
167
+ }
168
+
169
+ /**
170
+ * Getter for current shipping rate
171
+ *
172
+ * @return Mage_Sales_Model_Quote_Address_Rate
173
+ */
174
+ public function getCurrentShippingRate()
175
+ {
176
+ return $this->_currentShippingRate;
177
+ }
178
+
179
+ /**
180
+ * Return formatted shipping price.
181
+ *
182
+ * @param float $price
183
+ * @param bool $isInclTax
184
+ *
185
+ * @return bool
186
+ */
187
+ protected function _getShippingPrice($price, $isInclTax)
188
+ {
189
+ return $this->_formatPrice($this->helper('tax')->getShippingPrice($price, $isInclTax, $this->_shippingAddress));
190
+ }
191
+
192
+ /**
193
+ * Format price based on store convert price method.
194
+ *
195
+ * @param float $price
196
+ * @return string
197
+ */
198
+ protected function _formatPrice($price)
199
+ {
200
+ return $this->getQuote()->getStore()->convertPrice($price, true);
201
+ }
202
+
203
+ /**
204
+ * Retrieve payment method and assign additional template values
205
+ *
206
+ * @return Fontis_Masterpass_Block_Checkout_Review
207
+ */
208
+ protected function _beforeToHtml()
209
+ {
210
+ $this->setPaymentMethodTitle($this->getQuotePayment()->getMethodInstance()->getTitle());
211
+
212
+ $quote = $this->getQuote();
213
+ if ($quote->getIsVirtual()) {
214
+ $this->setShippingRateRequired(false);
215
+ } else {
216
+ $this->setShippingRateRequired(true);
217
+
218
+ // prepare shipping rates
219
+ $this->_shippingAddress = $quote->getShippingAddress();
220
+ $groups = $this->_shippingAddress->getGroupedAllShippingRates();
221
+ if ($groups && $this->_shippingAddress) {
222
+ $this->setShippingRateGroups($groups);
223
+ // determine current selected code & name
224
+ foreach ($groups as $code => $rates) {
225
+ foreach ($rates as $rate) {
226
+ if ($this->_shippingAddress->getShippingMethod() == $rate->getCode()) {
227
+ $this->_currentShippingRate = $rate;
228
+ break(2);
229
+ }
230
+ }
231
+ }
232
+ }
233
+
234
+ // misc shipping parameters
235
+ $this->setShippingMethodSubmitUrl($this->getUrl("masterpass/checkout/saveShippingMethod"))
236
+ ->setCanEditShippingAddress(false) // MasterPass doesn't let the customer return to edit details at present.
237
+ ->setCanEditShippingMethod(true); // MasterPass doesn't support handling shipping methods at present, so this must always be true.
238
+ }
239
+
240
+ $this->setPlaceOrderUrl($this->getUrl("masterpass/checkout/placeOrder"));
241
+
242
+ return parent::_beforeToHtml();
243
+ }
244
+ }
app/code/community/Fontis/Masterpass/Block/Checkout/Review/Details.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Block_Checkout_Review_Details extends Mage_Checkout_Block_Cart_Totals
20
+ {
21
+ protected $_address = null;
22
+
23
+ /**
24
+ * Get shipping address from quote.
25
+ *
26
+ * @return Mage_Sales_Model_Order_Address
27
+ */
28
+ public function getAddress()
29
+ {
30
+ if ($this->_address === null) {
31
+ $this->_address = $this->getQuote()->getShippingAddress();
32
+ }
33
+ return $this->_address;
34
+ }
35
+
36
+ /**
37
+ * Return review quote totals.
38
+ *
39
+ * @return array
40
+ */
41
+ public function getTotals()
42
+ {
43
+ return $this->getQuote()->getTotals();
44
+ }
45
+ }
app/code/community/Fontis/Masterpass/Block/Checkoutlink.php ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Block_Checkoutlink extends Fontis_Masterpass_Block_Abstract
20
+ {
21
+ const BASE_URL_SECURE = "https://www.mastercard.com/mc_us/wallet/img/en/US/mcpp_wllt_btn_chk_";
22
+ const BASE_URL = "http://www.mastercard.com/mc_us/wallet/img/en/US/mcpp_wllt_btn_chk_";
23
+
24
+ protected $checkoutButtonSizes = array(
25
+ Fontis_Masterpass_Model_System_CheckoutButton::SIZE_SMALL => "147x034px.png",
26
+ Fontis_Masterpass_Model_System_CheckoutButton::SIZE_MEDIUM => "180x042px.png",
27
+ Fontis_Masterpass_Model_System_CheckoutButton::SIZE_LARGE => "290x068px.png",
28
+ Fontis_Masterpass_Model_System_CheckoutButton::SIZE_LARGEST => "360x084px.png",
29
+ );
30
+
31
+ /**
32
+ * Whether the block should be eventually rendered.
33
+ *
34
+ * @var bool
35
+ */
36
+ protected $_shouldRender = true;
37
+
38
+ /**
39
+ * Check to see whether or not the button should be displayed.
40
+ *
41
+ * @return $this
42
+ */
43
+ protected function _beforeToHtml()
44
+ {
45
+ if (!$this->getMasterpassHelper()->isEnabled()) {
46
+ $this->_shouldRender = false;
47
+ }
48
+
49
+ return parent::_beforeToHtml();
50
+ }
51
+
52
+ /**
53
+ * Render the block if needed.
54
+ *
55
+ * @return string
56
+ */
57
+ protected function _toHtml()
58
+ {
59
+ if (!$this->_shouldRender) {
60
+ return '';
61
+ }
62
+ return parent::_toHtml();
63
+ }
64
+
65
+ /**
66
+ * Returns the URL that commences the MasterPass checkout process.
67
+ * It should point to the "start" controller action in the Checkout Controller inside this MasterPass module.
68
+ *
69
+ * @return string
70
+ */
71
+ public function getCheckoutUrl()
72
+ {
73
+ return $this->getMasterpassHelper()->getCheckoutRedirectUrl();
74
+ }
75
+
76
+ /**
77
+ * @param bool $useDefault force use of the default image
78
+ * @param bool $secure force use of secure/non-secure image base URL
79
+ * @return string
80
+ */
81
+ public function getImageUrl($useDefault = false, $secure = null)
82
+ {
83
+ if ($useDefault !== true) {
84
+ $imageUrl = trim(Mage::helper("fontis_masterpass/config")->getCheckoutButtonUrl());
85
+ if (!empty($imageUrl)) {
86
+ return $imageUrl;
87
+ }
88
+ }
89
+
90
+ if ($secure === true) {
91
+ $url = self::BASE_URL_SECURE;
92
+ } elseif ($secure === false) {
93
+ $url = self::BASE_URL;
94
+ } else {
95
+ if (Mage::helper("fontis_masterpass")->isSecure() === true) {
96
+ $url = self::BASE_URL_SECURE;
97
+ } else {
98
+ $url = self::BASE_URL;
99
+ }
100
+ }
101
+
102
+ $url .= $this->getSize();
103
+
104
+ return $url;
105
+ }
106
+
107
+ /**
108
+ * Get the size the button should be displayed at.
109
+ * If the size has not been set, it will return the default, which is the smallest available image.
110
+ *
111
+ * @return string
112
+ */
113
+ protected function getSize()
114
+ {
115
+ $size = (int) Mage::helper("fontis_masterpass/config")->getCheckoutButtonSize();
116
+ if (array_key_exists($size, $this->checkoutButtonSizes)) {
117
+ return $this->checkoutButtonSizes[$size];
118
+ } else {
119
+ return $this->checkoutButtonSizes[Fontis_Masterpass_Model_System_CheckoutButton::SIZE_SMALL];
120
+ }
121
+ }
122
+ }
app/code/community/Fontis/Masterpass/Block/Payment/Form.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Block_Payment_Form extends Mage_Payment_Block_Form
20
+ {
21
+ const LEARNMORE_BASEURL = "http://www.mastercard.com/mc_us/wallet/learnmore/";
22
+
23
+ const MARK_BASE_URL_SECURE = "https://www.mastercard.com/mc_us/wallet/img/en/US/mp_acc_046px_gif.gif";
24
+ const MARK_BASE_URL = "http://www.mastercard.com/mc_us/wallet/img/en/US/mp_acc_046px_gif.gif";
25
+ const MARK_DEFAULT_HEIGHT = 32;
26
+
27
+ protected function _construct()
28
+ {
29
+ parent::_construct();
30
+ $this->setTemplate("fontis/masterpass/payment/form.phtml");
31
+ }
32
+
33
+ public function getMethodLabelAfterHtml()
34
+ {
35
+ $language = Mage::helper("fontis_masterpass/config")->getLearnMoreLanguage();
36
+ return '<a href="' . self::LEARNMORE_BASEURL . $language . '" target="_blank">' . Mage::helper("fontis_masterpass")->__("Learn more") . '</a>';
37
+ }
38
+
39
+ /**
40
+ * @param bool $useDefault force use of the default image
41
+ * @param bool $secure force use of secure/non-secure image base URL
42
+ * @return string
43
+ */
44
+ public function getMarkImageUrl($useDefault = false, $secure = null)
45
+ {
46
+ if ($useDefault !== true) {
47
+ $imageUrl = trim(Mage::helper("fontis_masterpass/config")->getAcceptanceMarkUrl());
48
+ if (!empty($imageUrl)) {
49
+ return $imageUrl;
50
+ }
51
+ }
52
+
53
+ if ($secure === true) {
54
+ $url = self::MARK_BASE_URL_SECURE;
55
+ } elseif ($secure === false) {
56
+ $url = self::MARK_BASE_URL;
57
+ } else {
58
+ if (Mage::helper("fontis_masterpass")->isSecure() === true) {
59
+ $url = self::MARK_BASE_URL_SECURE;
60
+ } else {
61
+ $url = self::MARK_BASE_URL;
62
+ }
63
+ }
64
+
65
+ return $url;
66
+ }
67
+
68
+ /**
69
+ * This causes Magento to always use the getMethodTitle() function defined in this block.
70
+ *
71
+ * @return bool
72
+ */
73
+ public function hasMethodTitle()
74
+ {
75
+ return true;
76
+ }
77
+
78
+ /**
79
+ * @return string
80
+ */
81
+ public function getMethodTitle()
82
+ {
83
+ if (!($size = Mage::helper("fontis_masterpass/config")->getAcceptanceMarkSize())) {
84
+ $size = self::MARK_DEFAULT_HEIGHT;
85
+ }
86
+ $methodTitle = '<img src="' . $this->getMarkImageUrl() . '" alt="" class="v-middle" height="' . $size . 'px" /> &nbsp; ';
87
+ $methodTitle .= '<span id="masterpass_method_title">' . Mage::helper("fontis_masterpass/config")->getFrontendTitle() . '</span>';
88
+ return $methodTitle;
89
+ }
90
+ }
app/code/community/Fontis/Masterpass/Helper/Config.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Helper_Config extends Mage_Core_Helper_Abstract
20
+ {
21
+ /**
22
+ * This string should be used whereever the "MasterPass" branding name should appear
23
+ * on the frontend in text form.
24
+ *
25
+ * @return string
26
+ */
27
+ public function getFrontendTitle()
28
+ {
29
+ return Mage::getStoreConfig("fontis_masterpass/settings/title");
30
+ }
31
+
32
+ /**
33
+ * @return string
34
+ */
35
+ public function getCheckoutButtonUrl()
36
+ {
37
+ return Mage::getStoreConfig("fontis_masterpass/settings/checkoutbutton_url");
38
+ }
39
+
40
+ /**
41
+ * @return int
42
+ */
43
+ public function getCheckoutButtonSize()
44
+ {
45
+ return Mage::getStoreConfig("fontis_masterpass/settings/checkoutbutton_size");
46
+ }
47
+
48
+ /**
49
+ * @return string
50
+ */
51
+ public function getAcceptanceMarkUrl()
52
+ {
53
+ return Mage::getStoreConfig("fontis_masterpass/settings/acceptancemark_url");
54
+ }
55
+
56
+ /**
57
+ * @return int
58
+ */
59
+ public function getAcceptanceMarkSize()
60
+ {
61
+ return (int) Mage::getStoreConfig("fontis_masterpass/settings/acceptancemark_size");
62
+ }
63
+
64
+ /**
65
+ * @return string
66
+ */
67
+ public function getLearnMoreLanguage()
68
+ {
69
+ return Mage::getStoreConfig("fontis_masterpass/settings/learn_more_language");
70
+ }
71
+
72
+ /**
73
+ * @return int
74
+ */
75
+ public function getCurrentEnvironment()
76
+ {
77
+ return (int) Mage::getStoreConfig("fontis_masterpass/settings/environment");
78
+ }
79
+
80
+ /**
81
+ * The Checkout Identifier tells MasterPass which "checkout" to display to the user.
82
+ * This allows MasterPass to display some branded content (eg logos) to give the impression it is associated
83
+ * with the organisation using MasterPass.
84
+ *
85
+ * @return string
86
+ */
87
+ public function getCheckoutIdentifier()
88
+ {
89
+ return Mage::getStoreConfig("fontis_masterpass/settings/checkout_identifier");
90
+ }
91
+
92
+ /**
93
+ * @return string
94
+ */
95
+ public function getConsumerKey()
96
+ {
97
+ return Mage::getStoreConfig("fontis_masterpass/settings/consumer_key");
98
+ }
99
+
100
+ /**
101
+ * Get the code of the payment gateway used by the merchant to process credit card payments.
102
+ *
103
+ * @return string
104
+ */
105
+ public function getPaymentGateway()
106
+ {
107
+ return Mage::getStoreConfig("fontis_masterpass/settings/payment_gateway");
108
+ }
109
+
110
+ /**
111
+ * @return int
112
+ */
113
+ public function getPaymentSortOrder()
114
+ {
115
+ return (int) Mage::getStoreConfig("fontis_masterpass/settings/sort_order");
116
+ }
117
+
118
+ public function isTokenPaymentsAccepted()
119
+ {
120
+ return Mage::getStoreConfig("fontis_masterpass/settings/token_payments_accepted");
121
+ }
122
+
123
+ /**
124
+ * @param bool $returnAsArray
125
+ * @return string|array
126
+ */
127
+ public function getAcceptedCards($returnAsArray = false)
128
+ {
129
+ $cards = Mage::getStoreConfig("fontis_masterpass/settings/accepted_cards");
130
+ if ($cards === null) {
131
+ return null;
132
+ }
133
+ if ($returnAsArray) {
134
+ $cards = explode(",", $cards);
135
+ }
136
+ return $cards;
137
+ }
138
+
139
+ /**
140
+ * @return string
141
+ */
142
+ public function getPrivateKey()
143
+ {
144
+ return Mage::getStoreConfig("fontis_masterpass/settings/private_key");
145
+ }
146
+ }
app/code/community/Fontis/Masterpass/Helper/Data.php ADDED
@@ -0,0 +1,272 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Helper_Data extends Mage_Core_Helper_Abstract
20
+ {
21
+ /**
22
+ * Value specified in seconds.
23
+ */
24
+ const REDUCED_SESSION_LIFETIME = 300;
25
+
26
+ const MPASS_CC_NUMBER_ENC = "masterpassCcNumberEnc";
27
+ const MPASS_TXNID_LABEL = "mpass_txnid";
28
+
29
+ // API URLs
30
+ const URL_API_OAUTH = 1;
31
+ const URL_API_ONLINE = 2;
32
+
33
+ /**
34
+ * @var array
35
+ */
36
+ protected $_baseUrls = array(
37
+ Fontis_Masterpass_Model_System_Environment::ENV_PROD => "https://api.mastercard.com/",
38
+ Fontis_Masterpass_Model_System_Environment::ENV_SAND => "https://sandbox.api.mastercard.com/",
39
+ );
40
+
41
+ /**
42
+ * @var array
43
+ */
44
+ protected $_apiUrls = array(
45
+ self::URL_API_OAUTH => "oauth/",
46
+ self::URL_API_ONLINE => "online/",
47
+ );
48
+
49
+ /**
50
+ * @var array
51
+ */
52
+ protected $_sensitiveRequests = array(
53
+ "continue",
54
+ "review",
55
+ "saveShippingMethod",
56
+ "placeOrder",
57
+ );
58
+
59
+ /**
60
+ * This is THE function to call to check whether or not MasterPass is to be used.
61
+ * It checks several things to make sure that a transaction can actually happen
62
+ * with MasterPass, as well as checking the "enabled" config setting.
63
+ * This function is called at the start of every controller action, and should
64
+ * be called anywhere that is necessary to see whether the extension is active.
65
+ *
66
+ * @return bool
67
+ */
68
+ public function isEnabled()
69
+ {
70
+ if (Mage::getStoreConfig("fontis_masterpass/settings/enabled")) {
71
+ /** @var Fontis_Masterpass_Helper_Config $configHelper */
72
+ $configHelper = Mage::helper("fontis_masterpass/config");
73
+ if (!$configHelper->getCheckoutIdentifier()) {
74
+ return false;
75
+ }
76
+ if (!$configHelper->getConsumerKey()) {
77
+ return false;
78
+ }
79
+ if (!$configHelper->getPrivateKey()) {
80
+ return false;
81
+ }
82
+ if (!($paymentGateway = $configHelper->getPaymentGateway())) {
83
+ return false;
84
+ }
85
+ if ($configHelper->getAcceptedCards(false) === null) {
86
+ return false;
87
+ }
88
+ return true;
89
+ } else {
90
+ return false;
91
+ }
92
+ }
93
+
94
+ /**
95
+ * @return bool
96
+ */
97
+ public function canShowOnCheckout()
98
+ {
99
+ if ($this->isEnabled()) {
100
+ return Mage::getStoreConfigFlag("fontis_masterpass/settings/show_on_checkout");
101
+ }
102
+ return false;
103
+ }
104
+
105
+ /**
106
+ * Temporarily disable the CCV check on the payment gateway selected from the
107
+ * MasterPass system configuration page. This will allow MasterPass to process
108
+ * payments without having to turn off the "Use CCV" setting on the gateway.
109
+ */
110
+ public function temporarilyDisableCCVCheck()
111
+ {
112
+ $paymentGateway = Mage::helper("fontis_masterpass/config")->getPaymentGateway();
113
+
114
+ if (empty($paymentGateway)) {
115
+ Mage::throwException("Unable to place the order.");
116
+ }
117
+
118
+ Mage::app()->getStore()->setConfig("payment/$paymentGateway/useccv", "0");
119
+ }
120
+
121
+ /**
122
+ * This should cause a client's session lifetime to be reduced to just five
123
+ * minutes. We do this when storing a customer's credit card details in their
124
+ * session, to ensure the data does not persist for very long once they leave
125
+ * the site.
126
+ */
127
+ public function reduceClientSessionLifetime()
128
+ {
129
+ Mage::app()->getStore()->setConfig("web/cookie/cookie_lifetime", self::REDUCED_SESSION_LIFETIME);
130
+ }
131
+
132
+ /**
133
+ * Returns the URL that commences the MasterPass checkout process.
134
+ * It should point to the "start" controller action in the Checkout Controller inside this MasterPass module.
135
+ *
136
+ * @return string
137
+ */
138
+ public function getCheckoutRedirectUrl()
139
+ {
140
+ return Mage::getUrl("masterpass/checkout/start");
141
+ }
142
+
143
+ /**
144
+ * Returns the URL that customers should be sent back to from MasterPass (regardless of success or fail).
145
+ * It should point to the "continue" controller action in the Checkout Controller inside this MasterPass module.
146
+ *
147
+ * @return string
148
+ */
149
+ public function getCallbackUrl()
150
+ {
151
+ return Mage::getUrl("masterpass/checkout/continue");
152
+ }
153
+
154
+ /**
155
+ * @param int $environment
156
+ * @return string|null
157
+ */
158
+ public function getMasterpassBaseUrl($environment)
159
+ {
160
+ if (isset($this->_baseUrls[$environment])) {
161
+ return $this->_baseUrls[$environment];
162
+ } else {
163
+ return null;
164
+ }
165
+ }
166
+
167
+ /**
168
+ * @param int $api
169
+ * @param string $route
170
+ * @return string|null
171
+ */
172
+ public function getMasterpassApiUrl($api, $route)
173
+ {
174
+ if (isset($this->_apiUrls[$api])) {
175
+ $url = $this->getMasterpassBaseUrl(Mage::helper("fontis_masterpass/config")->getCurrentEnvironment());
176
+ $url .= $this->_apiUrls[$api] . $route;
177
+ return $url;
178
+ } else {
179
+ return null;
180
+ }
181
+ }
182
+
183
+ /**
184
+ * @param string $route
185
+ * @return string|null
186
+ */
187
+ public function getMasterpassOauthUrl($route)
188
+ {
189
+ return $this->getMasterpassApiUrl(self::URL_API_OAUTH, $route);
190
+ }
191
+
192
+ /**
193
+ * @param string $route
194
+ * @return string|null
195
+ */
196
+ public function getMasterpassOnlineUrl($route)
197
+ {
198
+ return $this->getMasterpassApiUrl(self::URL_API_ONLINE, $route);
199
+ }
200
+
201
+ /**
202
+ * Encodes all ASCII character to their decimal encodings.
203
+ *
204
+ * @param string $str
205
+ * @return string
206
+ */
207
+ public function htmlEncode($str)
208
+ {
209
+ // get rid of existing entities else double-escape
210
+ $str = html_entity_decode(stripslashes($str), ENT_QUOTES, "UTF-8");
211
+ $ar = preg_split('/(?<!^)(?!$)/u', $str ); // return array of every multi-byte character
212
+ $str2 = "";
213
+ foreach ($ar as $c) {
214
+ $o = ord($c);
215
+ if ((strlen($c) > 127) || /* multi-byte [unicode] */
216
+ ($o > 127)) /*Encodes everything above ascii 127*/
217
+ {
218
+ // convert to numeric entity
219
+ $c = mb_encode_numericentity($c, array(0x0, 0xffff, 0, 0xffff), "UTF-8");
220
+ }
221
+ $str2 .= $c;
222
+ }
223
+ return $str2;
224
+ }
225
+
226
+ /**
227
+ * Format a date in the format MasterPass expects.
228
+ * The function should take in a timestamp in the Unix date format.
229
+ * If the supplied date is not in this format, it attempts to convert it to this format.
230
+ *
231
+ * @param string $date
232
+ * @return string
233
+ */
234
+ public function formatDate($date)
235
+ {
236
+ if (!is_numeric($date)) {
237
+ $date = strtotime($date);
238
+ }
239
+ return date('Y-m-d\TH:i:s.000P', $date);
240
+ }
241
+
242
+ /**
243
+ * Check to see if an action is a "sensitive" action. This means that an encrypted credit card number
244
+ * is in the customer's session.
245
+ *
246
+ * @param Mage_Core_Controller_Request_Http $request
247
+ * @return bool
248
+ */
249
+ public function checkIfSensitiveRequest(Mage_Core_Controller_Request_Http $request)
250
+ {
251
+ if ($request->getRequestedRouteName() == "masterpass" && in_array($request->getRequestedActionName(), $this->_sensitiveRequests)) {
252
+ return true;
253
+ } else {
254
+ return false;
255
+ }
256
+ }
257
+
258
+ /**
259
+ * Check to see whether or not the current page is using SSL.
260
+ * This affects linked content such as images and scripts.
261
+ *
262
+ * @return bool
263
+ */
264
+ public function isSecure()
265
+ {
266
+ if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] === "on") {
267
+ return true;
268
+ } else {
269
+ return false;
270
+ }
271
+ }
272
+ }
app/code/community/Fontis/Masterpass/Model/Checkout.php ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Model_Checkout extends Mage_Core_Model_Abstract
20
+ {
21
+ // Cart XML
22
+ const CARTXML_GLOBAL = "ShoppingCartRequest";
23
+ const CARTXML_CART = "ShoppingCart";
24
+ const CARTXML_CURRENCY = "CurrencyCode";
25
+ const CARTXML_SUBTOTAL = "Subtotal";
26
+ const CARTXML_CARTITEM = "ShoppingCartItem";
27
+ const CARTXML_DESCRIPTION = "Description";
28
+ const CARTXML_QTY = "Quantity";
29
+ const CARTXML_VALUE = "Value";
30
+ const CARTXML_IMGURL = "ImageURL";
31
+
32
+ // Order XML
33
+ const ORDERXML_GLOBAL = "MerchantTransactions";
34
+ const ORDERXML_TXNID = "TransactionId";
35
+ const ORDERXML_CONSUMERKEY = "ConsumerKey";
36
+ const ORDERXML_CURRENCY = "Currency";
37
+ const ORDERXML_AMOUNT = "OrderAmount";
38
+ const ORDERXML_DATE = "PurchaseDate";
39
+ const ORDERXML_STATUS = "TransactionStatus";
40
+ const ORDERXML_APPROVALCODE = "ApprovalCode";
41
+
42
+ const ORDER_STATUS_SUCCESS = "Success";
43
+ const ORDER_STATUS_FAIL = "Failure";
44
+
45
+ const ORDER_APPROVALCODE_DEFAULT = "UNAVBL";
46
+
47
+ /**
48
+ * Turn the customer's shopping cart into an XML document.
49
+ *
50
+ * @param Mage_Sales_Model_Quote $quote
51
+ * @return SimpleXmlElement
52
+ */
53
+ public function generateCartXml(Mage_Sales_Model_Quote $quote)
54
+ {
55
+ Mage::dispatchEvent("fontis_masterpass_generate_cartxml_before", array("quote" => $quote));
56
+
57
+ //TODO: test with gift cards/voucher codes etc
58
+ $shoppingCartXml = new SimpleXmlElement("<" . self::CARTXML_GLOBAL . "></" . self::CARTXML_GLOBAL . ">");
59
+
60
+ $cart = $shoppingCartXml->addChild(self::CARTXML_CART);
61
+ $cart->addChild(self::CARTXML_CURRENCY, $quote->getStoreCurrencyCode());
62
+ $cart->addChild(self::CARTXML_SUBTOTAL, (int) bcmul($quote->getGrandTotal(), 100));
63
+
64
+ // Using $quote->getAllVisibleItems() accounts for bundle products, configurable products, etc.
65
+ foreach ($quote->getAllVisibleItems() as $cartItem) {
66
+ $product = $cartItem->getProduct();
67
+ $node = $cart->addChild(self::CARTXML_CARTITEM);
68
+ $node->addChild(self::CARTXML_DESCRIPTION, $product->getName());
69
+ $node->addChild(self::CARTXML_QTY, $cartItem->getQty());
70
+ $node->addChild(self::CARTXML_VALUE, (int) bcmul($product->getFinalPrice(), 100));
71
+ $node->addChild(self::CARTXML_IMGURL, $product->getThumbnailUrl());
72
+ }
73
+
74
+ Mage::dispatchEvent("fontis_masterpass_generate_cartxml_after", array("quote" => $quote));
75
+
76
+ return $shoppingCartXml;
77
+ }
78
+
79
+ /**
80
+ * Set available address fields on the supplied address object.
81
+ *
82
+ * @param Mage_Sales_Model_Quote_Address $address
83
+ * @param array $details
84
+ * @throws Exception
85
+ */
86
+ public function addDataToAddress(Mage_Sales_Model_Quote_Address $address, array $details)
87
+ {
88
+ Mage::dispatchEvent("fontis_masterpass_add_address_data_before", array("address" => $address));
89
+
90
+ foreach ($details as $key => $detail) {
91
+ $address->setDataUsingMethod($key, $detail);
92
+ }
93
+ $address->implodeStreetAddress()->setCollectShippingRates(true);
94
+ $validate = $address->validate();
95
+ if ($validate !== true) {
96
+ $message = "Failed to validate address after inserting address data.\n";
97
+ $message .= "Validation errors:\n" . print_r($validate, true);
98
+ $message .= "\nAddress details processed from XML retrieved from MasterPass:\n" . print_r($details, true);
99
+ throw new Exception($message);
100
+ }
101
+ $address->save();
102
+
103
+ Mage::dispatchEvent("fontis_masterpass_add_address_data_after", array("address" => $address));
104
+ }
105
+
106
+ /**
107
+ * Set available payment fields on the supplied payment object.
108
+ *
109
+ * @param Mage_Sales_Model_Quote_Payment $payment
110
+ * @param array $details
111
+ */
112
+ public function addPaymentData(Mage_Sales_Model_Quote_Payment $payment, array $details)
113
+ {
114
+ Mage::dispatchEvent("fontis_masterpass_add_payment_data_before", array("payment" => $payment));
115
+
116
+ $payment->importData($details);
117
+
118
+ Mage::dispatchEvent("fontis_masterpass_add_payment_data_after", array("payment" => $payment));
119
+ }
120
+
121
+ /**
122
+ * Update the shipping method set on the customer's quote.
123
+ *
124
+ * @param Mage_Sales_Model_Quote $quote
125
+ * @param string $methodCode
126
+ */
127
+ public function updateShippingMethod(Mage_Sales_Model_Quote $quote, $methodCode)
128
+ {
129
+ Mage::dispatchEvent("fontis_masterpass_update_shipping_method_before", array("quote" => $quote, "shipping_method" => $methodCode));
130
+
131
+ $changed = false;
132
+ if (!$quote->getIsVirtual() && $shippingAddress = $quote->getShippingAddress()) {
133
+ if ($methodCode != $shippingAddress->getShippingMethod()) {
134
+ $shippingAddress->setShippingMethod($methodCode)->setCollectShippingRates(true);
135
+ $quote->collectTotals()->save();
136
+ $changed = true;
137
+ }
138
+ }
139
+
140
+ Mage::dispatchEvent("fontis_masterpass_update_shipping_method_after", array("quote" => $quote, "shipping_method" => $methodCode, "changed" => $changed));
141
+ }
142
+
143
+ /**
144
+ * All of the logic involved in placing an order in Magento.
145
+ *
146
+ * @param Mage_Sales_Model_Quote $quote
147
+ * @return Mage_Sales_Model_Order
148
+ */
149
+ public function placeOrder(Mage_Sales_Model_Quote $quote)
150
+ {
151
+ Mage::dispatchEvent("fontis_masterpass_place_order_before", array("quote" => $quote));
152
+
153
+ // Check to see if the customer is logged in or not.
154
+ if (!$quote->getCustomerId()) {
155
+ $quote->setCustomerIsGuest(true)
156
+ ->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID)
157
+ ->setCustomerEmail($quote->getBillingAddress()->getEmail());
158
+ }
159
+ $quote->collectTotals();
160
+
161
+ /** @var Mage_Sales_Model_Service_Quote $service */
162
+ $service = Mage::getModel("sales/service_quote", $quote);
163
+
164
+ // The Mage_Sales_Model_Service_Quote interface changed from v1.4.1.0 CE onwards.
165
+ // This accounts for this change.
166
+ if (method_exists($service, "submitAll")) {
167
+ $service->submitAll();
168
+ $order = $service->getOrder();
169
+ } else {
170
+ $order = $service->submit();
171
+ }
172
+ $order->save();
173
+
174
+ Mage::dispatchEvent("fontis_masterpass_place_order_after", compact("quote", "order"));
175
+
176
+ return $order;
177
+ }
178
+
179
+ /**
180
+ * Turn the customer's order into an XML document.
181
+ *
182
+ * @param Mage_Sales_Model_Order $order
183
+ * @param string $transactionId
184
+ * @return SimpleXmlElement
185
+ */
186
+ public function generateOrderXml(Mage_Sales_Model_Order $order, $transactionId)
187
+ {
188
+ Mage::dispatchEvent("fontis_masterpass_generate_orderxml_before", array("order" => $order));
189
+
190
+ // This is not an accident. The specification requires the same tag nested inside itself.
191
+ $orderXml = new SimpleXmlElement("<" . self::ORDERXML_GLOBAL . "></" . self::ORDERXML_GLOBAL . ">");
192
+ $main = $orderXml->addChild(self::ORDERXML_GLOBAL);
193
+
194
+ $main->addChild(self::ORDERXML_TXNID, $transactionId);
195
+ $main->addChild(self::ORDERXML_CURRENCY, $order->getOrderCurrencyCode());
196
+ $main->addChild(self::ORDERXML_AMOUNT, (int) bcmul($order->getGrandTotal(), 100));
197
+ $main->addChild(self::ORDERXML_DATE, Mage::helper("fontis_masterpass")->formatDate($order->getCreatedAtStoreDate()->toValue()));
198
+ $main->addChild(self::ORDERXML_STATUS, self::ORDER_STATUS_SUCCESS);
199
+ // The default is used for everything because we don't know where the 6-digit approval code is supposed to come from.
200
+ $main->addChild(self::ORDERXML_APPROVALCODE, self::ORDER_APPROVALCODE_DEFAULT);
201
+
202
+ Mage::dispatchEvent("fontis_masterpass_generate_orderxml_after", array("order" => $order));
203
+
204
+ return $orderXml;
205
+ }
206
+ }
app/code/community/Fontis/Masterpass/Model/Directory/Region.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Model_Directory_Region extends Mage_Directory_Model_Region
20
+ {
21
+ /**
22
+ * Proper function to lookup region based on country ID and region ID.
23
+ * Magento's built-in functions are buggy and will only return a region if there is an
24
+ * entry in directory_country_region_name for the locale of the current store. If it
25
+ * can't find one, it won't return anything (not even the region with the "default_name"
26
+ * field filled.
27
+ *
28
+ * @param string $region
29
+ * @param string $countryId
30
+ * @return Mage_Directory_Model_Region
31
+ */
32
+ public function lookupRegion($region, $countryId)
33
+ {
34
+ /** @var Mage_Core_Model_Resource $resource */
35
+ $resource = Mage::getSingleton("core/resource");
36
+ $connection = $resource->getConnection(Mage_Core_Model_Resource::DEFAULT_READ_RESOURCE);
37
+
38
+ $select = $connection->select()
39
+ ->from(array("region" => $resource->getTableName("directory/country_region")))
40
+ ->where("region.country_id = ?", $countryId)
41
+ ->where("region.code = ?", $region);
42
+ $data = $connection->fetchRow($select);
43
+ if (!empty($data)) {
44
+ $this->setData($data);
45
+ } else {
46
+ return $this;
47
+ }
48
+
49
+ $locale = Mage::app()->getLocale()->getLocaleCode();
50
+ $select = $connection->select()
51
+ ->from(array("rname" => $resource->getTableName("directory/country_region_name")))
52
+ ->columns("rname.name")
53
+ ->where("rname.locale = ?", $locale)
54
+ ->where("rname.region_id = ?", $this->getId());
55
+ $name = $connection->fetchRow($select);
56
+ if (!empty($name)) {
57
+ $this->setName($name["name"]);
58
+ }
59
+
60
+ return $this;
61
+ }
62
+ }
app/code/community/Fontis/Masterpass/Model/Masterpass/Oauth.php ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Model_Masterpass_Oauth extends Mage_Core_Model_Abstract
20
+ {
21
+ const OAUTH_TOKEN = Zend_Oauth_Token::TOKEN_PARAM_KEY;
22
+ const OAUTH_VERIFIER = "oauth_verifier";
23
+ const OAUTH_CHECKOUT_RES_URL = "checkout_resource_url";
24
+ const OAUTH_CALLBACK_CONFIRMED = Zend_Oauth_Token::TOKEN_PARAM_CALLBACK_CONFIRMED;
25
+ const OAUTH_BODY_HASH = "oauth_body_hash";
26
+ const OAUTH_REQUEST_URL = "xoauth_request_auth_url";
27
+
28
+ /**
29
+ * Method used to sign Oauth requests.
30
+ * Currently MasterPass only supports RSA-SHA1.
31
+ *
32
+ * @var string
33
+ */
34
+ protected $_signatureMethod = "RSA-SHA1";
35
+
36
+ /**
37
+ * Oauth Version to use.
38
+ * Both Zend_Oauth and MasterPass do not currently support anything other than v1.0.
39
+ *
40
+ * @var string
41
+ */
42
+ protected $_oauthVersion = "1.0";
43
+
44
+ /**
45
+ * Realm for Oauth request.
46
+ * Used to differentiate between MasterPass mobile and desktop sites.
47
+ * According to documentation, not currently used, but is required.
48
+ *
49
+ * @var string
50
+ */
51
+ protected $_oauthRealm = "eWallet";
52
+
53
+ /**
54
+ * XML Version to use for payment data being requested from MasterPass.
55
+ * We always want to use v4, which is the most recent version MasterPass supports.
56
+ * Must be of the format "vX" where X is the version number.
57
+ *
58
+ * @var string
59
+ */
60
+ protected $_xmlVersion = "v4";
61
+
62
+ /**
63
+ * Holds config values to pass to the Zend_Oauth module.
64
+ *
65
+ * @var array
66
+ */
67
+ protected $_oauthConfig = null;
68
+
69
+ /**
70
+ * @var Fontis_Masterpass_Helper_Data
71
+ */
72
+ protected $_helper = null;
73
+
74
+ /**
75
+ * @var Fontis_Masterpass_Helper_Config
76
+ */
77
+ protected $_configHelper = null;
78
+
79
+ /**
80
+ * Initialises the object with default configuration.
81
+ */
82
+ public function __construct()
83
+ {
84
+ $this->_helper = Mage::helper("fontis_masterpass");
85
+ $this->_configHelper = Mage::helper("fontis_masterpass/config");
86
+ $this->_oauthConfig = array(
87
+ "consumerKey" => $this->_configHelper->getConsumerKey(),
88
+ "signatureMethod" => $this->_signatureMethod,
89
+ "version" => $this->_oauthVersion,
90
+ "accessTokenUrl" => $this->_helper->getMasterpassOauthUrl("consumer/v1/access_token"),
91
+ "rsaPrivateKey" => new Zend_Crypt_Rsa_Key_Private($this->_configHelper->getPrivateKey(), ""),
92
+ "realm" => $this->_oauthRealm,
93
+ );
94
+ }
95
+
96
+ /**
97
+ * Make the initial request to MasterPass to get an OAuth token.
98
+ * This token is used in future requests to the MasterPass API.
99
+ *
100
+ * @return Zend_Oauth_Token_Request
101
+ */
102
+ public function getRequestToken()
103
+ {
104
+ // Initialise the OAuth request.
105
+ $config = array_merge($this->_oauthConfig, array(
106
+ "callbackUrl" => $this->_helper->getCallbackUrl(),
107
+ "requestTokenUrl" => $this->_helper->getMasterpassOauthUrl("consumer/v1/request_token"),
108
+ "requestMethod" => Zend_Oauth::POST,
109
+ ));
110
+ $consumer = new Fontis_Masterpass_Model_Zend_OauthConsumer($config);
111
+ $request = new Fontis_Masterpass_Model_Zend_OauthRequestToken($consumer);
112
+ $request->setMethod(Zend_Oauth::POST);
113
+
114
+ // Make the request to MasterPass.
115
+ $requestToken = $request->execute();
116
+ return $requestToken;
117
+ }
118
+
119
+ /**
120
+ * Submit shopping cart XML to MasterPass.
121
+ *
122
+ * @param SimpleXMLElement|string $cartXml the customer's cart in XML form, according to MasterPass specifications
123
+ * @return Zend_Oauth_Token_Request
124
+ */
125
+ public function submitShoppingCartXml($cartXml)
126
+ {
127
+ return $this->submitXmlToMasterpass($cartXml, $this->_helper->getMasterpassOnlineUrl("v1/shopping-cart"));
128
+ }
129
+
130
+ /**
131
+ * Construct the URL used to redirect a customer to MasterPass.
132
+ *
133
+ * @param Zend_Oauth_Token_Request $requestToken the RequestToken object created from the original MasterPass API call
134
+ * @param bool $suppressShippingAddress whether or not the customer's cart contains just virtual and/or downloadable products
135
+ * @return string|null
136
+ */
137
+ public function getRedirectUrl($requestToken, $suppressShippingAddress)
138
+ {
139
+ // Get primary redirect URL from request token.
140
+ $url = $requestToken->getParam(self::OAUTH_REQUEST_URL);
141
+ if (!$url) {
142
+ return null;
143
+ }
144
+
145
+ // Add required query string parameters to the redirect URL.
146
+ // eg. https://sandbox.masterpass.com/Checkout/Authorize?acceptable_cards=master,visa&checkout_identifier=mycheckoutid&oauth_token=mytoken&version=v4&suppress_shipping_address=false&accept_reward_program=false
147
+ $queryParameters = array(
148
+ "acceptable_cards" => $this->_configHelper->getAcceptedCards(false),
149
+ "checkout_identifier" => $this->_configHelper->getCheckoutIdentifier(),
150
+ "oauth_token" => $requestToken->getParam(self::OAUTH_TOKEN),
151
+ "version" => $this->_xmlVersion,
152
+ "suppress_shipping_address" => $suppressShippingAddress ? "true" : "false", // For situations such as the cart containing all virtual items
153
+ "accept_reward_program" => "false", // We don't want MasterPass to deal with any vouchers or gift cards.
154
+ );
155
+
156
+ $queryString = http_build_query($queryParameters);
157
+ return $url . "?" . $queryString;
158
+ }
159
+
160
+ /**
161
+ * Get access token from MasterPass.
162
+ * This token is later used to retrieve the customer's payment and shipping details from MasterPass.
163
+ *
164
+ * @param array $queryData the query string appended to the MasterPass callback URL by MasterPass
165
+ * @param Zend_Oauth_Token_Request $requestToken the RequestToken object created from the original MasterPass API call
166
+ * @return Zend_Oauth_Token_Access
167
+ */
168
+ public function getAccessToken($queryData, $requestToken)
169
+ {
170
+ // Initialise the OAuth request.
171
+ $config = array_merge($this->_oauthConfig, array(
172
+ "accessTokenUrl" => $this->_helper->getMasterpassOauthUrl("consumer/v1/access_token"),
173
+ "requestMethod" => Zend_Oauth::POST,
174
+ ));
175
+ $consumer = new Fontis_Masterpass_Model_Zend_OauthConsumer($config);
176
+ $request = new Fontis_Masterpass_Model_Zend_OauthAccessToken($consumer);
177
+ $request->setMethod(Zend_Oauth::POST);
178
+
179
+ // Make the request to MasterPass.
180
+ $accessToken = $consumer->getAccessToken($queryData, $requestToken, Zend_Oauth::POST, $request);
181
+ return $accessToken;
182
+ }
183
+
184
+ /**
185
+ * @param Zend_Oauth_Token_Access $accessToken
186
+ * @param string $checkoutResourceUrl the URL returned in the callback to retrieve the payment data from
187
+ * @return Zend_Oauth_Token_Request
188
+ */
189
+ public function getPaymentData($accessToken, $checkoutResourceUrl)
190
+ {
191
+ // Initialise the OAuth request.
192
+ $config = array_merge($this->_oauthConfig, array(
193
+ "requestTokenUrl" => $checkoutResourceUrl,
194
+ "requestMethod" => Zend_Oauth::GET,
195
+ ));
196
+ $consumer = new Fontis_Masterpass_Model_Zend_OauthConsumer($config);
197
+ // We're using a RequestToken rather than an AccessToken because this request doesn't need
198
+ // to be signed. It just needs an access token.
199
+ $request = new Fontis_Masterpass_Model_Zend_OauthRequestToken($consumer);
200
+ $request->setMethod(Zend_Oauth::GET);
201
+
202
+ // Manually set the OAuth token for this request.
203
+ $parameters = array(self::OAUTH_TOKEN => $accessToken->getToken());
204
+ // MasterPass may tack on query parameters to the checkout resource URL. We need to retrieve
205
+ // these and include them in the parameters used to generate the OAuth signature.
206
+ parse_str(parse_url($checkoutResourceUrl, PHP_URL_QUERY), $queryParams);
207
+ $request->setParameters(array_merge($parameters, $queryParams));
208
+
209
+ // Initialise the OAuth HTTP client.
210
+ $params = $request->assembleParams();
211
+ $client = $request->getRequestSchemeHeaderClient($params);
212
+
213
+ // Make the request to MasterPass.
214
+ $response = $client->request();
215
+ $return = new Zend_Oauth_Token_Request($response);
216
+ return $return;
217
+ }
218
+
219
+ /**
220
+ * Submit order XML to MasterPass.
221
+ *
222
+ * @param SimpleXMLElement|string $orderXml specific details about the customer's order in XML form, according to MasterPass specifications
223
+ * @return Zend_Oauth_Token_Request
224
+ */
225
+ public function submitTransactionPostback($orderXml)
226
+ {
227
+ return $this->submitXmlToMasterpass($orderXml, $this->_helper->getMasterpassOnlineUrl("v2/transaction"));
228
+ }
229
+
230
+ /**
231
+ * Generic function to submit XML to MasterPass.
232
+ *
233
+ * @param SimpleXMLElement|string $xml
234
+ * @param string $url
235
+ * @return Zend_Oauth_Token_Request
236
+ */
237
+ protected function submitXmlToMasterpass($xml, $url)
238
+ {
239
+ // Ensure the XML is in string form.
240
+ if ($xml instanceof SimpleXMLElement) {
241
+ $xml = $xml->asXML();
242
+ }
243
+
244
+ // Initialise the OAuth request.
245
+ $config = array_merge($this->_oauthConfig, array(
246
+ "requestTokenUrl" => $url,
247
+ "requestMethod" => Zend_Oauth::POST,
248
+ ));
249
+ $consumer = new Fontis_Masterpass_Model_Zend_OauthConsumer($config);
250
+ $request = new Fontis_Masterpass_Model_Zend_OauthRequestToken($consumer);
251
+ $request->setMethod(Zend_Oauth::POST);
252
+ // oauth_body_hash doesn't appear to be a standard OAuth field.
253
+ // It is however something that MasterPass requires.
254
+ $request->setParameters(array(self::OAUTH_BODY_HASH => $this->generateBodyHash($xml)));
255
+
256
+ // Initialise the OAuth HTTP client.
257
+ $params = $request->assembleParams();
258
+ $client = $request->getRequestSchemeHeaderClient($params);
259
+ $client->setRawData($xml);
260
+ $client->setEncType("application/xml");
261
+
262
+ // Make the request to MasterPass.
263
+ $response = $client->request();
264
+ $return = new Zend_Oauth_Token_Request($response);
265
+ return $return;
266
+ }
267
+
268
+ /**
269
+ * Generate hash from body content.
270
+ * Taken from the MasterPass sample code.
271
+ *
272
+ * @param string $body
273
+ * @return string
274
+ */
275
+ protected function generateBodyHash($body)
276
+ {
277
+ $sha1Hash = sha1($body, true);
278
+ return base64_encode($sha1Hash);
279
+ }
280
+ }
app/code/community/Fontis/Masterpass/Model/Masterpass/Order.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Model_Masterpass_Order extends Mage_Core_Model_Abstract
20
+ {
21
+ /**
22
+ * If the postback to MasterPass is successful, they return the same data back to us.
23
+ * This function verifies that the returned data matches the order XML we generated.
24
+ * Ideally, this function would be a straight string comparison. Unfortunately, we
25
+ * can't guarantee that will work.
26
+ *
27
+ * @param SimpleXMLElement $orderXml
28
+ * @param SimpleXMLElement $orderPostbackXml
29
+ * @return bool
30
+ */
31
+ public function verifyOrderPostback(SimpleXMLElement $orderXml, SimpleXMLElement $orderPostbackXml)
32
+ {
33
+ $orderXmlCheck = $orderXml->{Fontis_Masterpass_Model_Checkout::ORDERXML_GLOBAL};
34
+ $orderPostbackXmlCheck = $orderPostbackXml->{Fontis_Masterpass_Model_Checkout::ORDERXML_GLOBAL};
35
+ if (empty($orderXmlCheck) || empty($orderPostbackXmlCheck)) {
36
+ return false;
37
+ }
38
+
39
+ /**
40
+ * We cannot guarantee that MasterPass will return the order date in the same format as:
41
+ * a) the format of the date we supplied
42
+ * b) the format they specified in their own documentation
43
+ */
44
+ $date1 = $orderXmlCheck->{Fontis_Masterpass_Model_Checkout::ORDERXML_DATE};
45
+ $date2 = $orderPostbackXmlCheck->{Fontis_Masterpass_Model_Checkout::ORDERXML_DATE};
46
+ if (empty($date1) || empty($date2)) {
47
+ return false;
48
+ }
49
+ $date1 = strtotime($date1);
50
+ $date2 = strtotime($date2);
51
+ if ($date1 != $date2) {
52
+ return false;
53
+ }
54
+
55
+ foreach ($orderXmlCheck->children() as $childName => $childNode) {
56
+ if ($childName == Fontis_Masterpass_Model_Checkout::ORDERXML_DATE) {
57
+ // We've already checked this.
58
+ continue;
59
+ }
60
+
61
+ $temp1 = (string) $childNode;
62
+ $tempNode = $orderPostbackXmlCheck->{$childName};
63
+ if (empty($tempNode)) {
64
+ return false;
65
+ }
66
+ $temp2 = (string) $tempNode;
67
+
68
+ if ($temp1 != $temp2) {
69
+ return false;
70
+ }
71
+ }
72
+
73
+ return true;
74
+ }
75
+ }
app/code/community/Fontis/Masterpass/Model/Masterpass/Payment.php ADDED
@@ -0,0 +1,346 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Model_Masterpass_Payment extends Mage_Core_Model_Abstract
20
+ {
21
+ const PDATA_BILLING_GROUP = "BillingAddress";
22
+ const PDATA_SHIPPING_GROUP = "ShippingAddress";
23
+ const PDATA_PAYMENT_GROUP = "Card";
24
+ const PDATA_CUSTOMER_GROUP = "Contact";
25
+ const PDATA_TRANSACTIONID = "TransactionId";
26
+
27
+ const MAGE_ADDRESS_EMAIL = "email";
28
+ const MAGE_ADDRESS_FIRSTNAME = "firstname";
29
+ const MAGE_ADDRESS_MIDDLENAME = "middlename";
30
+ const MAGE_ADDRESS_LASTNAME = "lastname";
31
+ const MAGE_ADDRESS_PHONE = "telephone";
32
+ const MAGE_ADDRESS_STREET = "street";
33
+
34
+ const PDATA_PAYMENT_CARD_TYPE = "BrandId";
35
+ const MAGE_PAYMENT_CARD_TYPE = "cc_type";
36
+
37
+ /**
38
+ * Maps MasterPass address fields to Magento quote address fields.
39
+ *
40
+ * @var array
41
+ */
42
+ protected $_addressFieldMapping = array(
43
+ "City" => "city",
44
+ "Country" => "country_id",
45
+ "CountrySubdivision" => "region",
46
+ "Line1" => "street1",
47
+ "Line2" => "street2",
48
+ "Line3" => "street3",
49
+ "PostalCode" => "postcode",
50
+ );
51
+
52
+ /**
53
+ * Maps MasterPass credit card fields to Magento quote payment fields.
54
+ *
55
+ * @var array
56
+ */
57
+ protected $_paymentFieldMapping = array(
58
+ "CardHolderName" => "cc_owner",
59
+ "AccountNumber" => "cc_number",
60
+ "ExpiryMonth" => "cc_exp_month",
61
+ "ExpiryYear" => "cc_exp_year",
62
+ );
63
+
64
+ /**
65
+ * @param SimpleXMLElement $paymentDataXml
66
+ * @param bool $ignoreShippingAddress
67
+ * @return array
68
+ * @throws Exception
69
+ * @throws Fontis_Masterpass_PaymentException
70
+ */
71
+ public function processPaymentData(SimpleXMLElement $paymentDataXml, $ignoreShippingAddress)
72
+ {
73
+ if (empty($paymentDataXml)) {
74
+ throw new Exception("Cannot process empty XML object.");
75
+ }
76
+
77
+ $return = array();
78
+
79
+ // Get the address and payment data necessary for Magento from the XML.
80
+ $return["billingAddress"] = $this->extractBillingAddressFromPaymentData($paymentDataXml);
81
+ $return["payment"] = $this->extractPaymentDetailsFromPaymentData($paymentDataXml);
82
+ if ($ignoreShippingAddress !== true) {
83
+ $return["shippingAddress"] = $this->extractShippingAddressFromPaymentData($paymentDataXml);
84
+ }
85
+
86
+ // Get the MasterPass transaction ID from the XML.
87
+ $transactionIdXml = $paymentDataXml->{self::PDATA_TRANSACTIONID};
88
+ if (empty($transactionIdXml)) {
89
+ throw new Fontis_Masterpass_PaymentException("Transaction ID was missing from XML.");
90
+ }
91
+ $return["transactionId"] = (string) $transactionIdXml;
92
+
93
+ return $return;
94
+ }
95
+
96
+ /**
97
+ * Takes the full payment data XML (as a SimpleXMLElement object) retrieved from MasterPass and extracts
98
+ * the billing address details from it.
99
+ *
100
+ * @param SimpleXMLElement $paymentDataXml the entire XML document retrieved from MasterPass
101
+ * @return array
102
+ * @throws Exception
103
+ * @throws Fontis_Masterpass_PaymentException
104
+ */
105
+ public function extractBillingAddressFromPaymentData(SimpleXMLElement $paymentDataXml)
106
+ {
107
+ if (empty($paymentDataXml)) {
108
+ throw new Exception("Cannot process empty XML object.");
109
+ }
110
+
111
+ $paymentData = $paymentDataXml->{self::PDATA_PAYMENT_GROUP};
112
+ if (empty($paymentData)) {
113
+ throw new Fontis_Masterpass_PaymentException("Payment data was missing from XML.");
114
+ }
115
+ $billingData = $paymentData->{self::PDATA_BILLING_GROUP};
116
+ if (empty($billingData)) {
117
+ throw new Fontis_Masterpass_PaymentException("Billing address data was missing from XML.");
118
+ }
119
+ $billingDataArray = $this->processAddressFields($billingData);
120
+
121
+ $billingDataArray = $this->attachContactDetailsToBillingDataArray($billingDataArray, $paymentDataXml);
122
+
123
+ return $billingDataArray;
124
+ }
125
+
126
+ /**
127
+ * @param array $billingDataArray
128
+ * @param SimpleXMLElement $paymentDataXml the entire XML document retrieved from MasterPass
129
+ * @return array
130
+ * @throws Exception
131
+ * @throws Fontis_Masterpass_PaymentException
132
+ */
133
+ protected function attachContactDetailsToBillingDataArray(array $billingDataArray, SimpleXMLElement $paymentDataXml)
134
+ {
135
+ if (empty($paymentDataXml)) {
136
+ throw new Exception("Cannot process empty XML object.");
137
+ }
138
+
139
+ $contactData = $paymentDataXml->{self::PDATA_CUSTOMER_GROUP};
140
+ if (empty($contactData)) {
141
+ throw new Fontis_Masterpass_PaymentException("Contact data was missing from XML.");
142
+ }
143
+
144
+ $billingDataArray[self::MAGE_ADDRESS_EMAIL] = (string) $contactData->EmailAddress;
145
+ $billingDataArray[self::MAGE_ADDRESS_FIRSTNAME] = (string) $contactData->FirstName;
146
+ $billingDataArray[self::MAGE_ADDRESS_LASTNAME] = (string) $contactData->LastName;
147
+ $billingDataArray[self::MAGE_ADDRESS_PHONE] = (string) $contactData->PhoneNumber;
148
+
149
+ $middleInitial = $contactData->MiddleInitial;
150
+ if (!empty($middleInitial)) {
151
+ $billingDataArray[self::MAGE_ADDRESS_MIDDLENAME] = (string) $middleInitial;
152
+ }
153
+
154
+ return $billingDataArray;
155
+ }
156
+
157
+ /**
158
+ * Takes the full payment data XML (as a SimpleXMLElement object) retrieved from MasterPass and extracts
159
+ * the shipping address details from it.
160
+ *
161
+ * @param SimpleXMLElement $paymentDataXml the entire XML document retrieved from MasterPass
162
+ * @return array
163
+ * @throws Exception
164
+ * @throws Fontis_Masterpass_PaymentException
165
+ */
166
+ public function extractShippingAddressFromPaymentData(SimpleXMLElement $paymentDataXml)
167
+ {
168
+ if (empty($paymentDataXml)) {
169
+ throw new Exception("Cannot process empty XML object.");
170
+ }
171
+
172
+ $shippingData = $paymentDataXml->{self::PDATA_SHIPPING_GROUP};
173
+ if (empty($shippingData)) {
174
+ throw new Fontis_Masterpass_PaymentException("Shipping address data was missing from XML.");
175
+ }
176
+ $shippingDataArray = $this->processAddressFields($shippingData);
177
+
178
+ $shippingDataArray = $this->attachContactDetailsToShippingDataArray($shippingDataArray, $paymentDataXml);
179
+
180
+ return $shippingDataArray;
181
+ }
182
+
183
+ /**
184
+ * @param array $shippingDataArray
185
+ * @param SimpleXMLElement $paymentDataXml the entire XML document retrieved from MasterPass
186
+ * @return array
187
+ * @throws Fontis_Masterpass_PaymentException
188
+ */
189
+ protected function attachContactDetailsToShippingDataArray(array $shippingDataArray, SimpleXMLElement $paymentDataXml)
190
+ {
191
+ $contactData = $paymentDataXml->{self::PDATA_CUSTOMER_GROUP};
192
+ if (empty($contactData)) {
193
+ throw new Fontis_Masterpass_PaymentException("Contact data was missing from XML.");
194
+ }
195
+
196
+ $shippingData = $paymentDataXml->{self::PDATA_SHIPPING_GROUP};
197
+ if (empty($shippingData)) {
198
+ throw new Fontis_Masterpass_PaymentException("Shipping address data was missing from XML.");
199
+ }
200
+
201
+ list($firstName, $middleName, $lastName) = $this->explodeName((string) $shippingData->RecipientName);
202
+
203
+ $shippingDataArray[self::MAGE_ADDRESS_EMAIL] = (string) $contactData->EmailAddress;
204
+ $shippingDataArray[self::MAGE_ADDRESS_FIRSTNAME] = $firstName;
205
+ $shippingDataArray[self::MAGE_ADDRESS_MIDDLENAME] = $middleName;
206
+ $shippingDataArray[self::MAGE_ADDRESS_LASTNAME] = $lastName;
207
+ $shippingDataArray[self::MAGE_ADDRESS_PHONE] = (string) $shippingData->RecipientPhoneNumber;
208
+
209
+ return $shippingDataArray;
210
+ }
211
+
212
+ /**
213
+ * Splits a string up into three parts based on the number of words (names) in the string.
214
+ * If there are three or more words (names) in the supplied string, all except the first and last word will be
215
+ * placed into the middle element of the returned array.
216
+ *
217
+ * @param string $name
218
+ * @return array
219
+ */
220
+ protected function explodeName($name)
221
+ {
222
+ $parts = explode(" ", $name);
223
+ $count = count($parts);
224
+ if ($count < 2) {
225
+ // If the customer only entered one name, put it in the first name field.
226
+ return array($parts[0], "", "");
227
+ } elseif ($count == 2) {
228
+ // If the customer entered two names, put them in the first and last name fields.
229
+ return array($parts[0], "", $parts[1]);
230
+ } else {
231
+ // If the customer entered 3 or more names, put all but the first and last name into the middle name field.
232
+ return array($parts[0], implode(" ", array_slice($parts, 1, ($count - 2))), $parts[($count - 1)]);
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Turn address information from the MasterPass-supplied data into the address information
238
+ * Magento expects.
239
+ *
240
+ * @param SimpleXMLElement $xmlNode
241
+ * @return array
242
+ */
243
+ protected function processAddressFields(SimpleXMLElement $xmlNode)
244
+ {
245
+ $address = array(self::MAGE_ADDRESS_STREET => array());
246
+ foreach ($this->_addressFieldMapping as $key => $field) {
247
+ $tempField = $xmlNode->{$key};
248
+ if (!empty($tempField)) {
249
+ if (stripos($field, self::MAGE_ADDRESS_STREET) === false) {
250
+ $address[$field] = (string) $tempField;
251
+ } else {
252
+ $address[self::MAGE_ADDRESS_STREET][] = (string) $tempField;
253
+ }
254
+ }
255
+ }
256
+
257
+ $address = $this->processRegion($address);
258
+ return $address;
259
+ }
260
+
261
+ /**
262
+ * Turn the region information from the MasterPass-supplied address into the region
263
+ * information Magento expects.
264
+ *
265
+ * @param array $address
266
+ * @return array
267
+ */
268
+ protected function processRegion(array $address)
269
+ {
270
+ if (!$address["region"]) {
271
+ return $address;
272
+ }
273
+
274
+ // The region field may arrive from MasterPass in the form "AU-VIC" for countries that have set regions.
275
+ // Check to see if we need to strip off the country code from the front.
276
+ if (preg_match("/^[A-Z][A-Z]-[A-Z]+/", $address["region"])) {
277
+ $region = explode("-", $address["region"]);
278
+ $address["region"] = $region[1];
279
+ }
280
+
281
+ if (!$address["country_id"]) {
282
+ return $address;
283
+ }
284
+
285
+ $regionModel = Mage::getModel("fontis_masterpass/directory_region")->lookupRegion($address["region"], $address["country_id"]);
286
+ if ($id = $regionModel->getId()) {
287
+ if ($name = $regionModel->getName()) {
288
+ $address["region_id"] = $id;
289
+ $address["region"] = $name;
290
+ }
291
+ }
292
+
293
+ return $address;
294
+ }
295
+
296
+ /**
297
+ * Takes the full payment data XML (as a SimpleXMLElement object) retrieved from MasterPass and extracts
298
+ * the payment details from it.
299
+ *
300
+ * @param SimpleXMLElement $paymentDataXml the entire XML document retrieved from MasterPass
301
+ * @return array
302
+ * @throws Exception
303
+ * @throws Fontis_Masterpass_PaymentException
304
+ */
305
+ public function extractPaymentDetailsFromPaymentData(SimpleXMLElement $paymentDataXml)
306
+ {
307
+ if (empty($paymentDataXml)) {
308
+ throw new Exception("Cannot process empty XML object.");
309
+ }
310
+
311
+ $paymentData = $paymentDataXml->{self::PDATA_PAYMENT_GROUP};
312
+ if (empty($paymentData)) {
313
+ throw new Fontis_Masterpass_PaymentException("Payment data was missing from XML.");
314
+ }
315
+ $paymentDataArray = $this->processPaymentFields($paymentData);
316
+
317
+ return $paymentDataArray;
318
+ }
319
+
320
+ /**
321
+ * Turn the payment information from the MasterPass-supplied data into the payment
322
+ * information Magento expects.
323
+ *
324
+ * @param SimpleXMLElement $xmlNode
325
+ * @return array
326
+ * @throws Fontis_Masterpass_PaymentException
327
+ */
328
+ protected function processPaymentFields(SimpleXMLElement $xmlNode)
329
+ {
330
+ $payment = array();
331
+ foreach ($this->_paymentFieldMapping as $key => $field) {
332
+ $tempField = $xmlNode->{$key};
333
+ if (!empty($tempField)) {
334
+ $payment[$field] = (string) $tempField;
335
+ }
336
+ }
337
+
338
+ $ccType = $xmlNode->{self::PDATA_PAYMENT_CARD_TYPE};
339
+ if (empty($ccType)) {
340
+ throw new Fontis_Masterpass_PaymentException("Credit card type was missing from XML.");
341
+ }
342
+ $payment[self::MAGE_PAYMENT_CARD_TYPE] = Mage::getModel("fontis_masterpass/system_cards")->lookupMageCode((string) $ccType);
343
+
344
+ return $payment;
345
+ }
346
+ }
app/code/community/Fontis/Masterpass/Model/Observer.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Model_Observer
20
+ {
21
+ /**
22
+ * Check to see if there is an encrypted credit card number in the user's session.
23
+ * If there is, and we're not in the middle of a specific MasterPass request, clear
24
+ * it from the session.
25
+ *
26
+ * Observes event "controller_action_predispatch".
27
+ *
28
+ * @param Varien_Event_Observer $observer
29
+ */
30
+ public function checkMasterpassDataInSession(Varien_Event_Observer $observer)
31
+ {
32
+ /** @var $this Mage_Core_Controller_Varien_Action */
33
+ $controller = $observer->getEvent()->getControllerAction();
34
+ if (!(Mage::helper("fontis_masterpass")->checkIfSensitiveRequest($controller->getRequest()))) {
35
+ Mage::getSingleton("checkout/session")->unsetData(Fontis_Masterpass_Helper_Data::MPASS_CC_NUMBER_ENC);
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Observes event "controller_action_predispatch_checkout_onepage_saveOrder".
41
+ *
42
+ * @param Varien_Event_Observer $observer
43
+ */
44
+ public function redirectUserToMasterpass(Varien_Event_Observer $observer)
45
+ {
46
+ $request = $observer->getEvent()->getControllerAction()->getRequest();
47
+ if ($data = $request->getPost("payment", false)) {
48
+ if ($data["method"] == Fontis_Masterpass_Model_Payment::PAYMENT_CODE) {
49
+ $redirectUrl = Mage::helper("fontis_masterpass")->getCheckoutRedirectUrl();
50
+ if ($observer->getEvent()->getDirectRedirect() === true) {
51
+ header('Location: ' . $redirectUrl);
52
+ } else {
53
+ echo Mage::helper("core")->jsonEncode(array("redirect" => $redirectUrl));
54
+ }
55
+ exit;
56
+ }
57
+ }
58
+ }
59
+ }
app/code/community/Fontis/Masterpass/Model/Payment.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Model_Payment extends Mage_Payment_Model_Method_Abstract
20
+ {
21
+ const PAYMENT_CODE = "fontis_masterpass";
22
+
23
+ protected $_code = self::PAYMENT_CODE;
24
+
25
+ protected $_canUseInternal = false;
26
+ protected $_canUseCheckout = true;
27
+ protected $_canUseForMultishipping = false;
28
+
29
+ protected $_formBlockType = "fontis_masterpass/payment_form";
30
+
31
+ /**
32
+ * @param $quote
33
+ * @return bool
34
+ */
35
+ public function isAvailable($quote = null)
36
+ {
37
+ return Mage::helper("fontis_masterpass")->canShowOnCheckout();
38
+ }
39
+
40
+ /**
41
+ * @return string
42
+ */
43
+ public function getTitle()
44
+ {
45
+ return Mage::helper("fontis_masterpass/config")->getFrontendTitle();
46
+ }
47
+
48
+ /**
49
+ * @param int $ignore
50
+ * @return Fontis_Masterpass_Model_Payment
51
+ */
52
+ public function setSortOrder($ignore)
53
+ {
54
+ $this->setData("sort_order", Mage::helper("fontis_masterpass/config")->getPaymentSortOrder());
55
+ return $this;
56
+ }
57
+ }
app/code/community/Fontis/Masterpass/Model/System/Cards.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Model_System_Cards extends Mage_Core_Model_Config_Data
20
+ {
21
+ const MASTERCARD = "master";
22
+ const AMEX = "amex";
23
+ const DINERS = "diners";
24
+ const DISCOVER = "discover";
25
+ const MAESTRO = "maestro";
26
+ const VISA = "visa";
27
+
28
+ public static $_options = array(
29
+ self::MASTERCARD => "MasterCard",
30
+ self::AMEX => "American Express",
31
+ self::DINERS => "Diners Club",
32
+ self::DISCOVER => "Discover",
33
+ self::MAESTRO => "Maestro",
34
+ self::VISA => "Visa",
35
+ );
36
+
37
+ const MAGE_MASTERCARD = "MC";
38
+ const MAGE_AMEX = "AE";
39
+ const MAGE_DINERS = "DICL";
40
+ const MAGE_DISCOVER = "DI";
41
+ const MAGE_MAESTRO = "SM";
42
+ const MAGE_VISA = "VI";
43
+
44
+ public static $_mageMap = array(
45
+ self::MASTERCARD => self::MAGE_MASTERCARD,
46
+ self::AMEX => self::MAGE_AMEX,
47
+ self::DINERS => self::MAGE_DINERS,
48
+ self::DISCOVER => self::MAGE_DISCOVER,
49
+ self::MAESTRO => self::MAGE_MAESTRO,
50
+ self::VISA => self::MAGE_VISA,
51
+ );
52
+
53
+ /**
54
+ * @return array
55
+ */
56
+ public function toOptionArray()
57
+ {
58
+ $options = array();
59
+ foreach (self::$_options as $key => $option) {
60
+ $options[] = array("value" => $key, "label" => $option);
61
+ }
62
+ return $options;
63
+ }
64
+
65
+ /**
66
+ * @return array
67
+ */
68
+ public function getCards()
69
+ {
70
+ return self::$_options;
71
+ }
72
+
73
+ /**
74
+ * @param string $masterpassCode
75
+ * @return string|null
76
+ */
77
+ public function lookupMageCode($masterpassCode)
78
+ {
79
+ if (!array_key_exists($masterpassCode, self::$_mageMap)) {
80
+ return null;
81
+ } else {
82
+ return self::$_mageMap[$masterpassCode];
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Ensure the selected credit card types are available for the selected payment gateway.
88
+ *
89
+ * @return Mage_Core_Model_Abstract
90
+ */
91
+ protected function _beforeSave()
92
+ {
93
+ if ($config = $this->_pullOutConfig()) {
94
+ $paymentConfig = Mage::getStoreConfig("payment");
95
+ $validCCTypes = explode(",", Mage::getModel($paymentConfig[$config["value"]]["model"])->getConfigData("cctypes"));
96
+
97
+ foreach ($config["cards"] as $card) {
98
+ $mageCode = $this->lookupMageCode($card);
99
+ if (!in_array($mageCode, $validCCTypes)) {
100
+ Mage::throwException("One or more of the accepted cards you selected is not enabled for use with the payment gateway you selected.");
101
+ }
102
+ }
103
+ }
104
+
105
+ return parent::_beforeSave();
106
+ }
107
+
108
+ /**
109
+ * This function is designed to be called when a user clicks on the Save button on the
110
+ * MasterPass system configuration page. It checks for the relevant POST data, and if
111
+ * it is there, returns it.
112
+ *
113
+ * @return array|null
114
+ */
115
+ protected function _pullOutConfig()
116
+ {
117
+ if ($result = Mage::app()->getRequest()->getPost("groups")) {
118
+ if (isset($result["settings"]) && $result = $result["settings"]) {
119
+ if (isset($result["fields"]) && $fields = $result["fields"]) {
120
+ if (isset($fields["payment_gateway"]) && $result = $fields["payment_gateway"]) {
121
+ if (isset($result["value"]) && $value = $result["value"]) {
122
+ if (isset($fields["accepted_cards"]) && $result = $fields["accepted_cards"]) {
123
+ if (isset($result["value"]) && $cards = $result["value"]) {
124
+ return array("value" => $value, "cards" => $cards);
125
+ }
126
+ }
127
+ }
128
+ }
129
+ }
130
+ }
131
+ }
132
+ return null;
133
+ }
134
+ }
app/code/community/Fontis/Masterpass/Model/System/CheckoutButton.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Model_System_CheckoutButton
20
+ {
21
+ const SIZE_SMALL = 1;
22
+ const SIZE_MEDIUM = 2;
23
+ const SIZE_LARGE = 3;
24
+ const SIZE_LARGEST = 4;
25
+
26
+ protected $sizes = array(
27
+ self::SIZE_SMALL => "Small",
28
+ self::SIZE_MEDIUM => "Medium",
29
+ self::SIZE_LARGE => "Large",
30
+ self::SIZE_LARGEST => "Largest",
31
+ );
32
+
33
+ /**
34
+ * @return array
35
+ */
36
+ public function toOptionArray()
37
+ {
38
+ $options = array();
39
+ $helper = Mage::helper("fontis_masterpass");
40
+ foreach ($this->sizes as $size => $label) {
41
+ $options[] = array(
42
+ "label" => $helper->__($label),
43
+ "value" => $size,
44
+ );
45
+ }
46
+ return $options;
47
+ }
48
+ }
app/code/community/Fontis/Masterpass/Model/System/Environment.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Model_System_Environment
20
+ {
21
+ const ENV_PROD = 1;
22
+ const ENV_SAND = 2;
23
+
24
+ public static $_options = array(
25
+ self::ENV_PROD => "Production",
26
+ self::ENV_SAND => "Sandbox",
27
+ );
28
+
29
+ /**
30
+ * @return array
31
+ */
32
+ public function toOptionArray()
33
+ {
34
+ $helper = Mage::helper("fontis_masterpass");
35
+ return array(
36
+ array("value" => self::ENV_PROD, "label" => $helper->__(self::$_options[self::ENV_PROD])),
37
+ array("value" => self::ENV_SAND, "label" => $helper->__(self::$_options[self::ENV_SAND])),
38
+ );
39
+ }
40
+ }
app/code/community/Fontis/Masterpass/Model/System/LearnmoreLanguage.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Model_System_LearnmoreLanguage
20
+ {
21
+ const LANG_ENGLISH = "en";
22
+ const LANG_SWEDISH = "se";
23
+ const LANG_FRENCH = "fr";
24
+ const LANG_ITALIAN = "it";
25
+ const LANG_SPANISH = "es";
26
+
27
+ protected $languages = array(
28
+ self::LANG_ENGLISH => "English",
29
+ self::LANG_SWEDISH => "Swedish",
30
+ self::LANG_FRENCH => "French",
31
+ self::LANG_ITALIAN => "Italian",
32
+ self::LANG_SPANISH => "Spanish",
33
+ );
34
+
35
+ public function toOptionArray()
36
+ {
37
+ $options = array();
38
+ $helper = Mage::helper("fontis_masterpass");
39
+ foreach ($this->languages as $code => $language) {
40
+ $options[] = array(
41
+ "label" => $helper->__($language),
42
+ "value" => $code,
43
+ );
44
+ }
45
+ return $options;
46
+ }
47
+ }
app/code/community/Fontis/Masterpass/Model/System/PaymentGateways.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Model_System_PaymentGateways
20
+ {
21
+ /**
22
+ * @return array
23
+ */
24
+ public function toOptionArray()
25
+ {
26
+ $request = Mage::app()->getRequest();
27
+ // Show payment methods enabled on store view when viewed by the associated store view scope
28
+ $storeCode = $request->getParam("store", null);
29
+
30
+ if (!$storeCode) {
31
+ $websiteCode = $request->getParam("website", null);
32
+
33
+ if ($websiteCode) {
34
+ $website = Mage::getModel("core/website")->load($websiteCode, "code");
35
+ $storeCode = $website->getDefaultStore();
36
+ }
37
+ }
38
+
39
+ /** @var Mage_Core_Model_Config_Element $paymentMethodConfigXml */
40
+ $paymentMethodConfigXml = Mage::getSingleton("adminhtml/config")->getSection("payment")->groups;
41
+ $methods = Mage::getSingleton("payment/config")->getActiveMethods($storeCode);
42
+
43
+ // Initialise it with an empty value/label so the user can deselect all available methods if desired.
44
+ // Doing so will put the extension in a disabled state.
45
+ $options = array(array("value" => "", "label" => ""));
46
+ foreach ($methods as $key => $method) {
47
+ if (!($method instanceof Mage_Payment_Model_Method_Cc)) {
48
+ continue;
49
+ }
50
+
51
+ if (!empty($paymentMethodConfigXml->{$key}->label)) {
52
+ $label = (string) $paymentMethodConfigXml->{$key}->label;
53
+ } else {
54
+ $label = $method->getTitle();
55
+ }
56
+ $options[] = array(
57
+ "value" => $key,
58
+ "label" => $label,
59
+ );
60
+ }
61
+
62
+ return $options;
63
+ }
64
+ }
app/code/community/Fontis/Masterpass/Model/Zend/OauthAccessToken.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Model_Zend_OauthAccessToken extends Zend_Oauth_Http_AccessToken
20
+ {
21
+ /**
22
+ * Generate and return a HTTP Client configured for the Header Request Scheme
23
+ * specified by OAuth, for use in requesting an Access Token.
24
+ *
25
+ * Overridden so that the OAuth realm actually gets set.
26
+ *
27
+ * @param array $params
28
+ * @return Zend_Http_Client
29
+ */
30
+ public function getRequestSchemeHeaderClient(array $params)
31
+ {
32
+ $client = parent::getRequestSchemeHeaderClient($params);
33
+ $headerValue = $this->_httpUtility->toAuthorizationHeader(
34
+ $params, $this->_consumer->getRealm()
35
+ );
36
+ $client->setHeaders("Authorization", $headerValue);
37
+ return $client;
38
+ }
39
+ }
app/code/community/Fontis/Masterpass/Model/Zend/OauthConfig.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Model_Zend_OauthConfig extends Zend_Oauth_Config
20
+ {
21
+ /**
22
+ * Realm used in the Authorization header for Oauth requests.
23
+ *
24
+ * @var string
25
+ */
26
+ protected $_realm = null;
27
+
28
+ /**
29
+ * Parse option array or Zend_Config instance and setup options using their
30
+ * relevant mutators.
31
+ *
32
+ * Overridden to allow the addition of the realm field to the Authorization header.
33
+ *
34
+ * @param array|Zend_Config $options
35
+ * @return Zend_Oauth_Config
36
+ */
37
+ public function setOptions(array $options)
38
+ {
39
+ if (array_key_exists("realm", $options)) {
40
+ $this->_realm = $options["realm"];
41
+ }
42
+ parent::setOptions($options);
43
+ }
44
+
45
+ /**
46
+ * Set realm.
47
+ *
48
+ * @param string $key
49
+ * @return Fontis_Masterpass_Model_Zend_OauthConfig
50
+ */
51
+ public function setRealm($key)
52
+ {
53
+ $this->_realm = $key;
54
+ return $this;
55
+ }
56
+
57
+ /**
58
+ * Get realm.
59
+ *
60
+ * @return string
61
+ */
62
+ public function getRealm()
63
+ {
64
+ return $this->_realm;
65
+ }
66
+ }
app/code/community/Fontis/Masterpass/Model/Zend/OauthConsumer.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Model_Zend_OauthConsumer extends Zend_Oauth_Consumer
20
+ {
21
+ /**
22
+ * Constructor; create a new object with an optional array|Zend_Config
23
+ * instance containing initialising options.
24
+ *
25
+ * Overridden to use the overridden OAuth Config class which allows setting
26
+ * of the realm field in the Authorization header.
27
+ *
28
+ * @param array|Zend_Config $options
29
+ */
30
+ public function __construct($options = null)
31
+ {
32
+ $this->_config = new Fontis_Masterpass_Model_Zend_OauthConfig();
33
+ if (!is_null($options)) {
34
+ if ($options instanceof Zend_Config) {
35
+ $options = $options->toArray();
36
+ }
37
+ $this->_config->setOptions($options);
38
+ }
39
+ }
40
+ }
app/code/community/Fontis/Masterpass/Model/Zend/OauthRequestToken.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_Model_Zend_OauthRequestToken extends Zend_Oauth_Http_RequestToken
20
+ {
21
+ /**
22
+ * Generate and return a HTTP Client configured for the Header Request Scheme
23
+ * specified by OAuth, for use in requesting a Request Token.
24
+ *
25
+ * Overridden so that the OAuth realm actually gets set.
26
+ *
27
+ * @param array $params
28
+ * @return Zend_Http_Client
29
+ */
30
+ public function getRequestSchemeHeaderClient(array $params)
31
+ {
32
+ $client = parent::getRequestSchemeHeaderClient($params);
33
+ $headerValue = $this->_httpUtility->toAuthorizationHeader(
34
+ $params, $this->_consumer->getRealm()
35
+ );
36
+ $client->setHeaders("Authorization", $headerValue);
37
+ return $client;
38
+ }
39
+ }
app/code/community/Fontis/Masterpass/PaymentException.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_PaymentException extends Exception
20
+ {
21
+ }
app/code/community/Fontis/Masterpass/controllers/CheckoutController.php ADDED
@@ -0,0 +1,639 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ class Fontis_Masterpass_CheckoutController extends Mage_Core_Controller_Front_Action
20
+ {
21
+ const RETURN_SUCCESS = 200;
22
+ const MPASS_REQUEST_TOKEN = "masterpassRequestToken";
23
+ const MPASS_TRANSACTION_ID = "masterpassTransactionId";
24
+ const MPASS_CARTXML_OAUTHTOKEN = "OAuthToken";
25
+ const MPASS_ORDERXML_CONSUMERKEY = "ConsumerKey";
26
+ const LOGFILE = "fontis_masterpass.log";
27
+
28
+ /**
29
+ * Stores the customer's quote object.
30
+ *
31
+ * @var Mage_Sales_Model_Quote
32
+ */
33
+ protected $_quote = null;
34
+
35
+ /**
36
+ * Stores the customer's checkout session object.
37
+ *
38
+ * @var Mage_Checkout_Model_Session
39
+ */
40
+ protected $_checkoutSession = null;
41
+
42
+ /**
43
+ * @var Fontis_Masterpass_Model_Masterpass_Oauth
44
+ */
45
+ protected $_oauth = null;
46
+
47
+ /**
48
+ * @var Fontis_Masterpass_Model_Checkout
49
+ */
50
+ protected $_checkout = null;
51
+
52
+ public function preDispatch()
53
+ {
54
+ $actionName = $this->getActionMethodName($this->getRequest()->getRequestedActionName());
55
+ if (!is_callable(array($this, $actionName))) {
56
+ // This request is going to 404, so we don't care.
57
+ return parent::preDispatch();
58
+ }
59
+ if (!Mage::helper('fontis_masterpass/config')->isTokenPaymentsAccepted()) {
60
+ if (Mage::helper("fontis_masterpass")->checkIfSensitiveRequest($this->getRequest())) {
61
+ Mage::helper("fontis_masterpass")->reduceClientSessionLifetime();
62
+ }
63
+ }
64
+ return parent::preDispatch();
65
+ }
66
+
67
+ /**
68
+ * Starts the MasterPass checkout process.
69
+ * Activated when the user clicks the "Checkout with MasterPass" button on the cart page.
70
+ *
71
+ * @return $this
72
+ */
73
+ public function startAction()
74
+ {
75
+ if (!Mage::helper("fontis_masterpass")->isEnabled()) {
76
+ // If MasterPass isn't enabled, pretend this controller action doesn't exist.
77
+ $this->_forward("noroute");
78
+ return $this;
79
+ }
80
+
81
+ try {
82
+ $this->_initialize();
83
+
84
+ // Start the connection to MasterPass and receive an OAuth token.
85
+ if (!($requestToken = $this->_initiateMasterpassConnection())) {
86
+ $this->_getCheckoutSession()->addError($this->__("Sorry, we were unable to start the checkout process with %s. Please try again.", Mage::helper("fontis_masterpass/config")->getFrontendTitle()));
87
+ return $this->_redirect("checkout/cart");
88
+ }
89
+
90
+ // Create an Order ID for the customer's quote. Used to track their order across requests.
91
+ $this->_getQuote()->reserveOrderId()->save();
92
+
93
+ // Submit the customer's shopping cart to MasterPass in XML form.
94
+ if ($this->_submitShoppingCartXml($requestToken)) {
95
+ // If we successfully submitted the customer's shopping cart to MasterPass, redirect the user to MasterPass.
96
+ return $this->_redirectToMasterpass($requestToken);
97
+ } else {
98
+ $this->_getCheckoutSession()->addError($this->__("Sorry, we were unable to start the checkout process with %s. Please try again.", Mage::helper("fontis_masterpass/config")->getFrontendTitle()));
99
+ }
100
+ } catch (Mage_Core_Exception $e) {
101
+ Mage::log($e->getMessage(), Zend_Log::ERR, self::LOGFILE);
102
+ $this->_getCheckoutSession()->addError($e->getMessage());
103
+ } catch (Exception $e) {
104
+ Mage::log($e->getMessage(), Zend_Log::ERR, self::LOGFILE);
105
+ $this->_getCheckoutSession()->addError($this->__("Sorry, we were unable to start the checkout process with %s. Please try again.", Mage::helper("fontis_masterpass/config")->getFrontendTitle()));
106
+ }
107
+
108
+ // If we reach here, there was an error of some kind.
109
+ return $this->_redirect("checkout/cart");
110
+ }
111
+
112
+ /**
113
+ * The MasterPass callback controller action.
114
+ * This is where MasterPass will redirect the user back to regardless of how they exit the checkout, so it needs
115
+ * to handle success and failure.
116
+ *
117
+ * @return $this
118
+ */
119
+ public function continueAction()
120
+ {
121
+ if (!Mage::helper("fontis_masterpass")->isEnabled()) {
122
+ // If MasterPass isn't enabled, pretend this controller action doesn't exist.
123
+ $this->_forward("noroute");
124
+ return $this;
125
+ }
126
+
127
+ try {
128
+ $this->_initialize();
129
+
130
+ // Check that we received all of the necessary information from MasterPass during the redirect to enable
131
+ // us to request the customer's payment details.
132
+ if (!$this->_verifyCallback()) {
133
+ return $this->_redirect("checkout/cart");
134
+ }
135
+
136
+ // Get the customer's payment details.
137
+ if ($paymentData = $this->_getMasterpassPaymentData()) {
138
+ // Ensure CCV check is disabled before any payment data is imported
139
+ Mage::helper("fontis_masterpass")->temporarilyDisableCCVCheck();
140
+
141
+ // Attach the customer's payment details (including addresses) to their quote.
142
+ $this->_attachMasterpassPaymentDataToQuote($paymentData);
143
+ return $this->_redirect("*/*/review");
144
+ } else {
145
+ // This means we were unable to retrieve the customer's payment details.
146
+ $this->_getCheckoutSession()->addError($this->__("Sorry, we were unable to retrieve your payment details from %s. Please try again.", Mage::helper("fontis_masterpass/config")->getFrontendTitle()));
147
+ }
148
+ } catch (Mage_Core_Exception $e) {
149
+ Mage::log($e->getMessage(), Zend_Log::ERR, self::LOGFILE);
150
+ $this->_getCheckoutSession()->addError($e->getMessage());
151
+ } catch (Exception $e) {
152
+ Mage::log($e->getMessage(), Zend_Log::ERR, self::LOGFILE);
153
+ $this->_getCheckoutSession()->addError($this->__("Sorry, we didn't receive enough information back from %s to complete the checkout. Please try again.", Mage::helper("fontis_masterpass/config")->getFrontendTitle()));
154
+ }
155
+
156
+ // If we reach here, there was an error of some kind.
157
+ return $this->_redirect("checkout/cart");
158
+ }
159
+
160
+ /**
161
+ * The MasterPass review step.
162
+ * The customer arrives here if they successfully completed the MasterPass checkout and were successfully
163
+ * returned to the site by MasterPass.
164
+ * This is the final review step before confirming the order.
165
+ *
166
+ * @return $this
167
+ */
168
+ public function reviewAction()
169
+ {
170
+ if (!Mage::helper("fontis_masterpass")->isEnabled()) {
171
+ // If MasterPass isn't enabled, pretend this controller action doesn't exist.
172
+ $this->_clearCcNumber();
173
+ $this->_forward("noroute");
174
+ return $this;
175
+ }
176
+
177
+ try {
178
+ $this->_initialize();
179
+
180
+ // Ensure CCV check is disabled before any validation of payment details
181
+ Mage::helper("fontis_masterpass")->temporarilyDisableCCVCheck();
182
+
183
+ $this->_getQuote()->setMayEditShippingMethod(true)->save();
184
+
185
+ $this->loadLayout();
186
+ $this->_initLayoutMessages("checkout/session");
187
+ $this->renderLayout();
188
+ return $this;
189
+ } catch (Mage_Core_Exception $e) {
190
+ Mage::log($e->getMessage(), Zend_Log::ERR, self::LOGFILE);
191
+ $this->_getCheckoutSession()->addError($e->getMessage());
192
+ } catch (Exception $e) {
193
+ Mage::log($e->getMessage(), Zend_Log::ERR, self::LOGFILE);
194
+ $this->_getCheckoutSession()->addError($this->__("Sorry, there was a problem loading your details. Please try again."));
195
+ }
196
+
197
+ // If we reach here, there was an error of some kind.
198
+ return $this->_redirect("checkout/cart");
199
+ }
200
+
201
+ /**
202
+ * Update shipping method on quote.
203
+ * This controller action supports ajax and non-ajax requests.
204
+ *
205
+ * @return $this
206
+ */
207
+ public function saveShippingMethodAction()
208
+ {
209
+ if (!Mage::helper("fontis_masterpass")->isEnabled()) {
210
+ // If MasterPass isn't enabled, pretend this controller action doesn't exist.
211
+ $this->_clearCcNumber();
212
+ $this->_forward("noroute");
213
+ return $this;
214
+ }
215
+
216
+ $isAjax = $this->getRequest()->getParam("isAjax");
217
+
218
+ try {
219
+ $this->_initialize();
220
+
221
+ // Ensure CCV check is disabled before any validation of payment details
222
+ Mage::helper("fontis_masterpass")->temporarilyDisableCCVCheck();
223
+
224
+ $this->_checkout->updateShippingMethod($this->_getQuote(), $this->getRequest()->getParam("shipping_method"));
225
+ if ($isAjax) {
226
+ $this->loadLayout("masterpass_checkout_review_details");
227
+ $response = $this->getLayout()
228
+ ->getBlock("root")
229
+ ->setQuote($this->_getQuote())
230
+ ->toHtml();
231
+ $this->getResponse()->setBody($response);
232
+ return $this;
233
+ }
234
+ } catch (Mage_Core_Exception $e) {
235
+ Mage::log($e->getMessage(), Zend_Log::ERR, self::LOGFILE);
236
+ $this->_getCheckoutSession()->addError($e->getMessage());
237
+ } catch (Exception $e) {
238
+ Mage::log($e->getMessage(), Zend_Log::ERR, self::LOGFILE);
239
+ $this->_getCheckoutSession()->addError($this->__("Unable to update shipping method."));
240
+ }
241
+ if ($isAjax) {
242
+ // If we reach here, there was an error of some kind.
243
+ $this->getResponse()->setBody('<script type="text/javascript">window.location.href = ' . Mage::getUrl("*/*/review") . ';</script>');
244
+ } else {
245
+ $this->_redirect("*/*/review");
246
+ }
247
+ return $this;
248
+ }
249
+
250
+ /**
251
+ * Submit the order.
252
+ *
253
+ * @return $this
254
+ */
255
+ public function placeOrderAction()
256
+ {
257
+ if (!Mage::helper("fontis_masterpass")->isEnabled()) {
258
+ // If MasterPass isn't enabled, pretend this controller action doesn't exist.
259
+ $this->_clearCcNumber();
260
+ $this->_forward("noroute");
261
+ return $this;
262
+ }
263
+
264
+ try {
265
+ $this->_initialize();
266
+
267
+ // Ensure CCV check is disabled and proceed to place order
268
+ Mage::helper("fontis_masterpass")->temporarilyDisableCCVCheck();
269
+ $quote = $this->_getQuote();
270
+ // Recover the customer's credit card number from their session.
271
+ if ($ccNumber = $this->_getCcNumber()) {
272
+ $quote->getPayment()->setCcNumber($ccNumber);
273
+ }
274
+ $order = $this->_checkout->placeOrder($quote);
275
+ // We don't need this anymore. Clear it immediately.
276
+ $this->_clearCcNumber();
277
+
278
+ // prepare session to success or cancellation page
279
+ $session = $this->_getCheckoutSession();
280
+ $session->clearHelperData();
281
+
282
+ // "last successful quote"
283
+ $quoteId = $quote->getId();
284
+ $session->setLastQuoteId($quoteId)->setLastSuccessQuoteId($quoteId);
285
+
286
+ if ($order) {
287
+ $session->setLastOrderId($order->getId())
288
+ ->setLastRealOrderId($order->getIncrementId());
289
+ $this->_noteSuccessfulMasterpassOrder($order);
290
+ $result = $this->_postCheckoutSuccessBackToMasterpass($order);
291
+ if ($result !== true) {
292
+ $this->_noteMasterpassPostbackFailure($order);
293
+ }
294
+ }
295
+
296
+ $redirect = "checkout/onepage/success";
297
+ } catch (Mage_Core_Exception $e) {
298
+ Mage::log($e->getMessage(), Zend_Log::ERR, self::LOGFILE);
299
+ $this->_getCheckoutSession()->addError($e->getMessage());
300
+ $redirect = "*/*/review";
301
+ } catch (Exception $e) {
302
+ Mage::log($e->getMessage(), Zend_Log::ERR, self::LOGFILE);
303
+ $this->_getCheckoutSession()->addError($this->__("Unable to place the order."));
304
+ $redirect = "*/*/review";
305
+ }
306
+
307
+ $this->_getQuote()->save();
308
+ return $this->_redirect($redirect);
309
+ }
310
+
311
+ /**
312
+ * Instantiate quote, checkout and Masterpass Oauth objects.
313
+ * Ensures the customer actually has items in their cart, and that they are actually worth more than zero.
314
+ *
315
+ * @throws Mage_Core_Exception
316
+ */
317
+ protected function _initialize()
318
+ {
319
+ $quote = $this->_getQuote();
320
+ if (!$quote->hasItems()) {
321
+ $this->getResponse()->setHeader("HTTP/1.1", "403 Forbidden");
322
+ Mage::throwException($this->__("You don't have any items in your cart."));
323
+ } elseif ($quote->getHasError()) {
324
+ $this->getResponse()->setHeader("HTTP/1.1", "403 Forbidden");
325
+ Mage::throwException($this->__("Sorry, we were unable to start the checkout process with %s.", Mage::helper("fontis_masterpass/config")->getFrontendTitle()));
326
+ } elseif (!$quote->getGrandTotal() && !$quote->hasNominalItems()) {
327
+ Mage::throwException($this->__("%s does not support processing orders with zero amount. To complete your purchase, proceed to the standard checkout process.", Mage::helper("fontis_masterpass/config")->getFrontendTitle()));
328
+ }
329
+
330
+ $this->_oauth = Mage::getModel("fontis_masterpass/masterpass_oauth");
331
+ $this->_checkout = Mage::getModel("fontis_masterpass/checkout");
332
+ }
333
+
334
+ /**
335
+ * Get checkout session object.
336
+ *
337
+ * @return Mage_Checkout_Model_Session
338
+ */
339
+ protected function _getCheckoutSession()
340
+ {
341
+ if ($this->_checkoutSession === null) {
342
+ $this->_checkoutSession = Mage::getSingleton("checkout/session");
343
+ }
344
+ return $this->_checkoutSession;
345
+ }
346
+
347
+ /**
348
+ * Get checkout quote object.
349
+ *
350
+ * @return Mage_Sales_Model_Quote
351
+ */
352
+ protected function _getQuote()
353
+ {
354
+ if ($this->_quote === null) {
355
+ $this->_quote = $this->_getCheckoutSession()->getQuote();
356
+ }
357
+ return $this->_quote;
358
+ }
359
+
360
+ /**
361
+ * Initiate the connection with MasterPass in order to get the URL to redirect the user to.
362
+ * This involves getting a request token back from MasterPass that contains an OAuth token
363
+ * and a URL to redirect the user to.
364
+ *
365
+ * @return Zend_Oauth_Token_Request|null
366
+ */
367
+ protected function _initiateMasterpassConnection()
368
+ {
369
+ $requestToken = $this->_oauth->getRequestToken();
370
+ if (!$requestToken || $requestToken->getResponse()->getStatus() != self::RETURN_SUCCESS) {
371
+ Mage::log("Unable to get a valid OAuth request token from MasterPass.", Zend_Log::WARN, self::LOGFILE);
372
+ return null;
373
+ } elseif (!($requestToken->getParam(Fontis_Masterpass_Model_Masterpass_Oauth::OAUTH_CALLBACK_CONFIRMED) == "true") ||
374
+ !($requestToken->getParam(Fontis_Masterpass_Model_Masterpass_Oauth::OAUTH_TOKEN))) {
375
+ Mage::log("Unable to get a valid OAuth request token from MasterPass.", Zend_Log::WARN, self::LOGFILE);
376
+ return null;
377
+ }
378
+
379
+ return $requestToken;
380
+ }
381
+
382
+ /**
383
+ * Submit the customer's shopping cart to MasterPass in XML form.
384
+ *
385
+ * @param Zend_Oauth_Token_Request $requestToken
386
+ * @return bool
387
+ */
388
+ protected function _submitShoppingCartXml(Zend_Oauth_Token_Request $requestToken)
389
+ {
390
+ $cartXml = $this->_checkout->generateCartXml($this->_getQuote());
391
+ $cartXml->addChild(self::MPASS_CARTXML_OAUTHTOKEN, $requestToken->getParam(Fontis_Masterpass_Model_Masterpass_Oauth::OAUTH_TOKEN));
392
+
393
+ $return = $this->_oauth->submitShoppingCartXml($cartXml);
394
+ if ($return->getResponse()->getStatus() != self::RETURN_SUCCESS) {
395
+ Mage::log("Invalid response from MasterPass when submitting shopping cart XML. Status of transaction: " . $return->getResponse()->getStatus(), Zend_Log::NOTICE, self::LOGFILE);
396
+ return false;
397
+ }
398
+ return true;
399
+ }
400
+
401
+ /**
402
+ * Determine where to redirect the customer when they click the "Buy with MasterPass" button.
403
+ * If we received a valid redirect URL from MasterPass, we should redirect them there.
404
+ * If not, take them back to the cart.
405
+ *
406
+ * @param Zend_Oauth_Token_Request $requestToken
407
+ * @return $this
408
+ */
409
+ protected function _redirectToMasterpass(Zend_Oauth_Token_Request $requestToken)
410
+ {
411
+ $url = $this->_oauth->getRedirectUrl($requestToken, $this->_getQuote()->isVirtual());
412
+ if ($url) {
413
+ $this->_getCheckoutSession()->setData(self::MPASS_REQUEST_TOKEN, $requestToken); // We need this in the callback.
414
+ $this->getResponse()->setRedirect($url);
415
+ return $this;
416
+ } else {
417
+ Mage::log("Unable to determine MasterPass redirect URL.", Zend_Log::ERR, self::LOGFILE);
418
+ $this->_getCheckoutSession()->addError($this->__("Sorry, we were unable to work out how to send you to %s. Please try again.", Mage::helper("fontis_masterpass/config")->getFrontendTitle()));
419
+ return $this->_redirect("checkout/cart");
420
+ }
421
+ }
422
+
423
+ /**
424
+ * Check whether or not the customer completed the MasterPass checkout successfully.
425
+ *
426
+ * @return bool
427
+ */
428
+ protected function _verifyCallback()
429
+ {
430
+ $queryData = $this->getRequest()->getQuery();
431
+
432
+ if (empty($queryData[Fontis_Masterpass_Model_Masterpass_Oauth::OAUTH_TOKEN]) ||
433
+ empty($queryData[Fontis_Masterpass_Model_Masterpass_Oauth::OAUTH_VERIFIER]) ||
434
+ empty($queryData[Fontis_Masterpass_Model_Masterpass_Oauth::OAUTH_CHECKOUT_RES_URL])) {
435
+ Mage::log("One or more of the required query string parameters were missing from the callback URL. Requested URL: " . $this->getRequest()->getRequestUri(), Zend_Log::NOTICE, self::LOGFILE);
436
+ $this->_getCheckoutSession()->addError($this->__("It looks like you didn't successfully complete the %s checkout. Please try again.", Mage::helper("fontis_masterpass/config")->getFrontendTitle()));
437
+ return false;
438
+ }
439
+
440
+ return true;
441
+ }
442
+
443
+ /**
444
+ * Retrieve the customer's payment data from MasterPass.
445
+ * This involves getting an access token based on the request token used for the original request, and then using
446
+ * this access token to retrieve the payment data.
447
+ *
448
+ * @return SimpleXMLElement|null
449
+ */
450
+ protected function _getMasterpassPaymentData()
451
+ {
452
+ // Get the original request token object used to initiate the MasterPass connection.
453
+ $masterpassRequestToken = $this->_getCheckoutSession()->getData(self::MPASS_REQUEST_TOKEN);
454
+ $this->_getCheckoutSession()->unsetData(self::MPASS_REQUEST_TOKEN);
455
+
456
+ // Get the access token from MasterPass based on the original request token.
457
+ $queryData = $this->getRequest()->getQuery();
458
+ $accessToken = $this->_oauth->getAccessToken($queryData, $masterpassRequestToken);
459
+ if (!$accessToken || $accessToken->getResponse()->getStatus() != self::RETURN_SUCCESS) {
460
+ Mage::log("Invalid response from MasterPass when obtaining Access Token.", Zend_Log::WARN, self::LOGFILE);
461
+ return null;
462
+ }
463
+
464
+ // Use the access token to get the customer's payment data from MasterPass.
465
+ $paymentDataRequest = $this->_oauth->getPaymentData($accessToken, $queryData[Fontis_Masterpass_Model_Masterpass_Oauth::OAUTH_CHECKOUT_RES_URL]);
466
+ if (!$paymentDataRequest || $paymentDataRequest->getResponse()->getStatus() != self::RETURN_SUCCESS) {
467
+ Mage::log("Invalid response from MasterPass when retrieving customer payment data.", Zend_Log::WARN, self::LOGFILE);
468
+ Mage::log("Checkout resource URL: " . $queryData[Fontis_Masterpass_Model_Masterpass_Oauth::OAUTH_CHECKOUT_RES_URL], Zend_Log::WARN, self::LOGFILE);
469
+ return null;
470
+ }
471
+
472
+ // Verify that we got back valid XML from MasterPass.
473
+ $paymentData = $paymentDataRequest->getResponse()->getBody();
474
+ $paymentDataXml = simplexml_load_string($paymentData);
475
+ if ($paymentDataXml === false) {
476
+ Mage::log("Received malformed XML from MasterPass when retrieving customer payment data.", Zend_Log::NOTICE, self::LOGFILE);
477
+ return null;
478
+ }
479
+ return $paymentDataXml;
480
+ }
481
+
482
+ /**
483
+ * Sends the payment data returned from MasterPass off for processing, and attaches the processed data to the
484
+ * customer's quote object in the checkout session.
485
+ *
486
+ * @param SimpleXMLElement $paymentDataXml
487
+ * @return bool
488
+ */
489
+ protected function _attachMasterpassPaymentDataToQuote(SimpleXMLElement $paymentDataXml)
490
+ {
491
+ $quote = $this->_getQuote();
492
+ $isVirtual = $quote->isVirtual();
493
+ $quoteInfo = Mage::getModel("fontis_masterpass/masterpass_payment")->processPaymentData($paymentDataXml, $isVirtual);
494
+
495
+ // Add the address information from the payment data to the quote.
496
+ $this->_checkout->addDataToAddress($quote->getBillingAddress(), $quoteInfo["billingAddress"]);
497
+ if ($isVirtual !== true) {
498
+ $this->_checkout->addDataToAddress($quote->getShippingAddress(), $quoteInfo["shippingAddress"]);
499
+ }
500
+
501
+ // Add the actual payment data to the quote.
502
+ $quoteInfo["payment"]["method"] = Mage::helper("fontis_masterpass/config")->getPaymentGateway();
503
+ $this->_checkout->addPaymentData($quote->getPayment(), $quoteInfo["payment"]);
504
+ // Save the credit card number to the customer's session, using Magento's encryption system.
505
+ if (!Mage::helper('fontis_masterpass/config')->isTokenPaymentsAccepted()) {
506
+ $this->_saveCcNumber($quoteInfo["payment"]["cc_number"]);
507
+ }
508
+
509
+ $quote->collectTotals()->save();
510
+
511
+ // Attach the MasterPass Transaction ID to the customer's checkout session for use in later requests.
512
+ $this->_getCheckoutSession()->setData(self::MPASS_TRANSACTION_ID, $quoteInfo["transactionId"]); // We need this in the callback.
513
+
514
+ return true;
515
+ }
516
+
517
+ /**
518
+ * Save an encrypted version of the customer's credit card number in their session.
519
+ *
520
+ * @param string $ccNumber
521
+ */
522
+ protected function _saveCcNumber($ccNumber)
523
+ {
524
+ $ccNumberEnc = Mage::helper("core")->encrypt($ccNumber);
525
+ $this->_getCheckoutSession()->setData(Fontis_Masterpass_Helper_Data::MPASS_CC_NUMBER_ENC, $ccNumberEnc);
526
+ }
527
+
528
+ /**
529
+ * Look for an encrypted credit card number in the customer's session. If it exists,
530
+ * decrypt it and return it.
531
+ *
532
+ * @return string|null
533
+ */
534
+ protected function _getCcNumber()
535
+ {
536
+ $ccNumberEnc = $this->_getCheckoutSession()->getData(Fontis_Masterpass_Helper_Data::MPASS_CC_NUMBER_ENC);
537
+ if (is_null($ccNumberEnc)) {
538
+ return null;
539
+ } else {
540
+ return Mage::helper("core")->decrypt($ccNumberEnc);
541
+ }
542
+ }
543
+
544
+ /**
545
+ * Clear the customer's credit card number from their session.
546
+ */
547
+ protected function _clearCcNumber()
548
+ {
549
+ $this->_getCheckoutSession()->unsetData(Fontis_Masterpass_Helper_Data::MPASS_CC_NUMBER_ENC);
550
+ }
551
+
552
+ /**
553
+ * Make a note of the fact that this is a MasterPass order.
554
+ * It achieves this by putting a comment on the order, and by attaching a custom field to the payment object. This
555
+ * custom field is stored in a serialised data field in the database, and is picked up by an appropriate block for
556
+ * rendering.
557
+ *
558
+ * @see Fontis_Masterpass_Block_Adminhtml_Sales_Orderpayment
559
+ * @param Mage_Sales_Model_Order $order
560
+ */
561
+ protected function _noteSuccessfulMasterpassOrder(Mage_Sales_Model_Order $order)
562
+ {
563
+ $transactionId = $this->_getCheckoutSession()->getData(self::MPASS_TRANSACTION_ID);
564
+
565
+ $order->addStatusHistoryComment($this->__("This is a MasterPass order. Transaction ID: " . $transactionId));
566
+
567
+ $order->getPayment()
568
+ ->setAdditionalInformation("cc_from", "masterpass")
569
+ ->setAdditionalInformation(Fontis_Masterpass_Helper_Data::MPASS_TXNID_LABEL, $transactionId)
570
+ ->save();
571
+
572
+ $order->save();
573
+ }
574
+
575
+ /**
576
+ * Returns true after a successful postback.
577
+ * Returns null if we never get a 200 OK response from MasterPass, or false if we did get
578
+ * a response from MasterPass but it didn't match what we expected.
579
+ *
580
+ * @param Mage_Sales_Model_Order $order
581
+ * @return bool|null
582
+ */
583
+ protected function _postCheckoutSuccessBackToMasterpass(Mage_Sales_Model_Order $order)
584
+ {
585
+ try {
586
+ // Retrieve the MasterPass transaction ID from the customer's checkout session.
587
+ $transactionId = $this->_getCheckoutSession()->getData(self::MPASS_TRANSACTION_ID);
588
+ $this->_getCheckoutSession()->unsetData(self::MPASS_TRANSACTION_ID);
589
+
590
+ // Retrieve key details from the customer's order object in XML form.
591
+ $orderXml = $this->_checkout->generateOrderXml($order, $transactionId);
592
+ // Insert the comsumer key into the XML.
593
+ $orderXml->{Fontis_Masterpass_Model_Checkout::ORDERXML_GLOBAL}->addChild(self::MPASS_ORDERXML_CONSUMERKEY, Mage::helper("fontis_masterpass/config")->getConsumerKey());
594
+
595
+ // POST the order XML to MasterPass.
596
+ $orderPostbackRequest = $this->_oauth->submitTransactionPostback($orderXml);
597
+ // If we don't get a 200 OK back from MasterPass, the postback didn't complete successfully.
598
+ if (!$orderPostbackRequest || $orderPostbackRequest->getResponse()->getStatus() != self::RETURN_SUCCESS) {
599
+ Mage::log("Invalid response from MasterPass when submitting order postback.", Zend_Log::WARN, self::LOGFILE);
600
+ return null;
601
+ }
602
+ } catch (Exception $e) {
603
+ Mage::log($e->getMessage(), Zend_Log::ERR, self::LOGFILE);
604
+ return null;
605
+ }
606
+
607
+ try {
608
+ // Verify the response we got back from MasterPass.
609
+ $orderPostback = $orderPostbackRequest->getResponse()->getBody();
610
+ $orderPostbackXml = simplexml_load_string($orderPostback);
611
+ if ($orderPostbackXml === false) {
612
+ Mage::log("Received malformed XML from MasterPass when submitting order postback.", Zend_Log::NOTICE, self::LOGFILE);
613
+ return false;
614
+ }
615
+
616
+ $check = Mage::getModel("fontis_masterpass/masterpass_order")->verifyOrderPostback($orderXml, $orderPostbackXml);
617
+ if ($check === true) {
618
+ return true;
619
+ } else {
620
+ return false;
621
+ }
622
+ } catch (Exception $e) {
623
+ Mage::log($e->getMessage(), Zend_Log::ERR, self::LOGFILE);
624
+ return false;
625
+ }
626
+ }
627
+
628
+ /**
629
+ * Make a note of the fact that a MasterPass order postback failed.
630
+ * Under normal circumstances, this event should never occur.
631
+ *
632
+ * @param Mage_Sales_Model_Order $order
633
+ */
634
+ protected function _noteMasterpassPostbackFailure(Mage_Sales_Model_Order $order)
635
+ {
636
+ $order->addStatusHistoryComment($this->__("Unable to inform MasterPass that this order was successful."));
637
+ $order->save();
638
+ }
639
+ }
app/code/community/Fontis/Masterpass/etc/config.xml ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!--
3
+ /**
4
+ * Fontis MasterPass Extension
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
+ *
13
+ * @category Fontis
14
+ * @package Fontis_MasterPass
15
+ * @author Matthew Gamble
16
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
17
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
18
+ */
19
+ -->
20
+ <config>
21
+ <modules>
22
+ <Fontis_Masterpass>
23
+ <version>1.0.2</version>
24
+ </Fontis_Masterpass>
25
+ </modules>
26
+ <global>
27
+ <blocks>
28
+ <fontis_masterpass>
29
+ <class>Fontis_Masterpass_Block</class>
30
+ </fontis_masterpass>
31
+ <adminhtml>
32
+ <rewrite>
33
+ <sales_order_payment>Fontis_Masterpass_Block_Adminhtml_Sales_Orderpayment</sales_order_payment>
34
+ </rewrite>
35
+ </adminhtml>
36
+ </blocks>
37
+ <helpers>
38
+ <fontis_masterpass>
39
+ <class>Fontis_Masterpass_Helper</class>
40
+ </fontis_masterpass>
41
+ </helpers>
42
+ <models>
43
+ <fontis_masterpass>
44
+ <class>Fontis_Masterpass_Model</class>
45
+ </fontis_masterpass>
46
+ </models>
47
+ </global>
48
+ <frontend>
49
+ <layout>
50
+ <updates>
51
+ <fontis_masterpass>
52
+ <file>fontis/masterpass.xml</file>
53
+ </fontis_masterpass>
54
+ </updates>
55
+ </layout>
56
+ <routers>
57
+ <masterpass>
58
+ <use>standard</use>
59
+ <args>
60
+ <module>Fontis_Masterpass</module>
61
+ <frontName>masterpass</frontName>
62
+ </args>
63
+ </masterpass>
64
+ </routers>
65
+ <secure_url>
66
+ <masterpass>/masterpass/</masterpass>
67
+ </secure_url>
68
+ <events>
69
+ <controller_action_predispatch>
70
+ <observers>
71
+ <masterpass_session_check>
72
+ <class>fontis_masterpass/observer</class>
73
+ <method>checkMasterpassDataInSession</method>
74
+ </masterpass_session_check>
75
+ </observers>
76
+ </controller_action_predispatch>
77
+ <controller_action_predispatch_checkout_onepage_saveOrder>
78
+ <observers>
79
+ <masterpass_checkout_redirect>
80
+ <class>fontis_masterpass/observer</class>
81
+ <method>redirectUserToMasterpass</method>
82
+ </masterpass_checkout_redirect>
83
+ </observers>
84
+ </controller_action_predispatch_checkout_onepage_saveOrder>
85
+ </events>
86
+ </frontend>
87
+ <adminhtml>
88
+ <acl>
89
+ <resources>
90
+ <admin>
91
+ <children>
92
+ <system>
93
+ <children>
94
+ <config>
95
+ <children>
96
+ <fontis_masterpass>
97
+ <title>MasterPass™</title>
98
+ </fontis_masterpass>
99
+ </children>
100
+ </config>
101
+ </children>
102
+ </system>
103
+ </children>
104
+ </admin>
105
+ </resources>
106
+ </acl>
107
+ </adminhtml>
108
+ <default>
109
+ <fontis_masterpass>
110
+ <settings>
111
+ <enabled>0</enabled>
112
+ <title>MasterPass™</title>
113
+ <environment>2</environment>
114
+ <acceptancemark_size>32</acceptancemark_size>
115
+ <learn_more_language>en</learn_more_language>
116
+ <token_payments_accepted>0</token_payments_accepted>
117
+ <show_on_checkout>0</show_on_checkout>
118
+ <sort_order>20</sort_order>
119
+ </settings>
120
+ </fontis_masterpass>
121
+ <payment>
122
+ <fontis_masterpass>
123
+ <active>1</active>
124
+ <model>fontis_masterpass/payment</model>
125
+ </fontis_masterpass>
126
+ </payment>
127
+ </default>
128
+ </config>
app/code/community/Fontis/Masterpass/etc/system.xml ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Fontis MasterPass Extension
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
+ *
13
+ * @category Fontis
14
+ * @package Fontis_MasterPass
15
+ * @author Matthew Gamble
16
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
17
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
18
+ */
19
+ -->
20
+ <config>
21
+ <sections>
22
+ <fontis_masterpass module="fontis_masterpass">
23
+ <label>MasterPass™</label>
24
+ <tab>sales</tab>
25
+ <frontend_type>text</frontend_type>
26
+ <sort_order>351</sort_order>
27
+ <show_in_default>1</show_in_default>
28
+ <show_in_website>1</show_in_website>
29
+ <show_in_store>1</show_in_store>
30
+ <groups>
31
+ <settings translate="label" module="fontis_masterpass">
32
+ <label>MasterPass Settings</label>
33
+ <frontend_type>text</frontend_type>
34
+ <sort_order>1</sort_order>
35
+ <expanded>1</expanded>
36
+ <show_in_default>1</show_in_default>
37
+ <show_in_website>1</show_in_website>
38
+ <show_in_store>1</show_in_store>
39
+ <fields>
40
+ <enabled translate="label">
41
+ <label>Enabled</label>
42
+ <frontend_type>select</frontend_type>
43
+ <source_model>adminhtml/system_config_source_yesno</source_model>
44
+ <sort_order>1</sort_order>
45
+ <show_in_default>1</show_in_default>
46
+ <show_in_website>1</show_in_website>
47
+ <show_in_store>1</show_in_store>
48
+ </enabled>
49
+ <title translate="label">
50
+ <label>Frontend Title</label>
51
+ <frontend_type>text</frontend_type>
52
+ <sort_order>2</sort_order>
53
+ <default>MasterPass™</default>
54
+ <show_in_default>1</show_in_default>
55
+ <show_in_website>1</show_in_website>
56
+ <show_in_store>1</show_in_store>
57
+ </title>
58
+ <checkoutbutton_url translate="label">
59
+ <label>Checkout Button URL</label>
60
+ <comment><![CDATA[Enter a protocol-independent URL for the "Buy with MasterPass" image you want to use on the checkout and cart. Only use this if you need it in a language other than English. Leave blank to use the default. Details can be found in the <a href="https://developer.mastercard.com/portal/display/api/MasterPass+-+Merchant+Checkout+-+Documentation" target="_blank">MasterPass Integration Guide</a>.]]></comment>
61
+ <tooltip>Failure to use a protocol-independent URL could result in insecure content warnings on your checkout and/or cart pages.</tooltip>
62
+ <frontend_type>text</frontend_type>
63
+ <sort_order>3</sort_order>
64
+ <show_in_default>1</show_in_default>
65
+ <show_in_website>1</show_in_website>
66
+ <show_in_store>1</show_in_store>
67
+ </checkoutbutton_url>
68
+ <checkoutbutton_size translate="label">
69
+ <label>Checkout Button Size</label>
70
+ <comment>The size of the default "Buy with MasterPass" checkout button displayed on the cart and checkout pages. This setting has no effect if the Checkout Button URL setting is not empty.</comment>
71
+ <frontend_type>select</frontend_type>
72
+ <source_model>fontis_masterpass/system_checkoutButton</source_model>
73
+ <sort_order>4</sort_order>
74
+ <show_in_default>1</show_in_default>
75
+ <show_in_website>1</show_in_website>
76
+ <show_in_store>1</show_in_store>
77
+ </checkoutbutton_size>
78
+ <acceptancemark_url translate="label">
79
+ <label>Acceptance Mark URL</label>
80
+ <comment><![CDATA[Enter a protocol-independent URL for the acceptance mark image you want to use on the checkout. Only use this if you need it in a language other than English. Leave blank to use the default. Details can be found in the <a href="https://developer.mastercard.com/portal/display/api/MasterPass+-+Merchant+Checkout+-+Documentation" target="_blank">MasterPass Integration Guide</a>.]]></comment>
81
+ <tooltip>Failure to use a protocol-independent URL could result in insecure content warnings on your checkout.</tooltip>
82
+ <frontend_type>text</frontend_type>
83
+ <sort_order>5</sort_order>
84
+ <show_in_default>1</show_in_default>
85
+ <show_in_website>1</show_in_website>
86
+ <show_in_store>1</show_in_store>
87
+ </acceptancemark_url>
88
+ <acceptancemark_size translate="label">
89
+ <label>Acceptance Mark Height Size</label>
90
+ <comment>The height of the acceptance mark image used on the checkout, in pixels. The browser will scale the image accordingly. Leave empty for the default (32px).</comment>
91
+ <validate>validate-number</validate>
92
+ <frontend_type>text</frontend_type>
93
+ <sort_order>6</sort_order>
94
+ <show_in_default>1</show_in_default>
95
+ <show_in_website>1</show_in_website>
96
+ <show_in_store>1</show_in_store>
97
+ </acceptancemark_size>
98
+ <learn_more_language translate="label">
99
+ <label>Language for Learn More link</label>
100
+ <frontend_type>select</frontend_type>
101
+ <source_model>fontis_masterpass/system_learnmoreLanguage</source_model>
102
+ <sort_order>7</sort_order>
103
+ <show_in_default>1</show_in_default>
104
+ <show_in_website>1</show_in_website>
105
+ <show_in_store>1</show_in_store>
106
+ </learn_more_language>
107
+ <payment_gateway translate="label">
108
+ <label>Payment Gateway</label>
109
+ <comment>The payment gateway used to process transactions using MasterPass-supplied details. Must support the accepted cards chosen below, and must not require credit card validation.</comment>
110
+ <tooltip>If your payment gateway is not showing up, check that it supports credit cards and that it is set to not require credit card validation.</tooltip>
111
+ <frontend_type>select</frontend_type>
112
+ <source_model>fontis_masterpass/system_paymentGateways</source_model>
113
+ <sort_order>10</sort_order>
114
+ <show_in_default>1</show_in_default>
115
+ <show_in_website>1</show_in_website>
116
+ <show_in_store>1</show_in_store>
117
+ </payment_gateway>
118
+ <token_payments_accepted translate="label">
119
+ <label>Token Payments Accepted</label>
120
+ <comment>Please refer to your gateway's documentation for token payment support or contact your gateway integration provider. Disabling this option will store the customers credit card number in the customer's checkout session.</comment>
121
+ <frontend_type>select</frontend_type>
122
+ <source_model>adminhtml/system_config_source_yesno</source_model>
123
+ <sort_order>11</sort_order>
124
+ <show_in_default>1</show_in_default>
125
+ <show_in_website>1</show_in_website>
126
+ <show_in_store>1</show_in_store>
127
+ </token_payments_accepted>
128
+ <accepted_cards translate="label">
129
+ <label>Accepted Cards</label>
130
+ <frontend_type>multiselect</frontend_type>
131
+ <backend_model>fontis_masterpass/system_cards</backend_model>
132
+ <source_model>fontis_masterpass/system_cards</source_model>
133
+ <sort_order>12</sort_order>
134
+ <show_in_default>1</show_in_default>
135
+ <show_in_website>1</show_in_website>
136
+ <show_in_store>1</show_in_store>
137
+ </accepted_cards>
138
+ <show_on_checkout translate="label">
139
+ <label>Show On Checkout</label>
140
+ <comment>Whether or not MasterPass should be displayed as a payment method on the checkout.</comment>
141
+ <frontend_type>select</frontend_type>
142
+ <source_model>adminhtml/system_config_source_yesno</source_model>
143
+ <sort_order>13</sort_order>
144
+ <show_in_default>1</show_in_default>
145
+ <show_in_website>1</show_in_website>
146
+ <show_in_store>1</show_in_store>
147
+ </show_on_checkout>
148
+ <sort_order translate="label">
149
+ <label>Sort Order</label>
150
+ <comment>This controls the order in which payment methods appear on the checkout.</comment>
151
+ <frontend_type>text</frontend_type>
152
+ <sort_order>14</sort_order>
153
+ <show_in_default>1</show_in_default>
154
+ <show_in_website>1</show_in_website>
155
+ <show_in_store>1</show_in_store>
156
+ <depends>
157
+ <show_on_checkout>1</show_on_checkout>
158
+ </depends>
159
+ </sort_order>
160
+ <environment translate="label">
161
+ <label>Environment</label>
162
+ <frontend_type>select</frontend_type>
163
+ <source_model>fontis_masterpass/system_environment</source_model>
164
+ <sort_order>20</sort_order>
165
+ <show_in_default>1</show_in_default>
166
+ <show_in_website>1</show_in_website>
167
+ <show_in_store>1</show_in_store>
168
+ </environment>
169
+ <checkout_identifier translate="label">
170
+ <label>Checkout Identifier</label>
171
+ <frontend_type>text</frontend_type>
172
+ <sort_order>21</sort_order>
173
+ <show_in_default>1</show_in_default>
174
+ <show_in_website>1</show_in_website>
175
+ <show_in_store>1</show_in_store>
176
+ </checkout_identifier>
177
+ <consumer_key translate="label">
178
+ <label>Consumer Key</label>
179
+ <frontend_type>text</frontend_type>
180
+ <sort_order>22</sort_order>
181
+ <show_in_default>1</show_in_default>
182
+ <show_in_website>1</show_in_website>
183
+ <show_in_store>1</show_in_store>
184
+ </consumer_key>
185
+ <private_key translate="label,comment">
186
+ <label>Private Key</label>
187
+ <comment>Enter a PEM-formatted RSA private key.</comment>
188
+ <frontend_type>textarea</frontend_type>
189
+ <sort_order>23</sort_order>
190
+ <show_in_default>1</show_in_default>
191
+ <show_in_website>1</show_in_website>
192
+ <show_in_store>1</show_in_store>
193
+ </private_key>
194
+ </fields>
195
+ </settings>
196
+ </groups>
197
+ </fontis_masterpass>
198
+ </sections>
199
+ </config>
app/design/frontend/base/default/layout/fontis/masterpass.xml ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Fontis MasterPass Extension
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
+ *
13
+ * @category Fontis
14
+ * @package Fontis_MasterPass
15
+ * @author Matthew Gamble
16
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
17
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
18
+ */
19
+ -->
20
+
21
+ <layout version="0.1.0">
22
+ <checkout_cart_index>
23
+ <reference name="checkout.cart.top_methods">
24
+ <block type="fontis_masterpass/checkoutlink" name="checkout.cart.methods.masterpass.top" template="fontis/masterpass/checkoutlink.phtml" />
25
+ </reference>
26
+
27
+ <reference name="checkout.cart.methods">
28
+ <block type="fontis_masterpass/checkoutlink" name="checkout.cart.methods.masterpass.bottom" template="fontis/masterpass/checkoutlink.phtml" />
29
+ </reference>
30
+ </checkout_cart_index>
31
+
32
+ <checkout_onepage_index>
33
+ <reference name="checkout.onepage.login.before">
34
+ <block type="fontis_masterpass/checkoutlink" name="checkout.cart.methods.masterpass.bottom" template="fontis/masterpass/checkoutlink.phtml" />
35
+ </reference>
36
+ </checkout_onepage_index>
37
+
38
+ <masterpass_checkout_review translate="label">
39
+ <label>MasterPass Order Review Form</label>
40
+ <remove name="right"/>
41
+ <remove name="left"/>
42
+
43
+ <reference name="root">
44
+ <action method="setTemplate"><template>page/1column.phtml</template></action>
45
+ </reference>
46
+ <reference name="head">
47
+ <action method="addItem"><type>skin_js</type><name>js/checkout/review.js</name></action>
48
+ </reference>
49
+ <reference name="content">
50
+ <block type="fontis_masterpass/checkout_review" name="masterpass.checkout.review" template="fontis/masterpass/review.phtml">
51
+ <block type="fontis_masterpass/checkout_review_details" name="masterpass.checkout.review.details" as="details" template="fontis/masterpass/review/details.phtml">
52
+ <action method="addItemRender"><type>default</type><block>checkout/cart_item_renderer</block><template>checkout/onepage/review/item.phtml</template></action>
53
+ <action method="addItemRender"><type>grouped</type><block>checkout/cart_item_renderer_grouped</block><template>checkout/onepage/review/item.phtml</template></action>
54
+ <action method="addItemRender"><type>configurable</type><block>checkout/cart_item_renderer_configurable</block><template>checkout/onepage/review/item.phtml</template></action>
55
+ <block type="checkout/cart_totals" name="masterpass.checkout.review.details.totals" as="totals" template="checkout/onepage/review/totals.phtml"/>
56
+ </block>
57
+ </block>
58
+ </reference>
59
+ </masterpass_checkout_review>
60
+
61
+ <masterpass_checkout_review_details>
62
+ <block type="fontis_masterpass/checkout_review_details" name="root" output="toHtml" template="fontis/masterpass/review/details.phtml">
63
+ <action method="addItemRender"><type>default</type><block>checkout/cart_item_renderer</block><template>checkout/onepage/review/item.phtml</template></action>
64
+ <action method="addItemRender"><type>grouped</type><block>checkout/cart_item_renderer_grouped</block><template>checkout/onepage/review/item.phtml</template></action>
65
+ <action method="addItemRender"><type>configurable</type><block>checkout/cart_item_renderer_configurable</block><template>checkout/onepage/review/item.phtml</template></action>
66
+ <block type="checkout/cart_totals" name="masterpass.checkout.review.details.totals" as="totals" template="checkout/onepage/review/totals.phtml"/>
67
+ </block>
68
+ </masterpass_checkout_review_details>
69
+ </layout>
app/design/frontend/base/default/template/fontis/masterpass/checkoutlink.phtml ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+ ?>
19
+ <?php /** @var $this Fontis_Masterpass_Block_Checkoutlink */ ?>
20
+ <?php $translation = $this->__("Check out with %s", Mage::helper("fontis_masterpass/config")->getFrontendTitle()); ?>
21
+ <a href="<?php echo $this->getCheckoutUrl(); ?>" class="masterpass-checkoutlink"><img src="<?php echo $this->getImageUrl(); ?>" title="<?php echo $translation; ?>" alt="<?php echo $translation; ?>" /></a>
app/design/frontend/base/default/template/fontis/masterpass/payment/form.phtml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+ ?>
19
+ <?php /** @var $this Fontis_Masterpass_Block_Payment_Form */ ?>
20
+ <ul class="form-list" id="payment_form_<?php echo $this->getMethodCode(); ?>" style="display:none;">
21
+ <li class="form-alt"><?php echo $this->__("You will be redirected to the %s website when you place an order.", Mage::helper("fontis_masterpass/config")->getFrontendTitle()); ?></li>
22
+ </ul>
app/design/frontend/base/default/template/fontis/masterpass/review.phtml ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+ ?>
19
+ <?php /** @var Fontis_Masterpass_Block_Checkout_Review $this */ ?>
20
+ <div class="page-title">
21
+ <div class="left"><h1><?php echo $this->__("Review Order") ?></h1></div>
22
+ <div class="right"><img src="<?php echo $this->getMasterpassAcceptanceMarkUrl(); ?>" alt="<?php echo Mage::helper("fontis_masterpass/config")->getFrontendTitle(); ?>" /></div>
23
+ <div class="clearfix"></div>
24
+ </div>
25
+ <?php echo $this->getMessagesBlock()->getGroupedHtml(); ?>
26
+
27
+ <?php if ($shippingAddress = $this->getShippingAddress()): ?>
28
+ <div class="info-set col2-set shipping-container">
29
+ <h2 class="legend"><?php echo $this->__("Shipping Information"); ?></h2>
30
+ <div class="col-1">
31
+ <div class="box">
32
+ <div class="box-title">
33
+ <h3><?php echo $this->__("Shipping Address"); ?><span class="separator"><?php if ($this->getCanEditShippingAddress()): ?> | </span><a href="<?php echo $this->getEditUrl(); ?>"><?php echo $this->__("Change Shipping Address"); ?></a><?php endif; ?></h3>
34
+ </div>
35
+ <div class="box-content">
36
+ <address><?php echo $this->renderAddress($shippingAddress); ?></address>
37
+ </div>
38
+ </div>
39
+ </div>
40
+ <div class="col-2">
41
+ <div class="box">
42
+ <div class="box-title">
43
+ <h3><?php echo $this->__("Shipping Method"); ?></h3>
44
+ </div>
45
+ <div class="box-content">
46
+ <?php if ($this->getCanEditShippingMethod() || !$this->getCurrentShippingRate()): ?>
47
+ <?php if ($groups = $this->getShippingRateGroups()): ?>
48
+ <?php $currentRate = $this->getCurrentShippingRate(); ?>
49
+ <form method="post" id="shipping_method_form" action="<?php echo $this->escapeHtml($this->getShippingMethodSubmitUrl()); ?>">
50
+ <fieldset>
51
+ <select name="shipping_method" id="shipping_method" style="width:250px;" class="required-entry">
52
+ <?php if (!$currentRate): ?>
53
+ <option value=""><?php echo $this->__("Please select a shipping method..."); ?></option>
54
+ <?php endif;?>
55
+ <?php foreach ($groups as $code => $rates): ?>
56
+ <optgroup label="<?php echo $this->getCarrierName($code); ?>" style="font-style:normal;">
57
+ <?php foreach ($rates as $rate):?>
58
+ <option value="<?php echo $this->renderShippingRateValue($rate); ?>"<?php echo ($currentRate === $rate) ? ' selected="selected"' : ''; ?>>
59
+ <?php echo $this->renderShippingRateOption($rate); ?>
60
+ </option>
61
+ <?php endforeach;?>
62
+ </optgroup>
63
+ <?php endforeach;?>
64
+ </select>
65
+ </fieldset>
66
+ <p class="actions">
67
+ <button id="update_shipping_method_submit" type="submit" class="button"><span><span><?php echo $this->__("Update Shipping Method"); ?></span></span></button>
68
+ </p>
69
+ </form>
70
+ <?php else: ?>
71
+ <p><strong><?php echo $this->__("Sorry, no quotes are available for this order at this time."); ?></strong></p>
72
+ <?php endif; ?>
73
+ <?php else: ?>
74
+ <p><strong><?php echo $this->renderShippingRateOption($this->getCurrentShippingRate()); ?></strong></p>
75
+ <?php endif; ?>
76
+ </div>
77
+ </div>
78
+ </div>
79
+ </div>
80
+ <?php endif; ?>
81
+
82
+ <div class="info-set col2-set billing-container">
83
+ <h2 class="legend"><?php echo $this->__("Billing Information"); ?></h2>
84
+ <div class="col-1">
85
+ <div class="box">
86
+ <div class="box-title">
87
+ <h3><?php echo $this->__("Billing Address"); ?></h3>
88
+ </div>
89
+ <div class="box-content">
90
+ <address>
91
+ <?php echo $this->renderAddress($this->getBillingAddress()); ?><br />
92
+ <?php echo $this->__("Payer Email: %s", $this->getBillingAddress()->getEmail()); ?>
93
+ </address>
94
+ </div>
95
+ </div>
96
+ </div>
97
+ <div class="col-2">
98
+ <div class="box">
99
+ <div class="box-title">
100
+ <h3><?php echo $this->__("Payment Method"); ?></h3>
101
+ </div>
102
+ <div class="box-content">
103
+ <?php echo $this->escapeHtml($this->getPaymentMethodTitle()); ?>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ </div>
108
+
109
+ <div class="info-set details-container">
110
+ <h2 class="legend"><?php echo $this->__("Items in Your Shopping Cart"); ?><span class="separator"> | </span><a href="<?php echo $this->getUrl("checkout/cart"); ?>"><?php echo $this->__("Edit Shopping Cart"); ?></a></h2>
111
+ <div id="details-reload">
112
+ <?php echo $this->getChildHtml("details"); ?>
113
+ </div>
114
+ </div>
115
+ <form method="post" id="order_review_form" action="<?php echo $this->getPlaceOrderUrl(); ?>">
116
+ <div class="buttons-set buttons-set-order" id="review-buttons-container">
117
+ <button id="review_button" value="<?php echo $this->__("Place Order"); ?>" class="button btn-checkout"><span><span><?php echo $this->__("Place Order"); ?></span></span></button>
118
+ <button type="submit" id="review_submit" value="<?php echo $this->__("Place Order"); ?>" class="button btn-checkout"><span><span><?php echo $this->__("Place Order"); ?></span></span></button>
119
+ <span class="please-wait" id="review-please-wait" style="display:none;">
120
+ <img src="<?php echo $this->getSkinUrl("images/opc-ajax-loader.gif"); ?>" alt="<?php echo $this->__("Submitting order information..."); ?>" title="<?php echo $this->__("Submitting order information..."); ?>" class="v-middle" /> <?php echo $this->__("Submitting order information..."); ?>
121
+ </span>
122
+ </div>
123
+ </form>
124
+ <script type="text/javascript">
125
+ //<![CDATA[
126
+ // submit buttons are not needed when submitting with ajax
127
+ $("review_submit").hide();
128
+ if ($("update_shipping_method_submit")) {
129
+ $("update_shipping_method_submit").hide();
130
+ }
131
+
132
+ MasterpassReviewAjax = new OrderReviewController($("order_review_form"), $("review_button"), $("shipping_method"), $("shipping_method_form"), "details-reload");
133
+ MasterpassReviewAjax.addPleaseWait($("review-please-wait"));
134
+ //]]>
135
+ </script>
app/design/frontend/base/default/template/fontis/masterpass/review/details.phtml ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis MasterPass Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Fontis
13
+ * @package Fontis_MasterPass
14
+ * @author Matthew Gamble
15
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+ ?>
19
+ <?php
20
+ /** @var Fontis_Masterpass_Block_Checkout_Review_Details $this */
21
+ /** @var Mage_Tax_Helper_Data $taxHelper */
22
+ $taxHelper = Mage::helper("tax");
23
+ $displayBothPrices = $taxHelper->displayCartBothPrices();
24
+ if ($displayBothPrices) {
25
+ $colspan = 2;
26
+ $rowspan = 2;
27
+ } else {
28
+ $colspan = 1;
29
+ $rowspan = 1;
30
+ }
31
+ ?>
32
+ <table id="details-table" class="data-table">
33
+ <col />
34
+ <col width="1" />
35
+ <col width="1" />
36
+ <col width="1" />
37
+ <?php if ($displayBothPrices): ?>
38
+ <col width="1" />
39
+ <col width="1" />
40
+ <?php endif; ?>
41
+ <thead>
42
+ <tr>
43
+ <th rowspan="<?php echo $rowspan ?>"><?php echo $this->__("Product Name") ?></th>
44
+ <th colspan="<?php echo $colspan ?>" class="a-center"><?php echo $this->__("Price"); ?></th>
45
+ <th rowspan="<?php echo $rowspan ?>" class="a-center"><?php echo $this->__("Qty"); ?></th>
46
+ <th colspan="<?php echo $colspan ?>" class="a-center"><?php echo $this->__("Subtotal"); ?></th>
47
+ </tr>
48
+ <?php if ($displayBothPrices): ?>
49
+ <tr>
50
+ <th class="a-right"><?php echo $taxHelper->getIncExcTaxLabel(false); ?></th>
51
+ <th><?php echo $taxHelper->getIncExcTaxLabel(true); ?></th>
52
+ <th class="a-right"><?php echo $taxHelper->getIncExcTaxLabel(false); ?></th>
53
+ <th><?php echo $taxHelper->getIncExcTaxLabel(true); ?></th>
54
+ </tr>
55
+ <?php endif; ?>
56
+ </thead>
57
+ <?php echo $this->getChildHtml("totals"); ?>
58
+ <tbody>
59
+ <?php foreach ($this->getItems() as $item): ?>
60
+ <?php echo $this->getItemHtml($item); ?>
61
+ <?php endforeach ?>
62
+ </tbody>
63
+ </table>
64
+ <script type="text/javascript">decorateTable("details-table");</script>
app/etc/modules/Fontis_Masterpass.xml ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!--
3
+ /**
4
+ * Fontis MasterPass Extension
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
+ *
13
+ * @category Fontis
14
+ * @package Fontis_MasterPass
15
+ * @author Matthew Gamble
16
+ * @copyright Copyright (c) 2014 Fontis Pty. Ltd. (http://www.fontis.com.au)
17
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
18
+ */
19
+ -->
20
+ <config>
21
+ <modules>
22
+ <Fontis_Masterpass>
23
+ <active>true</active>
24
+ <codePool>community</codePool>
25
+ </Fontis_Masterpass>
26
+ </modules>
27
+ </config>
package.xml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Fontis_Masterpass</name>
4
+ <version>1.0.2</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://opensource.org/licenses/osl-3.0.php">Open Software License (OSL 3.0)</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Fontis extension for the MasterPass credit card wallet.</summary>
10
+ <description>Fontis extension for the MasterPass credit card wallet.</description>
11
+ <notes>Initial release.</notes>
12
+ <authors><author><name>Fontis</name><user>fontis</user><email>magento@fontis.com.au</email></author></authors>
13
+ <date>2014-11-12</date>
14
+ <time>22:49:56</time>
15
+ <contents><target name="magecommunity"><dir name="Fontis"><dir name="Masterpass"><dir name="Block"><file name="Abstract.php" hash="47b102fcdd3905b27ee6f01337933e90"/><dir name="Adminhtml"><dir name="Sales"><file name="Orderpayment.php" hash="43160821fa99f4fe28cf9b868402563f"/></dir></dir><dir name="Checkout"><dir name="Review"><file name="Details.php" hash="7482ce9f7202aea96d8739bc4d2e3ead"/></dir><file name="Review.php" hash="1232e6d22c6e3dbbc22fb415621ca72d"/></dir><file name="Checkoutlink.php" hash="bfc6fef1489fffd3ccb04a09eff1632e"/><dir name="Payment"><file name="Form.php" hash="f43f85d1b8a4448acf033d7bf421efc3"/></dir></dir><dir name="Helper"><file name="Config.php" hash="7f65b1d5d64ee3ac7be10408cc8dfb78"/><file name="Data.php" hash="d73d0e7fca0c1d92f513fba181587681"/></dir><dir name="Model"><file name="Checkout.php" hash="86bff3358db390aeba8082d5290e99de"/><dir name="Directory"><file name="Region.php" hash="282b276397f6fd265c1668b6bfd1b3d5"/></dir><dir name="Masterpass"><file name="Oauth.php" hash="dabe166d7ef955f05795c58ae5375361"/><file name="Order.php" hash="3a28848782d39c71be0233d458eceede"/><file name="Payment.php" hash="4124c5243fe755924ac202237f9e2fa9"/></dir><file name="Observer.php" hash="4a35d7d2a73545c2bbf9f8a8c1d5403f"/><file name="Payment.php" hash="855625334fbb824091e219bcda38c377"/><dir name="System"><file name="Cards.php" hash="7711c978a2724a575ac8d191e224722a"/><file name="CheckoutButton.php" hash="e0045a562c8d3477a321301e5564d381"/><file name="Environment.php" hash="643a075830befa0ad2091f1452631f88"/><file name="LearnmoreLanguage.php" hash="13d7e277aa2556832c7b4a39801c2940"/><file name="PaymentGateways.php" hash="8a66634400d18d223d29ff2c3c7c7cf1"/></dir><dir name="Zend"><file name="OauthAccessToken.php" hash="45399520776b512f0ea2bf7fe4a04d28"/><file name="OauthConfig.php" hash="5b00c78561e4dfa6f72873a52ed8e0c5"/><file name="OauthConsumer.php" hash="63d5f2a52e981d1f14306578fd328ac4"/><file name="OauthRequestToken.php" hash="aa9f5803aad5e39b7c7166095c346316"/></dir></dir><file name="PaymentException.php" hash="ac7bca3ceaef694c9b971701e8e22caf"/><dir name="controllers"><file name="CheckoutController.php" hash="cf5af9a7faead65236fee2c62b35b27f"/></dir><dir name="etc"><file name="config.xml" hash="b916ca9f337ef6b7aa2bfaece00f5e4b"/><file name="system.xml" hash="3184988e01b0cf6971f3b7709eb97938"/></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><dir name="fontis"><file name="masterpass.xml" hash="9b6fa1b858eacac59d89aede7bddcbcd"/></dir></dir><dir name="template"><dir name="fontis"><dir name="masterpass"><file name="checkoutlink.phtml" hash="ebedc09adebae02f1493e26e6fdfb0f7"/><dir name="payment"><file name="form.phtml" hash="a8fcd72b9d9ecb73ff29a42e3ae02ecc"/></dir><dir name="review"><file name="details.phtml" hash="07fb60473e5d7b45245155735586aebe"/></dir><file name="review.phtml" hash="e9c9f93c2753bf33f0b4cf222d98af3f"/></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Fontis_Masterpass.xml" hash="96142b38d1ba4473d735981d6b4d8075"/></dir></target></contents>
16
+ <compatible/>
17
+ <dependencies><required><php><min>5.3.0</min><max>6.0.0</max></php></required></dependencies>
18
+ </package>