myPOS_Virtual - Version 1.0.0

Version Notes

myPOS Virtual for shopping cart is an effective and secure way for accepting card payments on your website. Just install the plugin and let your customers pay for your goods and services easily and secure using their Debit/Credit card. You will also need to register for myPOS account at www.mypos.eu.

Download this release

Release Info

Developer iPay International S.A.
Extension myPOS_Virtual
Version 1.0.0
Comparing to
See all releases


Version 1.0.0

app/code/community/Mypos/Virtual/Helper/Data.php ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Mypos_Virtual_Helper_Data extends Mage_Core_Helper_Abstract
3
+ {
4
+ public $privateKey;
5
+ public $publicKey;
6
+ public $isTest;
7
+ public $formUrl;
8
+ public $sid;
9
+ public $walletNumber;
10
+ public $ipcVersion;
11
+ public $keyindex;
12
+
13
+ public function __construct()
14
+ {
15
+ $this->isTest = boolval(Mage::getStoreConfig('payment/mypos_virtual/test'));
16
+ $this->ipcVersion = '1.0';
17
+
18
+ if ($this->isTest)
19
+ {
20
+ $this->sid = Mage::getStoreConfig('payment/mypos_virtual/developer_sid');
21
+ $this->walletNumber = Mage::getStoreConfig('payment/mypos_virtual/developer_wallet_number');
22
+ $this->privateKey = Mage::getStoreConfig('payment/mypos_virtual/developer_store_private_key');
23
+ $this->publicKey = Mage::getStoreConfig('payment/mypos_virtual/developer_ipc_public_certificate');
24
+ $this->formUrl = Mage::getStoreConfig('payment/mypos_virtual/developer_url');
25
+ $this->privateKey = Mage::getStoreConfig('payment/mypos_virtual/developer_store_private_key');
26
+ $this->publicKey = Mage::getStoreConfig('payment/mypos_virtual/developer_ipc_public_certificate');
27
+ $this->keyindex = Mage::getStoreConfig('payment/mypos_virtual/developer_keyindex');
28
+ }
29
+ else
30
+ {
31
+ $this->sid = Mage::getStoreConfig('payment/mypos_virtual/production_sid');
32
+ $this->walletNumber = Mage::getStoreConfig('payment/mypos_virtual/production_wallet_number');
33
+ $this->privateKey = Mage::getStoreConfig('payment/mypos_virtual/production_store_private_key');
34
+ $this->publicKey = Mage::getStoreConfig('payment/mypos_virtual/production_ipc_public_certificate');
35
+ $this->formUrl = Mage::getStoreConfig('payment/mypos_virtual/production_url');
36
+ $this->privateKey = Mage::getStoreConfig('payment/mypos_virtual/production_store_private_key');
37
+ $this->publicKey = Mage::getStoreConfig('payment/mypos_virtual/production_ipc_public_certificate');
38
+ $this->keyindex = Mage::getStoreConfig('payment/mypos_virtual/production_keyindex');
39
+ }
40
+ }
41
+
42
+ public function getFormUrl()
43
+ {
44
+ return $this->formUrl;
45
+ }
46
+
47
+ public function getOrderOKUrl()
48
+ {
49
+ return Mage::getUrl('mypos_virtual/payment/success', array('_secure' => true));
50
+ }
51
+
52
+ public function getOrderCancelUrl()
53
+ {
54
+ return Mage::getUrl('mypos_virtual/payment/cancel', array('_secure' => true));
55
+ }
56
+
57
+ public function getOrderNotifyUrl()
58
+ {
59
+ return Mage::getUrl('mypos_virtual/payment/notify', array('_secure' => true));
60
+ }
61
+
62
+ public function getPost(Mage_Sales_Model_Order $_order)
63
+ {
64
+ $billing_address = $_order->getBillingAddress();
65
+ $items = $_order->getItemsCollection(array(), true);
66
+
67
+ $post = array();
68
+ $post['IPCmethod'] = 'IPCPurchase';
69
+ $post['IPCVersion'] = $this->ipcVersion;
70
+ $post['IPCLanguage'] = 'en';
71
+ $post['WalletNumber'] = $this->walletNumber;
72
+ $post['SID'] = $this->sid;
73
+ $post['keyindex'] = $this->keyindex;
74
+ $post['Source'] = 'sc_magento';
75
+
76
+ $post['Amount'] = number_format($_order->getBaseGrandTotal(), 2);
77
+ $post['Currency'] = $_order->getBaseCurrency()->getCode();
78
+ $post['OrderID'] = $_order->getRealOrderId();
79
+ $post['URL_OK'] = $this->getOrderOKUrl();
80
+ $post['URL_CANCEL'] = $this->getOrderCancelUrl();
81
+ $post['URL_Notify'] = $this->getOrderNotifyUrl();
82
+ $post['CustomerIP'] = $_SERVER['REMOTE_ADDR'];
83
+ $post['CustomerEmail'] = $_order->getCustomerEmail();
84
+ $post['CustomerFirstNames'] = $_order->getCustomerFirstname();
85
+ $post['CustomerFamilyName'] = $_order->getCustomerLastname();
86
+ $post['CustomerCountry'] = $billing_address->getCountryModel()->getIso3Code();
87
+ $post['CustomerCity'] = $billing_address->getCity();
88
+ $post['CustomerZIPCode'] = $billing_address->getPostcode();
89
+ $post['CustomerAddress'] = $billing_address->getStreetFull();
90
+ $post['CustomerPhone'] = $billing_address->getTelephone();
91
+ $post['Note'] = 'Mypos Virtual Checkout Magento Extension';
92
+ $post['CartItems'] = $_order->getTotalItemCount() + 1;
93
+
94
+ $index = 1;
95
+ /**
96
+ * @var Mage_Sales_Model_Order_Item $item
97
+ */
98
+ foreach($items as $item)
99
+ {
100
+ $post['Article_' . $index] = html_entity_decode(strip_tags($item->getName()));
101
+ $post['Quantity_' . $index] = number_format($item->getQtyOrdered());
102
+ $post['Price_' . $index] = number_format($item->getBaseOriginalPrice(), 2);
103
+ $post['Amount_' . $index] = number_format($item->getBaseOriginalPrice() * $item->getQtyOrdered(), 2);
104
+ $post['Currency_' . $index] = $_order->getBaseCurrency()->getCode();
105
+
106
+ $index++;
107
+ }
108
+
109
+ $post['Article_' . $index] = $_order->getShippingDescription();
110
+ $post['Quantity_' . $index] = 1;
111
+ $post['Price_' . $index] = number_format($_order->getBaseShippingAmount(), 2);
112
+ $post['Amount_' . $index] = number_format($_order->getBaseShippingAmount() * 1, 2);
113
+ $post['Currency_' . $index] = $_order->getBaseCurrency()->getCode();
114
+
115
+ $post['Signature'] = $this->createSignature($post);
116
+
117
+ return $post;
118
+ }
119
+
120
+ private function createSignature($post)
121
+ {
122
+ $concData = base64_encode(implode('-', $post));
123
+ $privKeyObj = openssl_get_privatekey($this->privateKey);
124
+ openssl_sign($concData, $signature, $privKeyObj, OPENSSL_ALGO_SHA256);
125
+ return base64_encode($signature);
126
+ }
127
+
128
+ public function isValidSignature($post)
129
+ {
130
+ // Save signature
131
+ $signature = $post['Signature'];
132
+
133
+ // Remove signature from POST data array
134
+ unset($post['Signature']);
135
+
136
+ // Concatenate all values
137
+ $concData = base64_encode(implode('-', $post));
138
+
139
+ // Extract public key from certificate
140
+ $pubKeyId = openssl_get_publickey($this->publicKey);
141
+
142
+ // Verify signature
143
+ $result = openssl_verify($concData, base64_decode($signature), $pubKeyId, OPENSSL_ALGO_SHA256);
144
+
145
+ //Free key resource
146
+ openssl_free_key($pubKeyId);
147
+
148
+ if ($result == 1)
149
+ {
150
+ return true;
151
+ }
152
+ else
153
+ {
154
+ return false;
155
+ }
156
+ }
157
+
158
+ public function getRefundData(Mage_Sales_Model_Order $order, $transactionId, $amount)
159
+ {
160
+ $post = array();
161
+ $post['IPCmethod'] = 'IPCRefund';
162
+ $post['IPCVersion'] = $this->ipcVersion;
163
+ $post['IPCLanguage'] = 'en';
164
+ $post['WalletNumber'] = $this->walletNumber;
165
+ $post['SID'] = $this->sid;
166
+ $post['keyindex'] = $this->keyindex;
167
+ $post['Source'] = 'sc_magento';
168
+
169
+ $post['IPC_Trnref'] = $transactionId;
170
+ $post['OrderID'] = $order->getRealOrderId();
171
+ $post['Amount'] = number_format($amount, 2);
172
+ $post['Currency'] = $order->getBaseCurrency()->getCode();
173
+ $post['OutputFormat'] = 'xml';
174
+
175
+ $post['Signature'] = $this->createSignature($post);
176
+
177
+ return $post;
178
+ }
179
+
180
+ public function xml2Post($xml)
181
+ {
182
+ $xml = simplexml_load_string($xml);
183
+
184
+ $post = array();
185
+
186
+ foreach ($xml->children() as $child)
187
+ {
188
+ $post[$child->getName()] = (string) $child;
189
+ }
190
+
191
+ return $post;
192
+ }
193
+ }
app/code/community/Mypos/Virtual/Model/Standard.php ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Mypos_Virtual_Model_Standard extends Mage_Payment_Model_Method_Abstract {
3
+ private static $logFilename = 'mypos_virtual.log';
4
+ protected $_code = 'mypos_virtual';
5
+
6
+ protected $_isInitializeNeeded = true;
7
+ protected $_canUseInternal = false;
8
+ protected $_canUseForMultishipping = false;
9
+ protected $_canRefund = true;
10
+ protected $_canRefundInvoicePartial = true;
11
+
12
+ private $transactionId;
13
+
14
+ public function getOrderPlaceRedirectUrl() {
15
+ return Mage::getUrl('mypos_virtual/payment/redirect', array('_secure' => true));
16
+ }
17
+
18
+ public function processBeforeRefund($invoice, $payment){
19
+ $this->transactionId = $invoice->getTransactionId();
20
+ return $this;
21
+ }
22
+
23
+ /**
24
+ * Check whether payment method can be used
25
+ *
26
+ * @param Mage_Sales_Model_Quote|null $quote
27
+ *
28
+ * @return bool
29
+ */
30
+ public function isAvailable($quote = null)
31
+ {
32
+ $checkResult = parent::isAvailable($quote);
33
+
34
+ if ($checkResult)
35
+ {
36
+ $currency_code = Mage::app()->getStore()->getCurrentCurrencyCode();
37
+
38
+ if (!in_array($currency_code, array('EUR', 'USD', 'GBP', 'HRK', 'CHF', 'RON', 'JPY', 'BGN')))
39
+ {
40
+ $checkResult = false;
41
+ }
42
+ }
43
+
44
+ return $checkResult;
45
+ }
46
+
47
+ public function refund(Varien_Object $payment, $amount){
48
+
49
+ /**
50
+ * @var Mypos_Virtual_Helper_Data $helper
51
+ */
52
+ $helper = Mage::helper('mypos_virtual');
53
+
54
+ /**
55
+ * @var Mage_Sales_Model_Order $order
56
+ */
57
+ $order = $payment->getOrder();
58
+
59
+ Mage::log('Create IPCRefund request for order: ' . $order->getRealOrderId() . '.', null, self::$logFilename);
60
+
61
+ $post = $helper->getRefundData($order, $this->transactionId, $amount);
62
+
63
+ //open connection
64
+ $ch = curl_init($helper->getFormUrl());
65
+
66
+ //set the url, number of POST vars, POST data
67
+ curl_setopt($ch, CURLOPT_URL, $helper->getFormUrl());
68
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
69
+ curl_setopt($ch, CURLOPT_POST,1);
70
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
71
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION ,1);
72
+ curl_setopt($ch, CURLOPT_HEADER ,0); // DO NOT RETURN HTTP HEADERS
73
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER ,1); // RETURN THE CONTENTS OF THE CALL
74
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120); // Timeout on connect (2 minutes)
75
+
76
+ //execute post
77
+ $result = curl_exec($ch);
78
+ curl_close($ch);
79
+
80
+ // Parse xml
81
+ $post = $helper->xml2Post($result);
82
+
83
+ if ($helper->isValidSignature($post))
84
+ {
85
+ Mage::log('Valid signature for IPCRefund request for order: ' . $order->getRealOrderId() . '.', null, self::$logFilename);
86
+
87
+ if ($post['Status'] != 0)
88
+ {
89
+ Mage::log('There was an error when processing IPCRefund response for order: ' . $order->getRealOrderId() . ' with status ' . $post['Status'] . '.', null, self::$logFilename);
90
+ Mage::throwException("There was an error processing the refund.");
91
+ }
92
+ else
93
+ {
94
+ $this->_addTransaction(
95
+ $payment,
96
+ $post['IPC_Trnref'] . '-' . time(),
97
+ Mage_Sales_Model_Order_Payment_Transaction::TYPE_REFUND,
98
+ array(),
99
+ array('Amount' => $post['Amount']),
100
+ 'Transaction from refund.'
101
+ );
102
+
103
+ Mage::log('Successfully processed IPCRefund response for order: ' . $order->getRealOrderId() . '.', null, self::$logFilename);
104
+ }
105
+ }
106
+ else
107
+ {
108
+ Mage::log('Invalid signature from IPCRefund response for order: ' . $order->getRealOrderId() . '.', null, self::$logFilename);
109
+ Mage::throwException("Invalid signature from response.");
110
+ }
111
+
112
+ return $this;
113
+ }
114
+
115
+ /**
116
+ * Add payment transaction
117
+ *
118
+ * @param Mage_Sales_Model_Order_Payment $payment
119
+ * @param string $transactionId
120
+ * @param string $transactionType
121
+ * @param array $transactionDetails
122
+ * @param array $transactionAdditionalInfo
123
+ * @return null|Mage_Sales_Model_Order_Payment_Transaction
124
+ */
125
+ public function _addTransaction(Mage_Sales_Model_Order_Payment $payment, $transactionId, $transactionType,
126
+ array $transactionDetails = array(), array $transactionAdditionalInfo = array(), $message = false
127
+ ) {
128
+ $payment->setTransactionId($transactionId);
129
+ $payment->resetTransactionAdditionalInfo();
130
+
131
+ foreach ($transactionDetails as $key => $value) {
132
+ $payment->setData($key, $value);
133
+ }
134
+ foreach ($transactionAdditionalInfo as $key => $value) {
135
+ $payment->setTransactionAdditionalInfo($key, $value);
136
+ }
137
+
138
+ $transaction = $payment->addTransaction($transactionType, null, false , $message);
139
+
140
+ foreach ($transactionDetails as $key => $value) {
141
+ $payment->unsetData($key);
142
+ }
143
+
144
+ $payment->unsLastTransId();
145
+
146
+ /**
147
+ * It for self using
148
+ */
149
+ $transaction->setMessage($message);
150
+
151
+ return $transaction;
152
+ }
153
+ }
154
+ ?>
app/code/community/Mypos/Virtual/controllers/PaymentController.php ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Mypos Virtual Checkout Payment Controller
4
+ * @author Intercard Finance AD
5
+ */
6
+
7
+ class Mypos_Virtual_PaymentController extends Mage_Core_Controller_Front_Action {
8
+ public static $logFilename = 'mypos_virtual.log';
9
+
10
+ public function __construct(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response, array $invokeArgs = array())
11
+ {
12
+ parent::__construct($request, $response, $invokeArgs);
13
+ }
14
+
15
+ public function redirectAction() {
16
+ $block = $this->getLayout()->createBlock('Mage_Core_Block_Template', 'mypos_virtual', array('template' => 'mypos_virtual/redirect.phtml'));
17
+
18
+ /**
19
+ * Retrieve order id
20
+ */
21
+ $orderId = Mage::getSingleton('checkout/session')->getLastRealOrderId();
22
+
23
+ /**
24
+ * @var Mypos_Virtual_Helper_Data $helper
25
+ */
26
+ $helper = Mage::helper('mypos_virtual');
27
+
28
+ Mage::log('Redirect to checkout. OrderID: ' . $orderId . ' Url: ' . $helper->getFormUrl(), null, self::$logFilename);
29
+
30
+ echo $block->toHtml();
31
+ }
32
+
33
+ public function notifyAction() {
34
+ Mage::log('Received notify url request.', null, self::$logFilename);
35
+
36
+ if($this->getRequest()->isPost()) {
37
+ /**
38
+ * @var Mypos_Virtual_Helper_Data $helper
39
+ */
40
+ $helper = Mage::helper('mypos_virtual');
41
+
42
+ $post = $this->getRequest()->getPost();
43
+
44
+ // Check if we have a valid signature.
45
+ if ($helper->isValidSignature($post))
46
+ {
47
+ if ($post['IPCmethod'] == 'IPCPurchaseNotify')
48
+ {
49
+ Mage::log('Received IPCPurchaseNotify request for order: ' . $post['OrderId'] . '.', null, self::$logFilename);
50
+
51
+ // Payment was successful, so update the order's state,
52
+ // send order email and move to the success page
53
+
54
+ /**
55
+ * @var Mage_Sales_Model_Order $order
56
+ */
57
+ $order = Mage::getModel('sales/order');
58
+ $order->loadByIncrementId($post['OrderID']);
59
+
60
+ try {
61
+ if(!$order->canInvoice())
62
+ {
63
+ Mage::throwException(Mage::helper('core')->__('Cannot create an invoice.'));
64
+ }
65
+
66
+ /**
67
+ * @var Mage_Sales_Model_Service_Order $serviceOrder
68
+ */
69
+ $serviceOrder = Mage::getModel('sales/service_order', $order);
70
+
71
+ $invoice = $serviceOrder->prepareInvoice();
72
+
73
+ if (!$invoice->getTotalQty()) {
74
+ Mage::throwException(Mage::helper('core')->__('Cannot create an invoice without products.'));
75
+ }
76
+
77
+ $invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::NOT_CAPTURE);
78
+ $invoice->setTransactionId($post['IPC_Trnref']);
79
+ $invoice->register();
80
+
81
+ /**
82
+ * @var Mage_Core_Model_Resource_Transaction $transactionSave
83
+ */
84
+ $transactionSave = Mage::getModel('core/resource_transaction');
85
+
86
+ $transactionSave
87
+ ->addObject($invoice)
88
+ ->addObject($invoice->getOrder());
89
+
90
+ /**
91
+ * @var Mypos_Virtual_Model_Standard $model
92
+ */
93
+ $model = Mage::getModel('mypos_virtual/standard', $order);
94
+
95
+ $model->_addTransaction(
96
+ $order->getPayment(),
97
+ $post['IPC_Trnref'],
98
+ Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE,
99
+ array(),
100
+ array('Amount' => $post['Amount']),
101
+ 'Transaction from notify url.'
102
+ );
103
+
104
+ $transactionSave->save();
105
+
106
+ $order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true, 'Gateway has authorized the payment.');
107
+ $order->sendNewOrderEmail();
108
+ $order->setEmailSent(true);
109
+ $order->save();
110
+
111
+ echo 'OK';
112
+
113
+ Mage::log('Created invoice and set order: ' . $post['OrderID'] . ' to processing.', null, self::$logFilename);
114
+
115
+ exit;
116
+ }
117
+ catch (Mage_Core_Exception $e) {
118
+ echo $e->getMessage();
119
+ Mage::log('Error in IPCPurchaseNotify order: ' . $post['OrderID'] . '.', null, self::$logFilename);
120
+ exit;
121
+ }
122
+ }
123
+ else if ($post['IPCmethod'] == 'IPCPurchaseRollback')
124
+ {
125
+ Mage::log('Received IPCPurchaseRollback request for order: ' . $post['OrderID'] . '.', null, self::$logFilename);
126
+ /**
127
+ * @var Mage_Sales_Model_Order $order
128
+ */
129
+ $order = Mage::getModel('sales/order');
130
+ $order->loadByIncrementId($post['OrderID']);
131
+
132
+ if($order->getId())
133
+ {
134
+ /**
135
+ * @var Mage_Sales_Model_Service_Order $service
136
+ */
137
+ $service = Mage::getModel('sales/service_order', $order);
138
+
139
+ $service->prepareCreditmemo()->register()->save();
140
+
141
+ // Flag the order as 'cancelled' and save it
142
+ $order
143
+ ->cancel()
144
+ ->setState(Mage_Sales_Model_Order::STATE_CANCELED, true, 'Gateway has declined the payment.')
145
+ ->save()
146
+ ;
147
+
148
+ echo 'OK';
149
+
150
+ Mage::log('Set order: ' . $post['OrderId'] . ' as canceled.', null, self::$logFilename);
151
+
152
+ exit;
153
+ }
154
+
155
+ Mage::log('Order: ' . $post['OrderId'] . ' doesn\'t exist.', null, self::$logFilename);
156
+ echo 'Order ' . $post['OrderID'] . ' doesn\'t exist.';
157
+ exit;
158
+ }
159
+ }
160
+ else
161
+ {
162
+ Mage::log('Invalid signature in notify url request.', null, self::$logFilename);
163
+ }
164
+ }
165
+ else
166
+ {
167
+ Mage::log('No post data in notify url request.', null, self::$logFilename);
168
+ }
169
+
170
+ Mage_Core_Controller_Varien_Action::_redirect('');
171
+ }
172
+
173
+ public function successAction()
174
+ {
175
+ if ($this->getRequest()->isPost()) {
176
+ /**
177
+ * @var Mypos_Virtual_Helper_Data $helper
178
+ */
179
+ $helper = Mage::helper('mypos_virtual');
180
+
181
+ $post = $this->getRequest()->getPost();
182
+
183
+ // Check if we have a valid signature.
184
+ if ($helper->isValidSignature($post))
185
+ {
186
+ if ($post['IPCmethod'] == 'IPCPurchaseOK')
187
+ {
188
+ $this->redirectSuccess();
189
+ }
190
+ }
191
+ }
192
+ else
193
+ {
194
+ Mage_Core_Controller_Varien_Action::_redirect('');
195
+ }
196
+ }
197
+
198
+ public function cancelAction() {
199
+ Mage::log('Received cancel url request.', null, self::$logFilename);
200
+ if ($this->getRequest()->isPost()) {
201
+
202
+ /**
203
+ * @var Mypos_Virtual_Helper_Data $helper
204
+ */
205
+ $helper = Mage::helper('mypos_virtual');
206
+
207
+ $post = $this->getRequest()->getPost();
208
+
209
+ // Check if we have a valid signature.
210
+ if ($helper->isValidSignature($post))
211
+ {
212
+ if ($post['IPCmethod'] == 'IPCPurchaseCancel')
213
+ {
214
+ Mage::log('Received IPCPurchaseCancel request for order: ' . $post['OrderId'] . '.', null, self::$logFilename);
215
+
216
+ /**
217
+ * @var Mage_Sales_Model_Order $order
218
+ */
219
+ $order = Mage::getModel('sales/order');
220
+ $order->loadByIncrementId($post['OrderID']);
221
+
222
+ if($order->getId())
223
+ {
224
+ // Flag the order as 'cancelled' and save it
225
+ $order
226
+ ->setState(Mage_Sales_Model_Order::STATE_CANCELED, true, 'User has canceled the payment.')
227
+ ->save()
228
+ ;
229
+
230
+ Mage::log('Order: ' . $post['OrderId'] . ' canceled by user.', null, self::$logFilename);
231
+ }
232
+ else
233
+ {
234
+ Mage::log('No order with id: ' . $post['OrderId'] . ' exist.', null, self::$logFilename);
235
+ }
236
+
237
+ $this->redirectFailure();
238
+ }
239
+ }
240
+ else
241
+ {
242
+ Mage::log('Invalid signature in cancel url request.', null, self::$logFilename);
243
+ }
244
+ }
245
+ else
246
+ {
247
+ Mage::log('No post data in cancel url request.', null, self::$logFilename);
248
+ Mage_Core_Controller_Varien_Action::_redirect('');
249
+ }
250
+
251
+ }
252
+
253
+ private function redirectFailure()
254
+ {
255
+ Mage::getSingleton('core/session')->addError('Your order has been canceled.');
256
+ Mage_Core_Controller_Varien_Action::_redirect('customer/account/', array('_secure'=>true));
257
+ }
258
+
259
+ private function redirectSuccess()
260
+ {
261
+ Mage_Core_Controller_Varien_Action::_redirect('checkout/onepage/success', array('_secure'=>true));
262
+ }
263
+ }
app/code/community/Mypos/Virtual/etc/config.xml ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Mypos_Virtual>
5
+ <version>1.0.0</version>
6
+ </Mypos_Virtual>
7
+ </modules>
8
+ <global>
9
+ <models>
10
+ <mypos_virtual>
11
+ <class>Mypos_Virtual_Model</class>
12
+ </mypos_virtual>
13
+ </models>
14
+ <helpers>
15
+ <mypos_virtual>
16
+ <class>Mypos_Virtual_Helper</class>
17
+ </mypos_virtual>
18
+ </helpers>
19
+ <blocks>
20
+ <mypos_virtual>
21
+ <class>Mypos_Virtual_Model_Block</class>
22
+ </mypos_virtual>
23
+ </blocks>
24
+ </global>
25
+ <default>
26
+ <payment>
27
+ <mypos_virtual>
28
+ <model>mypos_virtual/standard</model>
29
+ <active>1</active>
30
+ <test>1</test>
31
+ <title>myPOS Virtual</title>
32
+ <payment_action>sale</payment_action>
33
+ <sort_order>1</sort_order>
34
+ <developer_url>https://www.mypos.eu/vmp/checkout-test</developer_url>
35
+ <production_url>https://www.mypos.eu/vmp/checkout</production_url>
36
+ </mypos_virtual>
37
+ </payment>
38
+ </default>
39
+ <frontend>
40
+ <routers>
41
+ <mypos_virtual>
42
+ <use>standard</use>
43
+ <args>
44
+ <module>Mypos_Virtual</module>
45
+ <frontName>mypos_virtual</frontName>
46
+ </args>
47
+ </mypos_virtual>
48
+ </routers>
49
+ </frontend>
50
+ </config>
app/code/community/Mypos/Virtual/etc/system.xml ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <payment>
5
+ <groups>To use this payment option you need to sign up for a myPOS account.
6
+ <mypos_virtual translate="label comment" module="paygate">
7
+ <label>myPOS Virtual</label>
8
+ <frontend_type>text</frontend_type>
9
+ <sort_order>100</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
+ <comment><![CDATA[To use this payment option you need to <a href="https://mypos.eu/en/register/" target="_blank">sign up</a> for a myPOS account.]]></comment>
14
+ <fields>
15
+ <active translate="label">
16
+ <label>Enabled</label>
17
+ <config_path>payment/mypos_virtual/active</config_path>
18
+ <frontend_type>select</frontend_type>
19
+ <source_model>adminhtml/system_config_source_yesno</source_model>
20
+ <sort_order>10</sort_order>
21
+ <show_in_default>1</show_in_default>
22
+ <show_in_website>1</show_in_website>
23
+ <show_in_store>0</show_in_store>
24
+ </active>
25
+ <title translate="label">
26
+ <label>Title</label>
27
+ <config_path>payment/mypos_virtual/title</config_path>
28
+ <frontend_type>text</frontend_type>
29
+ <sort_order>15</sort_order>
30
+ <show_in_default>1</show_in_default>
31
+ <show_in_website>1</show_in_website>
32
+ <show_in_store>1</show_in_store>
33
+ </title>
34
+ <test translate="label">
35
+ <label>Test Mode</label>
36
+ <config_path>payment/mypos_virtual/test</config_path>
37
+ <frontend_type>select</frontend_type>
38
+ <source_model>adminhtml/system_config_source_yesno</source_model>
39
+ <sort_order>18</sort_order>
40
+ <show_in_default>1</show_in_default>
41
+ <show_in_website>1</show_in_website>
42
+ <show_in_store>0</show_in_store>
43
+ <comment>
44
+ <![CDATA[Determines whether the myPOS Virtual test environment is used.]]>
45
+ </comment>
46
+ </test>
47
+ <sort_order translate="label">
48
+ <config_path>payment/mypos_virtual/sort_order</config_path>
49
+ <label>Sort Order</label>
50
+ <frontend_type>text</frontend_type>
51
+ <sort_order>100</sort_order>
52
+ <show_in_default>1</show_in_default>
53
+ <show_in_website>1</show_in_website>
54
+ <show_in_store>0</show_in_store>
55
+ </sort_order>
56
+ <developer_settings type="group" translate="label">
57
+ <label>Developer Settings</label>
58
+ <frontend_class>config-advanced</frontend_class>
59
+ <frontend_type>text</frontend_type>
60
+ <show_in_default>1</show_in_default>
61
+ <show_in_website>1</show_in_website>
62
+ <show_in_store>1</show_in_store>
63
+ <sort_order>20</sort_order>
64
+ <fields>
65
+ <developer_sid translate="label">
66
+ <label>Store ID</label>
67
+ <config_path>payment/mypos_virtual/developer_sid</config_path>
68
+ <frontend_type>text</frontend_type>
69
+ <sort_order>30</sort_order>
70
+ <show_in_default>1</show_in_default>
71
+ <show_in_website>1</show_in_website>
72
+ <show_in_store>0</show_in_store>
73
+ <comment>
74
+ <![CDATA[Store ID is given when you add a new online store. It could be reviewed in your online banking at mypos.eu - Menu Merchant services > myPOS Virtual > Online stores.]]>
75
+ </comment>
76
+ </developer_sid>
77
+
78
+ <developer_wallet_number translate="label">
79
+ <label>Client Number</label>
80
+ <config_path>payment/mypos_virtual/developer_wallet_number</config_path>
81
+ <frontend_type>text</frontend_type>
82
+ <sort_order>40</sort_order>
83
+ <show_in_default>1</show_in_default>
84
+ <show_in_website>1</show_in_website>
85
+ <show_in_store>0</show_in_store>
86
+ <comment>
87
+ <![CDATA[You can view your myPOS Client number in your online banking at mypos.eu]]>
88
+ </comment>
89
+ </developer_wallet_number>
90
+
91
+ <developer_store_private_key>
92
+ <label>Private Key</label>
93
+ <config_path>payment/mypos_virtual/developer_store_private_key</config_path>
94
+ <frontend_type>textarea</frontend_type>
95
+ <sort_order>50</sort_order>
96
+ <show_in_default>1</show_in_default>
97
+ <show_in_website>1</show_in_website>
98
+ <show_in_store>0</show_in_store>
99
+ <comment>
100
+ <![CDATA[The Private Key for your store is generated in your online banking at mypos.eu - Menu Merchant services > myPOS Virtual > Online stores > Keys menu.]]>
101
+ </comment>
102
+ </developer_store_private_key>
103
+
104
+ <developer_ipc_public_certificate>
105
+ <label>myPOS Public Certificate</label>
106
+ <config_path>payment/mypos_virtual/developer_ipc_public_certificate</config_path>
107
+ <frontend_type>file</frontend_type>
108
+ <frontend_type>textarea</frontend_type>
109
+ <sort_order>60</sort_order>
110
+ <show_in_default>1</show_in_default>
111
+ <show_in_website>1</show_in_website>
112
+ <show_in_store>0</show_in_store>
113
+ <comment>
114
+ <![CDATA[The myPOS Public Certificate is available for download in your online banking at mypos.eu - Menu Merchant services > myPOS Virtual > Online stores > Keys menu.]]>
115
+ </comment>
116
+ </developer_ipc_public_certificate>
117
+
118
+ <developer_url translate="label">
119
+ <label>Developer URL</label>
120
+ <config_path>payment/mypos_virtual/developer_url</config_path>
121
+ <frontend_type>text</frontend_type>
122
+ <sort_order>110</sort_order>
123
+ <show_in_default>1</show_in_default>
124
+ <show_in_website>1</show_in_website>
125
+ <show_in_store>0</show_in_store>
126
+ </developer_url>
127
+
128
+ <developer_keyindex translate="label">
129
+ <label>Developer Key Index</label>
130
+ <config_path>payment/mypos_virtual/developer_keyindex</config_path>
131
+ <frontend_type>text</frontend_type>
132
+ <sort_order>120</sort_order>
133
+ <show_in_default>1</show_in_default>
134
+ <show_in_website>1</show_in_website>
135
+ <show_in_store>0</show_in_store>
136
+ <comment>
137
+ <![CDATA[The Key Index assigned to the certificate could be reviewed in your online banking at mypos.eu - Menu Merchant services > myPOS Virtual > Online stores > Keys menu.]]>
138
+ </comment>
139
+ </developer_keyindex>
140
+ </fields>
141
+ </developer_settings>
142
+ <production_settings type="group" translate="label">
143
+ <label>Production Settings</label>
144
+ <frontend_class>config-advanced</frontend_class>
145
+ <frontend_type>text</frontend_type>
146
+ <show_in_default>1</show_in_default>
147
+ <show_in_website>1</show_in_website>
148
+ <show_in_store>1</show_in_store>
149
+ <sort_order>30</sort_order>
150
+ <fields>
151
+ <production_sid translate="label">
152
+ <label>Store ID</label>
153
+ <config_path>payment/mypos_virtual/production_sid</config_path>
154
+ <frontend_type>text</frontend_type>
155
+ <sort_order>30</sort_order>
156
+ <show_in_default>1</show_in_default>
157
+ <show_in_website>1</show_in_website>
158
+ <show_in_store>0</show_in_store>
159
+ <comment>
160
+ <![CDATA[Store ID is given when you add a new online store. It could be reviewed in your online banking at mypos.eu - Menu Merchant services > myPOS Virtual > Online stores.]]>
161
+ </comment>
162
+ </production_sid>
163
+ <production_wallet_number translate="label">
164
+ <label>Client Number</label>
165
+ <config_path>payment/mypos_virtual/production_wallet_number</config_path>
166
+ <frontend_type>text</frontend_type>
167
+ <sort_order>40</sort_order>
168
+ <show_in_default>1</show_in_default>
169
+ <show_in_website>1</show_in_website>
170
+ <show_in_store>0</show_in_store>
171
+ <comment>
172
+ <![CDATA[You can view your myPOS Client number in your online banking at mypos.eu]]>
173
+ </comment>
174
+ </production_wallet_number>
175
+
176
+ <production_store_private_key>
177
+ <label>Private Key</label>
178
+ <config_path>payment/mypos_virtual/production_store_private_key</config_path>
179
+ <frontend_type>textarea</frontend_type>
180
+ <sort_order>50</sort_order>
181
+ <show_in_default>1</show_in_default>
182
+ <show_in_website>1</show_in_website>
183
+ <show_in_store>0</show_in_store>
184
+ <comment>
185
+ <![CDATA[The Private Key for your store is generated in your online banking at mypos.eu - Menu Merchant services > myPOS Virtual > Online stores > Keys menu.]]>
186
+ </comment>
187
+ </production_store_private_key>
188
+
189
+ <production_ipc_public_certificate>
190
+ <label>myPOS Public Certificate</label>
191
+ <config_path>payment/mypos_virtual/production_ipc_public_certificate</config_path>
192
+ <frontend_type>textarea</frontend_type>
193
+ <sort_order>60</sort_order>
194
+ <show_in_default>1</show_in_default>
195
+ <show_in_website>1</show_in_website>
196
+ <show_in_store>0</show_in_store>
197
+ <comment>
198
+ <![CDATA[The myPOS Public Certificate is available for download in your online banking at mypos.eu - Menu Merchant services > myPOS Virtual > Online stores > Keys menu.]]>
199
+ </comment>
200
+ </production_ipc_public_certificate>
201
+
202
+ <production_url translate="label">
203
+ <label>Production URL</label>
204
+ <config_path>payment/mypos_virtual/production_url</config_path>
205
+ <frontend_type>text</frontend_type>
206
+ <sort_order>120</sort_order>
207
+ <show_in_default>1</show_in_default>
208
+ <show_in_website>1</show_in_website>
209
+ <show_in_store>0</show_in_store>
210
+ </production_url>
211
+
212
+ <production_keyindex translate="label">
213
+ <label>Production Key Index</label>
214
+ <config_path>payment/mypos_virtual/production_keyindex</config_path>
215
+ <frontend_type>text</frontend_type>
216
+ <sort_order>130</sort_order>
217
+ <show_in_default>1</show_in_default>
218
+ <show_in_website>1</show_in_website>
219
+ <show_in_store>0</show_in_store>
220
+ <comment>
221
+ <![CDATA[The Key Index assigned to the certificate could be reviewed in your online banking at mypos.eu - Menu Merchant services > myPOS Virtual > Online stores > Keys menu.]]>
222
+ </comment>
223
+ </production_keyindex>
224
+ </fields>
225
+ </production_settings>
226
+ </fields>
227
+ </mypos_virtual>
228
+ </groups>
229
+ </payment>
230
+ </sections>
231
+ </config>
app/design/frontend/base/default/template/mypos_virtual/redirect.phtml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Retrieve order
3
+ $_order = new Mage_Sales_Model_Order();
4
+ $orderId = Mage::getSingleton('checkout/session')->getLastRealOrderId();
5
+ $_order->loadByIncrementId($orderId);
6
+
7
+ /**
8
+ * @var Mypos_Virtual_Helper_Data $helper
9
+ */
10
+ $helper = Mage::helper('mypos_virtual');
11
+
12
+ ?>
13
+ <form name="mypos_virtual" method="post" action="<?php echo $helper->getFormUrl(); ?>">
14
+ <?php foreach($helper->getPost($_order) as $key => $value): ?>
15
+ <input type="hidden" name="<?php echo $key; ?>" value="<?php echo htmlspecialchars($value); ?>">
16
+ <?php endforeach; ?>
17
+ </form>
18
+ <script type="text/javascript">
19
+ document.mypos_virtual.submit();
20
+ </script>
app/etc/modules/Mypos_Virtual.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Mypos_Virtual>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </Mypos_Virtual>
8
+ </modules>
9
+ </config>
package.xml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>myPOS_Virtual</name>
4
+ <version>1.0.0</version>
5
+ <stability>stable</stability>
6
+ <license>GNU General Public License (GPL)</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Accept card payments in few easy steps! Try our simple and secure checkout solution for European merchants.</summary>
10
+ <description>myPOS Virtual is an extension especially designed for European-based merchants who need a simple and secure complete checkout solution. Start accepting credit and debit card payments at your online store in few easy steps.&#xD;
11
+ By using myPOS Virtual you enjoy a checkout extension backed-up by a comprehensive free merchant account with multiple currencies and an IBAN in Luxembourg.&#xD;
12
+ </description>
13
+ <notes>myPOS Virtual for shopping cart is an effective and secure way for accepting card payments on your website. Just install the plugin and let your customers pay for your goods and services easily and secure using their Debit/Credit card. You will also need to register for myPOS account at www.mypos.eu.</notes>
14
+ <authors><author><name>iPay International S.A.</name><user>ipay_developer</user><email>mvp@ipay.eu</email></author></authors>
15
+ <date>2015-10-28</date>
16
+ <time>07:14:42</time>
17
+ <contents><target name="magecommunity"><dir name="Mypos"><dir name="Virtual"><dir name="Helper"><file name="Data.php" hash="80bb4a2d794c32c2c4b62aecdd2d7e1b"/></dir><dir name="Model"><file name="Standard.php" hash="9c304393adbff742cbfec7af6a37bea7"/></dir><dir name="controllers"><file name="PaymentController.php" hash="725bd38de841efc89f205af4615d3349"/></dir><dir name="etc"><file name="config.xml" hash="51643300f013179eac57d538544420c1"/><file name="system.xml" hash="2d1fada936e99769bcca2350c69ce78a"/></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="mypos_virtual"><file name="redirect.phtml" hash="32904da0aa80adf0e0bc8b9c03c4f89e"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Mypos_Virtual.xml" hash="d38d8e8a3a6631179dfc3498736c75c9"/></dir></target></contents>
18
+ <compatible/>
19
+ <dependencies><required><php><min>5.2.0</min><max>5.6.9</max></php></required></dependencies>
20
+ </package>