SecurePay_SecureXML - Version 1.0.8.6

Version Notes

Provides support for the following kinds of credit-card transactions, via the SecurePay gateway:
Standard payment
Preauthorize
Complete
Void
Refund
FraudGuard (Standard & Preauthorize)

Download this release

Release Info

Developer John
Extension SecurePay_SecureXML
Version 1.0.8.6
Comparing to
See all releases


Code changes from version 1.0.7 to 1.0.8.6

app/code/local/SecurePay/Sxml/Block/Form/Cc.php CHANGED
@@ -1,12 +1,12 @@
1
- <?php
2
-
3
- class SecurePay_Sxml_Block_Form_Cc extends Mage_Payment_Block_Form_Cc
4
- {
5
- protected function _construct()
6
- {
7
- parent::_construct();
8
- $this->setTemplate('sxml/form/cc.phtml');
9
- }
10
- }
11
-
12
  ?>
1
+ <?php
2
+
3
+ class SecurePay_Sxml_Block_Form_Cc extends Mage_Payment_Block_Form_Cc
4
+ {
5
+ protected function _construct()
6
+ {
7
+ parent::_construct();
8
+ $this->setTemplate('sxml/form/cc.phtml');
9
+ }
10
+ }
11
+
12
  ?>
app/code/local/SecurePay/Sxml/Model/Sxml.php CHANGED
@@ -155,6 +155,7 @@ class SecurePay_Sxml_Model_Sxml extends Mage_Payment_Model_Method_Cc
155
  $status = $sxml->getResultByKeyName('responseCode');
156
 
157
  $payment->setCcTransId(''.$preauthID);
 
158
 
159
  if($this->getDebug())
160
  {
@@ -248,6 +249,7 @@ class SecurePay_Sxml_Model_Sxml extends Mage_Payment_Model_Method_Cc
248
  if($bankTxnID)
249
  {
250
  $payment->setCcTransId(''.$bankTxnID);
 
251
  }
252
 
253
  if($this->getDebug())
@@ -315,6 +317,7 @@ class SecurePay_Sxml_Model_Sxml extends Mage_Payment_Model_Method_Cc
315
  if($bankTxnID)
316
  {
317
  $payment->setCcTransId(''.$bankTxnID);
 
318
  }
319
 
320
  if($this->getDebug())
155
  $status = $sxml->getResultByKeyName('responseCode');
156
 
157
  $payment->setCcTransId(''.$preauthID);
158
+ $payment->setTransactionId(''.$preauthID);
159
 
160
  if($this->getDebug())
161
  {
249
  if($bankTxnID)
250
  {
251
  $payment->setCcTransId(''.$bankTxnID);
252
+ $payment->setTransactionId(''.$bankTxnID);
253
  }
254
 
255
  if($this->getDebug())
317
  if($bankTxnID)
318
  {
319
  $payment->setCcTransId(''.$bankTxnID);
320
+ $payment->setTransactionId(''.$bankTxnID);
321
  }
322
 
323
  if($this->getDebug())
app/code/local/SecurePay/Sxml/Model/Sxml/PaymentAction.php CHANGED
@@ -1,37 +1,37 @@
1
- <?php
2
- /**
3
- * SecurePay SecurePayXML Extension
4
- *
5
- * NOTICE OF LICENSE
6
- *
7
- * This source file is subject to the Open Software License (OSL 3.0)
8
- * that is bundled with this package in the file LICENSE.txt.
9
- * It is also available through the world-wide-web at this URL:
10
- * http://opensource.org/licenses/osl-3.0.php
11
- * If you did not receive a copy of the license and are unable to
12
- * obtain it through the world-wide-web, please send an email
13
- * to license@magentocommerce.com so we can send you a copy immediately.
14
- *
15
- * @category SecurePay
16
- * @package SecurePay_SecurePayXML
17
- * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
18
- */
19
-
20
- class SecurePay_Sxml_Model_Sxml_PaymentAction
21
- {
22
- public function toOptionArray()
23
- {
24
- return array(
25
- array(
26
- 'value' => SecurePay_Sxml_Model_Sxml::PAYMENT_ACTION_AUTH_CAPTURE,
27
- 'label' => Mage::helper('Sxml')->__('Authorize and Capture')
28
- ),
29
- array(
30
- 'value' => SecurePay_Sxml_Model_Sxml::PAYMENT_ACTION_AUTH,
31
- 'label' => Mage::helper('Sxml')->__('Authorize')
32
- )
33
- );
34
- }
35
- }
36
-
37
- ?>
1
+ <?php
2
+ /**
3
+ * SecurePay SecurePayXML Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * @category SecurePay
16
+ * @package SecurePay_SecurePayXML
17
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
18
+ */
19
+
20
+ class SecurePay_Sxml_Model_Sxml_PaymentAction
21
+ {
22
+ public function toOptionArray()
23
+ {
24
+ return array(
25
+ array(
26
+ 'value' => SecurePay_Sxml_Model_Sxml::PAYMENT_ACTION_AUTH_CAPTURE,
27
+ 'label' => Mage::helper('Sxml')->__('Authorize and Capture')
28
+ ),
29
+ array(
30
+ 'value' => SecurePay_Sxml_Model_Sxml::PAYMENT_ACTION_AUTH,
31
+ 'label' => Mage::helper('Sxml')->__('Authorize')
32
+ )
33
+ );
34
+ }
35
+ }
36
+
37
+ ?>
app/code/local/SecurePay/Sxml/Model/Sxml/Request.php CHANGED
@@ -1,8 +1,8 @@
1
- <?php
2
-
3
- class SecurePay_Sxml_Model_Sxml_Request extends Varien_Object
4
- {
5
-
6
- }
7
-
8
- ?>
1
+ <?php
2
+
3
+ class SecurePay_Sxml_Model_Sxml_Request extends Varien_Object
4
+ {
5
+
6
+ }
7
+
8
+ ?>
app/code/local/SecurePay/Sxml/etc/config.xml CHANGED
@@ -22,28 +22,28 @@
22
  </blocks>
23
  <helpers>
24
  <Sxml>
25
- <class>SecurePay_sxml_Helper</class>
26
  </Sxml>
27
  </helpers>
28
  <resources>
29
- <sxml_setup>
30
  <setup>
31
- <module>SecurePay_sxml</module>
32
  </setup>
33
  <connection>
34
  <use>local_setup</use>
35
  </connection>
36
- </sxml_setup>
37
- <sxml_write>
38
  <connection>
39
  <use>local_write</use>
40
  </connection>
41
- </sxml_write>
42
- <sxml_read>
43
  <connection>
44
  <use>local_read</use>
45
  </connection>
46
- </sxml_read>
47
  </resources>
48
  <payment>
49
  <cc>
22
  </blocks>
23
  <helpers>
24
  <Sxml>
25
+ <class>SecurePay_Sxml_Helper</class>
26
  </Sxml>
27
  </helpers>
28
  <resources>
29
+ <Sxml_setup>
30
  <setup>
31
+ <module>SecurePay_Sxml</module>
32
  </setup>
33
  <connection>
34
  <use>local_setup</use>
35
  </connection>
36
+ </Sxml_setup>
37
+ <Sxml_write>
38
  <connection>
39
  <use>local_write</use>
40
  </connection>
41
+ </Sxml_write>
42
+ <Sxml_read>
43
  <connection>
44
  <use>local_read</use>
45
  </connection>
46
+ </Sxml_read>
47
  </resources>
48
  <payment>
49
  <cc>
app/code/local/SecurePay/securepay_xml_api.php CHANGED
@@ -1,1157 +1,1121 @@
1
- <?php
2
-
3
- /**
4
- * securepay_xml_api.php:
5
- *
6
- * Contains a class for sending transaction requests to SecurePay,
7
- * and receiving responses from the SecurePay via the XML API
8
- *
9
- * This class requires cURL to be available to PHP
10
- *
11
- */
12
-
13
- define( 'SECUREPAY_GATEWAY_MODE_TEST', 1);
14
- define( 'SECUREPAY_GATEWAY_MODE_LIVE', 2);
15
- define( 'SECUREPAY_GATEWAY_MODE_PERIODIC_TEST', 3);
16
- define( 'SECUREPAY_GATEWAY_MODE_PERIODIC_LIVE', 4);
17
-
18
- /* The valid transaction types for this interface. */
19
-
20
- define( 'SECUREPAY_TXN_STANDARD', 0);
21
- define( 'SECUREPAY_TXN_REFUND', 4);
22
- define( 'SECUREPAY_TXN_REVERSE', 6);
23
- define( 'SECUREPAY_TXN_PREAUTH', 10); //To be included in a future revision
24
- define( 'SECUREPAY_TXN_ADVICE', 11);
25
-
26
- define( 'SECUREPAY_TXN_DIRECTDEBIT', 15); //To be included in a future revision
27
- define( 'SECUREPAY_TXN_DIRECTCREDIT', 17);
28
-
29
- define( 'SECUREPAY_TXN_IVR', 20);
30
-
31
- define( 'SECUREPAY_REQ_ECHO', 'Echo'); //To be included in a future revision
32
- define( 'SECUREPAY_REQ_PAYMENT', 'Payment');
33
- define( 'SECUREPAY_REQ_PERIODIC', 'Periodic'); //To be included in a future revision
34
-
35
- define( 'CURRENCY_DEFAULT', 'AUD');
36
-
37
- /**
38
- * securepay_xml_transaction
39
- *
40
- * This class handles XML SecurePay transactions
41
- *
42
- * It supports the following tranactions:
43
- * Credit Payment (standard)
44
- * Credit Refund
45
- * Credit Reversal
46
- * Credit Preauthorisation
47
- * Credit Preauthorised completion (Advice)
48
- *
49
- * It partially supports the following transactions (which are not yet required):
50
- * Direct Entry Credit
51
- * Direct Entry Debit
52
- *
53
- * It can support the following transactions in future:
54
- * Add Trigger/Peridic Payment
55
- * Delete Trigger/Periodic Payment
56
- * Trigger Triggered payment
57
- *
58
- * @param int mode - The kind of transaction object you would like to open. i.e. SECUREPAY_GATEWAY_MODE_TEST See top of this file for definitions.
59
- * @param string merchantID - The merchant's login ID, received from SecurePay
60
- * @param string merchantPW - The merchant's login password
61
- */
62
-
63
- class securepay_xml_transaction
64
- {
65
- const SECUREPAY_TEST_HOST = "https://www.securepay.com.au/test/payment";
66
- const SECUREPAY_LIVE_HOST = "https://www.securepay.com.au/xmlapi/payment";
67
-
68
- const TIMEOUT="60";
69
-
70
- const GATEWAY_ERROR_OBJECT_INVALID = "The Gateway Object is invalid (constructor failure?)";
71
- const GATEWAY_ERROR_CURL_ERROR = "CURL failed and reported the following error";
72
- const GATEWAY_ERROR_INVALID_CCNUMBER = "Parameter Check failure: Invalid credit card number";
73
- const GATEWAY_ERROR_INVALID_CCEXPIRY = "Parameter Check failure: Invalid credit card expiry date";
74
- const GATEWAY_ERROR_INVALID_CC_CVC = "Parameter Check failure: Invalid credit card verification code";
75
- const GATEWAY_ERROR_INVALID_TXN_AMT = "Parameter Check failure: Invalid transaction amount";
76
- const GATEWAY_ERROR_INVALID_REF_ID = "Parameter Check failure: Invalid transaction reference number";
77
- const GATEWAY_ERROR_INVALID_ACCOUNTNUMBER = "Parameter Check failure: Invalid account number";
78
- const GATEWAY_ERROR_INVALID_ACCOUNTNAME = "Parameter Check failure: Invalid account name";
79
- const GATEWAY_ERROR_INVALID_ACCOUNTBSB = "Parameter Check failure: Invalid BSB";
80
- const GATEWAY_ERROR_RESPONSE_ERROR = "A general response error was detected";
81
- const GATEWAY_ERROR_RESPONSE_INVALID = "A unspecified error was detected in the response content";
82
- const GATEWAY_ERROR_XML_PARSE_FAILED = "The response message could not be parsed (invalid XML?)";
83
- const GATEWAY_ERROR_RESPONSE_XML_MESSAGE_ERROR = "An unspecified error was found in the response message (missing field?)";
84
- const GATEWAY_ERROR_SECUREPAY_STATUS = "The remote Gateway reported the following status error";
85
- const GATEWAY_ERROR_TXN_DECLINED = "Transaction Declined";
86
-
87
- private $errorString;
88
- private $gatewayObjectValid = true;
89
- private $gatewayURL;
90
- private $merchantID;
91
- private $merchantPW;
92
- private $responseArray = array();
93
- private $txnType;
94
-
95
- private $ccNumber;
96
- private $ccVerify;
97
- private $ccExpiryMonth;
98
- private $ccExpiryYear;
99
-
100
- private $accNumber;
101
- private $accBSB;
102
- private $accName;
103
-
104
- private $txnReference;
105
- private $amount;
106
-
107
- private $currency=CURRENCY_DEFAULT;
108
-
109
- private $requestType;
110
- private $periodicType;
111
- private $periodicInterval;
112
-
113
- private $bankTxnID = 0;
114
-
115
- /**
116
- * __construct
117
- *
118
- * @param integer $gatewaymode
119
- * @param string $setup_merchantID
120
- * @param string $setup_merchantPW
121
- *
122
- */
123
- public function __construct( $gatewaymode, $setup_merchantID, $setup_merchantPW)
124
- {
125
-
126
- switch ( $gatewaymode )
127
- {
128
- case SECUREPAY_GATEWAY_MODE_TEST:
129
- $this->gatewayURL = self::SECUREPAY_TEST_HOST;
130
- break;
131
-
132
- case SECUREPAY_GATEWAY_MODE_LIVE:
133
- $this->gatewayURL = self::SECUREPAY_LIVE_HOST;
134
- break;
135
-
136
- default:
137
- $this->gatewayObjectValid = false;
138
- return;
139
- }
140
-
141
- if ( strlen( $setup_merchantID ) == 0
142
- || strlen( $setup_merchantPW ) == 0 )
143
- {
144
- $this->gatewayObjectValid = false;
145
- return;
146
- }
147
-
148
- $this->setAuth($setup_merchantID,$setup_merchantPW);
149
-
150
- }
151
-
152
- /**
153
- * reset
154
- *
155
- * To clear response variables: prevents mismatched results in certain failure cases.
156
- * This is called before each transaction, so be sure to check these values between transactions.
157
- */
158
- public function reset()
159
- {
160
- $this->errorString = NULL;
161
- $this->responseArray = array();
162
- $this->bankTxnID = 0;
163
- }
164
-
165
- public function isGatewayObjectValid()
166
- {
167
- return $this->gatewayObjectValid;
168
- }
169
-
170
- public function getAmount()
171
- {
172
- return $this->amount;
173
- }
174
-
175
- /**
176
- * setAmount
177
- *
178
- * Takes amount as a float; requires currency to be set
179
- *
180
- * @param float amount
181
- */
182
- public function setAmount($amount)
183
- {
184
- if($this->getCurrency() == 'JPY')
185
- $this->amount = $amount;
186
- else
187
- $this->amount = round($amount*100,0);
188
- return;
189
- }
190
-
191
- public function getCurrency()
192
- {
193
- return $this->currency;
194
- }
195
-
196
- public function setCurrency($cur)
197
- {
198
- $this->currency = $cur;
199
- return;
200
- }
201
-
202
- public function getTxnReference()
203
- {
204
- return $this->txnReference;
205
- }
206
-
207
- public function setTxnReference($ref)
208
- {
209
- $this->txnReference = $ref;
210
- return;
211
- }
212
-
213
- public function getTxnType()
214
- {
215
- return $this->txnType;
216
- }
217
-
218
- public function setTxnType($type)
219
- {
220
- $this->txnType = $type;
221
- return;
222
- }
223
-
224
- public function getPreauthID()
225
- {
226
- return $this->preauthID;
227
- }
228
-
229
- public function setPreauthID($id)
230
- {
231
- $this->preauthID = $id;
232
- return;
233
- }
234
-
235
- public function getAccBSB()
236
- {
237
- return $this->accBSB;
238
- }
239
-
240
- public function setAccBSB($bsb)
241
- {
242
- $this->accBSB = $bsb;
243
- return;
244
- }
245
-
246
- public function getAccNumber()
247
- {
248
- return $this->accNumber;
249
- }
250
-
251
- public function setAccNumber($Number)
252
- {
253
- $this->accNumber = $Number;
254
- return;
255
- }
256
-
257
- public function getAccName()
258
- {
259
- return $this->accName;
260
- }
261
-
262
- public function setAccName($name)
263
- {
264
- $this->accName = $name;
265
- return;
266
- }
267
-
268
- public function getCCNumber()
269
- {
270
- return $this->ccNumber;
271
- }
272
-
273
- public function setCCNumber($ccNumber)
274
- {
275
- $this->ccNumber = $ccNumber;
276
- return;
277
- }
278
-
279
- public function getClearCCNumber()
280
- {
281
- $t = $this->getCCNumber();
282
- $this->setCCNumber("0");
283
- return $t;
284
- }
285
-
286
- public function getCCVerify()
287
- {
288
- return $this->ccVerify;
289
- }
290
-
291
- public function setCCVerify($ver)
292
- {
293
- $this->ccVerify = $ver;
294
- return;
295
- }
296
-
297
- public function getClearCCVerify()
298
- {
299
- $t = $this->getCCVerify();
300
- $this->setCCVerify(0);
301
- return $t;
302
- }
303
-
304
- /* @return string month MM*/
305
- public function getCCExpiryMonth()
306
- {
307
- return $this->ccExpiryMonth;
308
- }
309
-
310
- /* @param string/int month MM or month M - If there are leading zeros, type needs to be a string*/
311
- public function setCCExpiryMonth($month)
312
- {
313
- $l = strlen(trim($month));
314
- if($l == 1)
315
- $this->ccExpiryMonth = sprintf("%02d",ltrim($month,'0'));
316
- else
317
- $this->ccExpiryMonth = $month;
318
- return;
319
- }
320
-
321
- /* @return string year YY*/
322
- public function getCCExpiryYear()
323
- {
324
- return $this->ccExpiryYear;
325
- }
326
-
327
- /* @param string year YY or year YYYY - If there are leading zeros, type needs to be a string*/
328
- public function setCCExpiryYear($year)
329
- {
330
- $y = ltrim(trim((string)$year),"0");
331
- $l = strlen($y);
332
- if($l==4)
333
- $this->ccExpiryYear = substr($y,2);
334
- else if($l>=5)
335
- $this->ccExpiryYear = 0;
336
- else if($l==1)
337
- $this->ccExpiryYear = sprintf("%02d",$y);
338
- else
339
- $this->ccExpiryYear = $year;
340
-
341
- return;
342
- }
343
-
344
- public function getMerchantID()
345
- {
346
- return $this->merchantID;
347
- }
348
-
349
- public function setMerchantID($id)
350
- {
351
- $this->merchantID = $id;
352
- return;
353
- }
354
-
355
- public function getMerchantPW ()
356
- {
357
- return $this->merchantPW;
358
- }
359
-
360
- public function setMerchantPW ($pw)
361
- {
362
- $this->merchantPW = $pw;
363
- return;
364
- }
365
-
366
- public function getBankTxnID ()
367
- {
368
- return $this->bankTxnID;
369
- }
370
-
371
- public function setBankTxnID ($id)
372
- {
373
- $this->bankTxnID = $id;
374
- return;
375
- }
376
-
377
- public function getRequestType ()
378
- {
379
- return $this->requestType;
380
- }
381
-
382
- public function setRequestType ($t)
383
- {
384
- $this->requestType = $t;
385
- return;
386
- }
387
-
388
- public function getPeriodicType ()
389
- {
390
- return $this->periodicType;
391
- }
392
-
393
- public function setPeriodicType ($t)
394
- {
395
- $this->periodicType = $t;
396
- return;
397
- }
398
-
399
- public function getPeriodicInterval ()
400
- {
401
- return $this->periodicInterval;
402
- }
403
-
404
- public function setPeriodicInterval ($t)
405
- {
406
- $this->periodicInterval = $t;
407
- return;
408
- }
409
-
410
- public function getErrorString ()
411
- {
412
- return $this->errorString;
413
- }
414
-
415
- public function getResultArray ()
416
- {
417
- return $this->responseArray;
418
- }
419
-
420
- public function getResultByKeyName ( $keyName)
421
- {
422
- if ( array_key_exists( $keyName, $this->responseArray) === true )
423
- {
424
- return $this->responseArray[$keyName];
425
- }
426
- else
427
- return false;
428
- }
429
-
430
- public function getTxnWasSuccesful()
431
- {
432
- if ( array_key_exists( "txnResult", $this->responseArray) === true
433
- && $this->responseArray["txnResult"] === true )
434
- return true;
435
- else
436
- return false;
437
- }
438
-
439
- public function setAuth($id, $pw)
440
- {
441
- $this->setMerchantID($id);
442
- $this->setMerchantPW($pw);
443
- return;
444
- }
445
-
446
- /**
447
- * processCreditStandard:
448
- *
449
- * Process a standard credit card payment
450
- *
451
- * @param float amount - Numeric and decimal only: no thousand separators
452
- * @param string txnReference - Merchant's unique transaction ID
453
- * @param int cardNumber - 12-18 digit credit-card number
454
- * @param int cardMonth - 2 digit month
455
- * @param int cardYear - 2 or 4 digit year
456
- * @param int cardVerify - 3 or 4 digit CVV (optional)
457
- * @param string currency - Exactly three characters. See SecurePay documentation for list of valid currencies. (optional)
458
- *
459
- * @return string txnID - Bank's unique transaction ID (use for reversal or refund), or FALSE in case of failure (check $this->getErrorText() afterwards).
460
- */
461
- public function processCreditStandard($amount, $txnReference, $cardNumber, $cardMonth, $cardYear, $cardVerify=0, $currency=CURRENCY_DEFAULT)
462
- {
463
- $this->reset();
464
-
465
- $this->setTxnType(SECUREPAY_TXN_STANDARD);
466
-
467
- $this->setAmount($amount);
468
- $this->setTxnReference($txnReference);
469
- $this->setCCNumber($cardNumber);
470
- if(strlen($cardVerify)!=0)
471
- $this->setCCVerify($cardVerify);
472
- $this->setCCExpiryYear($cardYear);
473
- $this->setCCExpiryMonth($cardMonth);
474
- if($currency)
475
- $this->setCurrency($currency);
476
-
477
- if($this->processTransaction());
478
- if(array_key_exists('banktxnID',$this->responseArray))
479
- return $this->responseArray['banktxnID'];
480
- return false;
481
- }
482
-
483
- /**
484
- * processCreditRefund:
485
- *
486
- * Refund a standard credit card payment. $amount can be less than the original transaction.
487
- *
488
- * @param float amount - Numeric and decimal only: no thousand separators
489
- * @param string txnReference - Merchant's unique transaction ID: must be same as in initial transaction
490
- * @param int txnID - Result of original transaction
491
- *
492
- * @return string txnID - Bank's unique transaction ID, or FALSE in case of failure (check $this->getErrorText() afterwards).
493
- */
494
- public function processCreditRefund($amount, $txnReference, $txnID)
495
- {
496
- $this->reset();
497
-
498
- $this->setTxnType(SECUREPAY_TXN_REFUND);
499
-
500
- $this->setAmount($amount);
501
- $this->setTxnReference($txnReference);
502
-
503
- $this->setBankTxnID($txnID);
504
-
505
- if($this->processTransaction());
506
- if(array_key_exists('banktxnID',$this->responseArray))
507
- return $this->responseArray['banktxnID'];
508
- return false;
509
- }
510
-
511
- /**
512
- * processCreditReverse:
513
- *
514
- * Reverse a standard credit card payment. $amount should be same as in original transaction.
515
- *
516
- * @param float amount - Numeric and decimal only: no thousand separators
517
- * @param string txnReference - Merchant's unique transaction ID: must be same as in initial transaction
518
- * @param int txnID - Result of original transaction
519
- *
520
- * @return string txnID - Bank's unique transaction ID, or FALSE in case of failure (check $this->getErrorText() afterwards).
521
- */
522
- public function processCreditReverse($amount, $txnReference, $txnID)
523
- {
524
- $this->reset();
525
-
526
- $this->setTxnType(SECUREPAY_TXN_REVERSE);
527
-
528
- $this->setAmount($amount);
529
- $this->setTxnReference($txnReference);
530
-
531
- $this->setBankTxnID($txnID);
532
-
533
- if($this->processTransaction());
534
- if(array_key_exists('banktxnID',$this->responseArray))
535
- return $this->responseArray['banktxnID'];
536
- return false;
537
- }
538
-
539
- /**
540
- * processCreditPreauth:
541
- *
542
- * Preauthorise a credit card payment
543
- *
544
- * @param float amount - Numeric and decimal only: no thousand separators
545
- * @param string txnReference - Merchant's unique transaction ID
546
- * @param int cardNumber - 12-18 digit credit-card number
547
- * @param int cardMonth - 2 digit month
548
- * @param int cardYear - 2 or 4 digit year
549
- * @param int cardVerify - 3 or 4 digit CVV (optional)
550
- * @param string currency - Exactly three characters. See SecurePay documentation for list of valid currencies. (optional)
551
- *
552
- * @return string preauthID - preauthorisation ID (use to execute transaction later (processCreditAdvice)), or FALSE (check $this->getErrorText() afterwards).
553
- */
554
- public function processCreditPreauth($amount, $txnReference, $cardNumber, $cardMonth, $cardYear, $cardVerify=0, $currency=CURRENCY_DEFAULT)
555
- {
556
- $this->reset();
557
-
558
- $this->setTxnType(SECUREPAY_TXN_PREAUTH);
559
-
560
- $this->setAmount($amount);
561
- $this->setTxnReference($txnReference);
562
- $this->setCCNumber($cardNumber);
563
- if(strlen($cardVerify)!=0)
564
- $this->setCCVerify($cardVerify);
565
- $this->setCCExpiryYear($cardYear);
566
- $this->setCCExpiryMonth($cardMonth);
567
-
568
- if($currency)
569
- $this->setCurrency($currency);
570
-
571
- if($this->processTransaction())
572
- {
573
- if(array_key_exists('preauthID',$this->responseArray))
574
- return $this->responseArray['preauthID'];
575
- }
576
-
577
- return false;
578
- }
579
-
580
- /**
581
- * processCreditAdvice:
582
- *
583
- * Execute a preauthorised transaction
584
- *
585
- * @param float amount - Numeric and decimal only: no thousand separators. Should be same as preauthorised amount.
586
- * @param string txnReference - Merchant's unique transaction ID: must be same as in initial transaction
587
- * @param string preauthID - Preauthorisation code which was returned from processCreditPreauth
588
- *
589
- * @return string txnID - Bank's unique transaction ID, or FALSE in case of failure (check $this->getErrorText() afterwards).
590
- */
591
- public function processCreditAdvice($amount, $txnReference, $preauthID)
592
- {
593
- $this->reset();
594
-
595
- $this->setTxnType(SECUREPAY_TXN_ADVICE);
596
-
597
- $this->setAmount($amount);
598
- $this->setTxnReference($txnReference);
599
- $this->setPreauthID($preauthID);
600
-
601
- if($this->processTransaction());
602
- if(array_key_exists('banktxnID',$this->responseArray))
603
- return $this->responseArray['banktxnID'];
604
- return false;
605
- }
606
-
607
- /*
608
- //Disabled for the time being: not required yet
609
- public function processDirectCredit($amount, $txnReference, $accName, $accBSB, $accNumber)
610
- {
611
- $this->reset();
612
-
613
- $this->setTxnType(SECUREPAY_TXN_DIRECTCREDIT);
614
-
615
- $this->setAmount($amount);
616
- $this->setTxnReference($txnReference);
617
- $this->setAccName($accName);
618
- $this->setAccNumber($accNumber);
619
- $this->setAccBSB($accBSB);
620
-
621
- return $this->processTransaction();
622
- }
623
-
624
- public function processDirectDebit($amount, $txnReference, $accName, $accBSB, $accNumber)
625
- {
626
- $this->reset();
627
-
628
- $this->setTxnType(SECUREPAY_TXN_DIRECTDEBIT);
629
-
630
- $this->setAmount($amount);
631
- $this->setTxnReference($txnReference);
632
- $this->setAccName($accName);
633
- $this->setAccNumber($accNumber);
634
- $this->setAccBSB($accBSB);
635
-
636
- return $this->processTransaction();
637
- }
638
- */
639
-
640
- /**
641
- * processTransaction:
642
- *
643
- * this function attempts to process a payment transaction using the
644
- * supplied details on the SecurePay SecureXML Gateway
645
- *
646
- * @return boolean Returns true for succesful (approved) transaction / false for failure (declined) or error
647
- *
648
- */
649
- private function processTransaction ()
650
- {
651
- // check that self is a valid gateway object
652
- if ( !$this->gatewayObjectValid )
653
- {
654
- $this->errorString = self::GATEWAY_ERROR_OBJECT_INVALID;
655
- return false;
656
- }
657
-
658
- // check parameters
659
- if( $this->getTxnType()==SECUREPAY_TXN_STANDARD ||
660
- $this->getTxnType()==SECUREPAY_TXN_PREAUTH )
661
- {
662
- if ($this->checkCCparameters() == false)
663
- return false;
664
- }
665
- else if ( $this->getTxnType()==SECUREPAY_TXN_DIRECTDEBIT ||
666
- $this->getTxnType()==SECUREPAY_TXN_DIRECTCREDIT )
667
- {
668
- if ($this->checkDirectparameters() == false)
669
- return false;
670
- }
671
- if ($this->checkTxnParameters() == false)
672
- {
673
- return false;
674
- }
675
-
676
- // create request message. This function will retrieve and destroy CC details, if we're in credit-card mode (!)
677
- $requestMessage = $this->createXMLTransactionRequestString();
678
-
679
- $this->responseArray["raw-XML-request"] = htmlentities($requestMessage);
680
-
681
- // send request
682
- $response = $this->sendRequest( $this->gatewayURL, $requestMessage );
683
-
684
- $this->responseArray["raw-response"] = htmlentities($response);
685
-
686
- // was a response received?
687
- if ( $response === false )
688
- {
689
- if ( strlen( $this->errorString ) == 0 )
690
- {
691
- $this->errorString = self::GATEWAY_ERROR_RESPONSE_ERROR;
692
- }
693
- return false;
694
- }
695
-
696
- // process response for validity
697
- if ( $this->processTransactionResponseMessageIntoResponseArray( $response ) === false )
698
- {
699
- if ( strlen( $this->errorString ) == 0 )
700
- {
701
- $this->errorString = self::GATEWAY_ERROR_RESPONSE_INVALID;
702
- }
703
- return false;
704
- }
705
-
706
- // if we get this far, the transaction is succesful and "approved"
707
- $this->responseArray["txnResult"] = true;
708
-
709
- return true;
710
- }
711
-
712
-
713
- /**
714
- * checkCCparameters
715
- *
716
- * Check the input parameters are valid for a credit card transaction
717
- *
718
- * @return boolean Return TRUE for all checks passed OK, or FALSE if an error is detected
719
- */
720
- private function checkCCparameters()
721
- {
722
- // the string ccNumber must be all numeric, and between 12 and 19 digits long
723
- if (strlen( $this->getCCNumber() ) < 12 ||
724
- strlen( $this->getCCNumber() ) > 19 ||
725
- preg_match("/\D/",$this->getCCNumber()) )// REGEXP: true if "any match for non-numeral"
726
- {
727
- $this->errorString = self::GATEWAY_ERROR_INVALID_CCNUMBER;
728
- return false;
729
- }
730
-
731
- // the string $ccExpiryMonth must be all numeric with value between 1 and 12
732
- if (preg_match("/\D/", $this->getCCExpiryMonth()) || // REGEXP: true if "any match for non-numeral"
733
- (int) $this->getCCExpiryMonth() < 1 ||
734
- (int) $this->getCCExpiryMonth() > 12 )
735
- {
736
- $this->errorString = self::GATEWAY_ERROR_INVALID_CCEXPIRY;
737
- return false;
738
- }
739
-
740
- // the string $ccExpiryYear must be all numeric with value between this year and this year + 12 years
741
- if (preg_match( "/\D/", $this->getCCExpiryYear()) || // REGEXP: true if "any match for non-numeral"
742
- (strlen($this->getCCExpiryYear()) != 2) || //YY form
743
- (int) $this->getCCExpiryYear() < (int) substr(date("Y"),2) || // Between now and now + 12
744
- (int) $this->getCCExpiryYear() > ( (int) substr(date("Y"),2) + 12 ) )
745
- {
746
- $this->errorString = self::GATEWAY_ERROR_INVALID_CCEXPIRY;
747
- return false;
748
- }
749
-
750
- // The CVC is an optional data item so only perform the checks if the parameter was present
751
- if ( strlen( $this->getCCVerify() ) != 0 )
752
- {
753
- // the string $ccVericationNumber must be all numeric with value between 000 and 9999
754
- if (preg_match( "/\D/", $this->getCCVerify() ) || // REGEXP: true if "any match for non-numeral"
755
- strlen( $this->getCCVerify() ) < 3 ||
756
- strlen( $this->getCCVerify() ) > 4 ||
757
- (int) $this->getCCVerify() < 0 ||
758
- (int) $this->getCCVerify() > 9999 )
759
- {
760
- $this->errorString = self::GATEWAY_ERROR_INVALID_CC_CVC;
761
- return false;
762
- }
763
- }
764
- return true;
765
- }
766
-
767
- /**
768
- * checkCCparameters
769
- *
770
- * Check the input parameters are valid for a credit card transaction
771
- *
772
- * @return boolean Return TRUE for all checks passed OK, or FALSE if an error is detected
773
- */
774
- private function checkDirectparameters()
775
- {
776
- // the string accNumber must be all numeric, and between 12 and 19 digits long
777
- if (preg_match( "/\D/", $this->getAccNumber() ) )// REGEXP: true if "any match for non-numeral"
778
- {
779
- $this->errorString = self::GATEWAY_ERROR_INVALID_ACCOUNTNUMBER;
780
- return false;
781
- }
782
-
783
- // the string $accName must be all numeric with value between 1 and 12
784
- if ( preg_match( "/\D/", $this->getAccName() )) // REGEXP: true if "any match for non-numeral"
785
- {
786
- print "Month\n";
787
- $this->errorString = self::GATEWAY_ERROR_INVALID_ACCOUNTNAME;
788
- return false;
789
- }
790
- // the string $accBSB must be all numeric with value between 000 and 9999
791
- if (preg_match( "/\D/", $this->getAccBSB())) // REGEXP: true if "any match for non-numeral"
792
- {
793
- $this->errorString = self::GATEWAY_ERROR_INVALID_BSB;
794
- return false;
795
- }
796
-
797
- return true;
798
- }
799
-
800
- /**
801
- * checkTxnParameters
802
- *
803
- * Check that the transaction input parameters are within requirements
804
- *
805
- * @param string $txnAmount
806
- * @param string $txnReference
807
- *
808
- * @return TRUE for pass, FALSE for fail
809
- */
810
- private function checkTxnParameters ()
811
- {
812
- $amount = $this->getAmount();
813
- if (preg_match( "/^[0-9]/", $amount)==false || (int) $amount < 0 )
814
- {
815
- $this->errorString = self::GATEWAY_ERROR_INVALID_TXN_AMT;
816
- return false;
817
- }
818
-
819
- $ref = $this->getTxnReference();
820
- if ( $this->getTxnType()==SECUREPAY_TXN_DIRECTDEBIT ||
821
- $this->getTxnType()==SECUREPAY_TXN_DIRECTCREDIT )
822
- {
823
- // Direct Entry Payment References need to conform to EBCDIC, and should be <= 18 characters
824
- if (strlen($ref) == 0 || strlen($ref)>18 ||
825
- preg_match('/[^0-9a-zA-Z*\.&\/-_\']/', $ref)) // REGEXP: match any non-EBCDIC character
826
- {
827
- $this->errorString = self::GATEWAY_ERROR_INVALID_REF_ID;
828
- return false;
829
- }
830
- }
831
- else
832
- {
833
- // Standard/Credit References can have any character except space and single quote
834
- if (strlen($ref) == 0 || strlen($ref)>59 ||
835
- preg_match('/[^ \']/', $ref)==false) // REGEXP: match invalid characters
836
- {
837
- $this->errorString = self::GATEWAY_ERROR_INVALID_REF_ID;
838
- return false;
839
- }
840
- }
841
- return true;
842
- }
843
-
844
- /**
845
- * createXMLTransactionRequestString:
846
- * Creates the XML request string for a transaction request message
847
- *
848
- * Note: calls to getClearCCNumber & getClearCCVerify: details are removed from their respective private variables here
849
- *
850
- * @return string xml_transaction
851
- */
852
- private function createXMLTransactionRequestString()
853
- {
854
- $x =
855
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>".
856
- "<SecurePayMessage>" .
857
- "<MessageInfo>" .
858
- "<messageID>".htmlentities($this->getTxnReference().date("his").current(split(' ',microtime( ))))."</messageID>".
859
- "<messageTimestamp>".htmlentities($this->getGMTTimeStamp())."</messageTimestamp>".
860
- "<timeoutValue>".self::TIMEOUT."</timeoutValue>".
861
- "<apiVersion>xml-4.2</apiVersion>" .
862
- "</MessageInfo>".
863
- "<MerchantInfo>".
864
- "<merchantID>".htmlentities($this->getMerchantID())."</merchantID>" .
865
- "<password>".htmlentities($this->getMerchantPW())."</password>" .
866
- "</MerchantInfo>".
867
- "<RequestType>Payment</RequestType>".
868
- "<Payment>".
869
- "<TxnList count=\"1\">".
870
- "<Txn ID=\"1\">".
871
- "<txnType>".htmlentities($this->getTxnType())."</txnType>".
872
- "<txnSource>23</txnSource>".
873
- "<amount>".htmlentities($this->getAmount())."</amount>";
874
- if( ($this->getTxnType()==SECUREPAY_TXN_STANDARD ||
875
- $this->getTxnType()==SECUREPAY_TXN_PREAUTH ) &&
876
- $this->getCurrency()!=CURRENCY_DEFAULT)
877
- {
878
- $x .= "<currency>".htmlentities($this->getCurrency())."</currency>";
879
- }
880
- $x .= "<purchaseOrderNo>".htmlentities($this->getTxnReference())."</purchaseOrderNo>";
881
- if( $this->getTxnType()==SECUREPAY_TXN_ADVICE)
882
- {
883
- $x .= "<preauthID>".htmlentities($this->getPreauthID())."</preauthID>";
884
- }
885
- if( $this->getTxnType()==SECUREPAY_TXN_REFUND ||
886
- $this->getTxnType()==SECUREPAY_TXN_REVERSE &&
887
- $this->getBankTxnID() != 0)
888
- {
889
- $x .= "<txnID>".htmlentities($this->getBankTxnID())."</txnID>";
890
- }
891
-
892
- if( $this->getTxnType()==SECUREPAY_TXN_STANDARD ||
893
- $this->getTxnType()==SECUREPAY_TXN_PREAUTH )
894
- {
895
- $x .= "<CreditCardInfo>".
896
- "<cardNumber>".htmlentities($this->getClearCCNumber())."</cardNumber>";
897
- if (trim($this->getCCVerify()) <> "")
898
- {
899
- $x .= "<cvv>".htmlentities($this->getClearCCVerify())."</cvv>";
900
- }
901
- $x .= "<expiryDate>".htmlentities(sprintf("%02d",$this->getCCExpiryMonth())."/".sprintf("%02d",$this->getCCExpiryYear()))."</expiryDate>".
902
- "</CreditCardInfo>";
903
- }
904
- else if ( $this->getTxnType()==SECUREPAY_TXN_DIRECTDEBIT ||
905
- $this->getTxnType()==SECUREPAY_TXN_DIRECTCREDIT )
906
- {
907
- $x .= "<DirectEntryInfo>".
908
- "<bsbNumber>".htmlentities($this->getAccBSB())."</bsbNumber>".
909
- "<accountNumber>".htmlentities($this->getAccNumber())."</accountNumber>".
910
- "<accountName>".htmlentities($this->getAccName())."</accountName>".
911
- "</DirectEntryInfo>";
912
- }
913
- $x .= "</Txn>".
914
- "</TxnList>".
915
- "</Payment>".
916
- "</SecurePayMessage>";
917
-
918
- return $x;
919
- }
920
-
921
-
922
- /**
923
- * getGMTTimeStamp:
924
- *
925
- * this function creates a timestamp formatted as per requirement in the
926
- * SecureXML documentation
927
- *
928
- * @return string The formatted timestamp
929
- */
930
- private function getGMTTimeStamp()
931
- {
932
- /* Format: YYYYDDMMHHNNSSKKK000sOOO
933
- YYYY is a 4-digit year
934
- DD is a 2-digit zero-padded day of month
935
- MM is a 2-digit zero-padded month of year (January = 01)
936
- HH is a 2-digit zero-padded hour of day in 24-hour clock format (midnight =0)
937
- NN is a 2-digit zero-padded minute of hour
938
- SS is a 2-digit zero-padded second of minute
939
- KKK is a 3-digit zero-padded millisecond of second
940
- 000 is a Static 0 characters, as SecurePay does not store nanoseconds
941
- sOOO is a Time zone offset, where s is �+� or �-�, and OOO = minutes, from GMT.
942
- */
943
-
944
-
945
- $val = date("Z") / 60;
946
- if ($val >= 0)
947
- {
948
- $val = "+" . strval($val);
949
- }
950
-
951
- $stamp = date("YdmGis000000") . $val;
952
-
953
- return $stamp;
954
- }
955
-
956
- /**
957
- * sendRequest:
958
- * uses cURL to open a Secure Socket connection to the gateway,
959
- * sends the transaction request and then returns the response
960
- * data
961
- *
962
- * @param $postURL The URL of the remote gateway to which the request is sent
963
- * @param $requestMessage
964
- */
965
- private function sendRequest( $postURL, $requestMessage )
966
- {
967
- $ch = curl_init();
968
-
969
- // Set up curl parameters
970
- curl_setopt( $ch, CURLOPT_URL, $postURL ); // set remote address
971
- curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 ); // Make CURL pass the response as a curl_exec return value instead of outputting to STDOUT
972
- curl_setopt( $ch, CURLOPT_POST, 1 ); // Activate the POST method
973
- curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
974
- curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 );
975
-
976
- curl_setopt( $ch, CURLOPT_POSTFIELDS, $requestMessage ); // add the request message itself
977
-
978
- // execute the connexion
979
- $result = curl_exec( $ch );
980
-
981
- $debugoutput = curl_getinfo($ch);
982
- $curl_error_message = curl_error( $ch ); // must retrieve an error message (if any) before closing the curl object
983
-
984
- curl_close($ch);
985
-
986
-
987
- if ( $result === false )
988
- {
989
- $this->errorString = self::GATEWAY_ERROR_CURL_ERROR.': '.$curl_error_message;
990
- return false;
991
- }
992
-
993
- // we do not need the header part of the response, trim it off the result
994
- $pos = strstr( $result, "\n" );
995
- $result = substr( $result, $pos );
996
-
997
- return $result;
998
- }
999
-
1000
- /**
1001
- * processTransactionResponseMessageIntoResponseArray:
1002
- * converts the response XML message into a nested array structure and then
1003
- * pulls out the relevant data into a simplified result array
1004
- *
1005
- * @param string $responseMessage - An XML response from the gateway
1006
- * @return boolean True to indicate succesful decoding of response message AND succesful txn result, false to indicate an error or declined result
1007
- */
1008
- private function processTransactionResponseMessageIntoResponseArray ( $responseMessage )
1009
- {
1010
- $xmlres = array();
1011
- $xmlres = $this->convertXMLToNestedArray( $responseMessage );
1012
-
1013
- if ( $xmlres === false )
1014
- {
1015
- if ( strlen( $this->errorString ) == 0 )
1016
- {
1017
- $this->errorString = self::GATEWAY_ERROR_RESPONSE_XML_MESSAGE_ERROR;
1018
- }
1019
- return false;
1020
- }
1021
-
1022
- $responseArray["raw-XML-response"] = htmlentities($responseMessage);
1023
-
1024
- $statusCode = trim( $xmlres['SecurePayMessage']['Status']['statusCode'] );
1025
- $statusDescription = trim($xmlres['SecurePayMessage']['Status']['statusDescription']);
1026
-
1027
- $responseArray["statusCode"] = $statusCode;
1028
- $responseArray["statusDescription"] = $statusDescription;
1029
-
1030
- // Three digit codes indicate a repsonse from the Securepay gateway (error detected by gateway)
1031
- if ( strcmp( $statusCode, '000' ) != 0 )
1032
- {
1033
- $this->errorString = self::GATEWAY_ERROR_SECUREPAY_STATUS.": ".$statusCode." ".$statusDescription;
1034
- return false;
1035
- }
1036
-
1037
- $responseArray["messageID"] = trim($xmlres['SecurePayMessage']['MessageInfo']['messageID']);
1038
- $responseArray["messageTimestamp"] = trim($xmlres['SecurePayMessage']['MessageInfo']['messageTimestamp']);
1039
- $responseArray["apiVersion"] = trim($xmlres['SecurePayMessage']['MessageInfo']['apiVersion']);
1040
- $responseArray["RequestType"] = trim($xmlres['SecurePayMessage']['RequestType']);
1041
- $responseArray["merchantID"] = trim($xmlres['SecurePayMessage']['MerchantInfo']['merchantID']);
1042
- $responseArray["txnType"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['txnType']);
1043
- $responseArray["txnSource"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['txnSource']);
1044
- $responseArray["amount"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['amount']);
1045
- $responseArray["approved"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['approved']);
1046
- $responseArray["responseCode"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['responseCode']);
1047
- $responseArray["responseText"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['responseText']);
1048
- $responseArray["banktxnID"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['txnID']);
1049
- $responseArray["settlementDate"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['settlementDate']);
1050
-
1051
- if( $this->getTxnType()==SECUREPAY_TXN_PREAUTH && array_key_exists('preauthID',$xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']))
1052
- {
1053
- $responseArray["preauthID"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['preauthID']);
1054
- }
1055
- if($this->getRequestType() == SECUREPAY_REQ_PERIODIC)
1056
- {
1057
- if( $this->getTxnType()==SECUREPAY_TXN_STANDARD ||
1058
- $this->getTxnType()==SECUREPAY_TXN_PREAUTH )
1059
- {
1060
- $responseArray["creditCardPAN"] = trim($xmlres['SecurePayMessage']['Periodic']['PeriodicList']['PeriodicItem']['CreditCardInfo']['pan']);
1061
- $responseArray["expiryDate"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['CreditCardInfo']['expiryDate']);
1062
- }
1063
- }
1064
- else if (strtoupper($responseArray['approved']) == 'YES' &&
1065
- ($this->getTxnType()==SECUREPAY_TXN_DIRECTDEBIT ||
1066
- $this->getTxnType()==SECUREPAY_TXN_DIRECTCREDIT) )
1067
- {
1068
- $responseArray["bsbNumber"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['DirectEntryInfo']['bsbNumber']);
1069
- $responseArray["accountNumber"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['DirectEntryInfo']['accountNumber']);
1070
- $responseArray["accountName"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['DirectEntryInfo']['accountName']);
1071
- }
1072
- else if ($this->getRequestType() == SECUREPAY_REQ_PAYMENT)
1073
- {
1074
- $responseArray["creditCardPAN"] = trim($xmlres['SecurePayMessage']['Periodic']['PeriodicList']['PeriodicItem']['CreditCardInfo']['pan']);
1075
- $responseArray["expiryDate"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['CreditCardInfo']['expiryDate']);
1076
- }
1077
- $this->responseArray = $responseArray;
1078
-
1079
- /* field "successful" = "Yes" means "triggered transaction successfully registered", anything else is failure */
1080
- /* responseCodes:
1081
- "00" indicates approved,
1082
- "08" is Honor with ID (approved) and
1083
- "77" is Approved (ANZ only).
1084
- Any other 2 digit code is a decline or error from the bank. */
1085
-
1086
- if ((strcasecmp( $responseArray["approved"], "Yes" ) == 0) &&
1087
- (strcmp( $responseArray["responseCode"], "00" ) === 0 ||
1088
- strcmp( $responseArray["responseCode"], "08" ) === 0 ||
1089
- strcmp( $responseArray["responseCode"], "77" ) === 0 ) )
1090
- {
1091
- return true;
1092
- }
1093
- else
1094
- {
1095
- $this->errorString = self::GATEWAY_ERROR_TXN_DECLINED." (".$responseArray["responseCode"]."): ".$responseArray["responseText"];
1096
- return false;
1097
- }
1098
- }
1099
-
1100
-
1101
- /**
1102
- * convertXMLToNestedArray:
1103
- * converts an XML document into a nested array structure
1104
- *
1105
- * @param string $XMLDocument An XML document
1106
- * @return boolean True to indicate succesful conversion of document, false to indicate an error
1107
- */
1108
- private function convertXMLToNestedArray ( $XMLDocument )
1109
- {
1110
-
1111
- $output = array();
1112
-
1113
- $parser = xml_parser_create();
1114
-
1115
- xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
1116
- xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
1117
- $parse_result = xml_parse_into_struct($parser, $XMLDocument, $values);
1118
-
1119
- if ( $parse_result === 0)
1120
- {
1121
- $this->errorString = self::GATEWAY_ERROR_XML_PARSE_FAILED.": ".xml_get_error_code ( $parser )." ".xml_error_string (xml_get_error_code ( $parser ) );
1122
- xml_parser_free($parser);
1123
-
1124
- return false;
1125
- }
1126
-
1127
- xml_parser_free($parser);
1128
-
1129
- $hash_stack = array();
1130
-
1131
- foreach ($values as $val)
1132
- {
1133
- switch ($val['type'])
1134
- {
1135
- case 'open':
1136
- array_push($hash_stack, $val['tag']);
1137
- break;
1138
-
1139
- case 'close':
1140
- array_pop($hash_stack);
1141
- break;
1142
-
1143
- case 'complete':
1144
- array_push($hash_stack, $val['tag']);
1145
- if ( array_key_exists('value', $val) )
1146
- eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['value']}\";");
1147
- else // to handle empty self closing tags i.e. <paymentInterval/>
1148
- eval("\$output['" . implode($hash_stack, "']['") . "'] = null;");
1149
- array_pop($hash_stack);
1150
- break;
1151
- }
1152
- }
1153
- return $output;
1154
- }
1155
- }
1156
-
1157
- ?>
1
+ <?php
2
+
3
+ /**
4
+ * securepay_xml_api.php:
5
+ *
6
+ * Contains a class for sending transaction requests to SecurePay,
7
+ * and receiving responses from the SecurePay via the XML API
8
+ *
9
+ * This class requires cURL to be available to PHP
10
+ *
11
+ */
12
+
13
+ define( 'SECUREPAY_GATEWAY_MODE_TEST', 1);
14
+ define( 'SECUREPAY_GATEWAY_MODE_LIVE', 2);
15
+ define( 'SECUREPAY_GATEWAY_MODE_PERIODIC_TEST', 3);
16
+ define( 'SECUREPAY_GATEWAY_MODE_PERIODIC_LIVE', 4);
17
+
18
+ /* The valid transaction types for this interface. */
19
+
20
+ define( 'SECUREPAY_TXN_STANDARD', 0);
21
+ define( 'SECUREPAY_TXN_REFUND', 4);
22
+ define( 'SECUREPAY_TXN_REVERSE', 6);
23
+ define( 'SECUREPAY_TXN_PREAUTH', 10); //To be included in a future revision
24
+ define( 'SECUREPAY_TXN_ADVICE', 11);
25
+
26
+ define( 'SECUREPAY_TXN_DIRECTDEBIT', 15); //To be included in a future revision
27
+ define( 'SECUREPAY_TXN_DIRECTCREDIT', 17);
28
+
29
+ define( 'SECUREPAY_TXN_IVR', 20);
30
+
31
+ define( 'SECUREPAY_REQ_ECHO', 'Echo'); //To be included in a future revision
32
+ define( 'SECUREPAY_REQ_PAYMENT', 'Payment');
33
+ define( 'SECUREPAY_REQ_PERIODIC', 'Periodic'); //To be included in a future revision
34
+
35
+ define( 'CURRENCY_DEFAULT', 'AUD');
36
+
37
+ /**
38
+ * securepay_xml_transaction
39
+ *
40
+ * This class handles XML SecurePay transactions
41
+ *
42
+ * It supports the following tranactions:
43
+ * Credit Payment (standard)
44
+ * Credit Refund
45
+ * Credit Reversal
46
+ * Credit Preauthorisation
47
+ * Credit Preauthorised completion (Advice)
48
+ *
49
+ * It partially supports the following transactions (which are not yet required):
50
+ * Direct Entry Credit
51
+ * Direct Entry Debit
52
+ *
53
+ * It can support the following transactions in future:
54
+ * Add Trigger/Peridic Payment
55
+ * Delete Trigger/Periodic Payment
56
+ * Trigger Triggered payment
57
+ *
58
+ * @param int mode - The kind of transaction object you would like to open. i.e. SECUREPAY_GATEWAY_MODE_TEST See top of this file for definitions.
59
+ * @param string merchantID - The merchant's login ID, received from SecurePay
60
+ * @param string merchantPW - The merchant's login password
61
+ */
62
+
63
+ class securepay_xml_transaction
64
+ {
65
+ const SECUREPAY_TEST_HOST = "https://www.securepay.com.au/test/payment";
66
+ const SECUREPAY_LIVE_HOST = "https://www.securepay.com.au/xmlapi/payment";
67
+
68
+ const TIMEOUT="60";
69
+
70
+ const GATEWAY_ERROR_OBJECT_INVALID = "The Gateway Object is invalid (constructor failure?)";
71
+ const GATEWAY_ERROR_CURL_ERROR = "CURL failed and reported the following error";
72
+ const GATEWAY_ERROR_INVALID_CCNUMBER = "Parameter Check failure: Invalid credit card number";
73
+ const GATEWAY_ERROR_INVALID_CCEXPIRY = "Parameter Check failure: Invalid credit card expiry date";
74
+ const GATEWAY_ERROR_INVALID_CC_CVC = "Parameter Check failure: Invalid credit card verification code";
75
+ const GATEWAY_ERROR_INVALID_TXN_AMT = "Parameter Check failure: Invalid transaction amount";
76
+ const GATEWAY_ERROR_INVALID_REF_ID = "Parameter Check failure: Invalid transaction reference number";
77
+ const GATEWAY_ERROR_INVALID_ACCOUNTNUMBER = "Parameter Check failure: Invalid account number";
78
+ const GATEWAY_ERROR_INVALID_ACCOUNTNAME = "Parameter Check failure: Invalid account name";
79
+ const GATEWAY_ERROR_INVALID_ACCOUNTBSB = "Parameter Check failure: Invalid BSB";
80
+ const GATEWAY_ERROR_RESPONSE_ERROR = "A general response error was detected";
81
+ const GATEWAY_ERROR_RESPONSE_INVALID = "A unspecified error was detected in the response content";
82
+ const GATEWAY_ERROR_XML_PARSE_FAILED = "The response message could not be parsed (invalid XML?)";
83
+ const GATEWAY_ERROR_RESPONSE_XML_MESSAGE_ERROR = "An unspecified error was found in the response message (missing field?)";
84
+ const GATEWAY_ERROR_SECUREPAY_STATUS = "The remote Gateway reported the following status error";
85
+ const GATEWAY_ERROR_TXN_DECLINED = "Transaction Declined";
86
+
87
+ private $errorString;
88
+ private $gatewayObjectValid = true;
89
+ private $gatewayURL;
90
+ private $merchantID;
91
+ private $merchantPW;
92
+ private $responseArray = array();
93
+ private $txnType;
94
+
95
+ private $ccNumber;
96
+ private $ccVerify;
97
+ private $ccExpiryMonth;
98
+ private $ccExpiryYear;
99
+
100
+ private $accNumber;
101
+ private $accBSB;
102
+ private $accName;
103
+
104
+ private $txnReference;
105
+ private $amount;
106
+
107
+ private $currency=CURRENCY_DEFAULT;
108
+
109
+ private $requestType;
110
+ private $periodicType;
111
+ private $periodicInterval;
112
+
113
+ private $bankTxnID = 0;
114
+
115
+ /**
116
+ * __construct
117
+ *
118
+ * @param integer $gatewaymode
119
+ * @param string $setup_merchantID
120
+ * @param string $setup_merchantPW
121
+ *
122
+ */
123
+ public function __construct( $gatewaymode, $setup_merchantID, $setup_merchantPW)
124
+ {
125
+
126
+ switch ( $gatewaymode )
127
+ {
128
+ case SECUREPAY_GATEWAY_MODE_TEST:
129
+ $this->gatewayURL = self::SECUREPAY_TEST_HOST;
130
+ break;
131
+
132
+ case SECUREPAY_GATEWAY_MODE_LIVE:
133
+ $this->gatewayURL = self::SECUREPAY_LIVE_HOST;
134
+ break;
135
+
136
+ default:
137
+ $this->gatewayObjectValid = false;
138
+ return;
139
+ }
140
+
141
+ if ( strlen( $setup_merchantID ) == 0
142
+ || strlen( $setup_merchantPW ) == 0 )
143
+ {
144
+ $this->gatewayObjectValid = false;
145
+ return;
146
+ }
147
+
148
+ $this->setAuth($setup_merchantID,$setup_merchantPW);
149
+
150
+ }
151
+
152
+ /**
153
+ * reset
154
+ *
155
+ * To clear response variables: prevents mismatched results in certain failure cases.
156
+ * This is called before each transaction, so be sure to check these values between transactions.
157
+ */
158
+ public function reset()
159
+ {
160
+ $this->errorString = NULL;
161
+ $this->responseArray = array();
162
+ $this->bankTxnID = 0;
163
+ }
164
+
165
+ public function isGatewayObjectValid()
166
+ {
167
+ return $this->gatewayObjectValid;
168
+ }
169
+
170
+ public function getAmount()
171
+ {
172
+ return $this->amount;
173
+ }
174
+
175
+ /**
176
+ * setAmount
177
+ *
178
+ * Takes amount as a float; requires currency to be set
179
+ *
180
+ * @param float amount
181
+ */
182
+ public function setAmount($amount)
183
+ {
184
+ if($this->getCurrency() == 'JPY')
185
+ $this->amount = $amount;
186
+ else
187
+ $this->amount = round($amount*100,0);
188
+ return;
189
+ }
190
+
191
+ public function getCurrency()
192
+ {
193
+ return $this->currency;
194
+ }
195
+
196
+ public function setCurrency($cur)
197
+ {
198
+ $this->currency = $cur;
199
+ return;
200
+ }
201
+
202
+ public function getTxnReference()
203
+ {
204
+ return $this->txnReference;
205
+ }
206
+
207
+ public function setTxnReference($ref)
208
+ {
209
+ $this->txnReference = $ref;
210
+ return;
211
+ }
212
+
213
+ public function getTxnType()
214
+ {
215
+ return $this->txnType;
216
+ }
217
+
218
+ public function setTxnType($type)
219
+ {
220
+ $this->txnType = $type;
221
+ return;
222
+ }
223
+
224
+ public function getPreauthID()
225
+ {
226
+ return $this->preauthID;
227
+ }
228
+
229
+ public function setPreauthID($id)
230
+ {
231
+ $this->preauthID = $id;
232
+ return;
233
+ }
234
+
235
+ public function getAccBSB()
236
+ {
237
+ return $this->accBSB;
238
+ }
239
+
240
+ public function setAccBSB($bsb)
241
+ {
242
+ $this->accBSB = $bsb;
243
+ return;
244
+ }
245
+
246
+ public function getAccNumber()
247
+ {
248
+ return $this->accNumber;
249
+ }
250
+
251
+ public function setAccNumber($Number)
252
+ {
253
+ $this->accNumber = $Number;
254
+ return;
255
+ }
256
+
257
+ public function getAccName()
258
+ {
259
+ return $this->accName;
260
+ }
261
+
262
+ public function setAccName($name)
263
+ {
264
+ $this->accName = $name;
265
+ return;
266
+ }
267
+
268
+ public function getCCNumber()
269
+ {
270
+ return $this->ccNumber;
271
+ }
272
+
273
+ public function setCCNumber($ccNumber)
274
+ {
275
+ $this->ccNumber = $ccNumber;
276
+ return;
277
+ }
278
+
279
+ public function getClearCCNumber()
280
+ {
281
+ $t = $this->getCCNumber();
282
+ $this->setCCNumber("0");
283
+ return $t;
284
+ }
285
+
286
+ public function getCCVerify()
287
+ {
288
+ return $this->ccVerify;
289
+ }
290
+
291
+ public function setCCVerify($ver)
292
+ {
293
+ $this->ccVerify = $ver;
294
+ return;
295
+ }
296
+
297
+ public function getClearCCVerify()
298
+ {
299
+ $t = $this->getCCVerify();
300
+ $this->setCCVerify(0);
301
+ return $t;
302
+ }
303
+
304
+ /* @return string month MM*/
305
+ public function getCCExpiryMonth()
306
+ {
307
+ return $this->ccExpiryMonth;
308
+ }
309
+
310
+ /* @param string/int month MM or month M - If there are leading zeros, type needs to be a string*/
311
+ public function setCCExpiryMonth($month)
312
+ {
313
+ $l = strlen(trim($month));
314
+ if($l == 1)
315
+ $this->ccExpiryMonth = sprintf("%02d",ltrim($month,'0'));
316
+ else
317
+ $this->ccExpiryMonth = $month;
318
+ return;
319
+ }
320
+
321
+ /* @return string year YY*/
322
+ public function getCCExpiryYear()
323
+ {
324
+ return $this->ccExpiryYear;
325
+ }
326
+
327
+ /* @param string year YY or year YYYY - If there are leading zeros, type needs to be a string*/
328
+ public function setCCExpiryYear($year)
329
+ {
330
+ $y = ltrim(trim((string)$year),"0");
331
+ $l = strlen($y);
332
+ if($l==4)
333
+ $this->ccExpiryYear = substr($y,2);
334
+ else if($l>=5)
335
+ $this->ccExpiryYear = 0;
336
+ else if($l==1)
337
+ $this->ccExpiryYear = sprintf("%02d",$y);
338
+ else
339
+ $this->ccExpiryYear = $year;
340
+
341
+ return;
342
+ }
343
+
344
+ public function getMerchantID()
345
+ {
346
+ return $this->merchantID;
347
+ }
348
+
349
+ public function setMerchantID($id)
350
+ {
351
+ $this->merchantID = $id;
352
+ return;
353
+ }
354
+
355
+ public function getMerchantPW ()
356
+ {
357
+ return $this->merchantPW;
358
+ }
359
+
360
+ public function setMerchantPW ($pw)
361
+ {
362
+ $this->merchantPW = $pw;
363
+ return;
364
+ }
365
+
366
+ public function getBankTxnID ()
367
+ {
368
+ return $this->bankTxnID;
369
+ }
370
+
371
+ public function setBankTxnID ($id)
372
+ {
373
+ $this->bankTxnID = $id;
374
+ return;
375
+ }
376
+
377
+ public function getRequestType ()
378
+ {
379
+ return $this->requestType;
380
+ }
381
+
382
+ public function setRequestType ($t)
383
+ {
384
+ $this->requestType = $t;
385
+ return;
386
+ }
387
+
388
+ public function getPeriodicType ()
389
+ {
390
+ return $this->periodicType;
391
+ }
392
+
393
+ public function setPeriodicType ($t)
394
+ {
395
+ $this->periodicType = $t;
396
+ return;
397
+ }
398
+
399
+ public function getPeriodicInterval ()
400
+ {
401
+ return $this->periodicInterval;
402
+ }
403
+
404
+ public function setPeriodicInterval ($t)
405
+ {
406
+ $this->periodicInterval = $t;
407
+ return;
408
+ }
409
+
410
+ public function getErrorString ()
411
+ {
412
+ return $this->errorString;
413
+ }
414
+
415
+ public function getResultArray ()
416
+ {
417
+ return $this->responseArray;
418
+ }
419
+
420
+ public function getResultByKeyName ( $keyName)
421
+ {
422
+ if ( array_key_exists( $keyName, $this->responseArray) === true )
423
+ {
424
+ return $this->responseArray[$keyName];
425
+ }
426
+ else
427
+ return false;
428
+ }
429
+
430
+ public function getTxnWasSuccesful()
431
+ {
432
+ if ( array_key_exists( "txnResult", $this->responseArray) === true
433
+ && $this->responseArray["txnResult"] === true )
434
+ return true;
435
+ else
436
+ return false;
437
+ }
438
+
439
+ public function setAuth($id, $pw)
440
+ {
441
+ $this->setMerchantID($id);
442
+ $this->setMerchantPW($pw);
443
+ return;
444
+ }
445
+
446
+ /**
447
+ * processCreditStandard:
448
+ *
449
+ * Process a standard credit card payment
450
+ *
451
+ * @param float amount - Numeric and decimal only: no thousand separators
452
+ * @param string txnReference - Merchant's unique transaction ID
453
+ * @param int cardNumber - 12-18 digit credit-card number
454
+ * @param int cardMonth - 2 digit month
455
+ * @param int cardYear - 2 or 4 digit year
456
+ * @param int cardVerify - 3 or 4 digit CVV (optional)
457
+ * @param string currency - Exactly three characters. See SecurePay documentation for list of valid currencies. (optional)
458
+ *
459
+ * @return string txnID - Bank's unique transaction ID (use for reversal or refund), or FALSE in case of failure (check $this->getErrorText() afterwards).
460
+ */
461
+ public function processCreditStandard($amount, $txnReference, $cardNumber, $cardMonth, $cardYear, $cardVerify=0, $currency=CURRENCY_DEFAULT)
462
+ {
463
+ $this->reset();
464
+
465
+ $this->setTxnType(SECUREPAY_TXN_STANDARD);
466
+
467
+ $this->setAmount($amount);
468
+ $this->setTxnReference($txnReference);
469
+ $this->setCCNumber($cardNumber);
470
+ if(strlen($cardVerify)!=0)
471
+ $this->setCCVerify($cardVerify);
472
+ $this->setCCExpiryYear($cardYear);
473
+ $this->setCCExpiryMonth($cardMonth);
474
+ if($currency)
475
+ $this->setCurrency($currency);
476
+
477
+ if($this->processTransaction());
478
+ if(array_key_exists('banktxnID',$this->responseArray))
479
+ return $this->responseArray['banktxnID'];
480
+ return false;
481
+ }
482
+
483
+ /**
484
+ * processCreditRefund:
485
+ *
486
+ * Refund a standard credit card payment. $amount can be less than the original transaction.
487
+ *
488
+ * @param float amount - Numeric and decimal only: no thousand separators
489
+ * @param string txnReference - Merchant's unique transaction ID: must be same as in initial transaction
490
+ * @param int txnID - Result of original transaction
491
+ *
492
+ * @return string txnID - Bank's unique transaction ID, or FALSE in case of failure (check $this->getErrorText() afterwards).
493
+ */
494
+ public function processCreditRefund($amount, $txnReference, $txnID)
495
+ {
496
+ $this->reset();
497
+
498
+ $this->setTxnType(SECUREPAY_TXN_REFUND);
499
+
500
+ $this->setAmount($amount);
501
+ $this->setTxnReference($txnReference);
502
+
503
+ $this->setBankTxnID($txnID);
504
+
505
+ if($this->processTransaction());
506
+ if(array_key_exists('banktxnID',$this->responseArray))
507
+ return $this->responseArray['banktxnID'];
508
+ return false;
509
+ }
510
+
511
+ /**
512
+ * processCreditReverse:
513
+ *
514
+ * Reverse a standard credit card payment. $amount should be same as in original transaction.
515
+ *
516
+ * @param float amount - Numeric and decimal only: no thousand separators
517
+ * @param string txnReference - Merchant's unique transaction ID: must be same as in initial transaction
518
+ * @param int txnID - Result of original transaction
519
+ *
520
+ * @return string txnID - Bank's unique transaction ID, or FALSE in case of failure (check $this->getErrorText() afterwards).
521
+ */
522
+ public function processCreditReverse($amount, $txnReference, $txnID)
523
+ {
524
+ $this->reset();
525
+
526
+ $this->setTxnType(SECUREPAY_TXN_REVERSE);
527
+
528
+ $this->setAmount($amount);
529
+ $this->setTxnReference($txnReference);
530
+
531
+ $this->setBankTxnID($txnID);
532
+
533
+ if($this->processTransaction());
534
+ if(array_key_exists('banktxnID',$this->responseArray))
535
+ return $this->responseArray['banktxnID'];
536
+ return false;
537
+ }
538
+
539
+ /**
540
+ * processCreditPreauth:
541
+ *
542
+ * Preauthorise a credit card payment
543
+ *
544
+ * @param float amount - Numeric and decimal only: no thousand separators
545
+ * @param string txnReference - Merchant's unique transaction ID
546
+ * @param int cardNumber - 12-18 digit credit-card number
547
+ * @param int cardMonth - 2 digit month
548
+ * @param int cardYear - 2 or 4 digit year
549
+ * @param int cardVerify - 3 or 4 digit CVV (optional)
550
+ * @param string currency - Exactly three characters. See SecurePay documentation for list of valid currencies. (optional)
551
+ *
552
+ * @return string preauthID - preauthorisation ID (use to execute transaction later (processCreditAdvice)), or FALSE (check $this->getErrorText() afterwards).
553
+ */
554
+ public function processCreditPreauth($amount, $txnReference, $cardNumber, $cardMonth, $cardYear, $cardVerify=0, $currency=CURRENCY_DEFAULT)
555
+ {
556
+ $this->reset();
557
+
558
+ $this->setTxnType(SECUREPAY_TXN_PREAUTH);
559
+
560
+ $this->setAmount($amount);
561
+ $this->setTxnReference($txnReference);
562
+ $this->setCCNumber($cardNumber);
563
+ if(strlen($cardVerify)!=0)
564
+ $this->setCCVerify($cardVerify);
565
+ $this->setCCExpiryYear($cardYear);
566
+ $this->setCCExpiryMonth($cardMonth);
567
+
568
+ if($currency)
569
+ $this->setCurrency($currency);
570
+
571
+ if($this->processTransaction())
572
+ {
573
+ if(array_key_exists('preauthID',$this->responseArray))
574
+ return $this->responseArray['preauthID'];
575
+ }
576
+
577
+ return false;
578
+ }
579
+
580
+ /**
581
+ * processCreditAdvice:
582
+ *
583
+ * Execute a preauthorised transaction
584
+ *
585
+ * @param float amount - Numeric and decimal only: no thousand separators. Should be same as preauthorised amount.
586
+ * @param string txnReference - Merchant's unique transaction ID: must be same as in initial transaction
587
+ * @param string preauthID - Preauthorisation code which was returned from processCreditPreauth
588
+ *
589
+ * @return string txnID - Bank's unique transaction ID, or FALSE in case of failure (check $this->getErrorText() afterwards).
590
+ */
591
+ public function processCreditAdvice($amount, $txnReference, $preauthID)
592
+ {
593
+ $this->reset();
594
+
595
+ $this->setTxnType(SECUREPAY_TXN_ADVICE);
596
+
597
+ $this->setAmount($amount);
598
+ $this->setTxnReference($txnReference);
599
+ $this->setPreauthID($preauthID);
600
+
601
+ if($this->processTransaction());
602
+ if(array_key_exists('banktxnID',$this->responseArray))
603
+ return $this->responseArray['banktxnID'];
604
+ return false;
605
+ }
606
+
607
+ /**
608
+ * processTransaction:
609
+ *
610
+ * this function attempts to process a payment transaction using the
611
+ * supplied details on the SecurePay SecureXML Gateway
612
+ *
613
+ * @return boolean Returns true for succesful (approved) transaction / false for failure (declined) or error
614
+ *
615
+ */
616
+ private function processTransaction ()
617
+ {
618
+ // check that self is a valid gateway object
619
+ if ( !$this->gatewayObjectValid )
620
+ {
621
+ $this->errorString = self::GATEWAY_ERROR_OBJECT_INVALID;
622
+ return false;
623
+ }
624
+
625
+ // check parameters
626
+ if( $this->getTxnType()==SECUREPAY_TXN_STANDARD ||
627
+ $this->getTxnType()==SECUREPAY_TXN_PREAUTH )
628
+ {
629
+ if ($this->checkCCparameters() == false)
630
+ return false;
631
+ }
632
+ else if ( $this->getTxnType()==SECUREPAY_TXN_DIRECTDEBIT ||
633
+ $this->getTxnType()==SECUREPAY_TXN_DIRECTCREDIT )
634
+ {
635
+ if ($this->checkDirectparameters() == false)
636
+ return false;
637
+ }
638
+ if ($this->checkTxnParameters() == false)
639
+ {
640
+ return false;
641
+ }
642
+
643
+ // create request message. This function will retrieve and destroy CC details, if we're in credit-card mode (!)
644
+ $requestMessage = $this->createXMLTransactionRequestString();
645
+
646
+ $this->responseArray["raw-XML-request"] = htmlentities($requestMessage);
647
+
648
+ // send request
649
+ $response = $this->sendRequest( $this->gatewayURL, $requestMessage );
650
+
651
+ $this->responseArray["raw-response"] = htmlentities($response);
652
+
653
+ // was a response received?
654
+ if ( $response === false )
655
+ {
656
+ if ( strlen( $this->errorString ) == 0 )
657
+ {
658
+ $this->errorString = self::GATEWAY_ERROR_RESPONSE_ERROR;
659
+ }
660
+ return false;
661
+ }
662
+
663
+ // process response for validity
664
+ if ( $this->processTransactionResponseMessageIntoResponseArray( $response ) === false )
665
+ {
666
+ if ( strlen( $this->errorString ) == 0 )
667
+ {
668
+ $this->errorString = self::GATEWAY_ERROR_RESPONSE_INVALID;
669
+ }
670
+ return false;
671
+ }
672
+
673
+ // if we get this far, the transaction is succesful and "approved"
674
+ $this->responseArray["txnResult"] = true;
675
+
676
+ return true;
677
+ }
678
+
679
+
680
+ /**
681
+ * checkCCparameters
682
+ *
683
+ * Check the input parameters are valid for a credit card transaction
684
+ *
685
+ * @return boolean Return TRUE for all checks passed OK, or FALSE if an error is detected
686
+ */
687
+ private function checkCCparameters()
688
+ {
689
+ // the string ccNumber must be all numeric, and between 12 and 19 digits long
690
+ if (strlen( $this->getCCNumber() ) < 12 ||
691
+ strlen( $this->getCCNumber() ) > 19 ||
692
+ preg_match("/\D/",$this->getCCNumber()) )// REGEXP: true if "any match for non-numeral"
693
+ {
694
+ $this->errorString = self::GATEWAY_ERROR_INVALID_CCNUMBER;
695
+ return false;
696
+ }
697
+
698
+ // the string $ccExpiryMonth must be all numeric with value between 1 and 12
699
+ if (preg_match("/\D/", $this->getCCExpiryMonth()) || // REGEXP: true if "any match for non-numeral"
700
+ (int) $this->getCCExpiryMonth() < 1 ||
701
+ (int) $this->getCCExpiryMonth() > 12 )
702
+ {
703
+ $this->errorString = self::GATEWAY_ERROR_INVALID_CCEXPIRY;
704
+ return false;
705
+ }
706
+
707
+ // the string $ccExpiryYear must be all numeric with value between this year and this year + 12 years
708
+ if (preg_match( "/\D/", $this->getCCExpiryYear()) || // REGEXP: true if "any match for non-numeral"
709
+ (strlen($this->getCCExpiryYear()) != 2) || //YY form
710
+ (int) $this->getCCExpiryYear() < (int) substr(date("Y"),2) || // Between now and now + 12
711
+ (int) $this->getCCExpiryYear() > ( (int) substr(date("Y"),2) + 12 ) )
712
+ {
713
+ $this->errorString = self::GATEWAY_ERROR_INVALID_CCEXPIRY;
714
+ return false;
715
+ }
716
+
717
+ // The CVC is an optional data item so only perform the checks if the parameter was present
718
+ if ( strlen( $this->getCCVerify() ) != 0 )
719
+ {
720
+ // the string $ccVericationNumber must be all numeric with value between 000 and 9999
721
+ if (preg_match( "/\D/", $this->getCCVerify() ) || // REGEXP: true if "any match for non-numeral"
722
+ strlen( $this->getCCVerify() ) < 3 ||
723
+ strlen( $this->getCCVerify() ) > 4 ||
724
+ (int) $this->getCCVerify() < 0 ||
725
+ (int) $this->getCCVerify() > 9999 )
726
+ {
727
+ $this->errorString = self::GATEWAY_ERROR_INVALID_CC_CVC;
728
+ return false;
729
+ }
730
+ }
731
+ return true;
732
+ }
733
+
734
+ /**
735
+ * checkCCparameters
736
+ *
737
+ * Check the input parameters are valid for a credit card transaction
738
+ *
739
+ * @return boolean Return TRUE for all checks passed OK, or FALSE if an error is detected
740
+ */
741
+ private function checkDirectparameters()
742
+ {
743
+ // the string accNumber must be all numeric, and between 12 and 19 digits long
744
+ if (preg_match( "/\D/", $this->getAccNumber() ) )// REGEXP: true if "any match for non-numeral"
745
+ {
746
+ $this->errorString = self::GATEWAY_ERROR_INVALID_ACCOUNTNUMBER;
747
+ return false;
748
+ }
749
+
750
+ // the string $accName must be all numeric with value between 1 and 12
751
+ if ( preg_match( "/\D/", $this->getAccName() )) // REGEXP: true if "any match for non-numeral"
752
+ {
753
+ print "Month\n";
754
+ $this->errorString = self::GATEWAY_ERROR_INVALID_ACCOUNTNAME;
755
+ return false;
756
+ }
757
+ // the string $accBSB must be all numeric with value between 000 and 9999
758
+ if (preg_match( "/\D/", $this->getAccBSB())) // REGEXP: true if "any match for non-numeral"
759
+ {
760
+ $this->errorString = self::GATEWAY_ERROR_INVALID_BSB;
761
+ return false;
762
+ }
763
+
764
+ return true;
765
+ }
766
+
767
+ /**
768
+ * checkTxnParameters
769
+ *
770
+ * Check that the transaction input parameters are within requirements
771
+ *
772
+ * @param string $txnAmount
773
+ * @param string $txnReference
774
+ *
775
+ * @return TRUE for pass, FALSE for fail
776
+ */
777
+ private function checkTxnParameters ()
778
+ {
779
+ $amount = $this->getAmount();
780
+ if (preg_match( "/^[0-9]/", $amount)==false || (int) $amount < 0 )
781
+ {
782
+ $this->errorString = self::GATEWAY_ERROR_INVALID_TXN_AMT;
783
+ return false;
784
+ }
785
+
786
+ $ref = $this->getTxnReference();
787
+ if ( $this->getTxnType()==SECUREPAY_TXN_DIRECTDEBIT ||
788
+ $this->getTxnType()==SECUREPAY_TXN_DIRECTCREDIT )
789
+ {
790
+ // Direct Entry Payment References need to conform to EBCDIC, and should be <= 18 characters
791
+ if (strlen($ref) == 0 || strlen($ref)>18 ||
792
+ preg_match('/[^0-9a-zA-Z*\.&\/-_\']/', $ref)) // REGEXP: match any non-EBCDIC character
793
+ {
794
+ $this->errorString = self::GATEWAY_ERROR_INVALID_REF_ID;
795
+ return false;
796
+ }
797
+ }
798
+ else
799
+ {
800
+ // Standard/Credit References can have any character except space and single quote
801
+ if (strlen($ref) == 0 || strlen($ref)>59 ||
802
+ preg_match('/[^ \']/', $ref)==false) // REGEXP: match invalid characters
803
+ {
804
+ $this->errorString = self::GATEWAY_ERROR_INVALID_REF_ID;
805
+ return false;
806
+ }
807
+ }
808
+ return true;
809
+ }
810
+
811
+ /**
812
+ * createXMLTransactionRequestString:
813
+ * Creates the XML request string for a transaction request message
814
+ *
815
+ * Note: calls to getClearCCNumber & getClearCCVerify: details are removed from their respective private variables here
816
+ *
817
+ * @return string xml_transaction
818
+ */
819
+ private function createXMLTransactionRequestString()
820
+ {
821
+ $x =
822
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>".
823
+ "<SecurePayMessage>" .
824
+ "<MessageInfo>" .
825
+ "<messageID>".htmlentities($this->getTxnReference().date("his").current(split(' ',microtime( ))))."</messageID>".
826
+ "<messageTimestamp>".htmlentities($this->getGMTTimeStamp())."</messageTimestamp>".
827
+ "<timeoutValue>".self::TIMEOUT."</timeoutValue>".
828
+ "<apiVersion>xml-4.2</apiVersion>" .
829
+ "</MessageInfo>".
830
+ "<MerchantInfo>".
831
+ "<merchantID>".htmlentities($this->getMerchantID())."</merchantID>" .
832
+ "<password>".htmlentities($this->getMerchantPW())."</password>" .
833
+ "</MerchantInfo>".
834
+ "<RequestType>Payment</RequestType>".
835
+ "<Payment>".
836
+ "<TxnList count=\"1\">".
837
+ "<Txn ID=\"1\">".
838
+ "<txnType>".htmlentities($this->getTxnType())."</txnType>".
839
+ "<txnSource>23</txnSource>".
840
+ "<amount>".htmlentities($this->getAmount())."</amount>";
841
+ if( ($this->getTxnType()==SECUREPAY_TXN_STANDARD ||
842
+ $this->getTxnType()==SECUREPAY_TXN_PREAUTH ) &&
843
+ $this->getCurrency()!=CURRENCY_DEFAULT)
844
+ {
845
+ $x .= "<currency>".htmlentities($this->getCurrency())."</currency>";
846
+ }
847
+ $x .= "<purchaseOrderNo>".htmlentities($this->getTxnReference())."</purchaseOrderNo>";
848
+ if( $this->getTxnType()==SECUREPAY_TXN_ADVICE)
849
+ {
850
+ $x .= "<preauthID>".htmlentities($this->getPreauthID())."</preauthID>";
851
+ }
852
+ if( $this->getTxnType()==SECUREPAY_TXN_REFUND ||
853
+ $this->getTxnType()==SECUREPAY_TXN_REVERSE &&
854
+ $this->getBankTxnID() != 0)
855
+ {
856
+ $x .= "<txnID>".htmlentities($this->getBankTxnID())."</txnID>";
857
+ }
858
+
859
+ if( $this->getTxnType()==SECUREPAY_TXN_STANDARD ||
860
+ $this->getTxnType()==SECUREPAY_TXN_PREAUTH )
861
+ {
862
+ $x .= "<CreditCardInfo>".
863
+ "<cardNumber>".htmlentities($this->getClearCCNumber())."</cardNumber>";
864
+ if (trim($this->getCCVerify()) <> "")
865
+ {
866
+ $x .= "<cvv>".htmlentities($this->getClearCCVerify())."</cvv>";
867
+ }
868
+ $x .= "<expiryDate>".htmlentities(sprintf("%02d",$this->getCCExpiryMonth())."/".sprintf("%02d",$this->getCCExpiryYear()))."</expiryDate>".
869
+ "</CreditCardInfo>";
870
+ }
871
+ else if ( $this->getTxnType()==SECUREPAY_TXN_DIRECTDEBIT ||
872
+ $this->getTxnType()==SECUREPAY_TXN_DIRECTCREDIT )
873
+ {
874
+ $x .= "<DirectEntryInfo>".
875
+ "<bsbNumber>".htmlentities($this->getAccBSB())."</bsbNumber>".
876
+ "<accountNumber>".htmlentities($this->getAccNumber())."</accountNumber>".
877
+ "<accountName>".htmlentities($this->getAccName())."</accountName>".
878
+ "</DirectEntryInfo>";
879
+ }
880
+ $x .= "</Txn>".
881
+ "</TxnList>".
882
+ "</Payment>".
883
+ "</SecurePayMessage>";
884
+
885
+ return $x;
886
+ }
887
+
888
+
889
+ /**
890
+ * getGMTTimeStamp:
891
+ *
892
+ * this function creates a timestamp formatted as per requirement in the
893
+ * SecureXML documentation
894
+ *
895
+ * @return string The formatted timestamp
896
+ */
897
+ private function getGMTTimeStamp()
898
+ {
899
+ /* Format: YYYYDDMMHHNNSSKKK000sOOO
900
+ YYYY is a 4-digit year
901
+ DD is a 2-digit zero-padded day of month
902
+ MM is a 2-digit zero-padded month of year (January = 01)
903
+ HH is a 2-digit zero-padded hour of day in 24-hour clock format (midnight =0)
904
+ NN is a 2-digit zero-padded minute of hour
905
+ SS is a 2-digit zero-padded second of minute
906
+ KKK is a 3-digit zero-padded millisecond of second
907
+ 000 is a Static 0 characters, as SecurePay does not store nanoseconds
908
+ sOOO is a Time zone offset, where s is �+� or �-�, and OOO = minutes, from GMT.
909
+ */
910
+
911
+
912
+ $val = date("Z") / 60;
913
+ if ($val >= 0)
914
+ {
915
+ $val = "+" . strval($val);
916
+ }
917
+
918
+ $stamp = date("YdmGis000000") . $val;
919
+
920
+ return $stamp;
921
+ }
922
+
923
+ /**
924
+ * sendRequest:
925
+ * uses cURL to open a Secure Socket connection to the gateway,
926
+ * sends the transaction request and then returns the response
927
+ * data
928
+ *
929
+ * @param $postURL The URL of the remote gateway to which the request is sent
930
+ * @param $requestMessage
931
+ */
932
+ private function sendRequest( $postURL, $requestMessage )
933
+ {
934
+ $ch = curl_init();
935
+
936
+ // Set up curl parameters
937
+ curl_setopt( $ch, CURLOPT_URL, $postURL ); // set remote address
938
+ curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 ); // Make CURL pass the response as a curl_exec return value instead of outputting to STDOUT
939
+ curl_setopt( $ch, CURLOPT_POST, 1 ); // Activate the POST method
940
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
941
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 );
942
+
943
+ curl_setopt( $ch, CURLOPT_POSTFIELDS, $requestMessage ); // add the request message itself
944
+
945
+ // execute the connexion
946
+ $result = curl_exec( $ch );
947
+
948
+ $debugoutput = curl_getinfo($ch);
949
+ $curl_error_message = curl_error( $ch ); // must retrieve an error message (if any) before closing the curl object
950
+
951
+ curl_close($ch);
952
+
953
+
954
+ if ( $result === false )
955
+ {
956
+ $this->errorString = self::GATEWAY_ERROR_CURL_ERROR.': '.$curl_error_message;
957
+ return false;
958
+ }
959
+
960
+ // we do not need the header part of the response, trim it off the result
961
+ $pos = strstr( $result, "\n" );
962
+ $result = substr( $result, $pos );
963
+
964
+ return $result;
965
+ }
966
+
967
+ /**
968
+ * processTransactionResponseMessageIntoResponseArray:
969
+ * converts the response XML message into a nested array structure and then
970
+ * pulls out the relevant data into a simplified result array
971
+ *
972
+ * @param string $responseMessage - An XML response from the gateway
973
+ * @return boolean True to indicate succesful decoding of response message AND succesful txn result, false to indicate an error or declined result
974
+ */
975
+ private function processTransactionResponseMessageIntoResponseArray ( $responseMessage )
976
+ {
977
+ $xmlres = array();
978
+ $xmlres = $this->convertXMLToNestedArray( $responseMessage );
979
+
980
+ if ( $xmlres === false )
981
+ {
982
+ if ( strlen( $this->errorString ) == 0 )
983
+ {
984
+ $this->errorString = self::GATEWAY_ERROR_RESPONSE_XML_MESSAGE_ERROR;
985
+ }
986
+ return false;
987
+ }
988
+
989
+ $responseArray["raw-XML-response"] = htmlentities($responseMessage);
990
+
991
+ $statusCode = trim( $xmlres['SecurePayMessage']['Status']['statusCode'] );
992
+ $statusDescription = trim($xmlres['SecurePayMessage']['Status']['statusDescription']);
993
+
994
+ $responseArray["statusCode"] = $statusCode;
995
+ $responseArray["statusDescription"] = $statusDescription;
996
+
997
+ // Three digit codes indicate a repsonse from the Securepay gateway (error detected by gateway)
998
+ if ( strcmp( $statusCode, '000' ) != 0 )
999
+ {
1000
+ $this->errorString = self::GATEWAY_ERROR_SECUREPAY_STATUS.": ".$statusCode." ".$statusDescription;
1001
+ return false;
1002
+ }
1003
+
1004
+ $responseArray["messageID"] = trim($xmlres['SecurePayMessage']['MessageInfo']['messageID']);
1005
+ $responseArray["messageTimestamp"] = trim($xmlres['SecurePayMessage']['MessageInfo']['messageTimestamp']);
1006
+ $responseArray["apiVersion"] = trim($xmlres['SecurePayMessage']['MessageInfo']['apiVersion']);
1007
+ $responseArray["RequestType"] = trim($xmlres['SecurePayMessage']['RequestType']);
1008
+ $responseArray["merchantID"] = trim($xmlres['SecurePayMessage']['MerchantInfo']['merchantID']);
1009
+ $responseArray["txnType"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['txnType']);
1010
+ $responseArray["txnSource"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['txnSource']);
1011
+ $responseArray["amount"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['amount']);
1012
+ $responseArray["approved"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['approved']);
1013
+ $responseArray["responseCode"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['responseCode']);
1014
+ $responseArray["responseText"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['responseText']);
1015
+ $responseArray["banktxnID"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['txnID']);
1016
+ $responseArray["settlementDate"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['settlementDate']);
1017
+
1018
+ if( $this->getTxnType()==SECUREPAY_TXN_PREAUTH && array_key_exists('preauthID',$xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']))
1019
+ {
1020
+ $responseArray["preauthID"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['preauthID']);
1021
+ }
1022
+ if($this->getRequestType() == SECUREPAY_REQ_PERIODIC)
1023
+ {
1024
+ if( $this->getTxnType()==SECUREPAY_TXN_STANDARD ||
1025
+ $this->getTxnType()==SECUREPAY_TXN_PREAUTH )
1026
+ {
1027
+ $responseArray["creditCardPAN"] = trim($xmlres['SecurePayMessage']['Periodic']['PeriodicList']['PeriodicItem']['CreditCardInfo']['pan']);
1028
+ $responseArray["expiryDate"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['CreditCardInfo']['expiryDate']);
1029
+ }
1030
+ }
1031
+ else if (strtoupper($responseArray['approved']) == 'YES' &&
1032
+ ($this->getTxnType()==SECUREPAY_TXN_DIRECTDEBIT ||
1033
+ $this->getTxnType()==SECUREPAY_TXN_DIRECTCREDIT) )
1034
+ {
1035
+ $responseArray["bsbNumber"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['DirectEntryInfo']['bsbNumber']);
1036
+ $responseArray["accountNumber"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['DirectEntryInfo']['accountNumber']);
1037
+ $responseArray["accountName"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['DirectEntryInfo']['accountName']);
1038
+ }
1039
+ else if ($this->getRequestType() == SECUREPAY_REQ_PAYMENT)
1040
+ {
1041
+ $responseArray["creditCardPAN"] = trim($xmlres['SecurePayMessage']['Periodic']['PeriodicList']['PeriodicItem']['CreditCardInfo']['pan']);
1042
+ $responseArray["expiryDate"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['CreditCardInfo']['expiryDate']);
1043
+ }
1044
+ $this->responseArray = $responseArray;
1045
+
1046
+ /* field "successful" = "Yes" means "triggered transaction successfully registered", anything else is failure */
1047
+ /* responseCodes:
1048
+ "00" indicates approved,
1049
+ "08" is Honor with ID (approved) and
1050
+ "77" is Approved (ANZ only).
1051
+ Any other 2 digit code is a decline or error from the bank. */
1052
+
1053
+ if (strcasecmp( $responseArray["approved"], "Yes" ) == 0)
1054
+ {
1055
+ return true;
1056
+ }
1057
+ else
1058
+ {
1059
+ $this->errorString = self::GATEWAY_ERROR_TXN_DECLINED." (".$responseArray["responseCode"]."): ".$responseArray["responseText"];
1060
+ return false;
1061
+ }
1062
+ }
1063
+
1064
+
1065
+ /**
1066
+ * convertXMLToNestedArray:
1067
+ * converts an XML document into a nested array structure
1068
+ *
1069
+ * @param string $XMLDocument An XML document
1070
+ * @return boolean True to indicate succesful conversion of document, false to indicate an error
1071
+ */
1072
+ private function convertXMLToNestedArray ( $XMLDocument )
1073
+ {
1074
+
1075
+ $output = array();
1076
+
1077
+ $parser = xml_parser_create();
1078
+
1079
+ xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
1080
+ xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
1081
+ $parse_result = xml_parse_into_struct($parser, $XMLDocument, $values);
1082
+
1083
+ if ( $parse_result === 0)
1084
+ {
1085
+ $this->errorString = self::GATEWAY_ERROR_XML_PARSE_FAILED.": ".xml_get_error_code ( $parser )." ".xml_error_string (xml_get_error_code ( $parser ) );
1086
+ xml_parser_free($parser);
1087
+
1088
+ return false;
1089
+ }
1090
+
1091
+ xml_parser_free($parser);
1092
+
1093
+ $hash_stack = array();
1094
+
1095
+ foreach ($values as $val)
1096
+ {
1097
+ switch ($val['type'])
1098
+ {
1099
+ case 'open':
1100
+ array_push($hash_stack, $val['tag']);
1101
+ break;
1102
+
1103
+ case 'close':
1104
+ array_pop($hash_stack);
1105
+ break;
1106
+
1107
+ case 'complete':
1108
+ array_push($hash_stack, $val['tag']);
1109
+ if ( array_key_exists('value', $val) )
1110
+ eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['value']}\";");
1111
+ else // to handle empty self closing tags i.e. <paymentInterval/>
1112
+ eval("\$output['" . implode($hash_stack, "']['") . "'] = null;");
1113
+ array_pop($hash_stack);
1114
+ break;
1115
+ }
1116
+ }
1117
+ return $output;
1118
+ }
1119
+ }
1120
+
1121
+ ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/SecurePay/securepay_xml_api.php~ ADDED
@@ -0,0 +1,1121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * securepay_xml_api.php:
5
+ *
6
+ * Contains a class for sending transaction requests to SecurePay,
7
+ * and receiving responses from the SecurePay via the XML API
8
+ *
9
+ * This class requires cURL to be available to PHP
10
+ *
11
+ */
12
+
13
+ define( 'SECUREPAY_GATEWAY_MODE_TEST', 1);
14
+ define( 'SECUREPAY_GATEWAY_MODE_LIVE', 2);
15
+ define( 'SECUREPAY_GATEWAY_MODE_PERIODIC_TEST', 3);
16
+ define( 'SECUREPAY_GATEWAY_MODE_PERIODIC_LIVE', 4);
17
+
18
+ /* The valid transaction types for this interface. */
19
+
20
+ define( 'SECUREPAY_TXN_STANDARD', 0);
21
+ define( 'SECUREPAY_TXN_REFUND', 4);
22
+ define( 'SECUREPAY_TXN_REVERSE', 6);
23
+ define( 'SECUREPAY_TXN_PREAUTH', 10); //To be included in a future revision
24
+ define( 'SECUREPAY_TXN_ADVICE', 11);
25
+
26
+ define( 'SECUREPAY_TXN_DIRECTDEBIT', 15); //To be included in a future revision
27
+ define( 'SECUREPAY_TXN_DIRECTCREDIT', 17);
28
+
29
+ define( 'SECUREPAY_TXN_IVR', 20);
30
+
31
+ define( 'SECUREPAY_REQ_ECHO', 'Echo'); //To be included in a future revision
32
+ define( 'SECUREPAY_REQ_PAYMENT', 'Payment');
33
+ define( 'SECUREPAY_REQ_PERIODIC', 'Periodic'); //To be included in a future revision
34
+
35
+ define( 'CURRENCY_DEFAULT', 'AUD');
36
+
37
+ /**
38
+ * securepay_xml_transaction
39
+ *
40
+ * This class handles XML SecurePay transactions
41
+ *
42
+ * It supports the following tranactions:
43
+ * Credit Payment (standard)
44
+ * Credit Refund
45
+ * Credit Reversal
46
+ * Credit Preauthorisation
47
+ * Credit Preauthorised completion (Advice)
48
+ *
49
+ * It partially supports the following transactions (which are not yet required):
50
+ * Direct Entry Credit
51
+ * Direct Entry Debit
52
+ *
53
+ * It can support the following transactions in future:
54
+ * Add Trigger/Peridic Payment
55
+ * Delete Trigger/Periodic Payment
56
+ * Trigger Triggered payment
57
+ *
58
+ * @param int mode - The kind of transaction object you would like to open. i.e. SECUREPAY_GATEWAY_MODE_TEST See top of this file for definitions.
59
+ * @param string merchantID - The merchant's login ID, received from SecurePay
60
+ * @param string merchantPW - The merchant's login password
61
+ */
62
+
63
+ class securepay_xml_transaction
64
+ {
65
+ const SECUREPAY_TEST_HOST = "https://www.securepay.com.au/test/payment";
66
+ const SECUREPAY_LIVE_HOST = "https://www.securepay.com.au/xmlapi/payment";
67
+
68
+ const TIMEOUT="60";
69
+
70
+ const GATEWAY_ERROR_OBJECT_INVALID = "The Gateway Object is invalid (constructor failure?)";
71
+ const GATEWAY_ERROR_CURL_ERROR = "CURL failed and reported the following error";
72
+ const GATEWAY_ERROR_INVALID_CCNUMBER = "Parameter Check failure: Invalid credit card number";
73
+ const GATEWAY_ERROR_INVALID_CCEXPIRY = "Parameter Check failure: Invalid credit card expiry date";
74
+ const GATEWAY_ERROR_INVALID_CC_CVC = "Parameter Check failure: Invalid credit card verification code";
75
+ const GATEWAY_ERROR_INVALID_TXN_AMT = "Parameter Check failure: Invalid transaction amount";
76
+ const GATEWAY_ERROR_INVALID_REF_ID = "Parameter Check failure: Invalid transaction reference number";
77
+ const GATEWAY_ERROR_INVALID_ACCOUNTNUMBER = "Parameter Check failure: Invalid account number";
78
+ const GATEWAY_ERROR_INVALID_ACCOUNTNAME = "Parameter Check failure: Invalid account name";
79
+ const GATEWAY_ERROR_INVALID_ACCOUNTBSB = "Parameter Check failure: Invalid BSB";
80
+ const GATEWAY_ERROR_RESPONSE_ERROR = "A general response error was detected";
81
+ const GATEWAY_ERROR_RESPONSE_INVALID = "A unspecified error was detected in the response content";
82
+ const GATEWAY_ERROR_XML_PARSE_FAILED = "The response message could not be parsed (invalid XML?)";
83
+ const GATEWAY_ERROR_RESPONSE_XML_MESSAGE_ERROR = "An unspecified error was found in the response message (missing field?)";
84
+ const GATEWAY_ERROR_SECUREPAY_STATUS = "The remote Gateway reported the following status error";
85
+ const GATEWAY_ERROR_TXN_DECLINED = "Transaction Declined";
86
+
87
+ private $errorString;
88
+ private $gatewayObjectValid = true;
89
+ private $gatewayURL;
90
+ private $merchantID;
91
+ private $merchantPW;
92
+ private $responseArray = array();
93
+ private $txnType;
94
+
95
+ private $ccNumber;
96
+ private $ccVerify;
97
+ private $ccExpiryMonth;
98
+ private $ccExpiryYear;
99
+
100
+ private $accNumber;
101
+ private $accBSB;
102
+ private $accName;
103
+
104
+ private $txnReference;
105
+ private $amount;
106
+
107
+ private $currency=CURRENCY_DEFAULT;
108
+
109
+ private $requestType;
110
+ private $periodicType;
111
+ private $periodicInterval;
112
+
113
+ private $bankTxnID = 0;
114
+
115
+ /**
116
+ * __construct
117
+ *
118
+ * @param integer $gatewaymode
119
+ * @param string $setup_merchantID
120
+ * @param string $setup_merchantPW
121
+ *
122
+ */
123
+ public function __construct( $gatewaymode, $setup_merchantID, $setup_merchantPW)
124
+ {
125
+
126
+ switch ( $gatewaymode )
127
+ {
128
+ case SECUREPAY_GATEWAY_MODE_TEST:
129
+ $this->gatewayURL = self::SECUREPAY_TEST_HOST;
130
+ break;
131
+
132
+ case SECUREPAY_GATEWAY_MODE_LIVE:
133
+ $this->gatewayURL = self::SECUREPAY_LIVE_HOST;
134
+ break;
135
+
136
+ default:
137
+ $this->gatewayObjectValid = false;
138
+ return;
139
+ }
140
+
141
+ if ( strlen( $setup_merchantID ) == 0
142
+ || strlen( $setup_merchantPW ) == 0 )
143
+ {
144
+ $this->gatewayObjectValid = false;
145
+ return;
146
+ }
147
+
148
+ $this->setAuth($setup_merchantID,$setup_merchantPW);
149
+
150
+ }
151
+
152
+ /**
153
+ * reset
154
+ *
155
+ * To clear response variables: prevents mismatched results in certain failure cases.
156
+ * This is called before each transaction, so be sure to check these values between transactions.
157
+ */
158
+ public function reset()
159
+ {
160
+ $this->errorString = NULL;
161
+ $this->responseArray = array();
162
+ $this->bankTxnID = 0;
163
+ }
164
+
165
+ public function isGatewayObjectValid()
166
+ {
167
+ return $this->gatewayObjectValid;
168
+ }
169
+
170
+ public function getAmount()
171
+ {
172
+ return $this->amount;
173
+ }
174
+
175
+ /**
176
+ * setAmount
177
+ *
178
+ * Takes amount as a float; requires currency to be set
179
+ *
180
+ * @param float amount
181
+ */
182
+ public function setAmount($amount)
183
+ {
184
+ if($this->getCurrency() == 'JPY')
185
+ $this->amount = $amount;
186
+ else
187
+ $this->amount = round($amount*100,0);
188
+ return;
189
+ }
190
+
191
+ public function getCurrency()
192
+ {
193
+ return $this->currency;
194
+ }
195
+
196
+ public function setCurrency($cur)
197
+ {
198
+ $this->currency = $cur;
199
+ return;
200
+ }
201
+
202
+ public function getTxnReference()
203
+ {
204
+ return $this->txnReference;
205
+ }
206
+
207
+ public function setTxnReference($ref)
208
+ {
209
+ $this->txnReference = $ref;
210
+ return;
211
+ }
212
+
213
+ public function getTxnType()
214
+ {
215
+ return $this->txnType;
216
+ }
217
+
218
+ public function setTxnType($type)
219
+ {
220
+ $this->txnType = $type;
221
+ return;
222
+ }
223
+
224
+ public function getPreauthID()
225
+ {
226
+ return $this->preauthID;
227
+ }
228
+
229
+ public function setPreauthID($id)
230
+ {
231
+ $this->preauthID = $id;
232
+ return;
233
+ }
234
+
235
+ public function getAccBSB()
236
+ {
237
+ return $this->accBSB;
238
+ }
239
+
240
+ public function setAccBSB($bsb)
241
+ {
242
+ $this->accBSB = $bsb;
243
+ return;
244
+ }
245
+
246
+ public function getAccNumber()
247
+ {
248
+ return $this->accNumber;
249
+ }
250
+
251
+ public function setAccNumber($Number)
252
+ {
253
+ $this->accNumber = $Number;
254
+ return;
255
+ }
256
+
257
+ public function getAccName()
258
+ {
259
+ return $this->accName;
260
+ }
261
+
262
+ public function setAccName($name)
263
+ {
264
+ $this->accName = $name;
265
+ return;
266
+ }
267
+
268
+ public function getCCNumber()
269
+ {
270
+ return $this->ccNumber;
271
+ }
272
+
273
+ public function setCCNumber($ccNumber)
274
+ {
275
+ $this->ccNumber = $ccNumber;
276
+ return;
277
+ }
278
+
279
+ public function getClearCCNumber()
280
+ {
281
+ $t = $this->getCCNumber();
282
+ $this->setCCNumber("0");
283
+ return $t;
284
+ }
285
+
286
+ public function getCCVerify()
287
+ {
288
+ return $this->ccVerify;
289
+ }
290
+
291
+ public function setCCVerify($ver)
292
+ {
293
+ $this->ccVerify = $ver;
294
+ return;
295
+ }
296
+
297
+ public function getClearCCVerify()
298
+ {
299
+ $t = $this->getCCVerify();
300
+ $this->setCCVerify(0);
301
+ return $t;
302
+ }
303
+
304
+ /* @return string month MM*/
305
+ public function getCCExpiryMonth()
306
+ {
307
+ return $this->ccExpiryMonth;
308
+ }
309
+
310
+ /* @param string/int month MM or month M - If there are leading zeros, type needs to be a string*/
311
+ public function setCCExpiryMonth($month)
312
+ {
313
+ $l = strlen(trim($month));
314
+ if($l == 1)
315
+ $this->ccExpiryMonth = sprintf("%02d",ltrim($month,'0'));
316
+ else
317
+ $this->ccExpiryMonth = $month;
318
+ return;
319
+ }
320
+
321
+ /* @return string year YY*/
322
+ public function getCCExpiryYear()
323
+ {
324
+ return $this->ccExpiryYear;
325
+ }
326
+
327
+ /* @param string year YY or year YYYY - If there are leading zeros, type needs to be a string*/
328
+ public function setCCExpiryYear($year)
329
+ {
330
+ $y = ltrim(trim((string)$year),"0");
331
+ $l = strlen($y);
332
+ if($l==4)
333
+ $this->ccExpiryYear = substr($y,2);
334
+ else if($l>=5)
335
+ $this->ccExpiryYear = 0;
336
+ else if($l==1)
337
+ $this->ccExpiryYear = sprintf("%02d",$y);
338
+ else
339
+ $this->ccExpiryYear = $year;
340
+
341
+ return;
342
+ }
343
+
344
+ public function getMerchantID()
345
+ {
346
+ return $this->merchantID;
347
+ }
348
+
349
+ public function setMerchantID($id)
350
+ {
351
+ $this->merchantID = $id;
352
+ return;
353
+ }
354
+
355
+ public function getMerchantPW ()
356
+ {
357
+ return $this->merchantPW;
358
+ }
359
+
360
+ public function setMerchantPW ($pw)
361
+ {
362
+ $this->merchantPW = $pw;
363
+ return;
364
+ }
365
+
366
+ public function getBankTxnID ()
367
+ {
368
+ return $this->bankTxnID;
369
+ }
370
+
371
+ public function setBankTxnID ($id)
372
+ {
373
+ $this->bankTxnID = $id;
374
+ return;
375
+ }
376
+
377
+ public function getRequestType ()
378
+ {
379
+ return $this->requestType;
380
+ }
381
+
382
+ public function setRequestType ($t)
383
+ {
384
+ $this->requestType = $t;
385
+ return;
386
+ }
387
+
388
+ public function getPeriodicType ()
389
+ {
390
+ return $this->periodicType;
391
+ }
392
+
393
+ public function setPeriodicType ($t)
394
+ {
395
+ $this->periodicType = $t;
396
+ return;
397
+ }
398
+
399
+ public function getPeriodicInterval ()
400
+ {
401
+ return $this->periodicInterval;
402
+ }
403
+
404
+ public function setPeriodicInterval ($t)
405
+ {
406
+ $this->periodicInterval = $t;
407
+ return;
408
+ }
409
+
410
+ public function getErrorString ()
411
+ {
412
+ return $this->errorString;
413
+ }
414
+
415
+ public function getResultArray ()
416
+ {
417
+ return $this->responseArray;
418
+ }
419
+
420
+ public function getResultByKeyName ( $keyName)
421
+ {
422
+ if ( array_key_exists( $keyName, $this->responseArray) === true )
423
+ {
424
+ return $this->responseArray[$keyName];
425
+ }
426
+ else
427
+ return false;
428
+ }
429
+
430
+ public function getTxnWasSuccesful()
431
+ {
432
+ if ( array_key_exists( "txnResult", $this->responseArray) === true
433
+ && $this->responseArray["txnResult"] === true )
434
+ return true;
435
+ else
436
+ return false;
437
+ }
438
+
439
+ public function setAuth($id, $pw)
440
+ {
441
+ $this->setMerchantID($id);
442
+ $this->setMerchantPW($pw);
443
+ return;
444
+ }
445
+
446
+ /**
447
+ * processCreditStandard:
448
+ *
449
+ * Process a standard credit card payment
450
+ *
451
+ * @param float amount - Numeric and decimal only: no thousand separators
452
+ * @param string txnReference - Merchant's unique transaction ID
453
+ * @param int cardNumber - 12-18 digit credit-card number
454
+ * @param int cardMonth - 2 digit month
455
+ * @param int cardYear - 2 or 4 digit year
456
+ * @param int cardVerify - 3 or 4 digit CVV (optional)
457
+ * @param string currency - Exactly three characters. See SecurePay documentation for list of valid currencies. (optional)
458
+ *
459
+ * @return string txnID - Bank's unique transaction ID (use for reversal or refund), or FALSE in case of failure (check $this->getErrorText() afterwards).
460
+ */
461
+ public function processCreditStandard($amount, $txnReference, $cardNumber, $cardMonth, $cardYear, $cardVerify=0, $currency=CURRENCY_DEFAULT)
462
+ {
463
+ $this->reset();
464
+
465
+ $this->setTxnType(SECUREPAY_TXN_STANDARD);
466
+
467
+ $this->setAmount($amount);
468
+ $this->setTxnReference($txnReference);
469
+ $this->setCCNumber($cardNumber);
470
+ if(strlen($cardVerify)!=0)
471
+ $this->setCCVerify($cardVerify);
472
+ $this->setCCExpiryYear($cardYear);
473
+ $this->setCCExpiryMonth($cardMonth);
474
+ if($currency)
475
+ $this->setCurrency($currency);
476
+
477
+ if($this->processTransaction());
478
+ if(array_key_exists('banktxnID',$this->responseArray))
479
+ return $this->responseArray['banktxnID'];
480
+ return false;
481
+ }
482
+
483
+ /**
484
+ * processCreditRefund:
485
+ *
486
+ * Refund a standard credit card payment. $amount can be less than the original transaction.
487
+ *
488
+ * @param float amount - Numeric and decimal only: no thousand separators
489
+ * @param string txnReference - Merchant's unique transaction ID: must be same as in initial transaction
490
+ * @param int txnID - Result of original transaction
491
+ *
492
+ * @return string txnID - Bank's unique transaction ID, or FALSE in case of failure (check $this->getErrorText() afterwards).
493
+ */
494
+ public function processCreditRefund($amount, $txnReference, $txnID)
495
+ {
496
+ $this->reset();
497
+
498
+ $this->setTxnType(SECUREPAY_TXN_REFUND);
499
+
500
+ $this->setAmount($amount);
501
+ $this->setTxnReference($txnReference);
502
+
503
+ $this->setBankTxnID($txnID);
504
+
505
+ if($this->processTransaction());
506
+ if(array_key_exists('banktxnID',$this->responseArray))
507
+ return $this->responseArray['banktxnID'];
508
+ return false;
509
+ }
510
+
511
+ /**
512
+ * processCreditReverse:
513
+ *
514
+ * Reverse a standard credit card payment. $amount should be same as in original transaction.
515
+ *
516
+ * @param float amount - Numeric and decimal only: no thousand separators
517
+ * @param string txnReference - Merchant's unique transaction ID: must be same as in initial transaction
518
+ * @param int txnID - Result of original transaction
519
+ *
520
+ * @return string txnID - Bank's unique transaction ID, or FALSE in case of failure (check $this->getErrorText() afterwards).
521
+ */
522
+ public function processCreditReverse($amount, $txnReference, $txnID)
523
+ {
524
+ $this->reset();
525
+
526
+ $this->setTxnType(SECUREPAY_TXN_REVERSE);
527
+
528
+ $this->setAmount($amount);
529
+ $this->setTxnReference($txnReference);
530
+
531
+ $this->setBankTxnID($txnID);
532
+
533
+ if($this->processTransaction());
534
+ if(array_key_exists('banktxnID',$this->responseArray))
535
+ return $this->responseArray['banktxnID'];
536
+ return false;
537
+ }
538
+
539
+ /**
540
+ * processCreditPreauth:
541
+ *
542
+ * Preauthorise a credit card payment
543
+ *
544
+ * @param float amount - Numeric and decimal only: no thousand separators
545
+ * @param string txnReference - Merchant's unique transaction ID
546
+ * @param int cardNumber - 12-18 digit credit-card number
547
+ * @param int cardMonth - 2 digit month
548
+ * @param int cardYear - 2 or 4 digit year
549
+ * @param int cardVerify - 3 or 4 digit CVV (optional)
550
+ * @param string currency - Exactly three characters. See SecurePay documentation for list of valid currencies. (optional)
551
+ *
552
+ * @return string preauthID - preauthorisation ID (use to execute transaction later (processCreditAdvice)), or FALSE (check $this->getErrorText() afterwards).
553
+ */
554
+ public function processCreditPreauth($amount, $txnReference, $cardNumber, $cardMonth, $cardYear, $cardVerify=0, $currency=CURRENCY_DEFAULT)
555
+ {
556
+ $this->reset();
557
+
558
+ $this->setTxnType(SECUREPAY_TXN_PREAUTH);
559
+
560
+ $this->setAmount($amount);
561
+ $this->setTxnReference($txnReference);
562
+ $this->setCCNumber($cardNumber);
563
+ if(strlen($cardVerify)!=0)
564
+ $this->setCCVerify($cardVerify);
565
+ $this->setCCExpiryYear($cardYear);
566
+ $this->setCCExpiryMonth($cardMonth);
567
+
568
+ if($currency)
569
+ $this->setCurrency($currency);
570
+
571
+ if($this->processTransaction())
572
+ {
573
+ if(array_key_exists('preauthID',$this->responseArray))
574
+ return $this->responseArray['preauthID'];
575
+ }
576
+
577
+ return false;
578
+ }
579
+
580
+ /**
581
+ * processCreditAdvice:
582
+ *
583
+ * Execute a preauthorised transaction
584
+ *
585
+ * @param float amount - Numeric and decimal only: no thousand separators. Should be same as preauthorised amount.
586
+ * @param string txnReference - Merchant's unique transaction ID: must be same as in initial transaction
587
+ * @param string preauthID - Preauthorisation code which was returned from processCreditPreauth
588
+ *
589
+ * @return string txnID - Bank's unique transaction ID, or FALSE in case of failure (check $this->getErrorText() afterwards).
590
+ */
591
+ public function processCreditAdvice($amount, $txnReference, $preauthID)
592
+ {
593
+ $this->reset();
594
+
595
+ $this->setTxnType(SECUREPAY_TXN_ADVICE);
596
+
597
+ $this->setAmount($amount);
598
+ $this->setTxnReference($txnReference);
599
+ $this->setPreauthID($preauthID);
600
+
601
+ if($this->processTransaction());
602
+ if(array_key_exists('banktxnID',$this->responseArray))
603
+ return $this->responseArray['banktxnID'];
604
+ return false;
605
+ }
606
+
607
+ /**
608
+ * processTransaction:
609
+ *
610
+ * this function attempts to process a payment transaction using the
611
+ * supplied details on the SecurePay SecureXML Gateway
612
+ *
613
+ * @return boolean Returns true for succesful (approved) transaction / false for failure (declined) or error
614
+ *
615
+ */
616
+ private function processTransaction ()
617
+ {
618
+ // check that self is a valid gateway object
619
+ if ( !$this->gatewayObjectValid )
620
+ {
621
+ $this->errorString = self::GATEWAY_ERROR_OBJECT_INVALID;
622
+ return false;
623
+ }
624
+
625
+ // check parameters
626
+ if( $this->getTxnType()==SECUREPAY_TXN_STANDARD ||
627
+ $this->getTxnType()==SECUREPAY_TXN_PREAUTH )
628
+ {
629
+ if ($this->checkCCparameters() == false)
630
+ return false;
631
+ }
632
+ else if ( $this->getTxnType()==SECUREPAY_TXN_DIRECTDEBIT ||
633
+ $this->getTxnType()==SECUREPAY_TXN_DIRECTCREDIT )
634
+ {
635
+ if ($this->checkDirectparameters() == false)
636
+ return false;
637
+ }
638
+ if ($this->checkTxnParameters() == false)
639
+ {
640
+ return false;
641
+ }
642
+
643
+ // create request message. This function will retrieve and destroy CC details, if we're in credit-card mode (!)
644
+ $requestMessage = $this->createXMLTransactionRequestString();
645
+
646
+ $this->responseArray["raw-XML-request"] = htmlentities($requestMessage);
647
+
648
+ // send request
649
+ $response = $this->sendRequest( $this->gatewayURL, $requestMessage );
650
+
651
+ $this->responseArray["raw-response"] = htmlentities($response);
652
+
653
+ // was a response received?
654
+ if ( $response === false )
655
+ {
656
+ if ( strlen( $this->errorString ) == 0 )
657
+ {
658
+ $this->errorString = self::GATEWAY_ERROR_RESPONSE_ERROR;
659
+ }
660
+ return false;
661
+ }
662
+
663
+ // process response for validity
664
+ if ( $this->processTransactionResponseMessageIntoResponseArray( $response ) === false )
665
+ {
666
+ if ( strlen( $this->errorString ) == 0 )
667
+ {
668
+ $this->errorString = self::GATEWAY_ERROR_RESPONSE_INVALID;
669
+ }
670
+ return false;
671
+ }
672
+
673
+ // if we get this far, the transaction is succesful and "approved"
674
+ $this->responseArray["txnResult"] = true;
675
+
676
+ return true;
677
+ }
678
+
679
+
680
+ /**
681
+ * checkCCparameters
682
+ *
683
+ * Check the input parameters are valid for a credit card transaction
684
+ *
685
+ * @return boolean Return TRUE for all checks passed OK, or FALSE if an error is detected
686
+ */
687
+ private function checkCCparameters()
688
+ {
689
+ // the string ccNumber must be all numeric, and between 12 and 19 digits long
690
+ if (strlen( $this->getCCNumber() ) < 12 ||
691
+ strlen( $this->getCCNumber() ) > 19 ||
692
+ preg_match("/\D/",$this->getCCNumber()) )// REGEXP: true if "any match for non-numeral"
693
+ {
694
+ $this->errorString = self::GATEWAY_ERROR_INVALID_CCNUMBER;
695
+ return false;
696
+ }
697
+
698
+ // the string $ccExpiryMonth must be all numeric with value between 1 and 12
699
+ if (preg_match("/\D/", $this->getCCExpiryMonth()) || // REGEXP: true if "any match for non-numeral"
700
+ (int) $this->getCCExpiryMonth() < 1 ||
701
+ (int) $this->getCCExpiryMonth() > 12 )
702
+ {
703
+ $this->errorString = self::GATEWAY_ERROR_INVALID_CCEXPIRY;
704
+ return false;
705
+ }
706
+
707
+ // the string $ccExpiryYear must be all numeric with value between this year and this year + 12 years
708
+ if (preg_match( "/\D/", $this->getCCExpiryYear()) || // REGEXP: true if "any match for non-numeral"
709
+ (strlen($this->getCCExpiryYear()) != 2) || //YY form
710
+ (int) $this->getCCExpiryYear() < (int) substr(date("Y"),2) || // Between now and now + 12
711
+ (int) $this->getCCExpiryYear() > ( (int) substr(date("Y"),2) + 12 ) )
712
+ {
713
+ $this->errorString = self::GATEWAY_ERROR_INVALID_CCEXPIRY;
714
+ return false;
715
+ }
716
+
717
+ // The CVC is an optional data item so only perform the checks if the parameter was present
718
+ if ( strlen( $this->getCCVerify() ) != 0 )
719
+ {
720
+ // the string $ccVericationNumber must be all numeric with value between 000 and 9999
721
+ if (preg_match( "/\D/", $this->getCCVerify() ) || // REGEXP: true if "any match for non-numeral"
722
+ strlen( $this->getCCVerify() ) < 3 ||
723
+ strlen( $this->getCCVerify() ) > 4 ||
724
+ (int) $this->getCCVerify() < 0 ||
725
+ (int) $this->getCCVerify() > 9999 )
726
+ {
727
+ $this->errorString = self::GATEWAY_ERROR_INVALID_CC_CVC;
728
+ return false;
729
+ }
730
+ }
731
+ return true;
732
+ }
733
+
734
+ /**
735
+ * checkCCparameters
736
+ *
737
+ * Check the input parameters are valid for a credit card transaction
738
+ *
739
+ * @return boolean Return TRUE for all checks passed OK, or FALSE if an error is detected
740
+ */
741
+ private function checkDirectparameters()
742
+ {
743
+ // the string accNumber must be all numeric, and between 12 and 19 digits long
744
+ if (preg_match( "/\D/", $this->getAccNumber() ) )// REGEXP: true if "any match for non-numeral"
745
+ {
746
+ $this->errorString = self::GATEWAY_ERROR_INVALID_ACCOUNTNUMBER;
747
+ return false;
748
+ }
749
+
750
+ // the string $accName must be all numeric with value between 1 and 12
751
+ if ( preg_match( "/\D/", $this->getAccName() )) // REGEXP: true if "any match for non-numeral"
752
+ {
753
+ print "Month\n";
754
+ $this->errorString = self::GATEWAY_ERROR_INVALID_ACCOUNTNAME;
755
+ return false;
756
+ }
757
+ // the string $accBSB must be all numeric with value between 000 and 9999
758
+ if (preg_match( "/\D/", $this->getAccBSB())) // REGEXP: true if "any match for non-numeral"
759
+ {
760
+ $this->errorString = self::GATEWAY_ERROR_INVALID_BSB;
761
+ return false;
762
+ }
763
+
764
+ return true;
765
+ }
766
+
767
+ /**
768
+ * checkTxnParameters
769
+ *
770
+ * Check that the transaction input parameters are within requirements
771
+ *
772
+ * @param string $txnAmount
773
+ * @param string $txnReference
774
+ *
775
+ * @return TRUE for pass, FALSE for fail
776
+ */
777
+ private function checkTxnParameters ()
778
+ {
779
+ $amount = $this->getAmount();
780
+ if (preg_match( "/^[0-9]/", $amount)==false || (int) $amount < 0 )
781
+ {
782
+ $this->errorString = self::GATEWAY_ERROR_INVALID_TXN_AMT;
783
+ return false;
784
+ }
785
+
786
+ $ref = $this->getTxnReference();
787
+ if ( $this->getTxnType()==SECUREPAY_TXN_DIRECTDEBIT ||
788
+ $this->getTxnType()==SECUREPAY_TXN_DIRECTCREDIT )
789
+ {
790
+ // Direct Entry Payment References need to conform to EBCDIC, and should be <= 18 characters
791
+ if (strlen($ref) == 0 || strlen($ref)>18 ||
792
+ preg_match('/[^0-9a-zA-Z*\.&\/-_\']/', $ref)) // REGEXP: match any non-EBCDIC character
793
+ {
794
+ $this->errorString = self::GATEWAY_ERROR_INVALID_REF_ID;
795
+ return false;
796
+ }
797
+ }
798
+ else
799
+ {
800
+ // Standard/Credit References can have any character except space and single quote
801
+ if (strlen($ref) == 0 || strlen($ref)>59 ||
802
+ preg_match('/[^ \']/', $ref)==false) // REGEXP: match invalid characters
803
+ {
804
+ $this->errorString = self::GATEWAY_ERROR_INVALID_REF_ID;
805
+ return false;
806
+ }
807
+ }
808
+ return true;
809
+ }
810
+
811
+ /**
812
+ * createXMLTransactionRequestString:
813
+ * Creates the XML request string for a transaction request message
814
+ *
815
+ * Note: calls to getClearCCNumber & getClearCCVerify: details are removed from their respective private variables here
816
+ *
817
+ * @return string xml_transaction
818
+ */
819
+ private function createXMLTransactionRequestString()
820
+ {
821
+ $x =
822
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>".
823
+ "<SecurePayMessage>" .
824
+ "<MessageInfo>" .
825
+ "<messageID>".htmlentities($this->getTxnReference().date("his").current(split(' ',microtime( ))))."</messageID>".
826
+ "<messageTimestamp>".htmlentities($this->getGMTTimeStamp())."</messageTimestamp>".
827
+ "<timeoutValue>".self::TIMEOUT."</timeoutValue>".
828
+ "<apiVersion>xml-4.2</apiVersion>" .
829
+ "</MessageInfo>".
830
+ "<MerchantInfo>".
831
+ "<merchantID>".htmlentities($this->getMerchantID())."</merchantID>" .
832
+ "<password>".htmlentities($this->getMerchantPW())."</password>" .
833
+ "</MerchantInfo>".
834
+ "<RequestType>Payment</RequestType>".
835
+ "<Payment>".
836
+ "<TxnList count=\"1\">".
837
+ "<Txn ID=\"1\">".
838
+ "<txnType>".htmlentities($this->getTxnType())."</txnType>".
839
+ "<txnSource>23</txnSource>".
840
+ "<amount>".htmlentities($this->getAmount())."</amount>";
841
+ if( ($this->getTxnType()==SECUREPAY_TXN_STANDARD ||
842
+ $this->getTxnType()==SECUREPAY_TXN_PREAUTH ) &&
843
+ $this->getCurrency()!=CURRENCY_DEFAULT)
844
+ {
845
+ $x .= "<currency>".htmlentities($this->getCurrency())."</currency>";
846
+ }
847
+ $x .= "<purchaseOrderNo>".htmlentities($this->getTxnReference())."</purchaseOrderNo>";
848
+ if( $this->getTxnType()==SECUREPAY_TXN_ADVICE)
849
+ {
850
+ $x .= "<preauthID>".htmlentities($this->getPreauthID())."</preauthID>";
851
+ }
852
+ if( $this->getTxnType()==SECUREPAY_TXN_REFUND ||
853
+ $this->getTxnType()==SECUREPAY_TXN_REVERSE &&
854
+ $this->getBankTxnID() != 0)
855
+ {
856
+ $x .= "<txnID>".htmlentities($this->getBankTxnID())."</txnID>";
857
+ }
858
+
859
+ if( $this->getTxnType()==SECUREPAY_TXN_STANDARD ||
860
+ $this->getTxnType()==SECUREPAY_TXN_PREAUTH )
861
+ {
862
+ $x .= "<CreditCardInfo>".
863
+ "<cardNumber>".htmlentities($this->getClearCCNumber())."</cardNumber>";
864
+ if (trim($this->getCCVerify()) <> "")
865
+ {
866
+ $x .= "<cvv>".htmlentities($this->getClearCCVerify())."</cvv>";
867
+ }
868
+ $x .= "<expiryDate>".htmlentities(sprintf("%02d",$this->getCCExpiryMonth())."/".sprintf("%02d",$this->getCCExpiryYear()))."</expiryDate>".
869
+ "</CreditCardInfo>";
870
+ }
871
+ else if ( $this->getTxnType()==SECUREPAY_TXN_DIRECTDEBIT ||
872
+ $this->getTxnType()==SECUREPAY_TXN_DIRECTCREDIT )
873
+ {
874
+ $x .= "<DirectEntryInfo>".
875
+ "<bsbNumber>".htmlentities($this->getAccBSB())."</bsbNumber>".
876
+ "<accountNumber>".htmlentities($this->getAccNumber())."</accountNumber>".
877
+ "<accountName>".htmlentities($this->getAccName())."</accountName>".
878
+ "</DirectEntryInfo>";
879
+ }
880
+ $x .= "</Txn>".
881
+ "</TxnList>".
882
+ "</Payment>".
883
+ "</SecurePayMessage>";
884
+
885
+ return $x;
886
+ }
887
+
888
+
889
+ /**
890
+ * getGMTTimeStamp:
891
+ *
892
+ * this function creates a timestamp formatted as per requirement in the
893
+ * SecureXML documentation
894
+ *
895
+ * @return string The formatted timestamp
896
+ */
897
+ private function getGMTTimeStamp()
898
+ {
899
+ /* Format: YYYYDDMMHHNNSSKKK000sOOO
900
+ YYYY is a 4-digit year
901
+ DD is a 2-digit zero-padded day of month
902
+ MM is a 2-digit zero-padded month of year (January = 01)
903
+ HH is a 2-digit zero-padded hour of day in 24-hour clock format (midnight =0)
904
+ NN is a 2-digit zero-padded minute of hour
905
+ SS is a 2-digit zero-padded second of minute
906
+ KKK is a 3-digit zero-padded millisecond of second
907
+ 000 is a Static 0 characters, as SecurePay does not store nanoseconds
908
+ sOOO is a Time zone offset, where s is �+� or �-�, and OOO = minutes, from GMT.
909
+ */
910
+
911
+
912
+ $val = date("Z") / 60;
913
+ if ($val >= 0)
914
+ {
915
+ $val = "+" . strval($val);
916
+ }
917
+
918
+ $stamp = date("YdmGis000000") . $val;
919
+
920
+ return $stamp;
921
+ }
922
+
923
+ /**
924
+ * sendRequest:
925
+ * uses cURL to open a Secure Socket connection to the gateway,
926
+ * sends the transaction request and then returns the response
927
+ * data
928
+ *
929
+ * @param $postURL The URL of the remote gateway to which the request is sent
930
+ * @param $requestMessage
931
+ */
932
+ private function sendRequest( $postURL, $requestMessage )
933
+ {
934
+ $ch = curl_init();
935
+
936
+ // Set up curl parameters
937
+ curl_setopt( $ch, CURLOPT_URL, $postURL ); // set remote address
938
+ curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 ); // Make CURL pass the response as a curl_exec return value instead of outputting to STDOUT
939
+ curl_setopt( $ch, CURLOPT_POST, 1 ); // Activate the POST method
940
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
941
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 );
942
+
943
+ curl_setopt( $ch, CURLOPT_POSTFIELDS, $requestMessage ); // add the request message itself
944
+
945
+ // execute the connexion
946
+ $result = curl_exec( $ch );
947
+
948
+ $debugoutput = curl_getinfo($ch);
949
+ $curl_error_message = curl_error( $ch ); // must retrieve an error message (if any) before closing the curl object
950
+
951
+ curl_close($ch);
952
+
953
+
954
+ if ( $result === false )
955
+ {
956
+ $this->errorString = self::GATEWAY_ERROR_CURL_ERROR.': '.$curl_error_message;
957
+ return false;
958
+ }
959
+
960
+ // we do not need the header part of the response, trim it off the result
961
+ $pos = strstr( $result, "\n" );
962
+ $result = substr( $result, $pos );
963
+
964
+ return $result;
965
+ }
966
+
967
+ /**
968
+ * processTransactionResponseMessageIntoResponseArray:
969
+ * converts the response XML message into a nested array structure and then
970
+ * pulls out the relevant data into a simplified result array
971
+ *
972
+ * @param string $responseMessage - An XML response from the gateway
973
+ * @return boolean True to indicate succesful decoding of response message AND succesful txn result, false to indicate an error or declined result
974
+ */
975
+ private function processTransactionResponseMessageIntoResponseArray ( $responseMessage )
976
+ {
977
+ $xmlres = array();
978
+ $xmlres = $this->convertXMLToNestedArray( $responseMessage );
979
+
980
+ if ( $xmlres === false )
981
+ {
982
+ if ( strlen( $this->errorString ) == 0 )
983
+ {
984
+ $this->errorString = self::GATEWAY_ERROR_RESPONSE_XML_MESSAGE_ERROR;
985
+ }
986
+ return false;
987
+ }
988
+
989
+ $responseArray["raw-XML-response"] = htmlentities($responseMessage);
990
+
991
+ $statusCode = trim( $xmlres['SecurePayMessage']['Status']['statusCode'] );
992
+ $statusDescription = trim($xmlres['SecurePayMessage']['Status']['statusDescription']);
993
+
994
+ $responseArray["statusCode"] = $statusCode;
995
+ $responseArray["statusDescription"] = $statusDescription;
996
+
997
+ // Three digit codes indicate a repsonse from the Securepay gateway (error detected by gateway)
998
+ if ( strcmp( $statusCode, '000' ) != 0 )
999
+ {
1000
+ $this->errorString = self::GATEWAY_ERROR_SECUREPAY_STATUS.": ".$statusCode." ".$statusDescription;
1001
+ return false;
1002
+ }
1003
+
1004
+ $responseArray["messageID"] = trim($xmlres['SecurePayMessage']['MessageInfo']['messageID']);
1005
+ $responseArray["messageTimestamp"] = trim($xmlres['SecurePayMessage']['MessageInfo']['messageTimestamp']);
1006
+ $responseArray["apiVersion"] = trim($xmlres['SecurePayMessage']['MessageInfo']['apiVersion']);
1007
+ $responseArray["RequestType"] = trim($xmlres['SecurePayMessage']['RequestType']);
1008
+ $responseArray["merchantID"] = trim($xmlres['SecurePayMessage']['MerchantInfo']['merchantID']);
1009
+ $responseArray["txnType"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['txnType']);
1010
+ $responseArray["txnSource"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['txnSource']);
1011
+ $responseArray["amount"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['amount']);
1012
+ $responseArray["approved"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['approved']);
1013
+ $responseArray["responseCode"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['responseCode']);
1014
+ $responseArray["responseText"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['responseText']);
1015
+ $responseArray["banktxnID"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['txnID']);
1016
+ $responseArray["settlementDate"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['settlementDate']);
1017
+
1018
+ if( $this->getTxnType()==SECUREPAY_TXN_PREAUTH && array_key_exists('preauthID',$xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']))
1019
+ {
1020
+ $responseArray["preauthID"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['preauthID']);
1021
+ }
1022
+ if($this->getRequestType() == SECUREPAY_REQ_PERIODIC)
1023
+ {
1024
+ if( $this->getTxnType()==SECUREPAY_TXN_STANDARD ||
1025
+ $this->getTxnType()==SECUREPAY_TXN_PREAUTH )
1026
+ {
1027
+ $responseArray["creditCardPAN"] = trim($xmlres['SecurePayMessage']['Periodic']['PeriodicList']['PeriodicItem']['CreditCardInfo']['pan']);
1028
+ $responseArray["expiryDate"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['CreditCardInfo']['expiryDate']);
1029
+ }
1030
+ }
1031
+ else if (strtoupper($responseArray['approved']) == 'YES' &&
1032
+ ($this->getTxnType()==SECUREPAY_TXN_DIRECTDEBIT ||
1033
+ $this->getTxnType()==SECUREPAY_TXN_DIRECTCREDIT) )
1034
+ {
1035
+ $responseArray["bsbNumber"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['DirectEntryInfo']['bsbNumber']);
1036
+ $responseArray["accountNumber"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['DirectEntryInfo']['accountNumber']);
1037
+ $responseArray["accountName"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['DirectEntryInfo']['accountName']);
1038
+ }
1039
+ else if ($this->getRequestType() == SECUREPAY_REQ_PAYMENT)
1040
+ {
1041
+ $responseArray["creditCardPAN"] = trim($xmlres['SecurePayMessage']['Periodic']['PeriodicList']['PeriodicItem']['CreditCardInfo']['pan']);
1042
+ $responseArray["expiryDate"] = trim($xmlres['SecurePayMessage']['Payment']['TxnList']['Txn']['CreditCardInfo']['expiryDate']);
1043
+ }
1044
+ $this->responseArray = $responseArray;
1045
+
1046
+ /* field "successful" = "Yes" means "triggered transaction successfully registered", anything else is failure */
1047
+ /* responseCodes:
1048
+ "00" indicates approved,
1049
+ "08" is Honor with ID (approved) and
1050
+ "77" is Approved (ANZ only).
1051
+ Any other 2 digit code is a decline or error from the bank. */
1052
+
1053
+ if (strcasecmp( $responseArray["approved"], "Yes" ) == 0)
1054
+ {
1055
+ return true;
1056
+ }
1057
+ else
1058
+ {
1059
+ $this->errorString = self::GATEWAY_ERROR_TXN_DECLINED." (".$responseArray["responseCode"]."): ".$responseArray["responseText"];
1060
+ return false;
1061
+ }
1062
+ }
1063
+
1064
+
1065
+ /**
1066
+ * convertXMLToNestedArray:
1067
+ * converts an XML document into a nested array structure
1068
+ *
1069
+ * @param string $XMLDocument An XML document
1070
+ * @return boolean True to indicate succesful conversion of document, false to indicate an error
1071
+ */
1072
+ private function convertXMLToNestedArray ( $XMLDocument )
1073
+ {
1074
+
1075
+ $output = array();
1076
+
1077
+ $parser = xml_parser_create();
1078
+
1079
+ xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
1080
+ xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
1081
+ $parse_result = xml_parse_into_struct($parser, $XMLDocument, $values);
1082
+
1083
+ if ( $parse_result === 0)
1084
+ {
1085
+ $this->errorString = self::GATEWAY_ERROR_XML_PARSE_FAILED.": ".xml_get_error_code ( $parser )." ".xml_error_string (xml_get_error_code ( $parser ) );
1086
+ xml_parser_free($parser);
1087
+
1088
+ return false;
1089
+ }
1090
+
1091
+ xml_parser_free($parser);
1092
+
1093
+ $hash_stack = array();
1094
+
1095
+ foreach ($values as $val)
1096
+ {
1097
+ switch ($val['type'])
1098
+ {
1099
+ case 'open':
1100
+ array_push($hash_stack, $val['tag']);
1101
+ break;
1102
+
1103
+ case 'close':
1104
+ array_pop($hash_stack);
1105
+ break;
1106
+
1107
+ case 'complete':
1108
+ array_push($hash_stack, $val['tag']);
1109
+ if ( array_key_exists('value', $val) )
1110
+ eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['value']}\";");
1111
+ else // to handle empty self closing tags i.e. <paymentInterval/>
1112
+ eval("\$output['" . implode($hash_stack, "']['") . "'] = null;");
1113
+ array_pop($hash_stack);
1114
+ break;
1115
+ }
1116
+ }
1117
+ return $output;
1118
+ }
1119
+ }
1120
+
1121
+ ?>
app/etc/modules/SecurePay_Sxml.xml CHANGED
@@ -1,12 +1,12 @@
1
- <?xml version="1.0"?>
2
- <config>
3
- <modules>
4
- <SecurePay_Sxml>
5
- <active>true</active>
6
- <codePool>local</codePool>
7
- <depends>
8
- <Mage_Payment />
9
- </depends>
10
- </SecurePay_Sxml>
11
- </modules>
12
- </config>
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <SecurePay_Sxml>
5
+ <active>true</active>
6
+ <codePool>local</codePool>
7
+ <depends>
8
+ <Mage_Payment />
9
+ </depends>
10
+ </SecurePay_Sxml>
11
+ </modules>
12
+ </config>
package.xml CHANGED
@@ -1,29 +1,28 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>SecurePay_SecureXML</name>
4
- <version>1.0.7</version>
5
  <stability>stable</stability>
6
- <license uri="http://www.opensource.org/licenses/osl-3.0.php">OSL v3.0</license>
7
  <channel>community</channel>
8
  <extends/>
9
- <summary>Provides credit-card transactions via the SecurePay XML API</summary>
10
- <description>Provides support for the following kinds of credit-card transaction:
11
- Standard (Payment)
12
- Preauthorise
13
- Advice (Complete/Capture)
14
- Reverse (Void)
15
- Refund</description>
16
- <notes>In the config options, select Authorize for preauth/complete mode, or Authorize and Capture for standard payment mode.
17
-
18
- If there is a problem with the initial transaction, the bank response code and text will be displayed to the user.
19
-
20
- /magento/var/log needs to exist and be writable in order to use Debug mode.
21
-
22
- Should work without issue in 1.4.0.0 (works fine in 1.4rc, though not 1.4-beta). Report any issues in the forum, or contact SecurePay support.</notes>
23
- <authors><author><name>Andrew Dubbeld</name><user>auto-converted</user><email>andrewd@securepay.com.au</email></author></authors>
24
- <date>2010-01-27</date>
25
- <time>22:02:36</time>
26
- <contents><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="sxml"><dir name="form"><file name="cc.phtml" hash="f2f93094119de0ba20028c431a19c5d5"/></dir></dir></dir></dir></dir></dir><dir name="frontend"><dir name="default"><dir name="default"><dir name="template"><dir name="sxml"><dir name="form"><file name="cc.phtml" hash="bf939e81578a8c00c9f81d046120e95b"/></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="SecurePay_Sxml.xml" hash="e466d9b1db62c1844ccf17cca44bee5e"/></dir></target><target name="magelocal"><dir name="SecurePay"><dir name="Sxml"><dir name="Block"><dir name="Form"><file name="Cc.php" hash="412525e5c8c79ebd26cbf6033618b615"/></dir></dir><dir name="etc"><file name="config.xml" hash="d42cdc5b98b7fbbb5a51f723a024a7ff"/><file name="system.xml" hash="8200cc68bbb66123b2324990d58c854c"/></dir><dir name="Helper"><file name="Data.php" hash="393c88c60eca919c13f255156355c536"/></dir><dir name="Model"><dir name="Source"><file name="Cctype.php" hash="bfe90747333890f72c94bd57b8b288c0"/></dir><dir name="Sxml"><file name="PaymentAction.php" hash="a5b8594da33b6113f3e9cc759c364d03"/><file name="Request.php" hash="95c4749da03d4e68b83706c8ce70ef0f"/><file name="Result.php" hash="f3f463587b5293a897f5c7e2bd4fc139"/></dir><file name="Sxml.php" hash="9fe1ea31214daf70269872abc2df0d6d"/></dir></dir><file name="securepay_xml_api.php" hash="eb7530a7170fb7756ca80bad9698468b"/></dir></target></contents>
27
  <compatible/>
28
- <dependencies/>
29
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>SecurePay_SecureXML</name>
4
+ <version>1.0.8.6</version>
5
  <stability>stable</stability>
6
+ <license uri="http://opensource.org/licenses/osl-3.0.php">Open Software License (OSL)</license>
7
  <channel>community</channel>
8
  <extends/>
9
+ <summary>Enables credit-card payments via the SecurePay gateway</summary>
10
+ <description>&lt;p&gt;The &lt;a href="http://securepay.com.au"&gt;SecurePay Australia&lt;/a&gt; XML API plugin enables support in Magento for the following credit-card transactions:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Standard Credit, when in Authorize + Capture mode&lt;/li&gt;&lt;li&gt;Preauth/Advice (Preauthorise + Complete), when in Authorize mode&lt;/li&gt;&lt;li&gt;Reverse (Void)&lt;/li&gt;&lt;li&gt;Refund&lt;/li&gt;&lt;li&gt;FraudGuard (Standard payment &amp; Preauth)&lt;/li&gt;&lt;/ul&gt;&#xD;
11
+ &lt;p&gt;The SecurePay payment gateway allows transactions from the following card types:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Visa&lt;/li&gt;&lt;li&gt;American Express&lt;/li&gt;&lt;li&gt;Mastercard&lt;/li&gt;&lt;li&gt;Diners Club&lt;/li&gt;&lt;li&gt;JCB&lt;/li&gt;&lt;/ul&gt;&#xD;
12
+ &lt;p&gt;1.0.8 adds support for FraudGuard transactions. If enabled in Magento and on your SecurePay account, all payments and preauthorizations will be screened for fraudulent activity.&lt;/p&gt;&#xD;
13
+ &lt;p&gt;Note: you may need to create the folder &lt;i&gt;magento/var/log&lt;/i&gt; (with +rwx permissions) in order to use Debug mode. Debug mode logs transaction details and issues to &lt;i&gt;magento/var/log/Sxml.log&lt;/i&gt;&lt;/p&gt;&#xD;
14
+ &lt;p&gt;This module has been tested and is working correctly with Magento 1.4.0.1&lt;/p&gt;</description>
15
+ <notes>Provides support for the following kinds of credit-card transactions, via the SecurePay gateway:&#xD;
16
+ Standard payment&#xD;
17
+ Preauthorize&#xD;
18
+ Complete&#xD;
19
+ Void&#xD;
20
+ Refund&#xD;
21
+ FraudGuard (Standard &amp; Preauthorize)</notes>
22
+ <authors><author><name>John</name><user>john</user><email>johno@straightsell.com.au</email></author></authors>
23
+ <date>2012-04-17</date>
24
+ <time>05:52:09</time>
25
+ <contents><target name="magelocal"><dir name="SecurePay"><dir name="Sxml"><dir name="Block"><dir name="Form"><file name="Cc.php" hash="d58103847e7d12bc789f4044026b2c86"/></dir></dir><dir name="Helper"><file name="Data.php" hash="393c88c60eca919c13f255156355c536"/></dir><dir name="Model"><dir name="Source"><file name="Cctype.php" hash="bfe90747333890f72c94bd57b8b288c0"/></dir><dir name="Sxml"><file name="PaymentAction.php" hash="daf4ec3ebdf722093c44339418fc2dd3"/><file name="Request.php" hash="185f7afd0d9e60d0e123839494ebf0cc"/><file name="Result.php" hash="f3f463587b5293a897f5c7e2bd4fc139"/></dir><file name="Sxml.php" hash="1c5708bd00e6bd0cddc65d488496ec92"/></dir><dir name="etc"><file name="config.xml" hash="65541a1f32d585c05f2ba2658ec9b3b6"/><file name="system.xml" hash="8200cc68bbb66123b2324990d58c854c"/></dir></dir><file name="securepay_xml_api.php" hash="1d0020fab36e49c5553bbf1f4e107cc0"/><file name="securepay_xml_api.php~" hash="7f3f7a88ffb9499d0284025a00972bd9"/></dir></target><target name="mage"><dir name="app"><dir name="design"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="sxml"><dir name="form"><file name="cc.phtml" hash=""/></dir></dir></dir></dir></dir></dir><dir name="frontend"><dir name="default"><dir name="default"><dir name="template"><dir name="sxml"><dir name="form"><file name="cc.phtml" hash=""/></dir></dir></dir></dir></dir></dir></dir><dir name="etc"><dir name="modules"><file name="SecurePay_Sxml.xml" hash=""/></dir></dir></dir></target></contents>
 
26
  <compatible/>
27
+ <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
28
  </package>