Version Notes
v0.1.1 - Initial Release
Download this release
Release Info
Developer | Kash Corp. |
Extension | kash_gateway |
Version | 0.1.1 |
Comparing to | |
See all releases |
Version 0.1.1
- app/code/local/Kash/Gateway/Block/Adminhtml/Info.php +24 -0
- app/code/local/Kash/Gateway/Block/Adminhtml/Sales/Order/Grid.php +24 -0
- app/code/local/Kash/Gateway/Block/Form/Bb.php +63 -0
- app/code/local/Kash/Gateway/Block/Review.php +185 -0
- app/code/local/Kash/Gateway/Block/Review/Details.php +31 -0
- app/code/local/Kash/Gateway/Helper/Checkout.php +67 -0
- app/code/local/Kash/Gateway/Helper/Data.php +10 -0
- app/code/local/Kash/Gateway/Model/Api/Abstract.php +357 -0
- app/code/local/Kash/Gateway/Model/Api/Bb.php +235 -0
- app/code/local/Kash/Gateway/Model/Cart.php +497 -0
- app/code/local/Kash/Gateway/Model/Checkout.php +655 -0
- app/code/local/Kash/Gateway/Model/Config.php +183 -0
- app/code/local/Kash/Gateway/Model/Method/Bb.php +111 -0
- app/code/local/Kash/Gateway/Model/Observer.php +68 -0
- app/code/local/Kash/Gateway/Model/Session.php +11 -0
- app/code/local/Kash/Gateway/controllers/BbController.php +448 -0
- app/code/local/Kash/Gateway/data/kash_gateway_setup/data-install-0.0.1.php +10 -0
- app/code/local/Kash/Gateway/data/kash_gateway_setup/data-upgrade-0.0.1-0.0.2.php +40 -0
- app/code/local/Kash/Gateway/etc/config.xml +119 -0
- app/code/local/Kash/Gateway/etc/system.xml +114 -0
- app/code/local/Kash/Gateway/sql/kash_gateway_setup/install-0.0.1.php +22 -0
- app/design/adminhtml/default/default/template/kash/info/default.phtml +30 -0
- app/design/frontend/base/default/layout/kash/gateway.xml +72 -0
- app/design/frontend/base/default/template/kash/container.phtml +5 -0
- app/design/frontend/base/default/template/kash/form.phtml +13 -0
- app/design/frontend/base/default/template/kash/js.phtml +56 -0
- app/design/frontend/base/default/template/kash/payment/mark.phtml +7 -0
- app/design/frontend/base/default/template/kash/payment/redirect.phtml +8 -0
- app/design/frontend/base/default/template/kash/payment/review.phtml +65 -0
- app/design/frontend/base/default/template/kash/payment/review/details.phtml +39 -0
- app/etc/modules/Kash_Gateway.xml +12 -0
- package.xml +22 -0
- skin/frontend/base/default/css/kash/start.css +3 -0
app/code/local/Kash/Gateway/Block/Adminhtml/Info.php
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Base payment iformation block
|
4 |
+
*
|
5 |
+
*/
|
6 |
+
class Kash_Gateway_Block_Adminhtml_Info extends Mage_Payment_Block_Info
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Payment rendered specific information
|
10 |
+
*
|
11 |
+
* @var Varien_Object
|
12 |
+
*/
|
13 |
+
protected $_paymentSpecificInformation = null;
|
14 |
+
|
15 |
+
protected function _construct()
|
16 |
+
{
|
17 |
+
parent::_construct();
|
18 |
+
$this->setTemplate('kash/info/default.phtml');
|
19 |
+
}
|
20 |
+
|
21 |
+
public function getAdditionalInformation(){
|
22 |
+
return $this->getInfo()->getAdditionalInformation();
|
23 |
+
}
|
24 |
+
}
|
app/code/local/Kash/Gateway/Block/Adminhtml/Sales/Order/Grid.php
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Kash_Gateway_Block_Adminhtml_Sales_Order_Grid extends Mage_Adminhtml_Block_Sales_Order_Grid {
|
4 |
+
|
5 |
+
protected function _prepareCollection()
|
6 |
+
{
|
7 |
+
$collection = Mage::getResourceModel($this->_getCollectionClass());
|
8 |
+
|
9 |
+
$collection->join('sales/order_payment', '`main_table`.entity_id=`sales/order_payment`.entity_id', array('x_gateway_reference' =>'x_gateway_reference'), null,'left');
|
10 |
+
$this->setCollection($collection);
|
11 |
+
return Mage_Adminhtml_Block_Widget_Grid::_prepareCollection();
|
12 |
+
}
|
13 |
+
|
14 |
+
protected function _prepareColumns()
|
15 |
+
{
|
16 |
+
parent::_prepareColumns();
|
17 |
+
$this->addColumnAfter('x_gateway_reference', array(
|
18 |
+
'header' => Mage::helper('catalog')->__('Gateway Reference'),
|
19 |
+
'index' => 'x_gateway_reference',
|
20 |
+
'type' => 'text'
|
21 |
+
),'sku');
|
22 |
+
}
|
23 |
+
|
24 |
+
}
|
app/code/local/Kash/Gateway/Block/Form/Bb.php
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Payment BB "form"
|
5 |
+
*
|
6 |
+
* @author Blue Badger <jonathan@badger.blue>
|
7 |
+
*/
|
8 |
+
class Kash_Gateway_Block_Form_Bb extends Mage_Payment_Block_Form
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* Payment method code
|
12 |
+
* @var string
|
13 |
+
*/
|
14 |
+
protected $_methodCode = Kash_Gateway_Model_Config::METHOD_GATEWAY_KASH;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Config model instance
|
18 |
+
*
|
19 |
+
* @var Kash_Gateway_Model_Config
|
20 |
+
*/
|
21 |
+
protected $_config;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Set template and redirect message
|
25 |
+
*/
|
26 |
+
protected function _construct()
|
27 |
+
{
|
28 |
+
$this->_config = Mage::getModel('kash_gateway/config')->setMethod($this->getMethodCode());
|
29 |
+
$locale = Mage::app()->getLocale();
|
30 |
+
$mark = Mage::getConfig()->getBlockClassName('core/template');
|
31 |
+
$mark = new $mark;
|
32 |
+
$mark->setTemplate('kash/payment/mark.phtml')
|
33 |
+
->setPaymentImageSrc($this->_config->getPaymentImageUrl($locale->getLocaleCode()))
|
34 |
+
->setMessage(
|
35 |
+
Mage::helper('kash_gateway')->__($this->_config->title)
|
36 |
+
);
|
37 |
+
$this->setTemplate('kash/payment/redirect.phtml')
|
38 |
+
->setRedirectMessage(
|
39 |
+
Mage::helper('kash_gateway')->__('')
|
40 |
+
)
|
41 |
+
->setMethodTitle('')
|
42 |
+
->setMethodLabelAfterHtml($mark->toHtml())
|
43 |
+
;
|
44 |
+
$result = parent::_construct();
|
45 |
+
return $result;
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Set data to block
|
50 |
+
*
|
51 |
+
* @return Mage_Core_Block_Abstract
|
52 |
+
*/
|
53 |
+
protected function _beforeToHtml()
|
54 |
+
{
|
55 |
+
$customerId = Mage::getSingleton('customer/session')->getCustomerId();
|
56 |
+
return parent::_beforeToHtml();
|
57 |
+
}
|
58 |
+
|
59 |
+
public function getMethodCode()
|
60 |
+
{
|
61 |
+
return $this->_methodCode;
|
62 |
+
}
|
63 |
+
}
|
app/code/local/Kash/Gateway/Block/Review.php
ADDED
@@ -0,0 +1,185 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Payment Onepage checkout block
|
4 |
+
*/
|
5 |
+
class Kash_Gateway_Block_Review extends Mage_Core_Block_Template
|
6 |
+
{
|
7 |
+
/**
|
8 |
+
* @var Mage_Sales_Model_Quote
|
9 |
+
*/
|
10 |
+
protected $_quote;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Currently selected shipping rate
|
14 |
+
*
|
15 |
+
* @var Mage_Sales_Model_Quote_Address_Rate
|
16 |
+
*/
|
17 |
+
protected $_currentShippingRate = null;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Quote object setter
|
21 |
+
*
|
22 |
+
* @param Mage_Sales_Model_Quote $quote
|
23 |
+
* @return $this
|
24 |
+
*/
|
25 |
+
public function setQuote(Mage_Sales_Model_Quote $quote)
|
26 |
+
{
|
27 |
+
$this->_quote = $quote;
|
28 |
+
return $this;
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Return quote billing address
|
33 |
+
*
|
34 |
+
* @return Mage_Sales_Model_Quote_Address
|
35 |
+
*/
|
36 |
+
public function getBillingAddress()
|
37 |
+
{
|
38 |
+
return $this->_quote->getBillingAddress();
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Return quote shipping address
|
43 |
+
*
|
44 |
+
* @return Mage_Sales_Model_Quote_Address
|
45 |
+
*/
|
46 |
+
public function getShippingAddress()
|
47 |
+
{
|
48 |
+
if ($this->_quote->getIsVirtual()) {
|
49 |
+
return false;
|
50 |
+
}
|
51 |
+
return $this->_quote->getShippingAddress();
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Get HTML output for specified address
|
56 |
+
*
|
57 |
+
* @param Mage_Sales_Model_Quote_Address
|
58 |
+
* @return string
|
59 |
+
*/
|
60 |
+
public function renderAddress($address)
|
61 |
+
{
|
62 |
+
return $address->getFormated(true);
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Return carrier name from config, base on carrier code
|
67 |
+
*
|
68 |
+
* @param $carrierCode string
|
69 |
+
* @return string
|
70 |
+
*/
|
71 |
+
public function getCarrierName($carrierCode)
|
72 |
+
{
|
73 |
+
if ($name = Mage::getStoreConfig("carriers/{$carrierCode}/title")) {
|
74 |
+
return $name;
|
75 |
+
}
|
76 |
+
return $carrierCode;
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Get either shipping rate code or empty value on error
|
81 |
+
*
|
82 |
+
* @param Varien_Object $rate
|
83 |
+
* @return string
|
84 |
+
*/
|
85 |
+
public function renderShippingRateValue(Varien_Object $rate)
|
86 |
+
{
|
87 |
+
if ($rate->getErrorMessage()) {
|
88 |
+
return '';
|
89 |
+
}
|
90 |
+
return $rate->getCode();
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Get shipping rate code title and its price or error message
|
95 |
+
*
|
96 |
+
* @param Varien_Object $rate
|
97 |
+
* @param string $format
|
98 |
+
* @param string $inclTaxFormat
|
99 |
+
* @return string
|
100 |
+
*/
|
101 |
+
public function renderShippingRateOption($rate, $format = '%s - %s%s', $inclTaxFormat = ' (%s %s)')
|
102 |
+
{
|
103 |
+
$renderedInclTax = '';
|
104 |
+
if ($rate->getErrorMessage()) {
|
105 |
+
$price = $rate->getErrorMessage();
|
106 |
+
} else {
|
107 |
+
$price = $this->_getShippingPrice($rate->getPrice(),
|
108 |
+
$this->helper('tax')->displayShippingPriceIncludingTax());
|
109 |
+
|
110 |
+
$incl = $this->_getShippingPrice($rate->getPrice(), true);
|
111 |
+
if (($incl != $price) && $this->helper('tax')->displayShippingBothPrices()) {
|
112 |
+
$renderedInclTax = sprintf($inclTaxFormat, Mage::helper('tax')->__('Incl. Tax'), $incl);
|
113 |
+
}
|
114 |
+
}
|
115 |
+
return sprintf($format, $this->escapeHtml($rate->getMethodTitle()), $price, $renderedInclTax);
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Getter for current shipping rate
|
120 |
+
*
|
121 |
+
* @return Mage_Sales_Model_Quote_Address_Rate
|
122 |
+
*/
|
123 |
+
public function getCurrentShippingRate()
|
124 |
+
{
|
125 |
+
return $this->_currentShippingRate;
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Return formatted shipping price
|
130 |
+
*
|
131 |
+
* @param float $price
|
132 |
+
* @param bool $isInclTax
|
133 |
+
*
|
134 |
+
* @return bool
|
135 |
+
*/
|
136 |
+
protected function _getShippingPrice($price, $isInclTax)
|
137 |
+
{
|
138 |
+
return $this->_formatPrice($this->helper('tax')->getShippingPrice($price, $isInclTax, $this->_address));
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Format price base on store convert price method
|
143 |
+
*
|
144 |
+
* @param float $price
|
145 |
+
* @return string
|
146 |
+
*/
|
147 |
+
protected function _formatPrice($price)
|
148 |
+
{
|
149 |
+
return $this->_quote->getStore()->convertPrice($price, true);
|
150 |
+
}
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Retrieve payment method and assign additional template values
|
154 |
+
*
|
155 |
+
* @return Kash_Gateway_Block_Review
|
156 |
+
*/
|
157 |
+
protected function _beforeToHtml()
|
158 |
+
{
|
159 |
+
$methodInstance = $this->_quote->getPayment()->getMethodInstance();
|
160 |
+
$this->setPaymentMethodTitle($methodInstance->getTitle());
|
161 |
+
|
162 |
+
$this->setShippingRateRequired(true);
|
163 |
+
if ($this->_quote->getIsVirtual()) {
|
164 |
+
$this->setShippingRateRequired(false);
|
165 |
+
} else {
|
166 |
+
// prepare shipping rates
|
167 |
+
$this->_address = $this->_quote->getShippingAddress();
|
168 |
+
$groups = $this->_address->getGroupedAllShippingRates();
|
169 |
+
if ($groups && $this->_address) {
|
170 |
+
$this->setShippingRateGroups($groups);
|
171 |
+
// determine current selected code & name
|
172 |
+
foreach ($groups as $code => $rates) {
|
173 |
+
foreach ($rates as $rate) {
|
174 |
+
if ($this->_address->getShippingMethod() == $rate->getCode()) {
|
175 |
+
$this->_currentShippingRate = $rate;
|
176 |
+
break(2);
|
177 |
+
}
|
178 |
+
}
|
179 |
+
}
|
180 |
+
}
|
181 |
+
}
|
182 |
+
|
183 |
+
return parent::_beforeToHtml();
|
184 |
+
}
|
185 |
+
}
|
app/code/local/Kash/Gateway/Block/Review/Details.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Payment Onepage checkout block
|
4 |
+
*/
|
5 |
+
class Kash_Gateway_Block_Review_Details extends Mage_Checkout_Block_Cart_Totals
|
6 |
+
{
|
7 |
+
protected $_address;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Return review shipping address
|
11 |
+
*
|
12 |
+
* @return Mage_Sales_Model_Order_Address
|
13 |
+
*/
|
14 |
+
public function getAddress()
|
15 |
+
{
|
16 |
+
if (empty($this->_address)) {
|
17 |
+
$this->_address = $this->getQuote()->getShippingAddress();
|
18 |
+
}
|
19 |
+
return $this->_address;
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Return review quote totals
|
24 |
+
*
|
25 |
+
* @return array
|
26 |
+
*/
|
27 |
+
public function getTotals()
|
28 |
+
{
|
29 |
+
return $this->getQuote()->getTotals();
|
30 |
+
}
|
31 |
+
}
|
app/code/local/Kash/Gateway/Helper/Checkout.php
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Checkout helper
|
5 |
+
*/
|
6 |
+
class Kash_Gateway_Helper_Checkout extends Mage_Core_Helper_Abstract
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Restore last active quote based on checkout session
|
10 |
+
*
|
11 |
+
* @return bool True if quote restored successfully, false otherwise
|
12 |
+
*/
|
13 |
+
public function restoreQuote()
|
14 |
+
{
|
15 |
+
$order = $this->_getCheckoutSession()->getLastRealOrder();
|
16 |
+
if ($order->getId()) {
|
17 |
+
$quote = $this->_getQuote($order->getQuoteId());
|
18 |
+
if ($quote->getId()) {
|
19 |
+
$quote->setIsActive(1)
|
20 |
+
->setReservedOrderId(null)
|
21 |
+
->save();
|
22 |
+
$this->_getCheckoutSession()
|
23 |
+
->replaceQuote($quote)
|
24 |
+
->unsLastRealOrderId();
|
25 |
+
return true;
|
26 |
+
}
|
27 |
+
}
|
28 |
+
return false;
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Cancel last placed order with specified comment message
|
33 |
+
*
|
34 |
+
* @param string $comment Comment appended to order history
|
35 |
+
* @return bool True if order cancelled, false otherwise
|
36 |
+
*/
|
37 |
+
public function cancelCurrentOrder($comment)
|
38 |
+
{
|
39 |
+
$order = $this->_getCheckoutSession()->getLastRealOrder();
|
40 |
+
if ($order->getId() && $order->getState() != Mage_Sales_Model_Order::STATE_CANCELED) {
|
41 |
+
$order->registerCancellation($comment)->save();
|
42 |
+
return true;
|
43 |
+
}
|
44 |
+
return false;
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Return checkout session instance
|
49 |
+
*
|
50 |
+
* @return Mage_Checkout_Model_Session
|
51 |
+
*/
|
52 |
+
protected function _getCheckoutSession()
|
53 |
+
{
|
54 |
+
return Mage::getSingleton('checkout/session');
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Return sales quote instance for specified ID
|
59 |
+
*
|
60 |
+
* @param int $quoteId Quote identifier
|
61 |
+
* @return Mage_Sales_Model_Quote
|
62 |
+
*/
|
63 |
+
protected function _getQuote($quoteId)
|
64 |
+
{
|
65 |
+
return Mage::getModel('sales/quote')->load($quoteId);
|
66 |
+
}
|
67 |
+
}
|
app/code/local/Kash/Gateway/Helper/Data.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Payment module base helper
|
5 |
+
*
|
6 |
+
* @author Blue Badger <jonathan@badger.blue>
|
7 |
+
*/
|
8 |
+
class Kash_Gateway_Helper_Data extends Mage_Core_Helper_Abstract {
|
9 |
+
|
10 |
+
}
|
app/code/local/Kash/Gateway/Model/Api/Abstract.php
ADDED
@@ -0,0 +1,357 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Abstract class for Paypal API wrappers
|
4 |
+
*/
|
5 |
+
abstract class Kash_Gateway_Model_Api_Abstract extends Varien_Object
|
6 |
+
{
|
7 |
+
/**
|
8 |
+
* Config instance
|
9 |
+
* @var Kash_Gateway_Model_Config
|
10 |
+
*/
|
11 |
+
protected $_config = null;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Global private to public interface map
|
15 |
+
* @var array
|
16 |
+
*/
|
17 |
+
protected $_globalMap = array();
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Filter callbacks for exporting $this data to API call
|
21 |
+
*
|
22 |
+
* @var array
|
23 |
+
*/
|
24 |
+
protected $_exportToRequestFilters = array();
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Filter callbacks for importing API result to $this data
|
28 |
+
*
|
29 |
+
* @var array
|
30 |
+
*/
|
31 |
+
protected $_importFromRequestFilters = array();
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Line items export to request mapping settings
|
35 |
+
* @var array
|
36 |
+
*/
|
37 |
+
protected $_lineItemExportItemsFormat = array();
|
38 |
+
protected $_lineItemExportItemsFilters = array();
|
39 |
+
protected $_lineItemTotalExportMap = array();
|
40 |
+
|
41 |
+
/**
|
42 |
+
* PayPal shopping cart instance
|
43 |
+
*
|
44 |
+
* @var Kash_Gateway_Model_Cart
|
45 |
+
*/
|
46 |
+
protected $_cart = null;
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Shipping options export to request mapping settings
|
50 |
+
* @var array
|
51 |
+
*/
|
52 |
+
protected $_shippingOptionsExportItemsFormat = array();
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Import $this public data to specified object or array
|
56 |
+
*
|
57 |
+
* @param array|Varien_Object $to
|
58 |
+
* @param array $publicMap
|
59 |
+
* @return array|Varien_Object
|
60 |
+
*/
|
61 |
+
public function &import($to, array $publicMap = array())
|
62 |
+
{
|
63 |
+
return Varien_Object_Mapper::accumulateByMap(array($this, 'getDataUsingMethod'), $to, $publicMap);
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Export $this public data from specified object or array
|
68 |
+
*
|
69 |
+
* @param array|Varien_Object $from
|
70 |
+
* @param array $publicMap
|
71 |
+
* @return Kash_Gateway_Model_Api_Abstract
|
72 |
+
*/
|
73 |
+
public function export($from, array $publicMap = array())
|
74 |
+
{
|
75 |
+
Varien_Object_Mapper::accumulateByMap($from, array($this, 'setDataUsingMethod'), $publicMap);
|
76 |
+
return $this;
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Set Payment cart instance
|
81 |
+
*
|
82 |
+
* @param Kash_Gateway_Model_Cart $cart
|
83 |
+
* @return Kash_Gateway_Model_Api_Abstract
|
84 |
+
*/
|
85 |
+
public function setPaymentCart(Kash_Gateway_Model_Cart $cart)
|
86 |
+
{
|
87 |
+
$this->_cart = $cart;
|
88 |
+
return $this;
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Config instance setter
|
93 |
+
* @param Kash_Gateway_Model_Config $config
|
94 |
+
* @return Kash_Gateway_Model_Api_Abstract
|
95 |
+
*/
|
96 |
+
public function setConfigObject(Kash_Gateway_Model_Config $config)
|
97 |
+
{
|
98 |
+
$this->_config = $config;
|
99 |
+
return $this;
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Current locale code getter
|
104 |
+
*
|
105 |
+
* @return string
|
106 |
+
*/
|
107 |
+
public function getLocaleCode()
|
108 |
+
{
|
109 |
+
return Mage::app()->getLocale()->getLocaleCode();
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Export $this public data to private request array
|
114 |
+
*
|
115 |
+
* @param array $privateRequestMap
|
116 |
+
* @param array $request
|
117 |
+
* @return array
|
118 |
+
*/
|
119 |
+
protected function &_exportToRequest(array $privateRequestMap, array $request = array())
|
120 |
+
{
|
121 |
+
$map = array();
|
122 |
+
foreach ($privateRequestMap as $key) {
|
123 |
+
if (isset($this->_globalMap[$key])) {
|
124 |
+
$map[$this->_globalMap[$key]] = $key;
|
125 |
+
}
|
126 |
+
}
|
127 |
+
$result = Varien_Object_Mapper::accumulateByMap(array($this, 'getDataUsingMethod'), $request, $map);
|
128 |
+
foreach ($privateRequestMap as $key) {
|
129 |
+
if (isset($this->_exportToRequestFilters[$key]) && isset($result[$key])) {
|
130 |
+
$callback = $this->_exportToRequestFilters[$key];
|
131 |
+
$privateKey = $result[$key];
|
132 |
+
$publicKey = $map[$this->_globalMap[$key]];
|
133 |
+
$result[$key] = call_user_func(array($this, $callback), $privateKey, $publicKey);
|
134 |
+
}
|
135 |
+
}
|
136 |
+
|
137 |
+
// TODO: Eventually fix this properly
|
138 |
+
// https://app.asana.com/0/56892580162484/63230238408321
|
139 |
+
$result['x_test'] = 'false';
|
140 |
+
|
141 |
+
return $result;
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Import $this public data from a private response array
|
146 |
+
*
|
147 |
+
* @param array $privateResponseMap
|
148 |
+
* @param array $response
|
149 |
+
*/
|
150 |
+
protected function _importFromResponse(array $privateResponseMap, array $response)
|
151 |
+
{
|
152 |
+
$map = array();
|
153 |
+
foreach ($privateResponseMap as $key) {
|
154 |
+
if (isset($this->_globalMap[$key])) {
|
155 |
+
$map[$key] = $this->_globalMap[$key];
|
156 |
+
}
|
157 |
+
if (isset($response[$key]) && isset($this->_importFromRequestFilters[$key])) {
|
158 |
+
$callback = $this->_importFromRequestFilters[$key];
|
159 |
+
$response[$key] = call_user_func(array($this, $callback), $response[$key], $key, $map[$key]);
|
160 |
+
}
|
161 |
+
}
|
162 |
+
Varien_Object_Mapper::accumulateByMap($response, array($this, 'setDataUsingMethod'), $map);
|
163 |
+
}
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Prepare line items request
|
167 |
+
*
|
168 |
+
* Returns true if there were line items added
|
169 |
+
*
|
170 |
+
* @param array &$request
|
171 |
+
* @param int $i
|
172 |
+
* @return true|bool
|
173 |
+
*/
|
174 |
+
protected function _exportLineItems(array &$request, $i = 0)
|
175 |
+
{
|
176 |
+
if (!$this->_cart) {
|
177 |
+
return;
|
178 |
+
}
|
179 |
+
|
180 |
+
// always add cart totals, even if line items are not requested
|
181 |
+
if ($this->_lineItemTotalExportMap) {
|
182 |
+
foreach ($this->_cart->getTotals() as $key => $total) {
|
183 |
+
if (isset($this->_lineItemTotalExportMap[$key])) { // !empty($total)
|
184 |
+
$privateKey = $this->_lineItemTotalExportMap[$key];
|
185 |
+
$request[$privateKey] = $this->_filterAmount($total);
|
186 |
+
}
|
187 |
+
}
|
188 |
+
}
|
189 |
+
|
190 |
+
// add cart line items
|
191 |
+
$items = $this->_cart->getItems();
|
192 |
+
if (empty($items) || !$this->getIsLineItemsEnabled()) {
|
193 |
+
return;
|
194 |
+
}
|
195 |
+
$result = null;
|
196 |
+
foreach ($items as $item) {
|
197 |
+
foreach ($this->_lineItemExportItemsFormat as $publicKey => $privateFormat) {
|
198 |
+
$result = true;
|
199 |
+
$value = $item->getDataUsingMethod($publicKey);
|
200 |
+
if (isset($this->_lineItemExportItemsFilters[$publicKey])) {
|
201 |
+
$callback = $this->_lineItemExportItemsFilters[$publicKey];
|
202 |
+
$value = call_user_func(array($this, $callback), $value);
|
203 |
+
}
|
204 |
+
if (is_float($value)) {
|
205 |
+
$value = $this->_filterAmount($value);
|
206 |
+
}
|
207 |
+
$request[sprintf($privateFormat, $i)] = $value;
|
208 |
+
}
|
209 |
+
$i++;
|
210 |
+
}
|
211 |
+
return $result;
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Prepare shipping options request
|
216 |
+
* Returns false if there are no shipping options
|
217 |
+
*
|
218 |
+
* @param array &$request
|
219 |
+
* @param int $i
|
220 |
+
* @return bool
|
221 |
+
*/
|
222 |
+
protected function _exportShippingOptions(array &$request, $i = 0)
|
223 |
+
{
|
224 |
+
$options = $this->getShippingOptions();
|
225 |
+
if (empty($options)) {
|
226 |
+
return false;
|
227 |
+
}
|
228 |
+
foreach ($options as $option) {
|
229 |
+
foreach ($this->_shippingOptionsExportItemsFormat as $publicKey => $privateFormat) {
|
230 |
+
$value = $option->getDataUsingMethod($publicKey);
|
231 |
+
if (is_float($value)) {
|
232 |
+
$value = $this->_filterAmount($value);
|
233 |
+
}
|
234 |
+
if (is_bool($value)) {
|
235 |
+
$value = $this->_filterBool($value);
|
236 |
+
}
|
237 |
+
$request[sprintf($privateFormat, $i)] = $value;
|
238 |
+
}
|
239 |
+
$i++;
|
240 |
+
}
|
241 |
+
return true;
|
242 |
+
}
|
243 |
+
|
244 |
+
/**
|
245 |
+
* Filter amounts in API calls
|
246 |
+
* @param float|string $value
|
247 |
+
* @return string
|
248 |
+
*/
|
249 |
+
protected function _filterAmount($value)
|
250 |
+
{
|
251 |
+
return sprintf('%.2F', $value);
|
252 |
+
}
|
253 |
+
|
254 |
+
/**
|
255 |
+
* Filter boolean values in API calls
|
256 |
+
*
|
257 |
+
* @param mixed $value
|
258 |
+
* @return string
|
259 |
+
*/
|
260 |
+
protected function _filterBool($value)
|
261 |
+
{
|
262 |
+
return ($value) ? 'true' : 'false';
|
263 |
+
}
|
264 |
+
|
265 |
+
/**
|
266 |
+
* Filter int values in API calls
|
267 |
+
*
|
268 |
+
* @param mixed $value
|
269 |
+
* @return int
|
270 |
+
*/
|
271 |
+
protected function _filterInt($value)
|
272 |
+
{
|
273 |
+
return (int)$value;
|
274 |
+
}
|
275 |
+
|
276 |
+
/**
|
277 |
+
* Unified getter that looks in data or falls back to config
|
278 |
+
*
|
279 |
+
* @param string $key
|
280 |
+
* @param mixed $default
|
281 |
+
* @return mixed
|
282 |
+
*/
|
283 |
+
protected function _getDataOrConfig($key, $default = null)
|
284 |
+
{
|
285 |
+
if ($this->hasData($key)) {
|
286 |
+
return $this->getData($key);
|
287 |
+
}
|
288 |
+
return $this->_config->$key ? $this->_config->$key : $default;
|
289 |
+
}
|
290 |
+
|
291 |
+
|
292 |
+
/**
|
293 |
+
* region_id workaround: Payment requires state code, try to find one in the address
|
294 |
+
* +/
|
295 |
+
* @param Varien_Object $address
|
296 |
+
* @return string
|
297 |
+
*/
|
298 |
+
protected function _lookupRegionCodeFromAddress(Varien_Object $address)
|
299 |
+
{
|
300 |
+
if ($regionId = $address->getData('region_id')) {
|
301 |
+
$region = Mage::getModel('directory/region')->load($regionId);
|
302 |
+
if ($region->getId()) {
|
303 |
+
return $region->getCode();
|
304 |
+
}
|
305 |
+
}
|
306 |
+
return '';
|
307 |
+
}
|
308 |
+
|
309 |
+
/**
|
310 |
+
* Build query string from request
|
311 |
+
*
|
312 |
+
* @param array $request
|
313 |
+
* @return string
|
314 |
+
*/
|
315 |
+
protected function _buildQuery($request)
|
316 |
+
{
|
317 |
+
return http_build_query($request);
|
318 |
+
}
|
319 |
+
|
320 |
+
/**
|
321 |
+
* Filter qty in API calls
|
322 |
+
* Paypal note: The value for quantity must be a positive integer. Null, zero, or negative numbers are not allowed.
|
323 |
+
*
|
324 |
+
* @param float|string|int $value
|
325 |
+
* @return string
|
326 |
+
*/
|
327 |
+
protected function _filterQty($value)
|
328 |
+
{
|
329 |
+
return intval($value);
|
330 |
+
}
|
331 |
+
|
332 |
+
/**
|
333 |
+
* Street address workaround: divides address lines into parts by specified keys
|
334 |
+
* (keys should go as 3rd, 4th[...] parameters)
|
335 |
+
* +/
|
336 |
+
* @param Varien_Object $address
|
337 |
+
* @param array $to
|
338 |
+
*/
|
339 |
+
protected function _importStreetFromAddress(Varien_Object $address, array &$to)
|
340 |
+
{
|
341 |
+
$keys = func_get_args(); array_shift($keys); array_shift($keys);
|
342 |
+
$street = $address->getStreet();
|
343 |
+
if (!$keys || !$street || !is_array($street)) {
|
344 |
+
return;
|
345 |
+
}
|
346 |
+
|
347 |
+
$street = Mage::helper('customer/address')
|
348 |
+
->convertStreetLines($address->getStreet(), count($keys));
|
349 |
+
|
350 |
+
$i = 0;
|
351 |
+
foreach ($keys as $key) {
|
352 |
+
$to[$key] = isset($street[$i]) ? $street[$i]: '';
|
353 |
+
$i++;
|
354 |
+
}
|
355 |
+
}
|
356 |
+
|
357 |
+
}
|
app/code/local/Kash/Gateway/Model/Api/Bb.php
ADDED
@@ -0,0 +1,235 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* BB API wrappers model
|
5 |
+
*/
|
6 |
+
class Kash_Gateway_Model_Api_Bb extends Kash_Gateway_Model_Api_Abstract
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Global public interface map
|
10 |
+
* @var array
|
11 |
+
*/
|
12 |
+
protected $_globalMap = array(
|
13 |
+
// each call
|
14 |
+
'x_amount' => 'amount',
|
15 |
+
'x_account_id' => 'x_account_id',
|
16 |
+
'x_currency' => 'currency_code',
|
17 |
+
'x_amount_tax' => 'tax_amount',
|
18 |
+
'x_amount_shipping' => 'shipping_amount',
|
19 |
+
'x_shop_country' => 'x_shop_country',
|
20 |
+
'x_shop_name' => 'x_shop_name',
|
21 |
+
'x_transaction_type' => 'x_transaction_type',
|
22 |
+
'x_description' => 'x_description',
|
23 |
+
'x_invoice' => 'x_invoice',
|
24 |
+
'x_test' => 'x_test',
|
25 |
+
// backwards compatibility
|
26 |
+
'x_customer_first_name' => 'firstname',
|
27 |
+
'x_customer_last_name' => 'lastname',
|
28 |
+
'x_customer_shipping_country' => 'countrycode',
|
29 |
+
'x_url_callback' => 'x_url_callback',
|
30 |
+
'x_url_cancel' => 'x_url_cancel',
|
31 |
+
'x_url_complete' => 'x_url_complete',
|
32 |
+
'x_reference' => 'x_reference'
|
33 |
+
);
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Interface map for response
|
37 |
+
* @var array
|
38 |
+
*/
|
39 |
+
public $responseMap = array(
|
40 |
+
'Amount' => 'x_amount',
|
41 |
+
'Result' => 'x_result',
|
42 |
+
'Gateway Reference' => 'x_gateway_reference',
|
43 |
+
'Test mode' => 'x_test'
|
44 |
+
);
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Filter callbacks for preparing internal amounts to NVP request
|
48 |
+
*
|
49 |
+
* @var array
|
50 |
+
*/
|
51 |
+
protected $_exportToRequestFilters = array(
|
52 |
+
'x_amount' => '_filterAmount',
|
53 |
+
'x_amount_shipping' => '_filterAmount',
|
54 |
+
'x_amount_tax' => '_filterAmount',
|
55 |
+
'x_test' => '_filterBool',
|
56 |
+
);
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Line items export mapping settings
|
60 |
+
* @var array
|
61 |
+
*/
|
62 |
+
protected $_lineItemTotalExportMap = array(
|
63 |
+
Kash_Gateway_Model_Cart::TOTAL_TAX => 'x_amount_tax',
|
64 |
+
Kash_Gateway_Model_Cart::TOTAL_SHIPPING => 'x_amount_shipping',
|
65 |
+
);
|
66 |
+
|
67 |
+
/**
|
68 |
+
* SetBBCheckout request/response map
|
69 |
+
* @var array
|
70 |
+
*/
|
71 |
+
protected $_setBBCheckoutRequest = array(
|
72 |
+
'x_reference', 'x_account_id', 'x_amount', 'x_currency', 'x_shop_country', 'x_shop_name', 'x_description', 'x_transaction_type',
|
73 |
+
'x_invoice', 'x_test', 'x_amount_shipping', 'x_amount_tax', 'x_url_callback', 'x_url_cancel', 'x_url_complete'
|
74 |
+
);
|
75 |
+
|
76 |
+
/**
|
77 |
+
* SetBBCheckout response map
|
78 |
+
* @var array
|
79 |
+
*/
|
80 |
+
protected $_setBBCheckoutResponse = array(
|
81 |
+
'x_account_id', 'x_reference', 'x_currency', 'x_test', 'x_amount', 'x_gateway_reference', 'x_timestamp',
|
82 |
+
'x_result', 'x_signature', 'x_amount_shipping', 'x_amount_tax'
|
83 |
+
);
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Map for billing address import/export
|
87 |
+
* @var array
|
88 |
+
*/
|
89 |
+
protected $_billingAddressMap = array(
|
90 |
+
'x_customer_email' => 'email',
|
91 |
+
'x_customer_first_name' => 'firstname',
|
92 |
+
'x_customer_last_name' => 'lastname',
|
93 |
+
'x_customer_shipping_country' => 'country_id', // iso-3166 two-character code
|
94 |
+
'x_customer_shipping_state' => 'region',
|
95 |
+
'x_customer_shipping_city' => 'city',
|
96 |
+
'x_customer_shipping_address1' => 'street',
|
97 |
+
'x_customer_shipping_address2' => 'street2',
|
98 |
+
'x_customer_shipping_zip' => 'postcode',
|
99 |
+
'x_customer_phone' => 'telephone',
|
100 |
+
);
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Map for billing address to do request (not response)
|
104 |
+
* Merging with $_billingAddressMap
|
105 |
+
*
|
106 |
+
* @var array
|
107 |
+
*/
|
108 |
+
protected $_billingAddressMapRequest = array();
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Map for shipping address import/export (extends billing address mapper)
|
112 |
+
* @var array
|
113 |
+
*/
|
114 |
+
protected $_shippingAddressMap = array(
|
115 |
+
'x_customer_shipping_country' => 'country_id',
|
116 |
+
'x_customer_shipping_state' => 'region',
|
117 |
+
'x_customer_shipping_city' => 'city',
|
118 |
+
'x_customer_shipping_address1' => 'street',
|
119 |
+
'x_customer_shipping_address2' => 'street2',
|
120 |
+
'x_customer_shipping_zip' => 'postcode',
|
121 |
+
'x_customer_phone' => 'telephone',
|
122 |
+
);
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Return request for API
|
126 |
+
*
|
127 |
+
*/
|
128 |
+
public function callSetBBCheckout()
|
129 |
+
{
|
130 |
+
$request = $this->_exportToRequest($this->_setBBCheckoutRequest);
|
131 |
+
$this->_exportLineItems($request);
|
132 |
+
|
133 |
+
// import/suppress shipping address, if any
|
134 |
+
if ($this->getAddress()) {
|
135 |
+
$request = $this->_importAddresses($request);
|
136 |
+
}
|
137 |
+
|
138 |
+
$date = Zend_Date::now();
|
139 |
+
$request['x_timestamp'] = $date->getIso();
|
140 |
+
$request['x_signature'] = $this->getSignature($request, $this->getHmacKey());
|
141 |
+
|
142 |
+
return $request;
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Gateway signing mechanism
|
147 |
+
*
|
148 |
+
* @param array $request
|
149 |
+
* @param $secret_key
|
150 |
+
* @return string
|
151 |
+
*/
|
152 |
+
public function getSignature(array $request, $secret_key)
|
153 |
+
{
|
154 |
+
ksort($request);
|
155 |
+
$signature = '';
|
156 |
+
foreach ($request as $key => $val) {
|
157 |
+
if ($key === 'x_signature') {
|
158 |
+
continue;
|
159 |
+
}
|
160 |
+
$signature .= $key . $val;
|
161 |
+
}
|
162 |
+
$sig = hash_hmac('sha256', $signature, $secret_key, false);
|
163 |
+
return $sig;
|
164 |
+
}
|
165 |
+
|
166 |
+
|
167 |
+
/**
|
168 |
+
* @param array $request
|
169 |
+
* @return string
|
170 |
+
*/
|
171 |
+
protected function _buildQuery($request)
|
172 |
+
{
|
173 |
+
return http_build_query($request);
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Prepare request data basing on provided addresses
|
178 |
+
* +/
|
179 |
+
* @param array $to
|
180 |
+
* @return array
|
181 |
+
*/
|
182 |
+
protected function _importAddresses(array $to)
|
183 |
+
{
|
184 |
+
$billingAddress = ($this->getBillingAddress()) ? $this->getBillingAddress() : $this->getAddress();
|
185 |
+
$shippingAddress = $this->getAddress();
|
186 |
+
|
187 |
+
$to = Varien_Object_Mapper::accumulateByMap(
|
188 |
+
$billingAddress,
|
189 |
+
$to,
|
190 |
+
array_merge(array_flip($this->_billingAddressMap), $this->_billingAddressMapRequest)
|
191 |
+
);
|
192 |
+
if ($regionCode = $this->_lookupRegionCodeFromAddress($billingAddress)) {
|
193 |
+
$to['x_customer_shipping_state'] = $regionCode;
|
194 |
+
}
|
195 |
+
if (!$this->getSuppressShipping()) {
|
196 |
+
$to = Varien_Object_Mapper::accumulateByMap($shippingAddress, $to, array_flip($this->_shippingAddressMap));
|
197 |
+
if ($regionCode = $this->_lookupRegionCodeFromAddress($shippingAddress)) {
|
198 |
+
$to['x_customer_shipping_state'] = $regionCode;
|
199 |
+
}
|
200 |
+
$this->_importStreetFromAddress($billingAddress, $to, 'x_customer_shipping_address1', 'x_customer_shipping_address2');
|
201 |
+
$this->_importStreetFromAddress($shippingAddress, $to, 'x_customer_shipping_address1', 'x_customer_shipping_address2');
|
202 |
+
}
|
203 |
+
return $to;
|
204 |
+
}
|
205 |
+
|
206 |
+
protected function getXAccountId()
|
207 |
+
{
|
208 |
+
$value = $this->_getDataOrConfig('x_account_id');
|
209 |
+
return $value;
|
210 |
+
}
|
211 |
+
|
212 |
+
protected function getXShopCountry()
|
213 |
+
{
|
214 |
+
$value = $this->_config->getMerchantCountry();
|
215 |
+
return $value;
|
216 |
+
}
|
217 |
+
|
218 |
+
protected function getXShopName()
|
219 |
+
{
|
220 |
+
$value = $this->_getDataOrConfig('x_shop_name');
|
221 |
+
return $value;
|
222 |
+
}
|
223 |
+
|
224 |
+
protected function getXTest()
|
225 |
+
{
|
226 |
+
$value = $this->_getDataOrConfig('x_test');
|
227 |
+
return $value;
|
228 |
+
}
|
229 |
+
|
230 |
+
public function getHmacKey()
|
231 |
+
{
|
232 |
+
$value = $this->_getDataOrConfig('server_key');
|
233 |
+
return $value;
|
234 |
+
}
|
235 |
+
}
|
app/code/local/Kash/Gateway/Model/Cart.php
ADDED
@@ -0,0 +1,497 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Payment-specific model for shopping cart items and totals
|
4 |
+
*/
|
5 |
+
class Kash_Gateway_Model_Cart
|
6 |
+
{
|
7 |
+
/**
|
8 |
+
* Totals that Payment suppports when passing shopping cart
|
9 |
+
*
|
10 |
+
* @var string
|
11 |
+
*/
|
12 |
+
const TOTAL_SUBTOTAL = 'subtotal';
|
13 |
+
const TOTAL_DISCOUNT = 'discount';
|
14 |
+
const TOTAL_TAX = 'tax';
|
15 |
+
const TOTAL_SHIPPING = 'shipping';
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Order or quote instance
|
19 |
+
*
|
20 |
+
* @var Mage_Sales_Model_Order
|
21 |
+
* @var Mage_Sales_Model_Quote
|
22 |
+
*/
|
23 |
+
protected $_salesEntity = null;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Rendered cart items
|
27 |
+
* Array of Varien_Objects
|
28 |
+
*
|
29 |
+
* @var array
|
30 |
+
*/
|
31 |
+
protected $_items = array();
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Rendered cart totals
|
35 |
+
* Associative array with the keys from constants above
|
36 |
+
*
|
37 |
+
* @var array
|
38 |
+
*/
|
39 |
+
protected $_totals = array();
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Set of optional descriptions for the item that may replace a total and composed of several amounts
|
43 |
+
* Array of strings
|
44 |
+
*
|
45 |
+
* @var array
|
46 |
+
*/
|
47 |
+
protected $_totalLineItemDescriptions = array();
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Lazy initialization indicator for rendering
|
51 |
+
*
|
52 |
+
* @var bool
|
53 |
+
*/
|
54 |
+
protected $_shouldRender = true;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Validation result for the rendered cart items
|
58 |
+
*
|
59 |
+
* @var bool
|
60 |
+
*/
|
61 |
+
protected $_areItemsValid = false;
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Validation result for the rendered totals
|
65 |
+
*
|
66 |
+
* @var bool
|
67 |
+
*/
|
68 |
+
protected $_areTotalsValid = false;
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Whether to render discount total as a line item
|
72 |
+
* Use case: WPP
|
73 |
+
*
|
74 |
+
* @var bool
|
75 |
+
*/
|
76 |
+
protected $_isDiscountAsItem = false;
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Whether to render shipping total as a line item
|
80 |
+
* Use case: WPS
|
81 |
+
*
|
82 |
+
* @var bool
|
83 |
+
*/
|
84 |
+
protected $_isShippingAsItem = false;
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Require instance of an order or a quote
|
88 |
+
*
|
89 |
+
* @param array $params
|
90 |
+
*/
|
91 |
+
public function __construct($params = array())
|
92 |
+
{
|
93 |
+
$salesEntity = array_shift($params);
|
94 |
+
if (is_object($salesEntity)
|
95 |
+
&& (($salesEntity instanceof Mage_Sales_Model_Order) || ($salesEntity instanceof Mage_Sales_Model_Quote))) {
|
96 |
+
$this->_salesEntity = $salesEntity;
|
97 |
+
} else {
|
98 |
+
throw new Exception('Invalid sales entity provided.');
|
99 |
+
}
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Getter for the current sales entity
|
104 |
+
*
|
105 |
+
* @return Mage_Sales_Model_Order
|
106 |
+
* @return Mage_Sales_Model_Quote
|
107 |
+
*/
|
108 |
+
public function getSalesEntity()
|
109 |
+
{
|
110 |
+
return $this->_salesEntity;
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Render and get line items
|
115 |
+
* By default returns false if the items are invalid
|
116 |
+
*
|
117 |
+
* @param bool $bypassValidation
|
118 |
+
* @return array|false
|
119 |
+
*/
|
120 |
+
public function getItems($bypassValidation = false)
|
121 |
+
{
|
122 |
+
$this->_render();
|
123 |
+
if (!$bypassValidation && !$this->_areItemsValid) {
|
124 |
+
return false;
|
125 |
+
}
|
126 |
+
return $this->_items;
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Render and get totals
|
131 |
+
* If the totals are invalid for any reason, they will be merged into one amount (subtotal is utilized for it)
|
132 |
+
* An option to substract discount from the subtotal is available
|
133 |
+
*
|
134 |
+
* @param bool $mergeDiscount
|
135 |
+
* @return array
|
136 |
+
*/
|
137 |
+
public function getTotals($mergeDiscount = false)
|
138 |
+
{
|
139 |
+
$this->_render();
|
140 |
+
|
141 |
+
// cut down totals to one total if they are invalid
|
142 |
+
if (!$this->_areTotalsValid) {
|
143 |
+
$totals = array(
|
144 |
+
self::TOTAL_SUBTOTAL => $this->_totals[self::TOTAL_SUBTOTAL] + $this->_totals[self::TOTAL_TAX]
|
145 |
+
);
|
146 |
+
if (!$this->_isShippingAsItem) {
|
147 |
+
$totals[self::TOTAL_SUBTOTAL] += $this->_totals[self::TOTAL_SHIPPING];
|
148 |
+
}
|
149 |
+
if (!$this->_isDiscountAsItem) {
|
150 |
+
$totals[self::TOTAL_SUBTOTAL] -= $this->_totals[self::TOTAL_DISCOUNT];
|
151 |
+
}
|
152 |
+
return $totals;
|
153 |
+
} elseif ($mergeDiscount) {
|
154 |
+
$totals = $this->_totals;
|
155 |
+
unset($totals[self::TOTAL_DISCOUNT]);
|
156 |
+
if (!$this->_isDiscountAsItem) {
|
157 |
+
$totals[self::TOTAL_SUBTOTAL] -= $this->_totals[self::TOTAL_DISCOUNT];
|
158 |
+
}
|
159 |
+
return $totals;
|
160 |
+
}
|
161 |
+
return $this->_totals;
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Add a line item
|
166 |
+
*
|
167 |
+
* @param string $name
|
168 |
+
* @param numeric $qty
|
169 |
+
* @param float $amount
|
170 |
+
* @param string $identifier
|
171 |
+
* @return Varien_Object
|
172 |
+
*/
|
173 |
+
public function addItem($name, $qty, $amount, $identifier = null)
|
174 |
+
{
|
175 |
+
$this->_shouldRender = true;
|
176 |
+
$item = new Varien_Object(array(
|
177 |
+
'name' => $name,
|
178 |
+
'qty' => $qty,
|
179 |
+
'amount' => (float)$amount,
|
180 |
+
));
|
181 |
+
if ($identifier) {
|
182 |
+
$item->setData('id', $identifier);
|
183 |
+
}
|
184 |
+
$this->_items[] = $item;
|
185 |
+
return $item;
|
186 |
+
}
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Remove item from cart by identifier
|
190 |
+
*
|
191 |
+
* @param string $identifier
|
192 |
+
* @return bool
|
193 |
+
*/
|
194 |
+
public function removeItem($identifier)
|
195 |
+
{
|
196 |
+
foreach ($this->_items as $key => $item) {
|
197 |
+
if ($item->getId() == $identifier) {
|
198 |
+
unset($this->_items[$key]);
|
199 |
+
return true;
|
200 |
+
}
|
201 |
+
}
|
202 |
+
return false;
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* Compound the specified amount with the specified total
|
207 |
+
*
|
208 |
+
* @param string $code
|
209 |
+
* @param float $amount
|
210 |
+
* @param string $lineItemDescription
|
211 |
+
* @return Kash_Gateway_Model_Cart
|
212 |
+
*/
|
213 |
+
public function updateTotal($code, $amount, $lineItemDescription = null)
|
214 |
+
{
|
215 |
+
$this->_shouldRender = true;
|
216 |
+
if (isset($this->_totals[$code])) {
|
217 |
+
$this->_totals[$code] += $amount;
|
218 |
+
if ($lineItemDescription) {
|
219 |
+
$this->_totalLineItemDescriptions[$code][] = $lineItemDescription;
|
220 |
+
}
|
221 |
+
}
|
222 |
+
return $this;
|
223 |
+
}
|
224 |
+
|
225 |
+
/**
|
226 |
+
* Get/Set whether to render the discount total as a line item
|
227 |
+
*
|
228 |
+
* @param $setValue
|
229 |
+
* @return bool|Kash_Gateway_Model_Cart
|
230 |
+
*/
|
231 |
+
public function isDiscountAsItem($setValue = null)
|
232 |
+
{
|
233 |
+
return $this->_totalAsItem('_isDiscountAsItem', $setValue);
|
234 |
+
}
|
235 |
+
|
236 |
+
/**
|
237 |
+
* Get/Set whether to render the discount total as a line item
|
238 |
+
*
|
239 |
+
* @param $setValue
|
240 |
+
* @return bool|Kash_Gateway_Model_Cart
|
241 |
+
*/
|
242 |
+
public function isShippingAsItem($setValue = null)
|
243 |
+
{
|
244 |
+
return $this->_totalAsItem('_isShippingAsItem', $setValue);
|
245 |
+
}
|
246 |
+
|
247 |
+
/**
|
248 |
+
* (re)Render all items and totals
|
249 |
+
*/
|
250 |
+
protected function _render()
|
251 |
+
{
|
252 |
+
if (!$this->_shouldRender) {
|
253 |
+
return;
|
254 |
+
}
|
255 |
+
|
256 |
+
// regular items from the sales entity
|
257 |
+
$this->_items = array();
|
258 |
+
foreach ($this->_salesEntity->getAllItems() as $item) {
|
259 |
+
if (!$item->getParentItem()) {
|
260 |
+
$this->_addRegularItem($item);
|
261 |
+
}
|
262 |
+
}
|
263 |
+
end($this->_items);
|
264 |
+
$lastRegularItemKey = key($this->_items);
|
265 |
+
|
266 |
+
// regular totals
|
267 |
+
$shippingDescription = '';
|
268 |
+
if ($this->_salesEntity instanceof Mage_Sales_Model_Order) {
|
269 |
+
$shippingDescription = $this->_salesEntity->getShippingDescription();
|
270 |
+
$this->_totals = array(
|
271 |
+
self::TOTAL_SUBTOTAL => $this->_salesEntity->getBaseSubtotal(),
|
272 |
+
self::TOTAL_TAX => $this->_salesEntity->getBaseTaxAmount(),
|
273 |
+
self::TOTAL_SHIPPING => $this->_salesEntity->getBaseShippingAmount(),
|
274 |
+
self::TOTAL_DISCOUNT => abs($this->_salesEntity->getBaseDiscountAmount()),
|
275 |
+
);
|
276 |
+
$this->_applyHiddenTaxWorkaround($this->_salesEntity);
|
277 |
+
} else {
|
278 |
+
$address = $this->_salesEntity->getIsVirtual() ?
|
279 |
+
$this->_salesEntity->getBillingAddress() : $this->_salesEntity->getShippingAddress();
|
280 |
+
$shippingDescription = $address->getShippingDescription();
|
281 |
+
$this->_totals = array (
|
282 |
+
self::TOTAL_SUBTOTAL => $this->_salesEntity->getBaseSubtotal(),
|
283 |
+
self::TOTAL_TAX => $address->getBaseTaxAmount(),
|
284 |
+
self::TOTAL_SHIPPING => $address->getBaseShippingAmount(),
|
285 |
+
self::TOTAL_DISCOUNT => abs($address->getBaseDiscountAmount()),
|
286 |
+
);
|
287 |
+
$this->_applyHiddenTaxWorkaround($address);
|
288 |
+
}
|
289 |
+
$originalDiscount = $this->_totals[self::TOTAL_DISCOUNT];
|
290 |
+
|
291 |
+
// arbitrary items, total modifications
|
292 |
+
Mage::dispatchEvent('payment_prepare_line_items', array('payment_cart' => $this));
|
293 |
+
|
294 |
+
// distinguish original discount among the others
|
295 |
+
if ($originalDiscount > 0.0001 && isset($this->_totalLineItemDescriptions[self::TOTAL_DISCOUNT])) {
|
296 |
+
$this->_totalLineItemDescriptions[self::TOTAL_DISCOUNT][] = Mage::helper('sales')->__('Discount (%s)', Mage::app()->getStore()->convertPrice($originalDiscount, true, false));
|
297 |
+
}
|
298 |
+
|
299 |
+
// discount, shipping as items
|
300 |
+
if ($this->_isDiscountAsItem && $this->_totals[self::TOTAL_DISCOUNT]) {
|
301 |
+
$this->addItem(Mage::helper('kash_gateway')->__('Discount'), 1, -1.00 * $this->_totals[self::TOTAL_DISCOUNT],
|
302 |
+
$this->_renderTotalLineItemDescriptions(self::TOTAL_DISCOUNT)
|
303 |
+
);
|
304 |
+
}
|
305 |
+
$shippingItemId = $this->_renderTotalLineItemDescriptions(self::TOTAL_SHIPPING, $shippingDescription);
|
306 |
+
if ($this->_isShippingAsItem && (float)$this->_totals[self::TOTAL_SHIPPING]) {
|
307 |
+
$this->addItem(Mage::helper('kash_gateway')->__('Shipping'), 1, (float)$this->_totals[self::TOTAL_SHIPPING],
|
308 |
+
$shippingItemId
|
309 |
+
);
|
310 |
+
}
|
311 |
+
|
312 |
+
// compound non-regular items into subtotal
|
313 |
+
foreach ($this->_items as $key => $item) {
|
314 |
+
if ($key > $lastRegularItemKey && $item->getAmount() != 0) {
|
315 |
+
$this->_totals[self::TOTAL_SUBTOTAL] += $item->getAmount();
|
316 |
+
}
|
317 |
+
}
|
318 |
+
|
319 |
+
$this->_validate();
|
320 |
+
// if cart items are invalid, prepare cart for transfer without line items
|
321 |
+
if (!$this->_areItemsValid) {
|
322 |
+
$this->removeItem($shippingItemId);
|
323 |
+
}
|
324 |
+
|
325 |
+
$this->_shouldRender = false;
|
326 |
+
}
|
327 |
+
|
328 |
+
/**
|
329 |
+
* Merge multiple descriptions by a total code into a string
|
330 |
+
*
|
331 |
+
* @param string $code
|
332 |
+
* @param string $prepend
|
333 |
+
* @param string $append
|
334 |
+
* @param string $glue
|
335 |
+
* @return string
|
336 |
+
*/
|
337 |
+
protected function _renderTotalLineItemDescriptions($code, $prepend = '', $append = '', $glue = '; ')
|
338 |
+
{
|
339 |
+
$result = array();
|
340 |
+
if ($prepend) {
|
341 |
+
$result[] = $prepend;
|
342 |
+
}
|
343 |
+
if (isset($this->_totalLineItemDescriptions[$code])) {
|
344 |
+
$result = array_merge($this->_totalLineItemDescriptions[$code]);
|
345 |
+
}
|
346 |
+
if ($append) {
|
347 |
+
$result[] = $append;
|
348 |
+
}
|
349 |
+
return implode($glue, $result);
|
350 |
+
}
|
351 |
+
|
352 |
+
/**
|
353 |
+
* Check the line items and totals according to Payment business logic limitations
|
354 |
+
*/
|
355 |
+
protected function _validate()
|
356 |
+
{
|
357 |
+
$this->_areItemsValid = true;
|
358 |
+
$this->_areTotalsValid = false;
|
359 |
+
|
360 |
+
$referenceAmount = $this->_salesEntity->getBaseGrandTotal();
|
361 |
+
|
362 |
+
$itemsSubtotal = 0;
|
363 |
+
foreach ($this->_items as $i) {
|
364 |
+
$itemsSubtotal = $itemsSubtotal + $i['qty'] * $i['amount'];
|
365 |
+
}
|
366 |
+
$sum = $itemsSubtotal + $this->_totals[self::TOTAL_TAX];
|
367 |
+
if (!$this->_isShippingAsItem) {
|
368 |
+
$sum += $this->_totals[self::TOTAL_SHIPPING];
|
369 |
+
}
|
370 |
+
if (!$this->_isDiscountAsItem) {
|
371 |
+
$sum -= $this->_totals[self::TOTAL_DISCOUNT];
|
372 |
+
}
|
373 |
+
/**
|
374 |
+
* numbers are intentionally converted to strings because of possible comparison error
|
375 |
+
* see http://php.net/float
|
376 |
+
*/
|
377 |
+
// match sum of all the items and totals to the reference amount
|
378 |
+
if (sprintf('%.4F', $sum) != sprintf('%.4F', $referenceAmount)) {
|
379 |
+
$adjustment = $sum - $referenceAmount;
|
380 |
+
$this->_totals[self::TOTAL_SUBTOTAL] = $this->_totals[self::TOTAL_SUBTOTAL] - $adjustment;
|
381 |
+
}
|
382 |
+
|
383 |
+
// Payment requires to have discount less than items subtotal
|
384 |
+
if (!$this->_isDiscountAsItem) {
|
385 |
+
$this->_areTotalsValid = round($this->_totals[self::TOTAL_DISCOUNT], 4) < round($itemsSubtotal, 4);
|
386 |
+
} else {
|
387 |
+
$this->_areTotalsValid = $itemsSubtotal > 0.00001;
|
388 |
+
}
|
389 |
+
|
390 |
+
$this->_areItemsValid = $this->_areItemsValid && $this->_areTotalsValid;
|
391 |
+
}
|
392 |
+
|
393 |
+
/**
|
394 |
+
* Check whether items are valid
|
395 |
+
*
|
396 |
+
* @return bool
|
397 |
+
*/
|
398 |
+
public function areItemsValid()
|
399 |
+
{
|
400 |
+
return $this->_areItemsValid;
|
401 |
+
}
|
402 |
+
|
403 |
+
/**
|
404 |
+
* Add a usual line item with amount and qty
|
405 |
+
*
|
406 |
+
* @param Varien_Object $salesItem
|
407 |
+
* @return Varien_Object
|
408 |
+
*/
|
409 |
+
protected function _addRegularItem(Varien_Object $salesItem)
|
410 |
+
{
|
411 |
+
if ($this->_salesEntity instanceof Mage_Sales_Model_Order) {
|
412 |
+
$qty = (int) $salesItem->getQtyOrdered();
|
413 |
+
$amount = (float) $salesItem->getBasePrice();
|
414 |
+
// TODO: nominal item for order
|
415 |
+
} else {
|
416 |
+
$qty = (int) $salesItem->getTotalQty();
|
417 |
+
$amount = $salesItem->isNominal() ? 0 : (float) $salesItem->getBaseCalculationPrice();
|
418 |
+
}
|
419 |
+
// workaround in case if item subtotal precision is not compatible with Payment (.2)
|
420 |
+
$subAggregatedLabel = '';
|
421 |
+
if ($amount - round($amount, 2)) {
|
422 |
+
$amount = $amount * $qty;
|
423 |
+
$subAggregatedLabel = ' x' . $qty;
|
424 |
+
$qty = 1;
|
425 |
+
}
|
426 |
+
|
427 |
+
// aggregate item price if item qty * price does not match row total
|
428 |
+
if (($amount * $qty) != $salesItem->getBaseRowTotal()) {
|
429 |
+
$amount = (float) $salesItem->getBaseRowTotal();
|
430 |
+
$subAggregatedLabel = ' x' . $qty;
|
431 |
+
$qty = 1;
|
432 |
+
}
|
433 |
+
|
434 |
+
return $this->addItem($salesItem->getName() . $subAggregatedLabel, $qty, $amount, $salesItem->getSku());
|
435 |
+
}
|
436 |
+
|
437 |
+
/**
|
438 |
+
* Get/Set for the specified variable.
|
439 |
+
* If the value changes, the re-rendering is commenced
|
440 |
+
*
|
441 |
+
* @param string $var
|
442 |
+
* @param $setValue
|
443 |
+
* @return bool|Kash_Gateway_Model_Cart
|
444 |
+
*/
|
445 |
+
private function _totalAsItem($var, $setValue = null)
|
446 |
+
{
|
447 |
+
if (null !== $setValue) {
|
448 |
+
if ($setValue != $this->$var) {
|
449 |
+
$this->_shouldRender = true;
|
450 |
+
}
|
451 |
+
$this->$var = $setValue;
|
452 |
+
return $this;
|
453 |
+
}
|
454 |
+
return $this->$var;
|
455 |
+
}
|
456 |
+
|
457 |
+
/**
|
458 |
+
* Add "hidden" discount and shipping tax
|
459 |
+
*
|
460 |
+
* Go ahead, try to understand ]:->
|
461 |
+
*
|
462 |
+
* Tax settings for getting "discount tax":
|
463 |
+
* - Catalog Prices = Including Tax
|
464 |
+
* - Apply Customer Tax = After Discount
|
465 |
+
* - Apply Discount on Prices = Including Tax
|
466 |
+
*
|
467 |
+
* Test case for getting "hidden shipping tax":
|
468 |
+
* - Make sure shipping is taxable (set shipping tax class)
|
469 |
+
* - Catalog Prices = Including Tax
|
470 |
+
* - Shipping Prices = Including Tax
|
471 |
+
* - Apply Customer Tax = After Discount
|
472 |
+
* - Create a shopping cart price rule with % discount applied to the Shipping Amount
|
473 |
+
* - run shopping cart and estimate shipping
|
474 |
+
*
|
475 |
+
* @param Mage_Core_Model_Abstract $salesEntity
|
476 |
+
*/
|
477 |
+
private function _applyHiddenTaxWorkaround($salesEntity)
|
478 |
+
{
|
479 |
+
$this->_totals[self::TOTAL_TAX] += (float)$salesEntity->getBaseHiddenTaxAmount();
|
480 |
+
$this->_totals[self::TOTAL_TAX] += (float)$salesEntity->getBaseShippingHiddenTaxAmount();
|
481 |
+
}
|
482 |
+
|
483 |
+
/**
|
484 |
+
* Check whether any item has negative amount
|
485 |
+
*
|
486 |
+
* @return bool
|
487 |
+
*/
|
488 |
+
public function hasNegativeItemAmount()
|
489 |
+
{
|
490 |
+
foreach ($this->_items as $item) {
|
491 |
+
if ($item->getAmount() < 0) {
|
492 |
+
return true;
|
493 |
+
}
|
494 |
+
}
|
495 |
+
return false;
|
496 |
+
}
|
497 |
+
}
|
app/code/local/Kash/Gateway/Model/Checkout.php
ADDED
@@ -0,0 +1,655 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Wrapper that performs Payment BB and Checkout communication
|
5 |
+
* Use current Payment BB method instance
|
6 |
+
*
|
7 |
+
* @author Blue Badger <jonathan@badger.blue>
|
8 |
+
*/
|
9 |
+
class Kash_Gateway_Model_Checkout
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* @var Mage_Sales_Model_Quote
|
13 |
+
*/
|
14 |
+
public $_quote = null;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Config instance
|
18 |
+
* @var Kash_Gateway_Model_Config
|
19 |
+
*/
|
20 |
+
protected $_config = null;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* API instance
|
24 |
+
* @var Kash_Gateway_Model_Api_Bb
|
25 |
+
*/
|
26 |
+
protected $_api = null;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Api Model Type
|
30 |
+
*
|
31 |
+
* @var string
|
32 |
+
*/
|
33 |
+
protected $_apiType = 'kash_gateway/api_bb';
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Payment method type
|
37 |
+
*/
|
38 |
+
protected $_methodType = Kash_Gateway_Model_Config::METHOD_GATEWAY_KASH;
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Params response
|
42 |
+
*/
|
43 |
+
protected $_params = null;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* State helper variables
|
47 |
+
* @var string
|
48 |
+
*/
|
49 |
+
protected $_redirectUrl = '';
|
50 |
+
protected $_pendingPaymentMessage = '';
|
51 |
+
protected $_checkoutRedirectUrl = '';
|
52 |
+
|
53 |
+
/**
|
54 |
+
* @var Mage_Customer_Model_Session
|
55 |
+
*/
|
56 |
+
protected $_customerSession;
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Redirect urls supposed to be set to support giropay
|
60 |
+
*
|
61 |
+
* @var array
|
62 |
+
*/
|
63 |
+
protected $_giropayUrls = array();
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Customer ID
|
67 |
+
*
|
68 |
+
* @var int
|
69 |
+
*/
|
70 |
+
protected $_customerId = null;
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Order
|
74 |
+
*
|
75 |
+
* @var Mage_Sales_Model_Quote
|
76 |
+
*/
|
77 |
+
protected $_order = null;
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Set quote and config instances
|
81 |
+
* @param array $params
|
82 |
+
* @throws Exception
|
83 |
+
*/
|
84 |
+
public function __construct($params = array())
|
85 |
+
{
|
86 |
+
if (isset($params['quote']) && $params['quote'] instanceof Mage_Sales_Model_Quote) {
|
87 |
+
$this->_quote = $params['quote'];
|
88 |
+
} else {
|
89 |
+
throw new Exception('Quote instance is required.');
|
90 |
+
}
|
91 |
+
if (isset($params['config']) && $params['config'] instanceof Kash_Gateway_Model_Config) {
|
92 |
+
$this->_config = $params['config'];
|
93 |
+
} else {
|
94 |
+
throw new Exception('Config instance is required.');
|
95 |
+
}
|
96 |
+
$this->_customerSession = isset($params['session']) && $params['session'] instanceof Mage_Customer_Model_Session
|
97 |
+
? $params['session'] : Mage::getSingleton('customer/session');
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Setter that enables giropay redirects flow
|
102 |
+
* +/
|
103 |
+
* @param string $callbackUrl - payment callback
|
104 |
+
* @param string $cancelUrl - payment cancellation result
|
105 |
+
* @param string $completeUrl - complete payment result
|
106 |
+
* @return $this
|
107 |
+
*/
|
108 |
+
public function prepareGiropayUrls($callbackUrl, $cancelUrl, $completeUrl)
|
109 |
+
{
|
110 |
+
$this->_giropayUrls = array($callbackUrl, $cancelUrl, $completeUrl);
|
111 |
+
return $this;
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Setter for customer Id
|
116 |
+
*
|
117 |
+
* @param int $id
|
118 |
+
* @return $this
|
119 |
+
*/
|
120 |
+
public function setCustomerId($id)
|
121 |
+
{
|
122 |
+
$this->_customerId = $id;
|
123 |
+
return $this;
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Setter for customer
|
128 |
+
*
|
129 |
+
* @param Mage_Customer_Model_Customer $customer
|
130 |
+
* @return $this
|
131 |
+
*/
|
132 |
+
public function setCustomer($customer)
|
133 |
+
{
|
134 |
+
$this->_quote->assignCustomer($customer);
|
135 |
+
$this->_customerId = $customer->getId();
|
136 |
+
return $this;
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Setter for customer with billing and shipping address changing ability
|
141 |
+
*
|
142 |
+
* @param Mage_Customer_Model_Customer $customer
|
143 |
+
* @param Mage_Sales_Model_Quote_Address $billingAddress
|
144 |
+
* @param Mage_Sales_Model_Quote_Address $shippingAddress
|
145 |
+
* @return $this
|
146 |
+
*/
|
147 |
+
public function setCustomerWithAddressChange($customer, $billingAddress = null, $shippingAddress = null)
|
148 |
+
{
|
149 |
+
$this->_quote->assignCustomerWithAddressChange($customer, $billingAddress, $shippingAddress);
|
150 |
+
$this->_customerId = $customer->getId();
|
151 |
+
return $this;
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Reserve order ID for specified quote and start checkout on Payment
|
156 |
+
*
|
157 |
+
* @return mixed
|
158 |
+
*/
|
159 |
+
public function start()
|
160 |
+
{
|
161 |
+
//$this->_quote->setCouponCode('code_test');
|
162 |
+
$this->_quote->collectTotals();
|
163 |
+
|
164 |
+
if (!$this->_quote->getGrandTotal() && !$this->_quote->hasNominalItems()) {
|
165 |
+
Mage::throwException(Mage::helper('kash_gateway')->__('Payment does not support processing orders with zero amount. To complete your purchase, proceed to the standard checkout process.'));
|
166 |
+
}
|
167 |
+
|
168 |
+
//Mage::helper('kash_gateway/checkout')->restoreQuote();
|
169 |
+
$this->_quote->reserveOrderId()->save();
|
170 |
+
// prepare API
|
171 |
+
$this->_getApi();
|
172 |
+
$this->_api->setAmount($this->_quote->getGrandTotal())
|
173 |
+
->setCurrencyCode($this->_quote->getBaseCurrencyCode())
|
174 |
+
->setXInvoice($this->_quote->getReservedOrderId());
|
175 |
+
list($callbackUrl, $cancelUrl, $completeUrl) = $this->_giropayUrls;
|
176 |
+
$this->_api->addData(array(
|
177 |
+
'x_url_callback' => $callbackUrl,
|
178 |
+
'x_url_cancel' => $cancelUrl,
|
179 |
+
'x_url_complete' => $completeUrl,
|
180 |
+
'x_transaction_type' => 'sale',
|
181 |
+
'x_description' => 'Order #' . $this->_quote->getReservedOrderId(),
|
182 |
+
'x_reference' => $this->_quote->getReservedOrderId(),
|
183 |
+
));
|
184 |
+
|
185 |
+
// supress or export shipping address
|
186 |
+
if ($this->_quote->getIsVirtual()) {
|
187 |
+
$this->_api->setRequireBillingAddress(1);
|
188 |
+
|
189 |
+
$this->_api->setSuppressShipping(true);
|
190 |
+
} else {
|
191 |
+
$address = $this->_quote->getShippingAddress();
|
192 |
+
if (true === $address->validate()) {
|
193 |
+
$this->_api->setAddress($address);
|
194 |
+
}
|
195 |
+
$this->_quote->getPayment()->save();
|
196 |
+
}
|
197 |
+
|
198 |
+
// add line items
|
199 |
+
$paymentCart = Mage::getModel('kash_gateway/cart', array($this->_quote));
|
200 |
+
$this->_api->setPaymentCart($paymentCart);
|
201 |
+
|
202 |
+
// call API and redirect with token
|
203 |
+
$token = $this->_api->getToken();
|
204 |
+
$token = $this->_api->callSetBBCheckout();
|
205 |
+
$this->_redirectUrl = $this->_config->post_url;
|
206 |
+
|
207 |
+
$this->_quote->getPayment()->save();
|
208 |
+
return $token;
|
209 |
+
}
|
210 |
+
|
211 |
+
/**
|
212 |
+
* Check whether system can skip order review page before placing order
|
213 |
+
* +/
|
214 |
+
* @return bool
|
215 |
+
*/
|
216 |
+
public function canSkipOrderReviewStep()
|
217 |
+
{
|
218 |
+
return $this->_config->isOrderReviewStepDisabled();
|
219 |
+
}
|
220 |
+
|
221 |
+
/**
|
222 |
+
* Set shipping method to quote, if needed
|
223 |
+
* @param string $methodCode
|
224 |
+
*/
|
225 |
+
public function updateShippingMethod($methodCode)
|
226 |
+
{
|
227 |
+
if (!$this->_quote->getIsVirtual() && $shippingAddress = $this->_quote->getShippingAddress()) {
|
228 |
+
if ($methodCode != $shippingAddress->getShippingMethod()) {
|
229 |
+
$this->_ignoreAddressValidation();
|
230 |
+
$shippingAddress->setShippingMethod($methodCode)->setCollectShippingRates(true);
|
231 |
+
$this->_quote->collectTotals()->save();
|
232 |
+
}
|
233 |
+
}
|
234 |
+
}
|
235 |
+
|
236 |
+
/**
|
237 |
+
* Place the order and recurring payment profiles when customer returned from payment
|
238 |
+
* Until this moment all quote data must be valid
|
239 |
+
*/
|
240 |
+
public function place()
|
241 |
+
{
|
242 |
+
$isNewCustomer = false;
|
243 |
+
switch ($this->getCheckoutMethod()) {
|
244 |
+
case Mage_Checkout_Model_Type_Onepage::METHOD_GUEST:
|
245 |
+
$this->_prepareGuestQuote();
|
246 |
+
break;
|
247 |
+
case Mage_Checkout_Model_Type_Onepage::METHOD_REGISTER:
|
248 |
+
$this->_prepareNewCustomerQuote();
|
249 |
+
$isNewCustomer = true;
|
250 |
+
break;
|
251 |
+
default:
|
252 |
+
$this->_prepareCustomerQuote();
|
253 |
+
break;
|
254 |
+
}
|
255 |
+
|
256 |
+
$this->setAdditionalInformation();
|
257 |
+
$this->_ignoreAddressValidation();
|
258 |
+
$this->_applyDiscount();
|
259 |
+
$this->_quote->collectTotals();
|
260 |
+
$service = Mage::getModel('sales/service_quote', $this->_quote);
|
261 |
+
$service->submitAll();
|
262 |
+
$this->_quote->save();
|
263 |
+
|
264 |
+
if ($isNewCustomer) {
|
265 |
+
try {
|
266 |
+
$this->_involveNewCustomer();
|
267 |
+
} catch (Exception $e) {
|
268 |
+
Mage::logException($e);
|
269 |
+
}
|
270 |
+
}
|
271 |
+
|
272 |
+
/** @var $order Mage_Sales_Model_Order */
|
273 |
+
$order = $service->getOrder();
|
274 |
+
if (!$order) {
|
275 |
+
return;
|
276 |
+
}
|
277 |
+
|
278 |
+
switch ($order->getState()) {
|
279 |
+
// even after placement payment can disallow to authorize/capture, but will wait until bank transfers money
|
280 |
+
case Mage_Sales_Model_Order::STATE_PENDING_PAYMENT:
|
281 |
+
// TODO
|
282 |
+
break;
|
283 |
+
// regular placement, when everything is ok
|
284 |
+
case Mage_Sales_Model_Order::STATE_PROCESSING:
|
285 |
+
case Mage_Sales_Model_Order::STATE_COMPLETE:
|
286 |
+
case Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW:
|
287 |
+
$order->queueNewOrderEmail();
|
288 |
+
break;
|
289 |
+
}
|
290 |
+
$this->_order = $order;
|
291 |
+
}
|
292 |
+
|
293 |
+
/**
|
294 |
+
* Set additional information
|
295 |
+
*/
|
296 |
+
public function setAdditionalInformation()
|
297 |
+
{
|
298 |
+
$payment = $this->_quote->getPayment();
|
299 |
+
$payment->setXGatewayReference($this->getParams('x_gateway_reference'));
|
300 |
+
|
301 |
+
$params = $this->getParams();
|
302 |
+
$result = array();
|
303 |
+
foreach ($this->_api->responseMap as $key => $val) {
|
304 |
+
$result[$key] = $params[$val];
|
305 |
+
}
|
306 |
+
$payment->setAdditionalInformation($result);
|
307 |
+
}
|
308 |
+
|
309 |
+
/** +/
|
310 |
+
* Make sure addresses will be saved without validation errors
|
311 |
+
*/
|
312 |
+
public function _ignoreAddressValidation()
|
313 |
+
{
|
314 |
+
$this->_quote->getBillingAddress()->setShouldIgnoreValidation(true);
|
315 |
+
if (!$this->_quote->getIsVirtual()) {
|
316 |
+
$this->_quote->getShippingAddress()->setShouldIgnoreValidation(true);
|
317 |
+
if (!$this->_quote->getBillingAddress()->getEmail()) {
|
318 |
+
$this->_quote->getBillingAddress()->setSameAsBilling(1);
|
319 |
+
}
|
320 |
+
}
|
321 |
+
}
|
322 |
+
|
323 |
+
/**
|
324 |
+
* Determine whether redirect somewhere specifically is required
|
325 |
+
*
|
326 |
+
* @return string
|
327 |
+
*/
|
328 |
+
public function getRedirectUrl()
|
329 |
+
{
|
330 |
+
return $this->_redirectUrl;
|
331 |
+
}
|
332 |
+
|
333 |
+
/**
|
334 |
+
* Return order
|
335 |
+
* +/
|
336 |
+
* @return Mage_Sales_Model_Order
|
337 |
+
*/
|
338 |
+
public function getOrder()
|
339 |
+
{
|
340 |
+
return $this->_order;
|
341 |
+
}
|
342 |
+
|
343 |
+
/**
|
344 |
+
* Get checkout method
|
345 |
+
* +/
|
346 |
+
* @return string
|
347 |
+
*/
|
348 |
+
public function getCheckoutMethod()
|
349 |
+
{
|
350 |
+
if ($this->getCustomerSession()->isLoggedIn()) {
|
351 |
+
return Mage_Checkout_Model_Type_Onepage::METHOD_CUSTOMER;
|
352 |
+
}
|
353 |
+
if (!$this->_quote->getCheckoutMethod()) {
|
354 |
+
if (Mage::helper('checkout')->isAllowedGuestCheckout($this->_quote)) {
|
355 |
+
$this->_quote->setCheckoutMethod(Mage_Checkout_Model_Type_Onepage::METHOD_GUEST);
|
356 |
+
} else {
|
357 |
+
$this->_quote->setCheckoutMethod(Mage_Checkout_Model_Type_Onepage::METHOD_REGISTER);
|
358 |
+
}
|
359 |
+
}
|
360 |
+
return $this->_quote->getCheckoutMethod();
|
361 |
+
}
|
362 |
+
|
363 |
+
/** +/
|
364 |
+
* @return Kash_Gateway_Model_Api_Bb
|
365 |
+
*/
|
366 |
+
public function _getApi()
|
367 |
+
{
|
368 |
+
if (null === $this->_api) {
|
369 |
+
$this->_api = Mage::getModel($this->_apiType)->setConfigObject($this->_config);
|
370 |
+
}
|
371 |
+
return $this->_api;
|
372 |
+
}
|
373 |
+
|
374 |
+
/**
|
375 |
+
* Prepare quote for guest checkout order submit
|
376 |
+
*
|
377 |
+
* @return $this
|
378 |
+
*/
|
379 |
+
protected function _prepareGuestQuote()
|
380 |
+
{
|
381 |
+
$quote = $this->_quote;
|
382 |
+
$quote->setCustomerId(null)
|
383 |
+
->setCustomerEmail($quote->getBillingAddress()->getEmail())
|
384 |
+
->setCustomerIsGuest(true)
|
385 |
+
->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID);
|
386 |
+
return $this;
|
387 |
+
}
|
388 |
+
|
389 |
+
/**
|
390 |
+
* Checks if customer with email coming from Express checkout exists
|
391 |
+
* +/
|
392 |
+
* @return int
|
393 |
+
*/
|
394 |
+
protected function _lookupCustomerId()
|
395 |
+
{
|
396 |
+
return Mage::getModel('customer/customer')
|
397 |
+
->setWebsiteId(Mage::app()->getWebsite()->getId())
|
398 |
+
->loadByEmail($this->_quote->getCustomerEmail())
|
399 |
+
->getId();
|
400 |
+
}
|
401 |
+
|
402 |
+
/**
|
403 |
+
* Prepare quote for customer registration and customer order submit
|
404 |
+
* and restore magento customer data from quote
|
405 |
+
*
|
406 |
+
* @return $this
|
407 |
+
*/
|
408 |
+
protected function _prepareNewCustomerQuote()
|
409 |
+
{
|
410 |
+
$quote = $this->_quote;
|
411 |
+
$billing = $quote->getBillingAddress();
|
412 |
+
$shipping = $quote->isVirtual() ? null : $quote->getShippingAddress();
|
413 |
+
|
414 |
+
$customerId = $this->_lookupCustomerId();
|
415 |
+
if ($customerId) {
|
416 |
+
$this->getCustomerSession()->loginById($customerId);
|
417 |
+
return $this->_prepareCustomerQuote();
|
418 |
+
}
|
419 |
+
|
420 |
+
$customer = $quote->getCustomer();
|
421 |
+
/** @var $customer Mage_Customer_Model_Customer */
|
422 |
+
$customerBilling = $billing->exportCustomerAddress();
|
423 |
+
$customer->addAddress($customerBilling);
|
424 |
+
$billing->setCustomerAddress($customerBilling);
|
425 |
+
$customerBilling->setIsDefaultBilling(true);
|
426 |
+
if ($shipping && !$shipping->getSameAsBilling()) {
|
427 |
+
$customerShipping = $shipping->exportCustomerAddress();
|
428 |
+
$customer->addAddress($customerShipping);
|
429 |
+
$shipping->setCustomerAddress($customerShipping);
|
430 |
+
$customerShipping->setIsDefaultShipping(true);
|
431 |
+
} elseif ($shipping) {
|
432 |
+
$customerBilling->setIsDefaultShipping(true);
|
433 |
+
}
|
434 |
+
|
435 |
+
if ($quote->getCustomerDob() && !$billing->getCustomerDob()) {
|
436 |
+
$billing->setCustomerDob($quote->getCustomerDob());
|
437 |
+
}
|
438 |
+
|
439 |
+
if ($quote->getCustomerTaxvat() && !$billing->getCustomerTaxvat()) {
|
440 |
+
$billing->setCustomerTaxvat($quote->getCustomerTaxvat());
|
441 |
+
}
|
442 |
+
|
443 |
+
if ($quote->getCustomerGender() && !$billing->getCustomerGender()) {
|
444 |
+
$billing->setCustomerGender($quote->getCustomerGender());
|
445 |
+
}
|
446 |
+
|
447 |
+
Mage::helper('core')->copyFieldset('checkout_onepage_billing', 'to_customer', $billing, $customer);
|
448 |
+
$customer->setEmail($quote->getCustomerEmail());
|
449 |
+
$customer->setPrefix($quote->getCustomerPrefix());
|
450 |
+
$customer->setFirstname($quote->getCustomerFirstname());
|
451 |
+
$customer->setMiddlename($quote->getCustomerMiddlename());
|
452 |
+
$customer->setLastname($quote->getCustomerLastname());
|
453 |
+
$customer->setSuffix($quote->getCustomerSuffix());
|
454 |
+
$customer->setPassword($customer->decryptPassword($quote->getPasswordHash()));
|
455 |
+
$customer->setPasswordHash($customer->hashPassword($customer->getPassword()));
|
456 |
+
$customer->save();
|
457 |
+
$quote->setCustomer($customer);
|
458 |
+
|
459 |
+
return $this;
|
460 |
+
}
|
461 |
+
|
462 |
+
/**
|
463 |
+
* Prepare quote for customer order submit
|
464 |
+
* +/
|
465 |
+
* @return Kash_Gateway_Model_Checkout
|
466 |
+
*/
|
467 |
+
protected function _prepareCustomerQuote()
|
468 |
+
{
|
469 |
+
$quote = $this->_quote;
|
470 |
+
$billing = $quote->getBillingAddress();
|
471 |
+
$shipping = $quote->isVirtual() ? null : $quote->getShippingAddress();
|
472 |
+
|
473 |
+
$customer = $this->getCustomerSession()->getCustomer();
|
474 |
+
if (!$billing->getCustomerId() || $billing->getSaveInAddressBook()) {
|
475 |
+
$customerBilling = $billing->exportCustomerAddress();
|
476 |
+
$customer->addAddress($customerBilling);
|
477 |
+
$billing->setCustomerAddress($customerBilling);
|
478 |
+
}
|
479 |
+
if ($shipping && ((!$shipping->getCustomerId() && !$shipping->getSameAsBilling())
|
480 |
+
|| (!$shipping->getSameAsBilling() && $shipping->getSaveInAddressBook()))
|
481 |
+
) {
|
482 |
+
$customerShipping = $shipping->exportCustomerAddress();
|
483 |
+
$customer->addAddress($customerShipping);
|
484 |
+
$shipping->setCustomerAddress($customerShipping);
|
485 |
+
}
|
486 |
+
|
487 |
+
if (isset($customerBilling) && !$customer->getDefaultBilling()) {
|
488 |
+
$customerBilling->setIsDefaultBilling(true);
|
489 |
+
}
|
490 |
+
if ($shipping && isset($customerBilling) && !$customer->getDefaultShipping() && $shipping->getSameAsBilling()) {
|
491 |
+
$customerBilling->setIsDefaultShipping(true);
|
492 |
+
} elseif ($shipping && isset($customerShipping) && !$customer->getDefaultShipping()) {
|
493 |
+
$customerShipping->setIsDefaultShipping(true);
|
494 |
+
}
|
495 |
+
$quote->setCustomer($customer);
|
496 |
+
|
497 |
+
return $this;
|
498 |
+
}
|
499 |
+
|
500 |
+
/**
|
501 |
+
* Involve new customer to system
|
502 |
+
*
|
503 |
+
* @return $this
|
504 |
+
*/
|
505 |
+
protected function _involveNewCustomer()
|
506 |
+
{
|
507 |
+
$customer = $this->_quote->getCustomer();
|
508 |
+
if ($customer->isConfirmationRequired()) {
|
509 |
+
$customer->sendNewAccountEmail('confirmation');
|
510 |
+
$url = Mage::helper('customer')->getEmailConfirmationUrl($customer->getEmail());
|
511 |
+
$this->getCustomerSession()->addSuccess(
|
512 |
+
Mage::helper('customer')->__('Account confirmation is required. Please, check your e-mail for confirmation link. To resend confirmation email please <a href="%s">click here</a>.', $url)
|
513 |
+
);
|
514 |
+
} else {
|
515 |
+
$customer->sendNewAccountEmail();
|
516 |
+
$this->getCustomerSession()->loginById($customer->getId());
|
517 |
+
}
|
518 |
+
return $this;
|
519 |
+
}
|
520 |
+
|
521 |
+
/**
|
522 |
+
* Get customer session object
|
523 |
+
* +/
|
524 |
+
* @return Mage_Customer_Model_Session
|
525 |
+
*/
|
526 |
+
public function getCustomerSession()
|
527 |
+
{
|
528 |
+
return $this->_customerSession;
|
529 |
+
}
|
530 |
+
|
531 |
+
/**
|
532 |
+
* Params response
|
533 |
+
*
|
534 |
+
* @param null $key
|
535 |
+
* @return mixed
|
536 |
+
*/
|
537 |
+
public function getParams($key = null)
|
538 |
+
{
|
539 |
+
if ($key) {
|
540 |
+
return array_key_exists($key, $this->_params) ? $this->_params[$key] : null;
|
541 |
+
}
|
542 |
+
return $this->_params;
|
543 |
+
}
|
544 |
+
|
545 |
+
/**
|
546 |
+
* Params response
|
547 |
+
*
|
548 |
+
* @param mixed $params
|
549 |
+
*/
|
550 |
+
public function setParams($params)
|
551 |
+
{
|
552 |
+
$this->_params = $params;
|
553 |
+
}
|
554 |
+
|
555 |
+
/**
|
556 |
+
* Check gateway signing mechanism
|
557 |
+
*
|
558 |
+
* @return string
|
559 |
+
*/
|
560 |
+
public function checkSignature()
|
561 |
+
{
|
562 |
+
$api = $this->_getApi();
|
563 |
+
$signature = $this->getParams('x_signature');
|
564 |
+
$sig = $api->getSignature($this->getParams(), $api->getHmacKey());
|
565 |
+
if ($sig === $signature) {
|
566 |
+
return true;
|
567 |
+
}
|
568 |
+
return false;
|
569 |
+
}
|
570 |
+
|
571 |
+
/**
|
572 |
+
* Check result completed|failed|pending
|
573 |
+
*
|
574 |
+
* @return bool
|
575 |
+
*/
|
576 |
+
public function checkResult()
|
577 |
+
{
|
578 |
+
$xResult = $this->getParams('x_result');
|
579 |
+
switch ($xResult) {
|
580 |
+
case 'completed':
|
581 |
+
return true;
|
582 |
+
default:
|
583 |
+
return false;
|
584 |
+
}
|
585 |
+
}
|
586 |
+
|
587 |
+
|
588 |
+
/**
|
589 |
+
* Apply Discount
|
590 |
+
*/
|
591 |
+
public function _applyDiscount()
|
592 |
+
{
|
593 |
+
$xAmount = $this->getParams('x_amount');
|
594 |
+
$shippingAmount = $this->_quote->getShippingAddress()->getBaseShippingAmount();
|
595 |
+
|
596 |
+
$xAmount = $xAmount - $shippingAmount;
|
597 |
+
$grandTotal = $this->_quote->getGrandTotal() - $shippingAmount;
|
598 |
+
|
599 |
+
$percent = round((100 - $xAmount * 100 / $grandTotal), 2);
|
600 |
+
|
601 |
+
$this->_quote->setCouponCode($this->_getCouponCode($percent));
|
602 |
+
}
|
603 |
+
|
604 |
+
/**
|
605 |
+
* Get coupon
|
606 |
+
* @param $percent
|
607 |
+
* @return string code
|
608 |
+
*/
|
609 |
+
protected function _getCouponCode($percent)
|
610 |
+
{
|
611 |
+
try {
|
612 |
+
$coupon = Mage::getModel('salesrule/coupon')->loadByCode(Kash_Gateway_Model_Config::GATEWAY_KASH_DISCOUNT_CODE);
|
613 |
+
if (!$coupon->isEmpty()) {
|
614 |
+
$ruleCoupon = Mage::getModel('salesrule/rule')->load($coupon->getRuleId(), 'rule_id');
|
615 |
+
if (!$ruleCoupon->isEmpty()) {
|
616 |
+
$ruleCoupon->setDiscountAmount($percent);
|
617 |
+
$ruleCoupon->save();
|
618 |
+
return $ruleCoupon->getCouponCode();
|
619 |
+
}
|
620 |
+
}
|
621 |
+
//when no discount
|
622 |
+
$coupon = Mage::getModel('salesrule/coupon')->loadByCode(Kash_Gateway_Model_Config::GATEWAY_KASH_DISCOUNT_CODE);
|
623 |
+
if (!$coupon->isEmpty()) {
|
624 |
+
$ruleCoupon = Mage::getModel('salesrule/rule')->load($coupon->getRuleId(), 'rule_id');
|
625 |
+
$ruleCoupon->delete();
|
626 |
+
$coupon->delete();
|
627 |
+
}
|
628 |
+
$ruleCoupon = Mage::getModel('salesrule/rule');
|
629 |
+
$ruleCoupon->setName('Discount for Kash Gateway')
|
630 |
+
->setDescription('this is a discount for the kash gateway')
|
631 |
+
->setFromDate(date('Y-m-d'))
|
632 |
+
->setCouponType(2)
|
633 |
+
->setCouponCode(Kash_Gateway_Model_Config::GATEWAY_KASH_DISCOUNT_CODE)
|
634 |
+
->setCustomerGroupIds(array(1))
|
635 |
+
->setIsActive(1)
|
636 |
+
->setStopRulesProcessing(0)
|
637 |
+
->setIsAdvanced(1)
|
638 |
+
->setProductIds('')
|
639 |
+
->setSortOrder(0)
|
640 |
+
->setSimpleAction('by_percent')
|
641 |
+
->setDiscountAmount($percent)
|
642 |
+
->setDiscountQty(null)
|
643 |
+
->setDiscountStep('0')
|
644 |
+
->setSimpleFreeShipping('0')
|
645 |
+
->setApplyToShipping('0')
|
646 |
+
->setIsRss(0)
|
647 |
+
->setWebsiteIds(array(1));
|
648 |
+
$ruleCoupon->save();
|
649 |
+
return $ruleCoupon->getCouponCode();
|
650 |
+
} catch (Exception $ex) {
|
651 |
+
Mage::logException($ex);
|
652 |
+
//Mage::throwException($ex);
|
653 |
+
}
|
654 |
+
}
|
655 |
+
}
|
app/code/local/Kash/Gateway/Model/Config.php
ADDED
@@ -0,0 +1,183 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Config model that is aware of all Kash_Gateway methods
|
5 |
+
* Works with Payment BB system configuration
|
6 |
+
*
|
7 |
+
* @author Blue Badger <jonathan@badger.blue>
|
8 |
+
*/
|
9 |
+
class Kash_Gateway_Model_Config
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* Config path for enabling/disabling order review step in express checkout
|
13 |
+
*/
|
14 |
+
const XML_PATH_GATEWAY_KASH_SKIP_ORDER_REVIEW_STEP_FLAG = 'payment/kash_gateway/skip_order_review_step';
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Website Payments Pro - BB Checkout
|
18 |
+
* @var string
|
19 |
+
*/
|
20 |
+
const METHOD_GATEWAY_KASH = 'kash_gateway';
|
21 |
+
|
22 |
+
/**
|
23 |
+
* URL for get request - BB Checkout
|
24 |
+
* @var string
|
25 |
+
*/
|
26 |
+
const REQUEST_GATEWAY_KASH = 'gateway/bb/getRequest';
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Discount code
|
30 |
+
*/
|
31 |
+
const GATEWAY_KASH_DISCOUNT_CODE ='discount_gatewaykash';
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Current payment method code
|
35 |
+
* @var string
|
36 |
+
*/
|
37 |
+
protected $_methodCode = null;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Current store id
|
41 |
+
*
|
42 |
+
* @var int
|
43 |
+
*/
|
44 |
+
protected $_storeId = null;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Set method and store id, if specified
|
48 |
+
*
|
49 |
+
* @param array $params
|
50 |
+
*/
|
51 |
+
public function __construct($params = array())
|
52 |
+
{
|
53 |
+
if ($params) {
|
54 |
+
$method = array_shift($params);
|
55 |
+
$this->setMethod($method);
|
56 |
+
if ($params) {
|
57 |
+
$storeId = array_shift($params);
|
58 |
+
$this->setStoreId($storeId);
|
59 |
+
}
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Method code setter +/
|
65 |
+
*
|
66 |
+
* @param string|Mage_Payment_Model_Method_Abstract $method
|
67 |
+
* @return Kash_Gateway_Model_Config
|
68 |
+
*/
|
69 |
+
public function setMethod($method)
|
70 |
+
{
|
71 |
+
if ($method instanceof Mage_Payment_Model_Method_Abstract) {
|
72 |
+
$this->_methodCode = $method->getCode();
|
73 |
+
} elseif (is_string($method)) {
|
74 |
+
$this->_methodCode = $method;
|
75 |
+
}
|
76 |
+
return $this;
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Payment method instance code getter +/
|
81 |
+
*
|
82 |
+
* @return string
|
83 |
+
*/
|
84 |
+
public function getMethodCode()
|
85 |
+
{
|
86 |
+
return $this->_methodCode;
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Store ID setter
|
91 |
+
*
|
92 |
+
* @param int $storeId
|
93 |
+
* @return Kash_Gateway_Model_Config
|
94 |
+
*/
|
95 |
+
public function setStoreId($storeId)
|
96 |
+
{
|
97 |
+
$this->_storeId = (int)$storeId;
|
98 |
+
return $this;
|
99 |
+
}
|
100 |
+
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Config field magic getter +/
|
104 |
+
* The specified key can be either in camelCase or under_score format
|
105 |
+
* Tries to map specified value according to set payment method code, into the configuration value
|
106 |
+
* Sets the values into public class parameters, to avoid redundant calls of this method
|
107 |
+
*
|
108 |
+
* @param string $key
|
109 |
+
* @return string|null
|
110 |
+
*/
|
111 |
+
public function __get($key)
|
112 |
+
{
|
113 |
+
$underscored = strtolower(preg_replace('/(.)([A-Z])/', "$1_$2", $key));
|
114 |
+
$value = Mage::getStoreConfig($this->_mapMethodFieldset($underscored), $this->_storeId);
|
115 |
+
$this->$key = $value;
|
116 |
+
$this->$underscored = $value;
|
117 |
+
return $value;
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Map Payment BB General Settings
|
122 |
+
* +/
|
123 |
+
* @param string $fieldName
|
124 |
+
* @return string|null
|
125 |
+
*/
|
126 |
+
protected function _mapMethodFieldset($fieldName)
|
127 |
+
{
|
128 |
+
if (!$this->_methodCode) {
|
129 |
+
return null;
|
130 |
+
}
|
131 |
+
switch ($fieldName) {
|
132 |
+
case 'merchant_country':
|
133 |
+
return "paypal/general/{$fieldName}";
|
134 |
+
case 'post_url':
|
135 |
+
case 'x_account_id':
|
136 |
+
case 'server_key':
|
137 |
+
if (Mage::getStoreConfig($this->_mapMethodFieldset('x_test'), $this->_storeId)) {
|
138 |
+
$fieldName .= '_test';
|
139 |
+
}
|
140 |
+
return "payment/{$this->_methodCode}/{$fieldName}";
|
141 |
+
default:
|
142 |
+
return "payment/{$this->_methodCode}/{$fieldName}";
|
143 |
+
}
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Return merchant country code, use default country if it not specified in General settings
|
148 |
+
* +/
|
149 |
+
* @return string
|
150 |
+
*/
|
151 |
+
public function getMerchantCountry()
|
152 |
+
{
|
153 |
+
$countryCode = Mage::getStoreConfig($this->_mapMethodFieldset('merchant_country'), $this->_storeId);
|
154 |
+
if (!$countryCode) {
|
155 |
+
$countryCode = Mage::helper('core')->getDefaultCountry($this->_storeId);
|
156 |
+
}
|
157 |
+
return $countryCode;
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Check whether order review step enabled in configuration
|
162 |
+
*
|
163 |
+
* @return bool
|
164 |
+
*/
|
165 |
+
public function isOrderReviewStepDisabled()
|
166 |
+
{
|
167 |
+
return Mage::getStoreConfigFlag(self::XML_PATH_GATEWAY_KASH_SKIP_ORDER_REVIEW_STEP_FLAG);
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Get Payment image URL
|
172 |
+
* Supposed to be used on payment methods selection
|
173 |
+
* $staticSize is applicable for static images only
|
174 |
+
*
|
175 |
+
* @param string $localeCode
|
176 |
+
* @return String
|
177 |
+
*/
|
178 |
+
public function getPaymentImageUrl($localeCode)
|
179 |
+
{
|
180 |
+
return 'https://offsite-gateway-sim.herokuapp.com/shopify.png';
|
181 |
+
}
|
182 |
+
}
|
183 |
+
|
app/code/local/Kash/Gateway/Model/Method/Bb.php
ADDED
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/** *
|
4 |
+
* Payment BB Module
|
5 |
+
*
|
6 |
+
* @author Blue Badger <jonathan@badger.blue>
|
7 |
+
*/
|
8 |
+
class Kash_Gateway_Model_Method_Bb extends Mage_Payment_Model_Method_Abstract
|
9 |
+
{
|
10 |
+
protected $_code = Kash_Gateway_Model_Config::METHOD_GATEWAY_KASH;
|
11 |
+
protected $_formBlockType = 'kash_gateway/form_bb';
|
12 |
+
protected $_infoBlockType = 'kash_gateway/adminhtml_info';
|
13 |
+
|
14 |
+
protected $_canUseInternal = false;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Config instance
|
18 |
+
*
|
19 |
+
* @var Kash_Gateway_Model_Config
|
20 |
+
*/
|
21 |
+
protected $_config = null;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Config model type
|
25 |
+
*
|
26 |
+
* @var string
|
27 |
+
*/
|
28 |
+
protected $_configType = 'kash_gateway/config';
|
29 |
+
|
30 |
+
public function __construct()
|
31 |
+
{
|
32 |
+
$this->_config = Mage::getModel($this->_configType, array($this->_code));
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Config instance setter
|
37 |
+
*
|
38 |
+
* @param Kash_Gateway_Model_Config $instace
|
39 |
+
* @param int $storeId
|
40 |
+
* @return $this
|
41 |
+
*/
|
42 |
+
public function setConfig(Kash_Gateway_Model_Config $instace, $storeId = null)
|
43 |
+
{
|
44 |
+
$this->_config = $instace;
|
45 |
+
if (null !== $storeId) {
|
46 |
+
$this->_config->setStoreId($storeId);
|
47 |
+
}
|
48 |
+
return $this;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Config instance getter
|
53 |
+
*
|
54 |
+
* @return Kash_Gateway_Model_Config
|
55 |
+
*/
|
56 |
+
public function getConfig()
|
57 |
+
{
|
58 |
+
return $this->_config;
|
59 |
+
}
|
60 |
+
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Store setter
|
64 |
+
* Also updates store ID in config object
|
65 |
+
*
|
66 |
+
* @param Mage_Core_Model_Store|int $store
|
67 |
+
* @return Kash_Gateway_Model_Method_Bb
|
68 |
+
*/
|
69 |
+
public function setStore($store)
|
70 |
+
{
|
71 |
+
$this->setData('store', $store);
|
72 |
+
if (null === $store) {
|
73 |
+
$store = Mage::app()->getStore()->getId();
|
74 |
+
}
|
75 |
+
$this->_config->setStoreId(is_object($store) ? $store->getId() : $store);
|
76 |
+
return $this;
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Custom getter for payment configuration
|
81 |
+
*
|
82 |
+
* @param string $field
|
83 |
+
* @param int $storeId
|
84 |
+
* @return mixed
|
85 |
+
*/
|
86 |
+
public function getConfigData($field, $storeId = null)
|
87 |
+
{
|
88 |
+
return $this->_config->$field;
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Checkout redirect URL getter for onepage checkout (hardcode)
|
93 |
+
*
|
94 |
+
* @see Mage_Checkout_OnepageController::savePaymentAction()
|
95 |
+
* @see Mage_Sales_Model_Quote_Payment::getCheckoutRedirectUrl()
|
96 |
+
* @return string
|
97 |
+
*/
|
98 |
+
public function getCheckoutRedirectUrl()
|
99 |
+
{
|
100 |
+
return Mage::getUrl('kash_gateway/bb/start', array('_secure'=>true));
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Whether can get recurring profile details
|
105 |
+
*/
|
106 |
+
public function canGetRecurringProfileDetails()
|
107 |
+
{
|
108 |
+
return true;
|
109 |
+
}
|
110 |
+
|
111 |
+
}
|
app/code/local/Kash/Gateway/Model/Observer.php
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Kash_Gateway_Model_Observer extends Varien_Object
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* Do not show discount in admin panel
|
7 |
+
*
|
8 |
+
* @param Varien_Object $observer
|
9 |
+
* @return Mage_Centinel_Model_Observer
|
10 |
+
*/
|
11 |
+
public function coreCollectionAbstractLoadBefore($observer)
|
12 |
+
{
|
13 |
+
if (Mage::app()->getRequest()->getRouteName() == 'adminhtml' &&
|
14 |
+
Mage::app()->getRequest()->getControllerName() == 'promo_quote'
|
15 |
+
) {
|
16 |
+
if ($observer->getCollection() instanceof Mage_SalesRule_Model_Resource_Rule_Collection) {
|
17 |
+
$select = $observer->getCollection()->getSelect();
|
18 |
+
$select->where('code NOT IN (?)', Kash_Gateway_Model_Config::GATEWAY_KASH_DISCOUNT_CODE);
|
19 |
+
$select->orWhere('code IS NULL');
|
20 |
+
}
|
21 |
+
}
|
22 |
+
return $this;
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Do not take the coupon with frontend for customers
|
27 |
+
*
|
28 |
+
* @param Varien_Object $observer
|
29 |
+
* @return Mage_Centinel_Model_Observer
|
30 |
+
*/
|
31 |
+
public function salesQuoteCollectTotalsBefore($observer)
|
32 |
+
{
|
33 |
+
$quote = $observer->getQuote();
|
34 |
+
$discount = $quote->getCouponCode();
|
35 |
+
if ($discount === Kash_Gateway_Model_Config::GATEWAY_KASH_DISCOUNT_CODE) {
|
36 |
+
$params = Mage::app()->getRequest()->getParams();
|
37 |
+
$param = array_key_exists('coupon_code', $params) ? $params['coupon_code'] : null;
|
38 |
+
if (Mage::app()->getRequest()->getRouteName() == 'checkout' ||
|
39 |
+
$param == $discount) {
|
40 |
+
$quote->setCouponCode('');
|
41 |
+
}
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Add payment data to info block
|
47 |
+
*
|
48 |
+
* @param Varien_Object $observer
|
49 |
+
* @return Mage_Centinel_Model_Observer
|
50 |
+
*/
|
51 |
+
public function paymentInfoBlockPrepareSpecificInformation($observer)
|
52 |
+
{
|
53 |
+
if ($observer->getEvent()->getBlock()->getIsSecureMode()) {
|
54 |
+
return;
|
55 |
+
}
|
56 |
+
|
57 |
+
$order = $observer->getEvent()->getPayment()->getOrder();
|
58 |
+
$discountAmount = abs($order->getDiscountAmount());
|
59 |
+
$subtotal = $order->getSubtotal();
|
60 |
+
|
61 |
+
$percent = round($discountAmount * 100 / $subtotal, 2);
|
62 |
+
$transport = $observer->getEvent()->getTransport();
|
63 |
+
$transport->setData('Gateway percent', $percent . '%');
|
64 |
+
|
65 |
+
return $this;
|
66 |
+
}
|
67 |
+
}
|
68 |
+
|
app/code/local/Kash/Gateway/Model/Session.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Payment transaction session namespace
|
4 |
+
*/
|
5 |
+
class Kash_Gateway_Model_Session extends Mage_Core_Model_Session_Abstract
|
6 |
+
{
|
7 |
+
public function __construct()
|
8 |
+
{
|
9 |
+
$this->init('payment');
|
10 |
+
}
|
11 |
+
}
|
app/code/local/Kash/Gateway/controllers/BbController.php
ADDED
@@ -0,0 +1,448 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Bb Checkout Controller
|
5 |
+
*
|
6 |
+
* @author Blue Badger <jonathan@badger.blue>
|
7 |
+
*/
|
8 |
+
class Kash_Gateway_BbController extends Mage_Core_Controller_Front_Action
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* @var Kash_Gateway_Model_Checkout
|
12 |
+
*/
|
13 |
+
protected $_checkout = null;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Checkout mode type
|
17 |
+
*
|
18 |
+
* @var string
|
19 |
+
*/
|
20 |
+
protected $_checkoutType = 'kash_gateway/checkout';
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var Kash_Gateway_Model_Config
|
24 |
+
*/
|
25 |
+
protected $_config = null;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Config mode type
|
29 |
+
*
|
30 |
+
* @var string
|
31 |
+
*/
|
32 |
+
protected $_configType = 'kash_gateway/config';
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @var Mage_Sales_Model_Quote
|
36 |
+
*/
|
37 |
+
protected $_quote = false;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Config method type
|
41 |
+
*
|
42 |
+
* @var string
|
43 |
+
*/
|
44 |
+
protected $_configMethod = Kash_Gateway_Model_Config::METHOD_GATEWAY_KASH;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Instantiate config
|
48 |
+
*/
|
49 |
+
protected function _construct()
|
50 |
+
{
|
51 |
+
parent::_construct();
|
52 |
+
$this->_config = Mage::getModel($this->_configType, array($this->_configMethod));
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Get form for requesting form
|
57 |
+
*/
|
58 |
+
public function startAction(){
|
59 |
+
$paymentParams = $this->getPaymentRequest();
|
60 |
+
if(!$paymentParams){
|
61 |
+
return;
|
62 |
+
}
|
63 |
+
$this->_initToken($paymentParams);
|
64 |
+
$this->loadLayout();
|
65 |
+
$contentBlock = $this->getLayout()->getBlock('content');
|
66 |
+
$formBlock = $contentBlock->getChild('block.form.request');
|
67 |
+
$formBlock->setInput($paymentParams);
|
68 |
+
$formBlock->setPostUrl($this->_config->post_url);
|
69 |
+
$this->renderLayout();
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Get form for requesting initial token and dispatching customer
|
74 |
+
*/
|
75 |
+
public function getRequestAction()
|
76 |
+
{
|
77 |
+
try {
|
78 |
+
$paymentParams = $this->getPaymentRequest();
|
79 |
+
if(!$paymentParams){
|
80 |
+
return;
|
81 |
+
}
|
82 |
+
$this->_initToken($paymentParams);
|
83 |
+
|
84 |
+
$this->loadLayout();
|
85 |
+
$block = $this->getLayout()->createBlock(
|
86 |
+
'Mage_Core_Block_Template',
|
87 |
+
'block_form_request',
|
88 |
+
array('template' => 'kash/form.phtml')
|
89 |
+
);
|
90 |
+
$block->setInput($paymentParams);
|
91 |
+
$block->setPostUrl($this->_config->post_url);
|
92 |
+
$this->getResponse()->setBody($block->toHtml());
|
93 |
+
return;
|
94 |
+
} catch (Mage_Core_Exception $e) {
|
95 |
+
$this->_getCheckoutSession()->addError($e->getMessage());
|
96 |
+
} catch (Exception $e) {
|
97 |
+
$this->_getCheckoutSession()->addError($this->__('Unable to start BB Checkout.'));
|
98 |
+
Mage::logException($e);
|
99 |
+
}
|
100 |
+
|
101 |
+
$this->_redirect('checkout/cart');
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Cancel Payment
|
106 |
+
*/
|
107 |
+
public function cancelAction()
|
108 |
+
{
|
109 |
+
$this->_initToken(false);
|
110 |
+
$this->_redirect('checkout/cart');
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Callback Payment
|
115 |
+
*/
|
116 |
+
public function callbackAction()
|
117 |
+
{
|
118 |
+
$param = Mage::app()->getRequest()->getParam('x_reference');
|
119 |
+
$quota = Mage::getModel('sales/quote')->load($param, 'reserved_order_id');
|
120 |
+
$this->_quote = $quota;
|
121 |
+
|
122 |
+
$this->_config->setStoreId($this->_getQuote()->getStoreId());
|
123 |
+
$this->_checkout = Mage::getSingleton($this->_checkoutType, array(
|
124 |
+
'config' => $this->_config,
|
125 |
+
'quote' => $quota,
|
126 |
+
));
|
127 |
+
|
128 |
+
$params = Mage::app()->getRequest()->getParams();
|
129 |
+
$this->_checkout->setParams($params);
|
130 |
+
|
131 |
+
if ($this->_checkout->checkSignature() &&
|
132 |
+
$this->_checkout->checkResult() &&
|
133 |
+
$quota->getIsActive()
|
134 |
+
) {
|
135 |
+
$this->_checkout->place();
|
136 |
+
$order = $this->_checkout->getOrder();
|
137 |
+
$this->invoiceOrder($order);
|
138 |
+
}
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Complete from Payment and dispatch customer to order review page
|
143 |
+
*/
|
144 |
+
public function completeAction()
|
145 |
+
{
|
146 |
+
try {
|
147 |
+
if (!$this->_initCheckout()) {
|
148 |
+
$this->getResponse()->setRedirect(Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB));
|
149 |
+
return;
|
150 |
+
}
|
151 |
+
if (!$this->_checkout->checkSignature()) {
|
152 |
+
Mage::log('All requests and responses must be signed/verified using HMAC-SHA256');
|
153 |
+
Mage::getSingleton('checkout/session')->addError('Not valid signature');
|
154 |
+
$this->_redirect('checkout/cart');
|
155 |
+
return;
|
156 |
+
}
|
157 |
+
if (!$this->_checkout->checkResult()) {
|
158 |
+
Mage::log('Result not completed');
|
159 |
+
Mage::getSingleton('checkout/session')->addError('Kash Gateway not completed');
|
160 |
+
$this->_redirect('checkout/cart');
|
161 |
+
return;
|
162 |
+
}
|
163 |
+
|
164 |
+
$this->placeOrder();
|
165 |
+
if (!$this->_checkout->canSkipOrderReviewStep()) {
|
166 |
+
$this->_redirect('checkout/onepage/success');
|
167 |
+
} else {
|
168 |
+
$this->_redirect('*/*/review');
|
169 |
+
}
|
170 |
+
return;
|
171 |
+
} catch (Mage_Core_Exception $e) {
|
172 |
+
Mage::getSingleton('checkout/session')->addError($e->getMessage());
|
173 |
+
} catch (Exception $e) {
|
174 |
+
Mage::getSingleton('checkout/session')->addError($this->__('Unable to process Kash Gateway Checkout approval.'));
|
175 |
+
Mage::logException($e);
|
176 |
+
}
|
177 |
+
$this->_redirect('checkout/cart');
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Review order after returning from Payment
|
182 |
+
*/
|
183 |
+
public function reviewAction()
|
184 |
+
{
|
185 |
+
try {
|
186 |
+
$session = $this->_getCheckoutSession();
|
187 |
+
// "last successful quote"
|
188 |
+
$quoteId = $session->getLastQuoteId();
|
189 |
+
$quota = Mage::getModel('sales/quote')->load($quoteId);
|
190 |
+
|
191 |
+
$this->loadLayout();
|
192 |
+
$this->_initLayoutMessages('kash_gateway/session');
|
193 |
+
$reviewBlock = $this->getLayout()->getBlock('gateway.kash.review');
|
194 |
+
$reviewBlock->setQuote($quota);
|
195 |
+
$detailsBlock = $reviewBlock->getChild('details')->setCustomQuote($quota);
|
196 |
+
if ($reviewBlock->getChild('shipping_method')) {
|
197 |
+
$reviewBlock->getChild('shipping_method')->setCustomQuote($quota);
|
198 |
+
}
|
199 |
+
if ($detailsBlock->getChild('totals')) {
|
200 |
+
$detailsBlock->getChild('totals')->setCustomQuote($quota);
|
201 |
+
}
|
202 |
+
$this->renderLayout();
|
203 |
+
return;
|
204 |
+
} catch (Mage_Core_Exception $e) {
|
205 |
+
Mage::getSingleton('checkout/session')->addError($e->getMessage());
|
206 |
+
} catch (Exception $e) {
|
207 |
+
Mage::getSingleton('checkout/session')->addError(
|
208 |
+
$this->__('Unable to initialize Kash Gateway Checkout review.')
|
209 |
+
);
|
210 |
+
Mage::logException($e);
|
211 |
+
}
|
212 |
+
$this->_redirect('checkout/cart');
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Submit the order
|
217 |
+
*/
|
218 |
+
protected function placeOrder()
|
219 |
+
{
|
220 |
+
try {
|
221 |
+
$this->_initToken();
|
222 |
+
$this->_checkout->place();
|
223 |
+
|
224 |
+
// prepare session to success or cancellation page
|
225 |
+
$session = $this->_getCheckoutSession();
|
226 |
+
$session->clearHelperData();
|
227 |
+
|
228 |
+
// "last successful quote"
|
229 |
+
$quoteId = $this->_getQuote()->getId();
|
230 |
+
$session->setLastQuoteId($quoteId)
|
231 |
+
->setLastSuccessQuoteId($quoteId);
|
232 |
+
|
233 |
+
// an order may be created
|
234 |
+
$order = $this->_checkout->getOrder();
|
235 |
+
$this->invoiceOrder($order);
|
236 |
+
if ($order) {
|
237 |
+
$session->setLastOrderId($order->getId())
|
238 |
+
->setLastRealOrderId($order->getIncrementId());
|
239 |
+
}
|
240 |
+
|
241 |
+
// redirect if Payment specified some URL
|
242 |
+
$url = $this->_checkout->getRedirectUrl();
|
243 |
+
if ($url) {
|
244 |
+
$this->getResponse()->setRedirect($url);
|
245 |
+
return;
|
246 |
+
}
|
247 |
+
$this->_initToken(false); // no need in token anymore
|
248 |
+
return;
|
249 |
+
} catch (Mage_Core_Exception $e) {
|
250 |
+
Mage::helper('checkout')->sendPaymentFailedEmail($this->_getQuote(), $e->getMessage());
|
251 |
+
$this->_getSession()->addError($e->getMessage());
|
252 |
+
$this->_redirect('*/*/review');
|
253 |
+
} catch (Exception $e) {
|
254 |
+
Mage::helper('checkout')->sendPaymentFailedEmail(
|
255 |
+
$this->_getQuote(),
|
256 |
+
$this->__('Unable to place the order.')
|
257 |
+
);
|
258 |
+
$this->_getSession()->addError($this->__('Unable to place the order.'));
|
259 |
+
Mage::logException($e);
|
260 |
+
$this->_redirect('*/*/review');
|
261 |
+
}
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* Auto invoice for order
|
266 |
+
*
|
267 |
+
* @param $order Mage_Sales_Model_Order
|
268 |
+
*/
|
269 |
+
protected function invoiceOrder($order)
|
270 |
+
{
|
271 |
+
if ($order->getState() == Mage_Sales_Model_Order::STATE_NEW) {
|
272 |
+
try {
|
273 |
+
if (!$order->canInvoice()) {
|
274 |
+
$order->addStatusHistoryComment('Kash Gateway: Order cannot be auto invoiced.', false);
|
275 |
+
$order->save();
|
276 |
+
}
|
277 |
+
$invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice();
|
278 |
+
|
279 |
+
$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_OFFLINE);
|
280 |
+
$invoice->register();
|
281 |
+
|
282 |
+
$invoice->getOrder()->setCustomerNoteNotify(false);
|
283 |
+
$invoice->getOrder()->setIsInProcess(true);
|
284 |
+
$order->addStatusHistoryComment('Automatically INVOICED by Kash Gateway.', false);
|
285 |
+
|
286 |
+
$transactionSave = Mage::getModel('core/resource_transaction')
|
287 |
+
->addObject($invoice)
|
288 |
+
->addObject($invoice->getOrder());
|
289 |
+
|
290 |
+
$transactionSave->save();
|
291 |
+
} catch (Exception $e) {
|
292 |
+
$order->addStatusHistoryComment('Kash Gateway: Exception occurred during automatically Invoice action. Exception message: ' . $e->getMessage(), false);
|
293 |
+
$order->save();
|
294 |
+
}
|
295 |
+
|
296 |
+
}
|
297 |
+
}
|
298 |
+
|
299 |
+
/**
|
300 |
+
* Search for proper checkout token in request or session or (un)set specified one
|
301 |
+
* Combined getter/setter
|
302 |
+
*
|
303 |
+
* @param string $setToken
|
304 |
+
* @return $this|mixed|null|string
|
305 |
+
*/
|
306 |
+
protected function _initToken($setToken = null)
|
307 |
+
{
|
308 |
+
if (null !== $setToken) {
|
309 |
+
if (false === $setToken) {
|
310 |
+
// security measure for avoid unsetting token twice
|
311 |
+
if (!$this->_getSession()->getBBCheckoutToken()) {
|
312 |
+
Mage::throwException($this->__('Payment Kash Gateway Checkout Token does not exist.'));
|
313 |
+
}
|
314 |
+
$this->_getSession()->unsBBCheckoutToken();
|
315 |
+
} else {
|
316 |
+
$this->_getSession()->setBBCheckoutToken($setToken['x_reference']);
|
317 |
+
}
|
318 |
+
return $this;
|
319 |
+
}
|
320 |
+
if ($setToken = $this->getRequest()->getParam('x_reference')) {
|
321 |
+
if ($setToken !== $this->_getSession()->getBBCheckoutToken()) {
|
322 |
+
Mage::throwException($this->__('Wrong Payment Kash Gateway Checkout Token specified.'));
|
323 |
+
}
|
324 |
+
} else {
|
325 |
+
$setToken = $this->_getSession()->getBBCheckoutToken();
|
326 |
+
}
|
327 |
+
return $setToken;
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* Payment session instance getter
|
332 |
+
*
|
333 |
+
* @return Kash_Gateway_Model_Session
|
334 |
+
*/
|
335 |
+
protected function _getSession()
|
336 |
+
{
|
337 |
+
return Mage::getSingleton('kash_gateway/session');
|
338 |
+
}
|
339 |
+
|
340 |
+
/**
|
341 |
+
* Return checkout session object
|
342 |
+
*
|
343 |
+
* @return Mage_Checkout_Model_Session
|
344 |
+
*/
|
345 |
+
protected function _getCheckoutSession()
|
346 |
+
{
|
347 |
+
return Mage::getSingleton('checkout/session');
|
348 |
+
}
|
349 |
+
|
350 |
+
/**
|
351 |
+
* Return checkout quote object
|
352 |
+
*
|
353 |
+
* @return Mage_Sales_Model_Quote
|
354 |
+
*/
|
355 |
+
private function _getQuote()
|
356 |
+
{
|
357 |
+
if (!$this->_quote) {
|
358 |
+
$this->_quote = $this->_getCheckoutSession()->getQuote();
|
359 |
+
}
|
360 |
+
return $this->_quote;
|
361 |
+
}
|
362 |
+
|
363 |
+
/**
|
364 |
+
* Redirect to login page
|
365 |
+
*
|
366 |
+
*/
|
367 |
+
public function redirectLogin()
|
368 |
+
{
|
369 |
+
$this->setFlag('', 'no-dispatch', true);
|
370 |
+
$this->getResponse()->setRedirect(
|
371 |
+
Mage::helper('core/url')->addRequestParam(
|
372 |
+
Mage::helper('customer')->getLoginUrl(),
|
373 |
+
array('context' => 'checkout')
|
374 |
+
)
|
375 |
+
);
|
376 |
+
}
|
377 |
+
|
378 |
+
|
379 |
+
/**
|
380 |
+
* Instantiate quote and checkout
|
381 |
+
*
|
382 |
+
* @param bool $callback
|
383 |
+
* @return Kash_Gateway_Model_Checkout
|
384 |
+
* @throws Mage_Core_Exception
|
385 |
+
*/
|
386 |
+
protected function _initCheckout($callback = false)
|
387 |
+
{
|
388 |
+
$quote = $this->_getQuote();
|
389 |
+
if (!$callback && (!$quote->hasItems() || $quote->getHasError())) {
|
390 |
+
//$this->getResponse()->setHeader('HTTP/1.1', '403 Forbidden');
|
391 |
+
Mage::log(Mage::helper('kash_gateway')->__('Unable to initialize Kash Gateway Checkout.'));
|
392 |
+
return null;
|
393 |
+
}
|
394 |
+
$this->_config->setStoreId($this->_getQuote()->getStoreId());
|
395 |
+
$this->_checkout = Mage::getSingleton($this->_checkoutType, array(
|
396 |
+
'config' => $this->_config,
|
397 |
+
'quote' => $quote,
|
398 |
+
));
|
399 |
+
|
400 |
+
$params = Mage::app()->getRequest()->getParams();
|
401 |
+
$this->_checkout->setParams($params);
|
402 |
+
return $this->_checkout;
|
403 |
+
}
|
404 |
+
|
405 |
+
/**
|
406 |
+
* Make params for Payment BB
|
407 |
+
*/
|
408 |
+
protected function getPaymentRequest(){
|
409 |
+
$this->_initCheckout();
|
410 |
+
|
411 |
+
if ($this->_getQuote()->getIsMultiShipping()) {
|
412 |
+
$this->_getQuote()->setIsMultiShipping(false);
|
413 |
+
$this->_getQuote()->removeAllAddresses();
|
414 |
+
}
|
415 |
+
|
416 |
+
$customer = Mage::getSingleton('customer/session')->getCustomer();
|
417 |
+
$quoteCheckoutMethod = $this->_getQuote()->getCheckoutMethod();
|
418 |
+
if ($customer && $customer->getId()) {
|
419 |
+
$this->_checkout->setCustomerWithAddressChange(
|
420 |
+
$customer, $this->_getQuote()->getBillingAddress(), $this->_getQuote()->getShippingAddress()
|
421 |
+
);
|
422 |
+
} elseif ((!$quoteCheckoutMethod
|
423 |
+
|| $quoteCheckoutMethod != Mage_Checkout_Model_Type_Onepage::METHOD_REGISTER)
|
424 |
+
&& !Mage::helper('checkout')->isAllowedGuestCheckout(
|
425 |
+
$this->_getQuote(),
|
426 |
+
$this->_getQuote()->getStoreId()
|
427 |
+
)
|
428 |
+
) {
|
429 |
+
Mage::getSingleton('core/session')->addNotice(
|
430 |
+
Mage::helper('kash_gateway')->__('To proceed to Checkout, please log in using your email address.')
|
431 |
+
);
|
432 |
+
$this->redirectLogin();
|
433 |
+
Mage::getSingleton('customer/session')
|
434 |
+
->setBeforeAuthUrl(Mage::getUrl('*/*/*', array('_current' => true, '_secure'=>true)));
|
435 |
+
return null;
|
436 |
+
}
|
437 |
+
|
438 |
+
// giropay
|
439 |
+
$this->_checkout->prepareGiropayUrls(
|
440 |
+
Mage::getUrl('gateway/bb/callback', array('_secure'=>true)),
|
441 |
+
Mage::getUrl('gateway/bb/cancel', array('_secure'=>true)),
|
442 |
+
Mage::getUrl('gateway/bb/complete', array('_secure'=>true))
|
443 |
+
);
|
444 |
+
|
445 |
+
$params = $this->_checkout->start();
|
446 |
+
return $params;
|
447 |
+
}
|
448 |
+
}
|
app/code/local/Kash/Gateway/data/kash_gateway_setup/data-install-0.0.1.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/* @var $installer Mage_Core_Model_Resource_Setup */
|
4 |
+
$installer = $this;
|
5 |
+
|
6 |
+
$installer->startSetup();
|
7 |
+
|
8 |
+
|
9 |
+
|
10 |
+
$installer->endSetup();
|
app/code/local/Kash/Gateway/data/kash_gateway_setup/data-upgrade-0.0.1-0.0.2.php
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/* @var $installer Mage_Core_Model_Resource_Setup */
|
4 |
+
$installer = $this;
|
5 |
+
|
6 |
+
$installer->startSetup();
|
7 |
+
|
8 |
+
try{
|
9 |
+
$coupon = Mage::getModel('salesrule/coupon')->loadByCode(Kash_Gateway_Model_Config::GATEWAY_KASH_DISCOUNT_CODE);
|
10 |
+
if(!$coupon->isEmpty()){
|
11 |
+
$ruleCoupon = Mage::getModel('salesrule/rule')->load($coupon->getRuleId(), 'rule_id');
|
12 |
+
$ruleCoupon->delete();
|
13 |
+
$coupon->delete();
|
14 |
+
}
|
15 |
+
$ruleCoupon = Mage::getModel('salesrule/rule');
|
16 |
+
$ruleCoupon->setName('Discount for Payment BB')
|
17 |
+
->setDescription('this is a discount for payment bb')
|
18 |
+
->setFromDate(date('Y-m-d'))
|
19 |
+
->setCouponType(2)
|
20 |
+
->setCouponCode(Kash_Gateway_Model_Config::GATEWAY_KASH_DISCOUNT_CODE)
|
21 |
+
->setCustomerGroupIds(array(1))
|
22 |
+
->setIsActive(1)
|
23 |
+
->setStopRulesProcessing(0)
|
24 |
+
->setIsAdvanced(1)
|
25 |
+
->setProductIds('')
|
26 |
+
->setSortOrder(0)
|
27 |
+
->setSimpleAction('by_percent')
|
28 |
+
//->setDiscountAmount(100)
|
29 |
+
->setDiscountQty(null)
|
30 |
+
->setDiscountStep('0')
|
31 |
+
->setSimpleFreeShipping('0')
|
32 |
+
->setApplyToShipping('0')
|
33 |
+
->setIsRss(0)
|
34 |
+
->setWebsiteIds(array(1));
|
35 |
+
$ruleCoupon->save();
|
36 |
+
}catch (Exception $ex){
|
37 |
+
Mage::logException($ex);
|
38 |
+
}
|
39 |
+
|
40 |
+
$installer->endSetup();
|
app/code/local/Kash/Gateway/etc/config.xml
ADDED
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<Kash_Gateway>
|
5 |
+
<version>0.1.1</version>
|
6 |
+
</Kash_Gateway>
|
7 |
+
</modules>
|
8 |
+
<global>
|
9 |
+
<models>
|
10 |
+
<kash_gateway>
|
11 |
+
<class>Kash_Gateway_Model</class>
|
12 |
+
<resourceModel>kash_gateway_resource</resourceModel>
|
13 |
+
</kash_gateway>
|
14 |
+
<kash_gateway_resource>
|
15 |
+
<class>Kash_Gateway_Model_Resource</class>
|
16 |
+
</kash_gateway_resource>
|
17 |
+
</models>
|
18 |
+
<blocks>
|
19 |
+
<kash_gateway>
|
20 |
+
<class>Kash_Gateway_Block</class>
|
21 |
+
</kash_gateway>
|
22 |
+
<adminhtml>
|
23 |
+
<rewrite>
|
24 |
+
<sales_order_grid>Kash_Gateway_Block_Adminhtml_Sales_Order_Grid</sales_order_grid>
|
25 |
+
</rewrite>
|
26 |
+
</adminhtml>
|
27 |
+
</blocks>
|
28 |
+
<helpers>
|
29 |
+
<kash_gateway>
|
30 |
+
<class>Kash_Gateway_Helper</class>
|
31 |
+
</kash_gateway>
|
32 |
+
</helpers>
|
33 |
+
<resources>
|
34 |
+
<kash_gateway_setup>
|
35 |
+
<setup>
|
36 |
+
<module>Kash_Gateway</module>
|
37 |
+
</setup>
|
38 |
+
</kash_gateway_setup>
|
39 |
+
</resources>
|
40 |
+
<fieldsets>
|
41 |
+
<sales_convert_quote_payment>
|
42 |
+
<x_gateway_reference>
|
43 |
+
<to_order_payment>*</to_order_payment>
|
44 |
+
</x_gateway_reference>
|
45 |
+
</sales_convert_quote_payment>
|
46 |
+
</fieldsets>
|
47 |
+
</global>
|
48 |
+
|
49 |
+
<frontend>
|
50 |
+
<layout>
|
51 |
+
<updates>
|
52 |
+
<kash_gateway>
|
53 |
+
<file>kash/gateway.xml</file>
|
54 |
+
</kash_gateway>
|
55 |
+
</updates>
|
56 |
+
</layout>
|
57 |
+
</frontend>
|
58 |
+
|
59 |
+
<adminhtml>
|
60 |
+
<events>
|
61 |
+
<core_collection_abstract_load_before>
|
62 |
+
<observers>
|
63 |
+
<kash_gateway>
|
64 |
+
<type>model</type>
|
65 |
+
<class>kash_gateway/observer</class>
|
66 |
+
<method>coreCollectionAbstractLoadBefore</method>
|
67 |
+
</kash_gateway>
|
68 |
+
</observers>
|
69 |
+
</core_collection_abstract_load_before>
|
70 |
+
<payment_info_block_prepare_specific_information>
|
71 |
+
<observers>
|
72 |
+
<kash_gateway>
|
73 |
+
<type>model</type>
|
74 |
+
<class>kash_gateway/observer</class>
|
75 |
+
<method>paymentInfoBlockPrepareSpecificInformation</method>
|
76 |
+
</kash_gateway>
|
77 |
+
</observers>
|
78 |
+
</payment_info_block_prepare_specific_information>
|
79 |
+
</events>
|
80 |
+
</adminhtml>
|
81 |
+
|
82 |
+
<default>
|
83 |
+
<payment>
|
84 |
+
<kash_gateway>
|
85 |
+
<active>0</active>
|
86 |
+
<bbtypes>AE,VI,MC,DI</bbtypes>
|
87 |
+
<model>kash_gateway/method_bb</model>
|
88 |
+
<order_status>processing</order_status>
|
89 |
+
<title>Direct Debit or Credit Card</title>
|
90 |
+
<post_url>https://gateway.withkash.com/</post_url>
|
91 |
+
<skip_order_review_step>0</skip_order_review_step>
|
92 |
+
<allowspecific>0</allowspecific>
|
93 |
+
</kash_gateway>
|
94 |
+
</payment>
|
95 |
+
</default>
|
96 |
+
|
97 |
+
<frontend>
|
98 |
+
<routers>
|
99 |
+
<kash_gateway>
|
100 |
+
<use>standard</use>
|
101 |
+
<args>
|
102 |
+
<module>Kash_Gateway</module>
|
103 |
+
<frontName>gateway</frontName>
|
104 |
+
</args>
|
105 |
+
</kash_gateway>
|
106 |
+
</routers>
|
107 |
+
<events>
|
108 |
+
<sales_quote_collect_totals_before>
|
109 |
+
<observers>
|
110 |
+
<kash_gateway>
|
111 |
+
<type>model</type>
|
112 |
+
<class>kash_gateway/observer</class>
|
113 |
+
<method>salesQuoteCollectTotalsBefore</method>
|
114 |
+
</kash_gateway>
|
115 |
+
</observers>
|
116 |
+
</sales_quote_collect_totals_before>
|
117 |
+
</events>
|
118 |
+
</frontend>
|
119 |
+
</config>
|
app/code/local/Kash/Gateway/etc/system.xml
ADDED
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<sections>
|
4 |
+
<payment>
|
5 |
+
<groups>
|
6 |
+
<kash_gateway translate="label">
|
7 |
+
<label>Kash Gateway</label>
|
8 |
+
<frontend_type>text</frontend_type>
|
9 |
+
<sort_order>30</sort_order>
|
10 |
+
<show_in_default>1</show_in_default>
|
11 |
+
<show_in_website>1</show_in_website>
|
12 |
+
<show_in_store>1</show_in_store>
|
13 |
+
<fields>
|
14 |
+
<active translate="label">
|
15 |
+
<label>Enabled</label>
|
16 |
+
<frontend_type>select</frontend_type>
|
17 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
18 |
+
<sort_order>1</sort_order>
|
19 |
+
<show_in_default>1</show_in_default>
|
20 |
+
<show_in_website>1</show_in_website>
|
21 |
+
<show_in_store>0</show_in_store>
|
22 |
+
</active>
|
23 |
+
<title translate="label">
|
24 |
+
<label>Title</label>
|
25 |
+
<frontend_type>text</frontend_type>
|
26 |
+
<sort_order>10</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 |
+
<comment>This controls the title that the user sees during checkout</comment>
|
31 |
+
</title>
|
32 |
+
<x_shop_name translate="label">
|
33 |
+
<label>Shop Name</label>
|
34 |
+
<frontend_type>text</frontend_type>
|
35 |
+
<sort_order>10</sort_order>
|
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 |
+
<frontend_class>required-entry</frontend_class>
|
40 |
+
</x_shop_name>
|
41 |
+
<x_account_id translate="label">
|
42 |
+
<label>Kash Account ID</label>
|
43 |
+
<frontend_type>text</frontend_type>
|
44 |
+
<frontend_class>required-entry</frontend_class>
|
45 |
+
<sort_order>11</sort_order>
|
46 |
+
<show_in_default>1</show_in_default>
|
47 |
+
<show_in_website>1</show_in_website>
|
48 |
+
<show_in_store>1</show_in_store>
|
49 |
+
<comment>This is the account ID you get from your Kash account</comment>
|
50 |
+
</x_account_id>
|
51 |
+
<server_key translate="label">
|
52 |
+
<label>Kash Server Key</label>
|
53 |
+
<frontend_type>text</frontend_type>
|
54 |
+
<frontend_class>required-entry</frontend_class>
|
55 |
+
<sort_order>12</sort_order>
|
56 |
+
<show_in_default>1</show_in_default>
|
57 |
+
<show_in_website>1</show_in_website>
|
58 |
+
<show_in_store>1</show_in_store>
|
59 |
+
<comment>This is the server key you get from your Kash account</comment>
|
60 |
+
</server_key>
|
61 |
+
<post_url translate="label">
|
62 |
+
<label>Gateway URL</label>
|
63 |
+
<frontend_type>text</frontend_type>
|
64 |
+
<frontend_class>required-entry</frontend_class>
|
65 |
+
<sort_order>14</sort_order>
|
66 |
+
<show_in_default>1</show_in_default>
|
67 |
+
<show_in_website>1</show_in_website>
|
68 |
+
<show_in_store>1</show_in_store>
|
69 |
+
<comment>Add a payment gateway with "Redirect URL" of https://offsite-gateway-sim.herokuapp.com/</comment>
|
70 |
+
</post_url>
|
71 |
+
<skip_order_review_step translate="label comment">
|
72 |
+
<label>Order Review Step</label>
|
73 |
+
<config_path>payment/kash_gateway/skip_order_review_step</config_path>
|
74 |
+
<frontend_type>select</frontend_type>
|
75 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
76 |
+
<sort_order>25</sort_order>
|
77 |
+
<show_in_default>1</show_in_default>
|
78 |
+
<show_in_website>1</show_in_website>
|
79 |
+
<show_in_store>1</show_in_store>
|
80 |
+
<shared>1</shared>
|
81 |
+
</skip_order_review_step>
|
82 |
+
<min_order_total translate="label">
|
83 |
+
<label>Minimum Order Total</label>
|
84 |
+
<frontend_type>text</frontend_type>
|
85 |
+
<sort_order>98</sort_order>
|
86 |
+
<show_in_default>1</show_in_default>
|
87 |
+
<show_in_website>1</show_in_website>
|
88 |
+
<show_in_store>1</show_in_store>
|
89 |
+
</min_order_total>
|
90 |
+
<max_order_total translate="label">
|
91 |
+
<label>Maximum Order Total</label>
|
92 |
+
<frontend_type>text</frontend_type>
|
93 |
+
<sort_order>99</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 |
+
</max_order_total>
|
98 |
+
<sort_order translate="label">
|
99 |
+
<label>Sort Order</label>
|
100 |
+
<frontend_type>text</frontend_type>
|
101 |
+
<sort_order>100</sort_order>
|
102 |
+
<show_in_default>1</show_in_default>
|
103 |
+
<show_in_website>1</show_in_website>
|
104 |
+
<show_in_store>1</show_in_store>
|
105 |
+
<frontend_class>validate-number</frontend_class>
|
106 |
+
</sort_order>
|
107 |
+
<model>
|
108 |
+
</model>
|
109 |
+
</fields>
|
110 |
+
</kash_gateway>
|
111 |
+
</groups>
|
112 |
+
</payment>
|
113 |
+
</sections>
|
114 |
+
</config>
|
app/code/local/Kash/Gateway/sql/kash_gateway_setup/install-0.0.1.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/* @var $installer Mage_Core_Model_Resource_Setup */
|
4 |
+
$installer = $this;
|
5 |
+
|
6 |
+
$installer->startSetup();
|
7 |
+
|
8 |
+
$installer->getConnection()
|
9 |
+
->addColumn($installer->getTable('sales/quote_payment'), 'x_gateway_reference', array(
|
10 |
+
'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
|
11 |
+
'comment' => 'Gateway Reference',
|
12 |
+
'length' => '255'
|
13 |
+
));
|
14 |
+
|
15 |
+
$installer->getConnection()
|
16 |
+
->addColumn($installer->getTable('sales/order_payment'), 'x_gateway_reference', array(
|
17 |
+
'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
|
18 |
+
'comment' => 'Gateway Reference',
|
19 |
+
'length' => '255'
|
20 |
+
));
|
21 |
+
|
22 |
+
$installer->endSetup();
|
app/design/adminhtml/default/default/template/kash/info/default.phtml
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @see Kash_Gateway_Block_Adminhtml_Info
|
4 |
+
*/
|
5 |
+
?>
|
6 |
+
<?php echo $this->escapeHtml($this->getMethod()->getTitle()) ?>
|
7 |
+
|
8 |
+
|
9 |
+
<table>
|
10 |
+
<?php if ($_specificInfo = $this->getAdditionalInformation()): ?>
|
11 |
+
<?php foreach ($_specificInfo as $_label => $_value): ?>
|
12 |
+
<tr>
|
13 |
+
<td><?php echo $this->escapeHtml($_label) ?>:</td>
|
14 |
+
<td><?php echo nl2br(implode($this->getValueAsArray($_value, true), "\n")) ?></td>
|
15 |
+
</tr>
|
16 |
+
<?php endforeach; ?>
|
17 |
+
<?php endif; ?>
|
18 |
+
|
19 |
+
<?php if ($_specificInfo = $this->getSpecificInformation()): ?>
|
20 |
+
<?php foreach ($_specificInfo as $_label => $_value): ?>
|
21 |
+
<tr>
|
22 |
+
<td><?php echo $this->escapeHtml($_label) ?>:</td>
|
23 |
+
<td><?php echo nl2br(implode($this->getValueAsArray($_value, true), "\n")) ?></td>
|
24 |
+
</tr>
|
25 |
+
<?php endforeach; ?>
|
26 |
+
<?php endif; ?>
|
27 |
+
</table>
|
28 |
+
|
29 |
+
|
30 |
+
<?php echo $this->getChildHtml() ?>
|
app/design/frontend/base/default/layout/kash/gateway.xml
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<layout version="0.1.0">
|
3 |
+
<default>
|
4 |
+
<reference name="before_body_end">
|
5 |
+
<block type="core/template" template="kash/js.phtml" before="-"/>
|
6 |
+
</reference>
|
7 |
+
</default>
|
8 |
+
|
9 |
+
<kash_gateway_bb_start>
|
10 |
+
<remove name="before_body_end"/>
|
11 |
+
<reference name="head">
|
12 |
+
<action method="addJs">
|
13 |
+
<script>lib/jquery/jquery-1.10.2.min.js</script>
|
14 |
+
</action>
|
15 |
+
<action method="addCss"><stylesheet>css/kash/start.css</stylesheet></action>
|
16 |
+
</reference>
|
17 |
+
<reference name="root">
|
18 |
+
<action method="setTemplate">
|
19 |
+
<template>page/empty.phtml</template>
|
20 |
+
</action>
|
21 |
+
<reference name="content">
|
22 |
+
<block type="core/template" name="block_form_request" as="block.form.request"
|
23 |
+
template="kash/form.phtml"/>
|
24 |
+
<block type="core/template" name="container_form" as="container_form"
|
25 |
+
template="kash/container.phtml"/>
|
26 |
+
</reference>
|
27 |
+
</reference>
|
28 |
+
</kash_gateway_bb_start>
|
29 |
+
|
30 |
+
<kash_gateway_bb_review>
|
31 |
+
<remove name="right"/>
|
32 |
+
<remove name="left"/>
|
33 |
+
|
34 |
+
<reference name="root">
|
35 |
+
<action method="setTemplate">
|
36 |
+
<template>page/1column.phtml</template>
|
37 |
+
</action>
|
38 |
+
</reference>
|
39 |
+
<reference name="content">
|
40 |
+
<!--<block type="checkout/onepage_success" name="checkout.success" template="checkout/success.phtml"/>-->
|
41 |
+
<block type="kash_gateway/review" name="gateway.kash.review" template="kash/payment/review.phtml">
|
42 |
+
<block type="kash_gateway/review_details" name="gateway.kash.review.details" as="details"
|
43 |
+
template="kash/payment/review/details.phtml">
|
44 |
+
<action method="addItemRender">
|
45 |
+
<type>default</type>
|
46 |
+
<block>checkout/cart_item_renderer</block>
|
47 |
+
<template>checkout/onepage/review/item.phtml</template>
|
48 |
+
</action>
|
49 |
+
<action method="addItemRender">
|
50 |
+
<type>grouped</type>
|
51 |
+
<block>checkout/cart_item_renderer_grouped</block>
|
52 |
+
<template>checkout/onepage/review/item.phtml</template>
|
53 |
+
</action>
|
54 |
+
<action method="addItemRender">
|
55 |
+
<type>configurable</type>
|
56 |
+
<block>checkout/cart_item_renderer_configurable</block>
|
57 |
+
<template>checkout/onepage/review/item.phtml</template>
|
58 |
+
</action>
|
59 |
+
<block type="checkout/cart_totals" name="gateway.kash.review.details.totals" as="totals"
|
60 |
+
template="checkout/onepage/review/totals.phtml"/>
|
61 |
+
</block>
|
62 |
+
</block>
|
63 |
+
</reference>
|
64 |
+
<reference name="head">
|
65 |
+
<action method="addItem">
|
66 |
+
<type>skin_js</type>
|
67 |
+
<name>js/checkout/review.js</name>
|
68 |
+
</action>
|
69 |
+
</reference>
|
70 |
+
<block type="core/text_list" name="additional.product.info"/>
|
71 |
+
</kash_gateway_bb_review>
|
72 |
+
</layout>
|
app/design/frontend/base/default/template/kash/container.phtml
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script type="text/javascript">
|
2 |
+
jQuery(document).ready(function() {
|
3 |
+
jQuery("#request-gateway-kash").trigger('submit');
|
4 |
+
});
|
5 |
+
</script>
|
app/design/frontend/base/default/template/kash/form.phtml
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$input = $this->getInput();
|
3 |
+
$action = $this->getPostUrl();
|
4 |
+
?>
|
5 |
+
|
6 |
+
<form id="request-gateway-kash" name="request-gateway-kash" action="<?php echo $action ?>" method="post">
|
7 |
+
<div>
|
8 |
+
<?php foreach($input as $key => $value): ?>
|
9 |
+
<input type="hidden" name="<?php echo $key; ?>" value="<?php echo $value; ?>"/>
|
10 |
+
<?php endforeach; ?>
|
11 |
+
</div>
|
12 |
+
</form>
|
13 |
+
|
app/design/frontend/base/default/template/kash/js.phtml
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$_methodCode = Kash_Gateway_Model_Config::METHOD_GATEWAY_KASH;
|
3 |
+
$_urlRequest = Mage::getUrl(Kash_Gateway_Model_Config::REQUEST_GATEWAY_KASH, array('_secure'=>true));
|
4 |
+
?>
|
5 |
+
<div id="form-element" style="display: none"></div>
|
6 |
+
|
7 |
+
<script type="text/javascript">
|
8 |
+
//<![CDATA[
|
9 |
+
Payment.addMethods({
|
10 |
+
save: function () {
|
11 |
+
if (checkout.loadWaiting != false) return;
|
12 |
+
var validator = new Validation(this.form);
|
13 |
+
if (this.validate() && validator.validate()) {
|
14 |
+
checkout.setLoadWaiting('payment');
|
15 |
+
if (this.currentMethod == '<?php echo $_methodCode ?>') {
|
16 |
+
new Ajax.Request(
|
17 |
+
payment.saveUrl,
|
18 |
+
{
|
19 |
+
asynchronous: true,
|
20 |
+
method: 'post',
|
21 |
+
onSuccess: function (response) {
|
22 |
+
new Ajax.Request(
|
23 |
+
'<?php echo $_urlRequest ?>',
|
24 |
+
{
|
25 |
+
asynchronous: true,
|
26 |
+
method: 'post',
|
27 |
+
onSuccess: function (response) {
|
28 |
+
$('form-element').insert(response.responseText);
|
29 |
+
jQuery("#request-gateway-kash").trigger('submit');
|
30 |
+
},
|
31 |
+
onFailure: checkout.ajaxFailure.bind(checkout),
|
32 |
+
parameters: Form.serialize(payment.form)
|
33 |
+
}
|
34 |
+
);
|
35 |
+
},
|
36 |
+
onFailure: checkout.ajaxFailure.bind(checkout),
|
37 |
+
parameters: Form.serialize(this.form)
|
38 |
+
});
|
39 |
+
} else {
|
40 |
+
var request = new Ajax.Request(
|
41 |
+
this.saveUrl,
|
42 |
+
{
|
43 |
+
asynchronous: true,
|
44 |
+
method: 'post',
|
45 |
+
onComplete: this.onComplete,
|
46 |
+
onSuccess: this.onSave,
|
47 |
+
onFailure: checkout.ajaxFailure.bind(checkout),
|
48 |
+
parameters: Form.serialize(this.form)
|
49 |
+
}
|
50 |
+
);
|
51 |
+
}
|
52 |
+
}
|
53 |
+
}
|
54 |
+
});
|
55 |
+
//]]>
|
56 |
+
</script>
|
app/design/frontend/base/default/template/kash/payment/mark.phtml
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @see Kash_Gateway_Block_Form_Bb
|
4 |
+
*/
|
5 |
+
?>
|
6 |
+
<?php echo $this->getMessage() ?>
|
7 |
+
|
app/design/frontend/base/default/template/kash/payment/redirect.phtml
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @see Kash_Gateway_Block_Form_Bb
|
4 |
+
*/
|
5 |
+
?>
|
6 |
+
<ul class="form-list" id="payment_form_<?php echo $this->getMethodCode() ?>">
|
7 |
+
<li class="form-alt"><?php echo $this->getRedirectMessage() ?></li>
|
8 |
+
</ul>
|
app/design/frontend/base/default/template/kash/payment/review.phtml
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/** @var Kash_Gateway_Block_Review */
|
3 |
+
?>
|
4 |
+
<div class="page-title">
|
5 |
+
<h1><?php echo $this->__('Complete Order') ?></h1>
|
6 |
+
</div>
|
7 |
+
<?php echo $this->getMessagesBlock()->toHtml() ?>
|
8 |
+
<?php if ($this->getShippingAddress()): ?>
|
9 |
+
<div class="info-set col2-set">
|
10 |
+
<div class="col-1">
|
11 |
+
<div class="box">
|
12 |
+
<div class="box-title">
|
13 |
+
<h3><?php echo $this->__('Shipping Address') ?><span class="separator"><?php if ($this->getCanEditShippingAddress()):?> | </span><a href="<?php echo $this->getEditUrl() ?>"><?php echo $this->__('Edit') ?></a><?php endif;?></h3>
|
14 |
+
</div>
|
15 |
+
<div class="box-content">
|
16 |
+
<address><?php echo $this->renderAddress($this->getShippingAddress())?></address>
|
17 |
+
</div>
|
18 |
+
</div>
|
19 |
+
</div>
|
20 |
+
<div class="col-2">
|
21 |
+
<div class="box">
|
22 |
+
<div class="box-title">
|
23 |
+
<h3><?php echo $this->__('Shipping Method') ?></h3>
|
24 |
+
</div>
|
25 |
+
<div class="box-content">
|
26 |
+
<?php if ($this->getCanEditShippingMethod() || !$this->getCurrentShippingRate()):?>
|
27 |
+
<?php if ($groups = $this->getShippingRateGroups()):?>
|
28 |
+
<?php $currentRate = $this->getCurrentShippingRate(); ?>
|
29 |
+
<fieldset>
|
30 |
+
<select name="shipping_method" id="shipping_method" style="width:250px;" class="required-entry">
|
31 |
+
<?php if (!$currentRate):?>
|
32 |
+
<option value=""><?php echo $this->__('Please select a shipping method...') ?></option>
|
33 |
+
<?php endif;?>
|
34 |
+
<?php foreach ($groups as $code => $rates):?>
|
35 |
+
<optgroup label="<?php echo $this->escapeHtml($this->getCarrierName($code)) ?>" style="font-style:normal;">
|
36 |
+
<?php foreach ($rates as $rate):?>
|
37 |
+
<option value="<?php echo $this->renderShippingRateValue($rate)?>"<?php echo ($currentRate === $rate) ? ' selected="selected"' : '' ;?>>
|
38 |
+
<?php echo $this->renderShippingRateOption($rate)?>
|
39 |
+
</option>
|
40 |
+
<?php endforeach;?>
|
41 |
+
</optgroup>
|
42 |
+
<?php endforeach;?>
|
43 |
+
</select>
|
44 |
+
</fieldset>
|
45 |
+
<?php endif;?>
|
46 |
+
<?php else: ?>
|
47 |
+
<p><strong><?php echo $this->renderShippingRateOption($this->getCurrentShippingRate())?></strong></p>
|
48 |
+
<?php endif; ?>
|
49 |
+
</div>
|
50 |
+
</div>
|
51 |
+
</div>
|
52 |
+
</div>
|
53 |
+
<?php endif; ?>
|
54 |
+
|
55 |
+
|
56 |
+
<div class="info-set">
|
57 |
+
<div id="details-reload">
|
58 |
+
<?php echo $this->getChildHtml('details') ?>
|
59 |
+
</div>
|
60 |
+
</div>
|
61 |
+
|
62 |
+
<div class="buttons-set buttons-set-order" id="review-buttons-container">
|
63 |
+
<button type="button" id="review_button" onclick="window.location.href='<?php echo Mage::getUrl('checkout/onepage/success'); ?>'" value="<?php echo $this->__('Close') ?>" class="button btn-checkout"><span><span><?php echo $this->__('Close') ?></span></span></button>
|
64 |
+
</div>
|
65 |
+
|
app/design/frontend/base/default/template/kash/payment/review/details.phtml
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @see Kash_Gateway_Block_Review_Details
|
4 |
+
*/
|
5 |
+
?>
|
6 |
+
<table id="details-table" class="data-table linearize-table">
|
7 |
+
<?php if ($this->helper('tax')->displayCartBothPrices()): $colspan = $rowspan = 2; else: $colspan = $rowspan = 1; endif; ?>
|
8 |
+
<col />
|
9 |
+
<col width="1" />
|
10 |
+
<col width="1" />
|
11 |
+
<col width="1" />
|
12 |
+
<?php if ($this->helper('tax')->displayCartBothPrices()): ?>
|
13 |
+
<col width="1" />
|
14 |
+
<col width="1" />
|
15 |
+
<?php endif; ?>
|
16 |
+
<thead>
|
17 |
+
<tr>
|
18 |
+
<th rowspan="<?php echo $rowspan ?>"><?php echo $this->__('Product') ?></th>
|
19 |
+
<th colspan="<?php echo $colspan ?>" class="a-center"><?php echo $this->__('Price') ?></th>
|
20 |
+
<th rowspan="<?php echo $rowspan ?>" class="a-center"><?php echo $this->__('Qty') ?></th>
|
21 |
+
<th colspan="<?php echo $colspan ?>" class="a-center"><?php echo $this->__('Subtotal') ?></th>
|
22 |
+
</tr>
|
23 |
+
<?php if ($this->helper('tax')->displayCartBothPrices()): ?>
|
24 |
+
<tr>
|
25 |
+
<th class="a-right"><?php echo $this->helper('tax')->getIncExcTaxLabel(false) ?></th>
|
26 |
+
<th><?php echo $this->helper('tax')->getIncExcTaxLabel(true) ?></th>
|
27 |
+
<th class="a-right"><?php echo $this->helper('tax')->getIncExcTaxLabel(false) ?></th>
|
28 |
+
<th><?php echo $this->helper('tax')->getIncExcTaxLabel(true) ?></th>
|
29 |
+
</tr>
|
30 |
+
<?php endif; ?>
|
31 |
+
</thead>
|
32 |
+
<?php echo $this->getChildHtml('totals'); ?>
|
33 |
+
<tbody>
|
34 |
+
<?php foreach($this->getItems() as $_item): ?>
|
35 |
+
<?php echo $this->getItemHtml($_item) ?>
|
36 |
+
<?php endforeach ?>
|
37 |
+
</tbody>
|
38 |
+
</table>
|
39 |
+
<script type="text/javascript">decorateTable('details-table');</script>
|
app/etc/modules/Kash_Gateway.xml
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<Kash_Gateway>
|
5 |
+
<active>true</active>
|
6 |
+
<codePool>local</codePool>
|
7 |
+
<depends>
|
8 |
+
<Mage_Payment/>
|
9 |
+
</depends>
|
10 |
+
</Kash_Gateway>
|
11 |
+
</modules>
|
12 |
+
</config>
|
package.xml
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<package>
|
3 |
+
<name>kash_gateway</name>
|
4 |
+
<version>0.1.1</version>
|
5 |
+
<stability>stable</stability>
|
6 |
+
<license>MITL</license>
|
7 |
+
<channel>community</channel>
|
8 |
+
<extends/>
|
9 |
+
<summary>Payment gateway that allows customers in the US to make payment via Direct Debit or Credit Card for just 0.5%.</summary>
|
10 |
+
<description>Kash (http://www.withkash.com) allows you to accept payments for just 0.5%!
|
11 |
+

|
12 |
+
Kash does this by offering customers the option to pay using their bank account. For customers that don't want to use their bank account to pay, they'll have the option of using credit card instead. You can choose to either charge the credit card processing fee to the customer, or pay for the fee yourself like you do currently.
|
13 |
+

|
14 |
+
You will need a Kash account in order to use this gateway. Please contact info@withkash.com for any questions.</description>
|
15 |
+
<notes>v0.1.1 - Initial Release</notes>
|
16 |
+
<authors><author><name>Kash Corp.</name><user>withkash</user><email>info@withkash.com</email></author></authors>
|
17 |
+
<date>2015-11-04</date>
|
18 |
+
<time>06:56:24</time>
|
19 |
+
<contents><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="css"><dir name="kash"><file name="start.css" hash="d310d178769035d366ebb2caff9bd4a3"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Kash_Gateway.xml" hash="03365c54da611a023ea2a12c6404c455"/></dir></target><target name="magelocal"><dir name="Kash"><dir><dir name="Gateway"><dir name="Block"><dir name="Adminhtml"><file name="Info.php" hash="186ac575a69755543d649d2174f43474"/><dir name="Sales"><dir name="Order"><file name="Grid.php" hash="757f5028ff98d3c375cf3345675d55b7"/></dir></dir></dir><dir name="Form"><file name="Bb.php" hash="2516cb64469800cfc450710250317d72"/></dir><dir name="Review"><file name="Details.php" hash="9a077c6688f913bd4f9fee74fad68b7e"/></dir><file name="Review.php" hash="a2a24914d577262188c491898c77307e"/></dir><dir name="Helper"><file name="Checkout.php" hash="89863d74391a81e7336073a8c9634ce8"/><file name="Data.php" hash="cc0eb77c1be47e1d4e846033cc2aed9a"/></dir><dir name="Model"><dir name="Api"><file name="Abstract.php" hash="99ed019c3e8e13caf90fa248e608c9ea"/><file name="Bb.php" hash="f1605310d4042b4704577fe2925c2a86"/></dir><file name="Cart.php" hash="ced06fca31abf3fbe20e3e2eb430cfea"/><file name="Checkout.php" hash="cad380737617bc30c2d067d9f42a7b36"/><file name="Config.php" hash="5299275ecc589f56c9bc9c9123e39405"/><dir name="Method"><file name="Bb.php" hash="6cd0683fa597d31d830ae7787b0284cd"/></dir><file name="Observer.php" hash="d7b27c64189811ac66d82cf6dd3841ff"/><file name="Session.php" hash="1778fbe493d2ceb81d8a20b58a21ce3c"/></dir><dir name="controllers"><file name="BbController.php" hash="6349cf80569789e5cedb77370063046e"/></dir><dir name="data"><dir name="kash_gateway_setup"><file name="data-install-0.0.1.php" hash="5fe91e15bc5e6269eadcc50f8991250a"/><file name="data-upgrade-0.0.1-0.0.2.php" hash="632331f77e2238438e1bddfe4c2b82bf"/></dir></dir><dir name="etc"><file name="config.xml" hash="3b9b94e4fdbd9364d0c24fe7306104d5"/><file name="system.xml" hash="6c4da7f0fd0f07f0577fa1aeb0abee25"/></dir><dir name="sql"><dir name="kash_gateway_setup"><file name="install-0.0.1.php" hash="9ecb52ba48345cdbee9ce0fd92d2aff9"/></dir></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="kash"><dir name="info"><file name="default.phtml" hash="79bcf1003e40c03ec35c383ec4ca5236"/></dir></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="kash"><file name="container.phtml" hash="9dafeab90d16b221ab8684990ef62ec3"/><file name="form.phtml" hash="0b4b05f427474b08d1c52cfc09fc3485"/><file name="js.phtml" hash="3a1b1a96fd25b4035f41dbe95633f229"/><dir><dir name="payment"><file name="mark.phtml" hash="01fa231a78eab8c435d6ea2ad508ef56"/><file name="redirect.phtml" hash="9cd530bec26cc5f76ab01cfb57095c32"/><dir name="review"><file name="details.phtml" hash="ff2ad65893e66920a4cc8b098dc397c1"/></dir><file name="review.phtml" hash="ef1d435a2bc0e9daff56594a715bed1a"/></dir></dir></dir></dir><dir name="layout"><dir name="kash"><file name="gateway.xml" hash="21bd19c6bc5830b2998afcc1bb1e1f27"/></dir></dir></dir></dir></dir></target></contents>
|
20 |
+
<compatible/>
|
21 |
+
<dependencies><required><php><min>5.4.45</min><max>5.6.15</max></php></required></dependencies>
|
22 |
+
</package>
|
skin/frontend/base/default/css/kash/start.css
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
.kash-gateway-bb-start {
|
2 |
+
background-color: rgba(0, 0, 0, 0.87);
|
3 |
+
}
|