Version Notes
This is the initial version. Please provide feedback to support@paystand.com
Download this release
Release Info
Developer | Scott Campbell |
Extension | PayStand_PayStandGateway |
Version | 1.0.2 |
Comparing to | |
See all releases |
Version 1.0.2
- app/code/local/PayStand/PayStandGateway/Helper/Data.php +6 -0
- app/code/local/PayStand/PayStandGateway/Model/PaymentMethod.php +329 -0
- app/code/local/PayStand/PayStandGateway/controllers/PaymentController.php +228 -0
- app/code/local/PayStand/PayStandGateway/etc/config.xml +76 -0
- app/code/local/PayStand/PayStandGateway/etc/system.xml +62 -0
- app/design/frontend/base/default/template/paystandgateway/redirect.phtml +270 -0
- app/etc/modules/PayStand_PayStandGateway.xml +12 -0
- package.xml +18 -0
app/code/local/PayStand/PayStandGateway/Helper/Data.php
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class PayStand_PayStandGateway_Helper_Data extends Mage_Core_Helper_Abstract
|
4 |
+
{
|
5 |
+
}
|
6 |
+
|
app/code/local/PayStand/PayStandGateway/Model/PaymentMethod.php
ADDED
@@ -0,0 +1,329 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
Copyright 2014 PayStand Inc.
|
5 |
+
|
6 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
7 |
+
you may not use this file except in compliance with the License.
|
8 |
+
You may obtain a copy of the License at
|
9 |
+
|
10 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
11 |
+
|
12 |
+
Unless required by applicable law or agreed to in writing, software
|
13 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
14 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15 |
+
See the License for the specific language governing permissions and
|
16 |
+
limitations under the License.
|
17 |
+
*/
|
18 |
+
|
19 |
+
if (!defined('PS_LOG')) {
|
20 |
+
define('PS_LOG', 'paystand.log');
|
21 |
+
}
|
22 |
+
if (!defined('PS_LIVE_URL')) {
|
23 |
+
define('PS_LIVE_URL', 'https://app.paystand.com');
|
24 |
+
}
|
25 |
+
if (!defined('PS_SANDBOX_URL')) {
|
26 |
+
define('PS_SANDBOX_URL', 'https://dev.paystand.biz');
|
27 |
+
}
|
28 |
+
if (!defined('PS_API')) {
|
29 |
+
define('PS_API', '/api/v2');
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* PayStand PayStandGateway PaymentMethod
|
34 |
+
*/
|
35 |
+
class PayStand_PayStandGateway_Model_PaymentMethod extends Mage_Payment_Model_Method_Abstract
|
36 |
+
{
|
37 |
+
/**
|
38 |
+
* Unique internal payment method identifier
|
39 |
+
* @var string [a-z0-9_]
|
40 |
+
*/
|
41 |
+
protected $_code = 'paystandgateway';
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Functionality availability flags
|
45 |
+
* @see all flags and their defaults in Mage_Payment_Model_Method_Abstract
|
46 |
+
* It is possible to have a custom dynamic logic by overloading
|
47 |
+
* public function can* for each flag respectively
|
48 |
+
*/
|
49 |
+
|
50 |
+
protected $_isGateway = true;
|
51 |
+
|
52 |
+
protected $_isInitializeNeeded = true;
|
53 |
+
protected $_canUseInternal = true;
|
54 |
+
protected $_canUseForMultishipping = false;
|
55 |
+
|
56 |
+
protected $accepted_currency_codes = array('USD');
|
57 |
+
|
58 |
+
|
59 |
+
/**
|
60 |
+
* PayStand API URLs
|
61 |
+
*/
|
62 |
+
protected $paystand_url;
|
63 |
+
protected $api_url;
|
64 |
+
protected $pm_url;
|
65 |
+
protected $pay_url;
|
66 |
+
|
67 |
+
// XXX merge review - do we need these functions vvv
|
68 |
+
/**
|
69 |
+
* Get config settings.
|
70 |
+
*/
|
71 |
+
public function getPayStandConfig()
|
72 |
+
{
|
73 |
+
Mage::log('PayStand getPayStandConfig', null, PS_LOG);
|
74 |
+
$this->org_id = $this->getConfigData('org_id');
|
75 |
+
$this->api_key = $this->getConfigData('api_key');
|
76 |
+
$this->use_sandbox = $this->getConfigData('use_sandbox');
|
77 |
+
if ($this->use_sandbox) {
|
78 |
+
$this->paystand_url = PS_SANDBOX_URL;
|
79 |
+
} else {
|
80 |
+
$this->paystand_url = PS_LIVE_URL;
|
81 |
+
}
|
82 |
+
$this->pm_url = $paystand_url . PS_API . '/paymentmethods';
|
83 |
+
$this->pay_url = $paystand_url . PS_API . '/payments';
|
84 |
+
Mage::log('PayStand config org_id: ' . $this->org_id, null, PS_LOG);
|
85 |
+
Mage::log('PayStand config pay_url: ' . $this->pay_url, null, PS_LOG);
|
86 |
+
}
|
87 |
+
|
88 |
+
public function getPayStandUrl()
|
89 |
+
{
|
90 |
+
if (empty($this->paystand_url)) {
|
91 |
+
$this->getPayStandConfig();
|
92 |
+
}
|
93 |
+
return $this->paystand_url;
|
94 |
+
}
|
95 |
+
|
96 |
+
public function getOrgId()
|
97 |
+
{
|
98 |
+
if (empty($this->org_id)) {
|
99 |
+
$this->getPayStandConfig();
|
100 |
+
}
|
101 |
+
return $this->org_id;
|
102 |
+
}
|
103 |
+
|
104 |
+
public function getApiKey()
|
105 |
+
{
|
106 |
+
if (empty($this->api_key)) {
|
107 |
+
$this->getPayStandConfig();
|
108 |
+
}
|
109 |
+
return $this->api_key;
|
110 |
+
}
|
111 |
+
// XXX merge review - do we need these functions ^^^
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Check method for processing with base currency
|
115 |
+
*
|
116 |
+
* @param string $currencyCode
|
117 |
+
* @return boolean
|
118 |
+
*/
|
119 |
+
public function canUseForCurrency($currencyCode)
|
120 |
+
{
|
121 |
+
if (!in_array($currencyCode, $this->getAcceptedCurrencyCodes())) {
|
122 |
+
Mage::log('PayStand False canUseForCurrency: ' . $currencyCode, null, PS_LOG);
|
123 |
+
return false;
|
124 |
+
}
|
125 |
+
return true;
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Return array of currency codes supported by Payment Gateway
|
130 |
+
*
|
131 |
+
* @return array
|
132 |
+
*/
|
133 |
+
public function getAcceptedCurrencyCodes()
|
134 |
+
{
|
135 |
+
return $this->accepted_currency_codes;
|
136 |
+
}
|
137 |
+
|
138 |
+
public function getOrderPlaceRedirectUrl()
|
139 |
+
{
|
140 |
+
$url = Mage::getUrl('paystandgateway/payment/redirect',
|
141 |
+
array('_secure' => true));
|
142 |
+
return $url;
|
143 |
+
}
|
144 |
+
|
145 |
+
// XXX merge review - do we need these functions? vvv
|
146 |
+
/**
|
147 |
+
* Send capture request to gateway
|
148 |
+
*
|
149 |
+
* @param Mage_Payment_Model_Info $payment
|
150 |
+
* @param decimal $amount
|
151 |
+
* @return PayStand_PayStandGateway_Model_PaymentMethod
|
152 |
+
*/
|
153 |
+
public function capture(Varien_Object $payment, $amount)
|
154 |
+
{
|
155 |
+
Mage::log('PayStand capture amount: ' . $amount, null, PS_LOG);
|
156 |
+
|
157 |
+
$this->getConfig();
|
158 |
+
|
159 |
+
if ($amount <= 0) {
|
160 |
+
Mage::log('PayStand capture invalid amount: ' . $amount, null, PS_LOG);
|
161 |
+
Mage::throwException('Invalid amount for capture.');
|
162 |
+
}
|
163 |
+
|
164 |
+
$card_number = $payment->getCcNumber();
|
165 |
+
$card_exp_month = $payment->getCcExpMonth();
|
166 |
+
$card_exp_year = $payment->getCcExpYear();
|
167 |
+
$cvc = $payment->getCcCid();
|
168 |
+
$order = $payment->getOrder();
|
169 |
+
$order_id = $order->getIncrementId();
|
170 |
+
$currency = $order->getBaseCurrencyCode();
|
171 |
+
$ip_address = $_SERVER['REMOTE_ADDR'];
|
172 |
+
$addr = $order->getBillingAddress();
|
173 |
+
if ($addr) {
|
174 |
+
$first_name = $addr->getData('firstname');
|
175 |
+
$last_name = $addr->getData('lastname');
|
176 |
+
$email = $addr->getData('email');
|
177 |
+
$street1 = $addr->getData('street');
|
178 |
+
$city = $addr->getData('city');
|
179 |
+
$state = $addr->getData('region');
|
180 |
+
$postal_code = $addr->getData('postcode');
|
181 |
+
$country = $addr->getData('country_id');
|
182 |
+
$phone = $addr->getData('telephone');
|
183 |
+
} else {
|
184 |
+
$first_name = '';
|
185 |
+
$last_name = '';
|
186 |
+
$email = '';
|
187 |
+
$street1 = '';
|
188 |
+
$city = '';
|
189 |
+
$state = '';
|
190 |
+
$postal_code = '';
|
191 |
+
$country = '';
|
192 |
+
$phone = '';
|
193 |
+
}
|
194 |
+
|
195 |
+
$rail = 'card';
|
196 |
+
|
197 |
+
$billing = array(
|
198 |
+
'full_name' => "Unknown Customer",
|
199 |
+
'email' => $email,
|
200 |
+
'address_line1' => $street1,
|
201 |
+
'address_line2' => $street2,
|
202 |
+
'address_city' => $city,
|
203 |
+
'address_state' => $state,
|
204 |
+
'address_zip' => $postal_code,
|
205 |
+
'address_country' => $country,
|
206 |
+
'card_number' => $card_number,
|
207 |
+
'card_cvv' => $cvc,
|
208 |
+
'card_month' => $card_exp_month,
|
209 |
+
'card_year' =>$car_exp_year
|
210 |
+
);
|
211 |
+
|
212 |
+
$request = array(
|
213 |
+
'action' => 'create_token',
|
214 |
+
'api_key' => $this->api_key,
|
215 |
+
'org_id' => $this->org_id,
|
216 |
+
'rail' => $rail,
|
217 |
+
'billing' => $billing
|
218 |
+
);
|
219 |
+
|
220 |
+
Mage::log('PayStand capture request: ' . print_r($request, true), null, PS_LOG);
|
221 |
+
|
222 |
+
$context = stream_context_create(array(
|
223 |
+
'http' => array(
|
224 |
+
'method' => 'POST',
|
225 |
+
'header' => "Content-Type: application/json\r\n",
|
226 |
+
'content' => json_encode($request)
|
227 |
+
)
|
228 |
+
));
|
229 |
+
|
230 |
+
$response = false;
|
231 |
+
$retry = 0;
|
232 |
+
$max_retries = 3;
|
233 |
+
while (($response === false) && ($retry < $max_retries)) {
|
234 |
+
if ($retry > 0) {
|
235 |
+
sleep(1);
|
236 |
+
}
|
237 |
+
$response = file_get_contents($this->pm_url, false, $context);
|
238 |
+
$retry++;
|
239 |
+
}
|
240 |
+
if ($response === false) {
|
241 |
+
Mage::log('PayStand capture failed to contact payment gateway: ' . $this->pm_url, null, PS_LOG);
|
242 |
+
Mage::throwException('Failed to contact payment gateway.');
|
243 |
+
}
|
244 |
+
|
245 |
+
Mage::log('PayStand capture response: ' . print_r($response, true), null, PS_LOG);
|
246 |
+
|
247 |
+
$response_data = json_decode($response, true);
|
248 |
+
$data = $response_data['data'];
|
249 |
+
$token = $data['token']['token'];
|
250 |
+
|
251 |
+
$billing = array(
|
252 |
+
'payment_token' => $token
|
253 |
+
);
|
254 |
+
|
255 |
+
$request = array(
|
256 |
+
'action' => 'pay',
|
257 |
+
'api_key' => $this->api_key,
|
258 |
+
'org_id' => $this->org_id,
|
259 |
+
'pre_fee_total' => 12.67,
|
260 |
+
'memo' => 'for tix',
|
261 |
+
'rail' => $rail,
|
262 |
+
'billing' => $billing
|
263 |
+
);
|
264 |
+
|
265 |
+
Mage::log('PayStand capture request: ' . print_r($request, true), null, PS_LOG);
|
266 |
+
|
267 |
+
$context = stream_context_create(array(
|
268 |
+
'http' => array(
|
269 |
+
'method' => 'POST',
|
270 |
+
'header' => "Content-Type: application/json\r\n",
|
271 |
+
'content' => json_encode($request)
|
272 |
+
)
|
273 |
+
));
|
274 |
+
|
275 |
+
$response = false;
|
276 |
+
$retry = 0;
|
277 |
+
$max_retries = 3;
|
278 |
+
while (($response === false) && ($retry < $max_retries)) {
|
279 |
+
if ($retry > 0) {
|
280 |
+
sleep(1);
|
281 |
+
}
|
282 |
+
$response = file_get_contents($this->pm_url, false, $context);
|
283 |
+
$retry++;
|
284 |
+
}
|
285 |
+
if ($response === false) {
|
286 |
+
Mage::throwException('Failed to contact payment gateway.');
|
287 |
+
}
|
288 |
+
|
289 |
+
Mage::log('PayStand capture response: ' . print_r($response, true), null, PS_LOG);
|
290 |
+
|
291 |
+
$response_data = json_decode($response, true);
|
292 |
+
$data = $response_data['data'];
|
293 |
+
$payment_status = $data['payment_status'];
|
294 |
+
$pre_fee_total = $data['pre_fee_total'];
|
295 |
+
$total_amount = $data['total_amount'];
|
296 |
+
$processing_fee = $total_amount - $pre_fee_total;
|
297 |
+
$success = $data['success'];
|
298 |
+
$txn_id = $data['order_id'];
|
299 |
+
|
300 |
+
$payment->setTransactionId($txn_id);
|
301 |
+
$payment->setIsTransactionClosed(1);
|
302 |
+
$payment->setTransactionAdditionalInfo(
|
303 |
+
Mage_Sales_Model_Order_Payment_Transaction::RAW_DETAILS,
|
304 |
+
array('payment_status' => $payment_status,
|
305 |
+
'processing_fee' => $processing_fee));
|
306 |
+
|
307 |
+
return $this;
|
308 |
+
}
|
309 |
+
|
310 |
+
/**
|
311 |
+
* Send refund request to gateway
|
312 |
+
*
|
313 |
+
* @param Mage_Payment_Model_Info $payment
|
314 |
+
* @param decimal $amount
|
315 |
+
* @return PayStand_PayStandGateway_Model_PaymentMethod
|
316 |
+
*/
|
317 |
+
public function refund(Varien_Object $payment, $amount)
|
318 |
+
{
|
319 |
+
if ($amount <= 0) {
|
320 |
+
Mage::throwException(Mage::helper('paygate')->__('Invalid amount for capture.'));
|
321 |
+
}
|
322 |
+
|
323 |
+
// XXX Implement
|
324 |
+
|
325 |
+
return $this;
|
326 |
+
}
|
327 |
+
// XXX merge review - do we need these functions? ^^^
|
328 |
+
}
|
329 |
+
|
app/code/local/PayStand/PayStandGateway/controllers/PaymentController.php
ADDED
@@ -0,0 +1,228 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
Copyright 2014 PayStand Inc.
|
5 |
+
|
6 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
7 |
+
you may not use this file except in compliance with the License.
|
8 |
+
You may obtain a copy of the License at
|
9 |
+
|
10 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
11 |
+
|
12 |
+
Unless required by applicable law or agreed to in writing, software
|
13 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
14 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15 |
+
See the License for the specific language governing permissions and
|
16 |
+
limitations under the License.
|
17 |
+
*/
|
18 |
+
|
19 |
+
if (!defined('PS_LOG')) {
|
20 |
+
define('PS_LOG', 'paystand.log');
|
21 |
+
}
|
22 |
+
if (!defined('PS_LIVE_URL')) {
|
23 |
+
define('PS_LIVE_URL', 'https://app.paystand.com');
|
24 |
+
}
|
25 |
+
if (!defined('PS_SANDBOX_URL')) {
|
26 |
+
define('PS_SANDBOX_URL', 'https://sandbox.paystand.co');
|
27 |
+
}
|
28 |
+
|
29 |
+
class PayStand_PayStandGateway_PaymentController extends Mage_Core_Controller_Front_Action
|
30 |
+
{
|
31 |
+
public function redirectAction()
|
32 |
+
{
|
33 |
+
$this->loadLayout();
|
34 |
+
$block = $this->getLayout()->createBlock('Mage_Core_Block_Template',
|
35 |
+
'paystandgateway',
|
36 |
+
array('template' => 'paystandgateway/redirect.phtml'));
|
37 |
+
$this->getLayout()->getBlock('content')->append($block);
|
38 |
+
$this->renderLayout();
|
39 |
+
}
|
40 |
+
|
41 |
+
public function responseAction()
|
42 |
+
{
|
43 |
+
$request = $this->getRequest();
|
44 |
+
$json = $request->getOriginalRequest()->getRawBody();
|
45 |
+
Mage::log('PayStand responseAction request: ' . print_r($json, true), null, PS_LOG);
|
46 |
+
$psn = json_decode($json, true);
|
47 |
+
$ok = $this->verify_psn($psn);
|
48 |
+
if (!$ok) {
|
49 |
+
Mage::log('PSN failed to verify', null, PS_LOG);
|
50 |
+
Mage::app()->getResponse()->setHeader('HTTP/1.1','400 Bad Request')
|
51 |
+
->sendResponse();
|
52 |
+
exit;
|
53 |
+
}
|
54 |
+
|
55 |
+
$order_id = $psn['order_id'];
|
56 |
+
$txn_id = $psn['txn_id'];
|
57 |
+
$payment_status = $psn['payment_status'];
|
58 |
+
$success = $psn['success'];
|
59 |
+
$rail = $psn['rail'];
|
60 |
+
|
61 |
+
$order = Mage::getModel('sales/order');
|
62 |
+
$order->loadByIncrementId($order_id);
|
63 |
+
$payment = $order->getPayment();
|
64 |
+
|
65 |
+
if ($success) {
|
66 |
+
$pre_fee_total = $psn['pre_fee_total'];
|
67 |
+
$total_amount = $psn['total_amount'];
|
68 |
+
$processing_fee = $total_amount - $pre_fee_total;
|
69 |
+
|
70 |
+
//$fee_item = new Mage_Sales_Model_Order_Item();
|
71 |
+
// XXX set fee in item
|
72 |
+
// XXX add fee item if not already there
|
73 |
+
//$order->addItem($fee_item);
|
74 |
+
|
75 |
+
// XXX set state to order_status from module system config
|
76 |
+
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true,
|
77 |
+
'Payment success.');
|
78 |
+
|
79 |
+
$payment->setTransactionId($txn_id);
|
80 |
+
$payment->setIsTransactionClosed(1);
|
81 |
+
$payment->setTransactionAdditionalInfo(
|
82 |
+
Mage_Sales_Model_Order_Payment_Transaction::RAW_DETAILS,
|
83 |
+
array('payment_status' => $payment_status,
|
84 |
+
'processing_fee' => $processing_fee));
|
85 |
+
|
86 |
+
$order->sendNewOrderEmail();
|
87 |
+
$order->setEmailSent(true);
|
88 |
+
$order->save();
|
89 |
+
|
90 |
+
Mage::getSingleton('checkout/session')->unsQuoteId();
|
91 |
+
Mage_Core_Controller_Varien_Action::_redirect(
|
92 |
+
'checkout/onepage/success', array('_secure' => true));
|
93 |
+
} else {
|
94 |
+
if ('failed' == $payment_status) {
|
95 |
+
$this->cancelAction();
|
96 |
+
Mage_Core_Controller_Varien_Action::_redirect(
|
97 |
+
'checkout/onepage/failure', array('_secure' => true));
|
98 |
+
}
|
99 |
+
}
|
100 |
+
}
|
101 |
+
|
102 |
+
public function cancelAction()
|
103 |
+
{
|
104 |
+
Mage::log('PayStand cancelAction', null, PS_LOG);
|
105 |
+
if (Mage::getSingleton('checkout/session')->getLastRealOrderId()) {
|
106 |
+
$order = Mage::getModel('sales/order')->loadByIncrementId(
|
107 |
+
Mage::getSingleton('checkout/session')->getLastRealOrderId());
|
108 |
+
if ($order->getId()) {
|
109 |
+
$order->cancel()->setState(Mage_Sales_Model_Order::STATE_CANCELED,
|
110 |
+
true, 'Payment failed or canceled.')->save();
|
111 |
+
}
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
function verify_psn($psn)
|
116 |
+
{
|
117 |
+
if (empty($psn) || !is_array($psn)) {
|
118 |
+
Mage::log('verify_psn psn is empty');
|
119 |
+
return false;
|
120 |
+
}
|
121 |
+
|
122 |
+
$api_key = Mage::getStoreConfig('payment/paystandgateway/api_key');
|
123 |
+
$use_sandbox = Mage::getStoreConfig('payment/paystandgateway/use_sandbox');
|
124 |
+
if ($use_sandbox) {
|
125 |
+
$paystand_url = PS_SANDBOX_URL;
|
126 |
+
} else {
|
127 |
+
$paystand_url = PS_LIVE_URL;
|
128 |
+
}
|
129 |
+
$endpoint = $paystand_url . '/api/v2/orders';
|
130 |
+
|
131 |
+
$request = array(
|
132 |
+
'action' => 'verify_psn',
|
133 |
+
'api_key' => $api_key,
|
134 |
+
'order_id' => $psn['txn_id'],
|
135 |
+
'psn' => $psn
|
136 |
+
);
|
137 |
+
|
138 |
+
Mage::log('verify_psn endpoint: ' . $endpoint, null, PS_LOG);
|
139 |
+
Mage::log('verify_psn request: ' . print_r($request, true), null, PS_LOG);
|
140 |
+
|
141 |
+
$context = stream_context_create(array(
|
142 |
+
'http' => array(
|
143 |
+
'method' => 'POST',
|
144 |
+
'header' => "Content-Type: application/json\r\n",
|
145 |
+
'content' => json_encode($request)
|
146 |
+
)
|
147 |
+
));
|
148 |
+
|
149 |
+
$response = false;
|
150 |
+
$retry = 0;
|
151 |
+
$max_retries = 3;
|
152 |
+
while (($response === false) && ($retry < $max_retries)) {
|
153 |
+
if ($retry > 0) {
|
154 |
+
sleep(1);
|
155 |
+
Mage::log('verify_psn retry: ' . $retry, null, PS_LOG);
|
156 |
+
}
|
157 |
+
$response = file_get_contents($endpoint, false, $context);
|
158 |
+
$retry++;
|
159 |
+
}
|
160 |
+
if ($response === false) {
|
161 |
+
Mage::log('verify_psn returned false', null, PS_LOG);
|
162 |
+
return false;
|
163 |
+
}
|
164 |
+
|
165 |
+
$response_data = json_decode($response, true);
|
166 |
+
Mage::log('verify_psn response: ' . print_r($response_data, true), null, PS_LOG);
|
167 |
+
|
168 |
+
if ($response_data['data'] !== true) {
|
169 |
+
Mage::log('verify_psn response was not success', null, PS_LOG);
|
170 |
+
return false;
|
171 |
+
}
|
172 |
+
|
173 |
+
$defined = array(
|
174 |
+
'txn_id', 'org_id', 'consumer_id', 'pre_fee_total',
|
175 |
+
'fee_merchant_owes', 'rate_merchant_owes',
|
176 |
+
'fee_consumer_owes', 'rate_consumer_owes', 'total_amount',
|
177 |
+
'payment_status', 'success'
|
178 |
+
);
|
179 |
+
$numerics = array(
|
180 |
+
'pre_fee_total', 'fee_merchant_owes', 'rate_merchant_owes',
|
181 |
+
'fee_consumer_owes', 'rate_consumer_owes', 'total_amount',
|
182 |
+
'txn_id', 'org_id', 'consumer_id'
|
183 |
+
);
|
184 |
+
|
185 |
+
foreach ($defined as $def) {
|
186 |
+
if (!isset($psn[$def])) {
|
187 |
+
Mage::log('PSN validation error: ' . $def . ' is not defined or is empty', null, PS_LOG);
|
188 |
+
return false;
|
189 |
+
}
|
190 |
+
}
|
191 |
+
|
192 |
+
foreach ($numerics as $numeric) {
|
193 |
+
if (!is_numeric($psn[$numeric])) {
|
194 |
+
Mage::log('PSN validation error: ' . $numeric . ' is not numeric', null, PS_LOG);
|
195 |
+
return false;
|
196 |
+
}
|
197 |
+
}
|
198 |
+
|
199 |
+
$order_id = false;
|
200 |
+
if (!empty($psn['order_id'])) {
|
201 |
+
$order_id = $psn['order_id'];
|
202 |
+
}
|
203 |
+
|
204 |
+
Mage::log('verify_psn order_id: ' . $order_id);
|
205 |
+
|
206 |
+
$order = false;
|
207 |
+
if ($order_id) {
|
208 |
+
$order = new Mage_Sales_Model_Order();
|
209 |
+
$order->loadByIncrementId($order_id);
|
210 |
+
}
|
211 |
+
if (!$order->getId()) {
|
212 |
+
Mage::log('Order not found for order id: ' . $order_id, null, PS_LOG);
|
213 |
+
return false;
|
214 |
+
}
|
215 |
+
|
216 |
+
$pre_fee_total = false;
|
217 |
+
if (!empty($psn['pre_fee_total'])) {
|
218 |
+
$pre_fee_total = $psn['pre_fee_total'];
|
219 |
+
}
|
220 |
+
if ($pre_fee_total != $order->getBaseGrandTotal()) {
|
221 |
+
Mage::log('PSN validation error: psn pre_fee_total: ' . $psn['pre_fee_total'] . ' not equal to order_total: ' . $order->getBaseGrandTotal(), null, PS_LOG);
|
222 |
+
return false;
|
223 |
+
}
|
224 |
+
|
225 |
+
return true;
|
226 |
+
}
|
227 |
+
}
|
228 |
+
|
app/code/local/PayStand/PayStandGateway/etc/config.xml
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<PayStand_PayStandGateway>
|
5 |
+
<version>1.0.2</version>
|
6 |
+
</PayStand_PayStandGateway>
|
7 |
+
</modules>
|
8 |
+
|
9 |
+
<global>
|
10 |
+
<blocks>
|
11 |
+
<paystandgateway>
|
12 |
+
<class>PayStand_PayStandGateway_Block</class>
|
13 |
+
</paystandgateway>
|
14 |
+
</blocks>
|
15 |
+
|
16 |
+
<models>
|
17 |
+
<paystandgateway>
|
18 |
+
<class>PayStand_PayStandGateway_Model</class>
|
19 |
+
</paystandgateway>
|
20 |
+
</models>
|
21 |
+
|
22 |
+
<resources>
|
23 |
+
<paystandgateway_setup>
|
24 |
+
<setup>
|
25 |
+
<module>PayStand_PayStandGateway</module>
|
26 |
+
</setup>
|
27 |
+
<connection>
|
28 |
+
<use>core_setup</use>
|
29 |
+
</connection>
|
30 |
+
</paystandgateway_setup>
|
31 |
+
<paystandgateway_write>
|
32 |
+
<connection>
|
33 |
+
<use>core_write</use>
|
34 |
+
</connection>
|
35 |
+
</paystandgateway_write>
|
36 |
+
<paystandgateway_read>
|
37 |
+
<connection>
|
38 |
+
<use>core_read</use>
|
39 |
+
</connection>
|
40 |
+
</paystandgateway_read>
|
41 |
+
</resources>
|
42 |
+
|
43 |
+
<helpers>
|
44 |
+
<paystandgateway>
|
45 |
+
<class>PayStand_PayStandGateway_Helper</class>
|
46 |
+
</paystandgateway>
|
47 |
+
</helpers>
|
48 |
+
</global>
|
49 |
+
|
50 |
+
<default>
|
51 |
+
<payment>
|
52 |
+
<paystandgateway>
|
53 |
+
<active>1</active>
|
54 |
+
<model>paystandgateway/paymentMethod</model>
|
55 |
+
<order_status>pending</order_status>
|
56 |
+
<title>PayStand (Card, eCheck, Bitcoin)</title>
|
57 |
+
|
58 |
+
<payment_action>sale</payment_action>
|
59 |
+
<allowspecific>0</allowspecific>
|
60 |
+
<sort_order>1</sort_order>
|
61 |
+
</paystandgateway>
|
62 |
+
</payment>
|
63 |
+
</default>
|
64 |
+
|
65 |
+
<frontend>
|
66 |
+
<routers>
|
67 |
+
<paystandgateway>
|
68 |
+
<use>standard</use>
|
69 |
+
<args>
|
70 |
+
<module>PayStand_PayStandGateway</module>
|
71 |
+
<frontName>paystandgateway</frontName>
|
72 |
+
</args>
|
73 |
+
</paystandgateway>
|
74 |
+
</routers>
|
75 |
+
</frontend>
|
76 |
+
</config>
|
app/code/local/PayStand/PayStandGateway/etc/system.xml
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<sections>
|
4 |
+
<payment>
|
5 |
+
<groups>
|
6 |
+
<paystandgateway translate="label" module="paystandgateway">
|
7 |
+
<label>Paystand PayStandGateway</label>
|
8 |
+
<!-- position between other payment methods -->
|
9 |
+
<sort_order>670</sort_order>
|
10 |
+
<show_in_default>1</show_in_default>
|
11 |
+
<show_in_website>1</show_in_website>
|
12 |
+
<show_in_store>0</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 |
+
<order_status translate="label">
|
24 |
+
<label>New order status</label>
|
25 |
+
<frontend_type>select</frontend_type>
|
26 |
+
<source_model>adminhtml/system_config_source_order_status</source_model>
|
27 |
+
<sort_order>4</sort_order>
|
28 |
+
<show_in_default>1</show_in_default>
|
29 |
+
<show_in_website>1</show_in_website>
|
30 |
+
<show_in_store>0</show_in_store>
|
31 |
+
</order_status>
|
32 |
+
<org_id translate="label">
|
33 |
+
<label>Org Id</label>
|
34 |
+
<frontend_type>text</frontend_type>
|
35 |
+
<sort_order>2</sort_order>
|
36 |
+
<show_in_default>1</show_in_default>
|
37 |
+
<show_in_website>1</show_in_website>
|
38 |
+
<show_in_store>0</show_in_store>
|
39 |
+
</org_id>
|
40 |
+
<api_key translate="label">
|
41 |
+
<label>Public API Key</label>
|
42 |
+
<frontend_type>text</frontend_type>
|
43 |
+
<sort_order>2</sort_order>
|
44 |
+
<show_in_default>1</show_in_default>
|
45 |
+
<show_in_website>1</show_in_website>
|
46 |
+
<show_in_store>0</show_in_store>
|
47 |
+
</api_key>
|
48 |
+
<use_sandbox translate="label">
|
49 |
+
<label>Use Sandbox</label>
|
50 |
+
<frontend_type>select</frontend_type>
|
51 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
52 |
+
<sort_order>1</sort_order>
|
53 |
+
<show_in_default>1</show_in_default>
|
54 |
+
<show_in_website>1</show_in_website>
|
55 |
+
<show_in_store>0</show_in_store>
|
56 |
+
</use_sandbox>
|
57 |
+
</fields>
|
58 |
+
</paystandgateway>
|
59 |
+
</groups>
|
60 |
+
</payment>
|
61 |
+
</sections>
|
62 |
+
</config>
|
app/design/frontend/base/default/template/paystandgateway/redirect.phtml
ADDED
@@ -0,0 +1,270 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if (!defined('PS_LOG')) {
|
4 |
+
define('PS_LOG', 'paystand.log');
|
5 |
+
}
|
6 |
+
if (!defined('PS_LIVE_URL')) {
|
7 |
+
define('PS_LIVE_URL', 'https://app.paystand.com');
|
8 |
+
}
|
9 |
+
if (!defined('PS_SANDBOX_URL')) {
|
10 |
+
define('PS_SANDBOX_URL', 'https://dev.paystand.biz');
|
11 |
+
}
|
12 |
+
|
13 |
+
$order = new Mage_Sales_Model_Order();
|
14 |
+
$session = Mage::getSingleton('checkout/session');
|
15 |
+
$order_id = $session->getLastRealOrderId();
|
16 |
+
$order->loadByIncrementId($order_id);
|
17 |
+
|
18 |
+
$org_id = Mage::getStoreConfig('payment/paystandgateway/org_id');
|
19 |
+
if (empty($org_id)) {
|
20 |
+
Mage::log('ERROR: org_id not defined in system configuration.', null, PS_LOG);
|
21 |
+
}
|
22 |
+
Mage::log('org_id: ' . $org_id, null, PS_LOG);
|
23 |
+
|
24 |
+
$api_key = Mage::getStoreConfig('payment/paystandgateway/api_key');
|
25 |
+
if (empty($api_key)) {
|
26 |
+
Mage::log('ERROR: api_key not defined in system configuration.', null, PS_LOG);
|
27 |
+
}
|
28 |
+
|
29 |
+
$use_sandbox = Mage::getStoreConfig('payment/paystandgateway/use_sandbox');
|
30 |
+
if ($use_sandbox) {
|
31 |
+
$paystand_url = PS_SANDBOX_URL;
|
32 |
+
} else {
|
33 |
+
$paystand_url = PS_LIVE_URL;
|
34 |
+
}
|
35 |
+
Mage::log('paystand_url: ' . $paystand_url, null, PS_LOG);
|
36 |
+
|
37 |
+
$return_url = $this->getUrl('checkout/onepage/success');
|
38 |
+
|
39 |
+
$currency = $order->getBaseCurrencyCode();
|
40 |
+
$pre_fee_total = $order->getBaseGrandTotal();
|
41 |
+
Mage::log('pre_fee_total: ' . $pre_fee_total, null, PS_LOG);
|
42 |
+
$shipping_handling = $order->getBaseShippingAmount();
|
43 |
+
$tax = $order->getBaseTaxAmount();
|
44 |
+
|
45 |
+
// Convert to pennies
|
46 |
+
$pre_fee_total = round($pre_fee_total * 100.0);
|
47 |
+
$shipping_handling = round($shipping_handling * 100.0);
|
48 |
+
$tax = round($tax * 100.0);
|
49 |
+
$subtotal = $pre_fee_total - $shipping_handling - $tax;
|
50 |
+
|
51 |
+
$final_item_name = 'Payment for Order#: ' . $order_id;
|
52 |
+
$items = $order->getAllItems();
|
53 |
+
foreach ($items as $item) {
|
54 |
+
$name = $item->getName();
|
55 |
+
$qty = $item->getQtyOrdered();
|
56 |
+
$qtyi = intval($qty);
|
57 |
+
$qtyf = floatval($qty);
|
58 |
+
if ($qtyi == $qtyf) {
|
59 |
+
$qty = $qtyi;
|
60 |
+
}
|
61 |
+
$final_item_name .= ", " . $qty . ' x ' . $name;
|
62 |
+
}
|
63 |
+
if (strlen($final_item_name) > 127) {
|
64 |
+
$final_item_name = substr($final_item_name, 0, 124) . '...';
|
65 |
+
}
|
66 |
+
$final_item_name = html_entity_decode($final_item_name, ENT_NOQUOTES,
|
67 |
+
'UTF-8');
|
68 |
+
Mage::log('final_item_name: ' . $final_item_name, null, PS_LOG);
|
69 |
+
|
70 |
+
$addr = $order->getBillingAddress();
|
71 |
+
$first_name = $addr->getData('firstname');
|
72 |
+
$last_name = $addr->getData('lastname');
|
73 |
+
$billing_full_name = trim($first_name . ' ' . $last_name);
|
74 |
+
$billing_email_address = $addr->getData('email');
|
75 |
+
$billing_street = $addr->getData('street');
|
76 |
+
$billing_city = $addr->getData('city');
|
77 |
+
$billing_state_name = $addr->getData('region');
|
78 |
+
|
79 |
+
$state_codes = array(
|
80 |
+
'alabama' => 'AL',
|
81 |
+
'alaska' => 'AK',
|
82 |
+
'arizona' => 'AZ',
|
83 |
+
'arkansas' => 'AR',
|
84 |
+
'california' => 'CA',
|
85 |
+
'colorado' => 'CO',
|
86 |
+
'connecticut' => 'CT',
|
87 |
+
'delaware' => 'DE',
|
88 |
+
'district of columbia' => 'DC',
|
89 |
+
'florida' => 'FL',
|
90 |
+
'georgia' => 'GA',
|
91 |
+
'hawaii' => 'HI',
|
92 |
+
'idaho' => 'ID',
|
93 |
+
'illinois' => 'IL',
|
94 |
+
'indiana' => 'IN',
|
95 |
+
'iowa' => 'IA',
|
96 |
+
'kansas' => 'KS',
|
97 |
+
'kentucky' => 'KY',
|
98 |
+
'louisiana' => 'LA',
|
99 |
+
'maine' => 'ME',
|
100 |
+
'maryland' => 'MD',
|
101 |
+
'massachusetts' => 'MA',
|
102 |
+
'michigan' => 'MI',
|
103 |
+
'minnesota' => 'MN',
|
104 |
+
'mississippi' => 'MS',
|
105 |
+
'missouri' => 'MO',
|
106 |
+
'montana' => 'MT',
|
107 |
+
'nebraska' => 'NE',
|
108 |
+
'nevada' => 'NV',
|
109 |
+
'new hampshire' => 'NH',
|
110 |
+
'new jersey' => 'NJ',
|
111 |
+
'new mexico' => 'NM',
|
112 |
+
'new york' => 'NY',
|
113 |
+
'north carolina' => 'NC',
|
114 |
+
'north dakota' => 'ND',
|
115 |
+
'ohio' => 'OH',
|
116 |
+
'oklahoma' => 'OK',
|
117 |
+
'oregon' => 'OR',
|
118 |
+
'pennsylvania' => 'PA',
|
119 |
+
'rhode island' => 'RI',
|
120 |
+
'south carolina' => 'SC',
|
121 |
+
'south dakota' => 'SD',
|
122 |
+
'tennessee' => 'TN',
|
123 |
+
'texas' => 'TX',
|
124 |
+
'utah' => 'UT',
|
125 |
+
'vermont' => 'VT',
|
126 |
+
'virginia' => 'VA',
|
127 |
+
'washington' => 'WA',
|
128 |
+
'west virginia' => 'WV',
|
129 |
+
'wisconsin' => 'WI',
|
130 |
+
'wyoming' => 'WY'
|
131 |
+
);
|
132 |
+
$billing_state_code = empty($state_codes[strtolower($billing_state_name)])
|
133 |
+
? false : $state_codes[strtolower($billing_state_name)];
|
134 |
+
$billing_state = empty($billing_state_code)
|
135 |
+
? $billing_state_name : $billing_state_code;
|
136 |
+
|
137 |
+
$billing_postalcode = $addr->getData('postcode');
|
138 |
+
$billing_country = $addr->getData('country_id');
|
139 |
+
$billing_phone = $addr->getData('telephone');
|
140 |
+
|
141 |
+
// json_encode parameters that users can enter to protect against quotes
|
142 |
+
// and other troublesome characters
|
143 |
+
if (is_numeric($org_id)) {
|
144 |
+
// We want to pass it as a string
|
145 |
+
$org_id_json = '"' . $org_id . '"';
|
146 |
+
} else {
|
147 |
+
// Probably bogus but maybe valid in the future
|
148 |
+
$org_id_json = json_encode($org_id);
|
149 |
+
}
|
150 |
+
$api_key_json = json_encode($api_key);
|
151 |
+
$return_url_json = json_encode($return_url);
|
152 |
+
$final_item_name_json = json_encode($final_item_name);
|
153 |
+
|
154 |
+
$billing_full_name_json = json_encode($billing_full_name);
|
155 |
+
$billing_email_address_json = json_encode($billing_email_address);
|
156 |
+
$billing_street_json = json_encode($billing_street);
|
157 |
+
$billing_city_json = json_encode($billing_city);
|
158 |
+
$billing_state_json = json_encode($billing_state);
|
159 |
+
$billing_postalcode_json = json_encode($billing_postalcode);
|
160 |
+
$billing_country_json = json_encode($billing_country);
|
161 |
+
$billing_phone_json = json_encode($billing_phone);
|
162 |
+
|
163 |
+
$markup = <<<EOF
|
164 |
+
<h2>Opening PayStand Checkout</h2>
|
165 |
+
<div id="paystand_element_id"></div>
|
166 |
+
<script type="text/javascript">
|
167 |
+
|
168 |
+
var PayStand = PayStand || {};
|
169 |
+
PayStand.checkouts = PayStand.checkouts || [];
|
170 |
+
PayStand.load = PayStand.load || function(){};
|
171 |
+
|
172 |
+
PayStand.checkoutUpdated = function() {
|
173 |
+
console.log('checkoutUpdated called.');
|
174 |
+
}
|
175 |
+
|
176 |
+
PayStand.checkoutComplete = function() {
|
177 |
+
console.log('checkoutComplete called.');
|
178 |
+
window.top.location.href = {$return_url_json};
|
179 |
+
}
|
180 |
+
|
181 |
+
var autoCheckout = {
|
182 |
+
api_key: {$api_key_json},
|
183 |
+
org_id: {$org_id_json},
|
184 |
+
element_ids: ["paystand_element_id"],
|
185 |
+
data_source: "org_defined",
|
186 |
+
st_platform: "magento-1.0.1",
|
187 |
+
checkout_type: "button",
|
188 |
+
redirect_url: {$return_url_json},
|
189 |
+
currency: "{$currency}",
|
190 |
+
amount: "{$subtotal}",
|
191 |
+
shipping_handling: "{$shipping_handling}",
|
192 |
+
tax: "{$tax}",
|
193 |
+
items: [
|
194 |
+
{
|
195 |
+
title: {$final_item_name_json},
|
196 |
+
quantity: "1",
|
197 |
+
item_price: "{$subtotal}"
|
198 |
+
}
|
199 |
+
],
|
200 |
+
billing: {
|
201 |
+
full_name: {$billing_full_name_json},
|
202 |
+
email_address: {$billing_email_address_json},
|
203 |
+
street: {$billing_street_json},
|
204 |
+
city: {$billing_city_json},
|
205 |
+
postalcode: {$billing_postalcode_json},
|
206 |
+
state: {$billing_state_json},
|
207 |
+
country: {$billing_country_json},
|
208 |
+
shipping_same: true
|
209 |
+
},
|
210 |
+
meta: {
|
211 |
+
order_id: "{$order_id}"
|
212 |
+
}
|
213 |
+
}
|
214 |
+
|
215 |
+
var buttonCheckout = {
|
216 |
+
api_key: {$api_key_json},
|
217 |
+
org_id: {$org_id_json},
|
218 |
+
element_ids: ["paystand_element_id"],
|
219 |
+
data_source: "org_defined",
|
220 |
+
st_platform: "magento-1.0.1",
|
221 |
+
checkout_type: "button",
|
222 |
+
redirect_url: {$return_url_json},
|
223 |
+
button_options: {
|
224 |
+
button_name: 'Pay with PayStand',
|
225 |
+
input: false,
|
226 |
+
variants: false
|
227 |
+
},
|
228 |
+
currency: "{$currency}",
|
229 |
+
amount: "{$subtotal}",
|
230 |
+
shipping_handling: "{$shipping_handling}",
|
231 |
+
tax: "{$tax}",
|
232 |
+
items: [
|
233 |
+
{
|
234 |
+
title: {$final_item_name_json},
|
235 |
+
quantity: "1",
|
236 |
+
item_price: "{$subtotal}"
|
237 |
+
}
|
238 |
+
],
|
239 |
+
billing: {
|
240 |
+
full_name: {$billing_full_name_json},
|
241 |
+
email_address: {$billing_email_address_json},
|
242 |
+
street: {$billing_street_json},
|
243 |
+
city: {$billing_city_json},
|
244 |
+
postalcode: {$billing_postalcode_json},
|
245 |
+
state: {$billing_state_json},
|
246 |
+
country: {$billing_country_json},
|
247 |
+
shipping_same: true
|
248 |
+
},
|
249 |
+
meta: {
|
250 |
+
order_id: "{$order_id}"
|
251 |
+
}
|
252 |
+
}
|
253 |
+
|
254 |
+
PayStand.checkouts.push(buttonCheckout);
|
255 |
+
|
256 |
+
PayStand.onLoad = function() {
|
257 |
+
PayStand.execute(autoCheckout);
|
258 |
+
};
|
259 |
+
|
260 |
+
PayStand.script = document.createElement('script');
|
261 |
+
PayStand.script.type = 'text/javascript';
|
262 |
+
PayStand.script.async = true;
|
263 |
+
PayStand.script.src = '{$paystand_url}/js/checkout.js';
|
264 |
+
var s = document.getElementsByTagName('script')[0];
|
265 |
+
s.parentNode.insertBefore(PayStand.script, s);
|
266 |
+
</script>
|
267 |
+
EOF;
|
268 |
+
|
269 |
+
echo $markup;
|
270 |
+
|
app/etc/modules/PayStand_PayStandGateway.xml
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<config>
|
2 |
+
<modules>
|
3 |
+
<PayStand_PayStandGateway>
|
4 |
+
<active>true</active>
|
5 |
+
<codePool>local</codePool>
|
6 |
+
<depends>
|
7 |
+
<Mage_Payment />
|
8 |
+
</depends>
|
9 |
+
</PayStand_PayStandGateway>
|
10 |
+
</modules>
|
11 |
+
</config>
|
12 |
+
|
package.xml
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<package>
|
3 |
+
<name>PayStand_PayStandGateway</name>
|
4 |
+
<version>1.0.2</version>
|
5 |
+
<stability>stable</stability>
|
6 |
+
<license uri="http://www.apache.org/licenses/LICENSE-2.0">Apache Software License</license>
|
7 |
+
<channel>community</channel>
|
8 |
+
<extends/>
|
9 |
+
<summary>The PayStand payment gateway provides next generation payment processing for Card, eCheck, and Bitcoin.</summary>
|
10 |
+
<description>PayStand provides modern payment processing with multiple payment methods including Credit Cards, eCheck, and Bitcoin. Requires Magento 1.5+ and a PayStand account. Sign up for an account at paystand.com</description>
|
11 |
+
<notes>This is the initial version. Please provide feedback to support@paystand.com</notes>
|
12 |
+
<authors><author><name>Scott Campbell</name><user>paystand</user><email>developers@paystand.com</email></author></authors>
|
13 |
+
<date>2015-12-31</date>
|
14 |
+
<time>05:22:12</time>
|
15 |
+
<contents><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="paystandgateway"><file name="redirect.phtml" hash="6bbf31e22f005f6dedaa0398d6ac5764"/></dir></dir></dir></dir></dir></target><target name="magelocal"><dir name="PayStand"><dir name="PayStandGateway"><dir name="Helper"><file name="Data.php" hash="a9c3c81147c6f2ac30498b2e94f16e7a"/></dir><dir name="Model"><file name="PaymentMethod.php" hash="a4371f08a9efd412073fe4038ac2e0b2"/></dir><dir name="controllers"><file name="PaymentController.php" hash="83adb50fb7535d57324c200bff0bdf4b"/></dir><dir name="etc"><file name="config.xml" hash="e364cf4ae17cabcfd8aa39dce34207db"/><file name="system.xml" hash="d88e4dbf2ce6cdc569478033f01805ee"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="PayStand_PayStandGateway.xml" hash="79a872581f3fe52e1dd3e9b0d34b1038"/></dir></target></contents>
|
16 |
+
<compatible/>
|
17 |
+
<dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php><package><name>Mage_Core_Modules</name><channel>community</channel><min>1.6.0</min><max>1.9.2</max></package><extension><name>Core</name><min/><max/></extension></required></dependencies>
|
18 |
+
</package>
|