Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
payment_gateway_sagepay.inc
1 <?php
18 require_once dirname(__FILE__).'/../../payment_gateway/payment_gateway.inc';
19 require_once dirname(__FILE__).'/sagepay_processor.inc';
20 
21 define('MIN_LINE_IN_ADDRESS', 1);
22 define('MAX_LINE_IN_ADDRESS', 3);
23 
36 {
37 
38 
43  private $_redirect_info = NULL;
44 
49  private $_pass_through_vars = NULL;
50 
51 
58  function __construct($assetid=0)
59  {
60  parent::__construct($assetid);
61 
62  }//end constructor
63 
64 
75  function _createAdditional(&$link)
76  {
77  if (!parent::_createAdditional($link)) return FALSE;
78 
79  return ($this->_createBodycopy('display_format', translate('default_bodycopy_content')) && $this->_createBodycopy('card_holder_verification', translate('card_holder_verification_bodycopy_content')));
80 
81  }//end _createAdditional()
82 
83 
93  function _createBodycopy($link_value, $content)
94  {
95  $GLOBALS['SQ_SYSTEM']->am->includeAsset('bodycopy');
96  $bodycopy = new Bodycopy();
97  $copy_link = Array('asset' => &$this, 'link_type' => SQ_LINK_TYPE_2, 'is_dependant' => 1, 'is_exclusive' => 1, 'value' => $link_value);
98 
99  $bodycopy->setAttrValue('name', ucwords(str_replace('_',' ', $link_value)));
100  $args = Array('content' => $content);
101  if ($bodycopy->create($copy_link, $args)) {
102  $child_bodycopy = $GLOBALS['SQ_SYSTEM']->am->getLink($bodycopy->id, SQ_LINK_TYPE_2, 'bodycopy_div');
103  $GLOBALS['SQ_SYSTEM']->am->releaseLock($child_bodycopy['minorid'], 'attributes');
104  return TRUE;
105  }
106  return FALSE;
107 
108  }//end _createBodycopy()
109 
110 
118  function _getAllowedLinks()
119  {
120  $page_links = parent::_getAllowedLinks();
121  $page_links[SQ_LINK_TYPE_2]['bodycopy'] = Array('card' => 2, 'exclusive' => TRUE);
122  return $page_links;
123 
124  }//end _getAllowedLinks()
125 
126 
141  {
142  $keywords = parent::getAvailableKeywords();
143 
144  $keywords['card_name'] = 'Name on Card';
145  $keywords['card_number'] = 'Card Number';
146  $keywords['card_start_month'] = 'Card Start Month';
147  $keywords['card_start_month_select'] = 'Card Start Month Select';
148  $keywords['card_start_year'] = 'Card Start Year';
149  $keywords['card_start_year_select_XX'] = 'Card Start Year Select';
150  $keywords['card_expiry_month'] = 'Card Expiry Month';
151  $keywords['card_expiry_month_select'] = 'Card Expiry Month Select';
152  $keywords['card_expiry_year'] = 'Card Expiry Year';
153  $keywords['card_expiry_year_select_XX'] = 'Card Expiry Year Select';
154  $keywords['card_issue_number'] = 'Card Issue Number';
155  $keywords['card_cv2'] = 'Card CV2';
156  $keywords['card_type'] = 'Card Type';
157 
158  $keywords['billing_first_names'] = 'Billing First Names';
159  $keywords['billing_surname'] = 'Billing Surname';
160  $keywords['billing_address1_X'] = 'Billing Address1 (X: 1 - 3)';
161  $keywords['billing_address2_X'] = 'Billing Address2 (X: 1 - 3)';
162  $keywords['billing_city'] = 'Billing City';
163  $keywords['billing_postcode'] = 'Billing Postcode';
164  $keywords['billing_country'] = 'Billing Country';
165  $keywords['billing_state'] = 'Billing State';
166  $keywords['billing_phone'] = 'Billing Phone';
167 
168  $keywords['delivery_first_names'] = 'Delivery First Names';
169  $keywords['delivery_surname'] = 'Delivery Surname';
170  $keywords['delivery_address1_X'] = 'Delivery Address1 (X: 1 - 3)';
171  $keywords['delivery_address2_X'] = 'Delivery Address2 (X: 1 - 3)';
172  $keywords['delivery_city'] = 'Delivery City';
173  $keywords['delivery_postcode'] = 'Delivery Postcode';
174  $keywords['delivery_country'] = 'Delivery Country';
175  $keywords['delivery_state'] = 'Delivery State';
176  $keywords['delivery_phone'] = 'Delivery Phone';
177 
178  $keywords['transaction_amount'] = 'Transaction Amount';
179  $keywords['processing_error'] = 'Processing Error (empty if no error)';
180  $keywords['submit_button'] = 'Submit Button';
181  $keywords['cancel_button'] = 'Cancel Button';
182  $keywords['reset_button'] = 'Reset Button';
183  $keywords['card_holder_verification_form'] = 'Card Holder Verification Form';
184 
185  return $keywords;
186 
187  }//end getAvailableKeywords()
188 
189 
200  function onRequestKeywords(&$broadcaster, $vars=Array())
201  {
202  $keywords = $this->getAvailableKeywords();
203  $vars['keywords'] = array_merge($vars['keywords'], $keywords);
204 
205  }//end onRequestKeywords()
206 
207 
220  public function getKeywordReplacement($keyword)
221  {
222  $replacement = NULL;
223 
224  if (0 === strpos($keyword, 'card_start_year_select_')) {
225  $period = substr($keyword, 23);
226  if (is_numeric($period)) {
227  $replacement = $this->getCardStartYearSelectKeywordReplacement($period);
228  }
229 
230  } else if (0 === strpos($keyword, 'card_expiry_year_select_')) {
231  $period = substr($keyword, 24);
232  if (is_numeric($period)) {
233  $replacement = $this->getCardExpiryYearSelectKeywordReplacement($period);
234  }
235 
236  } else if (0 === strpos($keyword, 'billing_address1_')) {
237  $line = (int)substr($keyword, 17);
238  if (($line >= MIN_LINE_IN_ADDRESS) && ($line <= MAX_LINE_IN_ADDRESS)) {
239  $replacement = $this->getBillingAddress1KeywordReplacement($line);
240  }
241 
242  } else if (0 === strpos($keyword, 'billing_address2_')) {
243  $line = (int)substr($keyword, 17);
244  if (($line >= MIN_LINE_IN_ADDRESS) && ($line <= MAX_LINE_IN_ADDRESS)) {
245  $replacement = $this->getBillingAddress2KeywordReplacement($line);
246  }
247 
248  } else if (0 === strpos($keyword, 'delivery_address1_')) {
249  $line = (int)substr($keyword, 18);
250  if (($line >= MIN_LINE_IN_ADDRESS) && ($line <= MAX_LINE_IN_ADDRESS)) {
251  $replacement = $this->getDeliveryAddress1KeywordReplacement($line);
252  }
253 
254  } else if (0 === strpos($keyword, 'delivery_address2_')) {
255  $line = (int)substr($keyword, 18);
256  if (($line >= MIN_LINE_IN_ADDRESS) && ($line <= MAX_LINE_IN_ADDRESS)) {
257  $replacement = $this->getDeliveryAddress2KeywordReplacement($line);
258  }
259 
260  } else {
261  $replacement = parent::getKeywordReplacement($keyword);
262 
263  }
264 
265  return $replacement;
266 
267  }//end getKeywordReplacement()
268 
269 
276  function printBody()
277  {
278  //this page is redirected to by the child iframe with unknown reference error
279  if (array_get_index($_GET, 'unknown_referer', FALSE)) {
280  trigger_error('Unknown caller reference');
281  exit;
282  }
283 
284  //this page is redirected to by the child iframe with an error message
285  if (array_get_index($_GET, 'error_message', FALSE)) {
286  $this->_setError($_GET['error_message']);
287  }
288 
289  $success = FALSE;
290  $is_in_frame = FALSE; //indicates whether this page is in the iframe after it is redirected to by the ACS
291 
292  if (empty($_POST['PaRes']) || empty($_POST['MD'])) {
293  //THIS PAGE IS REDIRECTED TO BY DELIVERY METHOD OR FORM ECOMMERCE ASSET NOT BY THE ACS
294  $amount = array_get_index($_SESSION,'SQ_ECOM_AMOUNT', 0);
295  $card_info = array_get_index($_REQUEST, $this->getPrefix().'_card', FALSE);
296  $action = array_get_index($_REQUEST, $this->getPrefix().'_action', FALSE);
297 
298  if ($action == 'Cancel') {
299  $this->returnToCaller('CANCEL');
300 
301  } else if (empty($amount)) {
302  unset($_SESSION['SQ_ECOM_AMOUNT']);
303  //clear pass through variables
304  if (isset($_SESSION['SQ_ECOM_PASS_THROUGH_VARS'])) {
305  unset($_SESSION['SQ_ECOM_PASS_THROUGH_VARS']);
306  }
307 
308  $this->appendPendingOrderAuditLog(translate('ecom_payment_no_amount'));
309 
310  $this->returnToCaller('SUCCESS');
311 
312  } else if ($card_info) {
313  $this->appendPendingOrderAuditLog(translate('ecom_payment_attempted_gateway_contacted'));
314 
315  $success = $this->processPayment($card_info);
316  //if success = 2, redirect to the Access Control Server (ACS) for Card Holder Verification
317  if ($success === 2) {
318  //store the md5 of MD to authenticate the payment after the card holder verify himself
319  $_SESSION['SQ_ECOM_MD'] = md5($this->_redirect_info['MD']);
320  //print the Card Holder Verification bodycopy
321  $this->printBodycopy('card_holder_verification');
322  return;
323  }
324  }
325 
326  } else if (!empty($_SESSION['SQ_ECOM_MD']) && (md5($_POST['MD']) == $_SESSION['SQ_ECOM_MD'])) {
327  //THIS PAGE IS REDIRECTED TO BY THE ACCESS CONTROL SERVER (ACS) OF ISSUEING BANK AFTER CARD HOLDER VERIFICATION PROCESS
328  $is_in_frame = TRUE;
329  unset($_SESSION['SQ_ECOM_MD']);
330  $success = $this->authorizePayment($_POST['MD'], $_POST['PaRes']);
331  if ($success === FALSE) {
332  //transaction fails, redirect the parent document of the iframe and display error
333  $this->_redirectParent($this->getURL().'?error_message='.urlencode($this->_tmp['error_message'][0]));
334  }
335  }
336 
337  //if transaction is accepted, redirect the user to the success page
338  if ($success === 1) {
339  unset($_SESSION['SQ_ECOM_AMOUNT']);
340  //clear pass through variables
341  if (isset($_SESSION['SQ_ECOM_PASS_THROUGH_VARS'])) {
342  unset($_SESSION['SQ_ECOM_PASS_THROUGH_VARS']);
343  }
344 
345  $this->appendPendingOrderAuditLog(translate('ecom_payment_succeeded'));
346 
347  $this->returnToCaller('SUCCESS', $is_in_frame);
348  } else {
349  if ($card_info) {
350  $this->appendPendingOrderAuditLog(translate('ecom_payment_declined'));
351  }
352  }
353 
354  //print default bodycopy
355  $this->printBodycopy('display_format');
356 
357  }//end printBody()
358 
359 
366  function printBodycopy($link_value)
367  {
368  $bodycopy = $this->getBodycopy($link_value);
369  if (is_null($bodycopy)) return;
370 
371  $keywords = $bodycopy->getKeywords();
372  $replacements = Array();
373  foreach ($keywords as $word) {
374  $replacements[$word] = $this->getKeywordReplacement($word);
375  }
376  $bodycopy->setKeywordReplacements($replacements);
377 
378  //OUTPUT HERE
379  if ($link_value == 'display_format') {
380  //the default body copy with card input
381  $datapath = sq_web_path('data').'/asset_types/payment_gateway_sagepay/files';
382  $card = $this->getPrefix().'_card';
383 
384  if ($this->attr('run_mode') != 'Live') {
385  echo '<h2 class="gateway-test-mode" style="color: white; background-color: #C00; padding: 5px">'.strtoupper($this->attr('run_mode')).' MODE</h2>';
386  }
387 
388  ?>
389  <script src="<?php echo $datapath; ?>/loader.js"></script>
390  <script>
391  var Loader = new Loader('<?php echo $card; ?>','#FFFFFF','Processing Transaction...','<?php echo $datapath; ?>/loader.gif');
392  Loader.print();
393  </script>
394  <form method="post" action="<?php echo $this->getURL(); ?>" onsubmit="Loader.show();">
395  <?php
396  $bodycopy->printBody();
397  echo '</form>';
398  } else {
399  //the card holder verification bodycopy
400  $bodycopy->printBody();
401  }
402 
403  }//end printBodycopy()
404 
405 
412  function getBodycopy($link_value)
413  {
414  $link = $GLOBALS['SQ_SYSTEM']->am->getLink($this->id, SQ_LINK_TYPE_2, 'bodycopy', TRUE, $link_value);
415  if (empty($link)) return NULL;
416  $bodycopy = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['minorid'], $link['minor_type_code']);
417  return $bodycopy;
418 
419  }//end getBodycopy()
420 
421 
430  function processPayment($card_info)
431  {
432  if (!$card_info) return FALSE;
433 
434  $amount = $_SESSION['SQ_ECOM_AMOUNT'];
435 
436  $processor = new SagePay_Processor($this->attr('protocol'), $this->attr('vendor'), $this->attr('timeout'), $this->attr('run_mode'));
437 
438  //SET AMOUNT
439  if (empty($amount)) {
440  $this->_setError(translate('sagepay_amount_not_specified'));
441  } else {
442  $processor->setAmount($amount, $this->attr('currency'));
443  }
444 
445  //SET MERCHANT REFERENCE
446  //merchant reference number should be generated here instead of inside default_delivery_method.inc or form_ecommerce.inc
447  //because the customer can try to pay many times until his card is accepted. So each time a payment transaction
448  //is sent to SagePay, a new merchant reference number should be used because using the old reference number can
449  //cause the "duplicate reference" error (VendorTxCode has been used before).
450  $processor->setMerchantReference(md5(session_id().time()));
451  //get the merchant reference number back, it might be changed because SagePay requires that merchant reference number length must be less than 40 characters
452  //it is not changed with the above md5 function which generates 32 character string, but we use it as general way here
453  $_SESSION['SQ_ECOM_REF_NO'] = $processor->getMerchantReference();
454 
455  //store the merchant reference number to the pending order asset before processing
456  $this->setPendingOrderMerchantReference($_SESSION['SQ_ECOM_REF_NO']);
457 
458  //SET CARD NAME
459  if (empty($card_info['name'])) {
460  $this->_setError(translate('sagepay_card_name_not_specified'));
461  } else {
462  $processor->setCardName($card_info['name']);
463  }
464 
465  //SET CARD NUMBER
466  if (empty($card_info['number'])) {
467  $this->_setError(translate('sagepay_card_number_not_specified'));
468  } else {
469  $card_info['number'] = str_replace(Array(' ', "\t"), '', $card_info['number']);
470  $processor->setCardNumber($card_info['number']);
471  }
472 
473  //SET CARD EXPIRY DATE
474  if ($this->_isValidDate(array_get_index($card_info, 'expiry_month', ''), array_get_index($card_info, 'expiry_year', ''))) {
475  $processor->setCardExpiryDate($card_info['expiry_month'], $card_info['expiry_year']);
476  } else {
477  $this->_setError(translate('sagepay_expiry_date_invalid'));
478  }
479 
480  //SET CARD START DATE IF SPECIFIED BECAUSE START DATE IS ONLY REQUIRED FOR SOME CARD TYPES, E.G. SOLO
481  if (!empty($card_info['start_month']) || !empty($card_info['start_year'])) {
482  if ($this->_isValidDate(array_get_index($card_info, 'start_month', ''), array_get_index($card_info, 'start_year', ''))) {
483  $processor->setCardStartDate($card_info['start_month'], $card_info['start_year']);
484  } else {
485  $this->_setError(translate('sagepay_start_date_invalid'));
486  }
487  }
488 
489  //SET CARD ISSUE NUMBER, IF SPECIFIED
490  if (!empty($card_info['issue_number'])) {
491  if ($this->_isValidIssueNumber($card_info['issue_number'])) {
492  $processor->setCardIssueNumber($card_info['issue_number']);
493  } else {
494  $this->_setError(translate('sagepay_issue_number_invalid'));
495  }
496  }
497 
498  //SET CARD CV2, IF SPECIFIED
499  if (!empty($card_info['cv2'])) {
500  if ($this->_isValidCV2($card_info['cv2'], $card_info['type'])) {
501  $processor->setCardCV2($card_info['cv2']);
502  } else {
503  $this->_setError(translate('sagepay_card_cv2_invalid'));
504  }
505  }
506 
507  //SET CARD TYPE
508  if (empty($card_info['type'])) {
509  $this->_setError(translate('sagepay_card_type_not_specified'));
510  } else {
511  $processor->setCardType($card_info['type']);
512  }
513 
514  //SET BILLING FIRST NAMES
515  $billing_first_names = array_get_index($card_info, 'billing_first_names', '');
516  if ($billing_first_names != '') {
517  $processor->setBillingFirstnames($billing_first_names);
518  }
519 
520  //SET BILLING SURNAME
521  $billing_surname = array_get_index($card_info, 'billing_surname', '');
522  if ($billing_surname != '') {
523  $processor->setBillingSurname($billing_surname);
524  }
525 
526  $billing_addr = '';
527  //SET BILLING ADDRESS 1
528  $billing_address1 = trim(array_get_index($card_info, 'billing_address1_'.MIN_LINE_IN_ADDRESS, ''));
529  for ($i = MIN_LINE_IN_ADDRESS + 1; $i <= MAX_LINE_IN_ADDRESS; $i++) {
530  $line = array_get_index($card_info, "billing_address1_$i", '');
531  if (trim($line) != '') {
532  $billing_address1 .= ", $line";
533  }
534  }
535  if ($billing_address1 != '') {
536  $billing_addr .= $billing_address1."\n";
537  $processor->setBillingAddress1($billing_address1);
538  }
539 
540  //SET BILLING ADDRESS 2
541  $billing_address2 = trim(array_get_index($card_info, 'billing_address2_'.MIN_LINE_IN_ADDRESS, ''));
542  for ($i = MIN_LINE_IN_ADDRESS + 1; $i <= MAX_LINE_IN_ADDRESS; $i++) {
543  $line = array_get_index($card_info, "billing_address2_$i", '');
544  if (trim($line) != '') {
545  $billing_address2 .= ", $line";
546  }
547  }
548  if ($billing_address2 != '') {
549  $billing_addr .= $billing_address2."\n";
550  $processor->setBillingAddress2($billing_address2);
551  }
552 
553  //SET BILLING CITY
554  $billing_city = array_get_index($card_info, 'billing_city', '');
555  if ($billing_city != '') {
556  $billing_addr .= $billing_city."\n";
557  $processor->setBillingCity($billing_city);
558  }
559 
560  //SET BILLING STATE
561  $billing_state = array_get_index($card_info, 'billing_state', '');
562  if ($billing_state != '') {
563  $billing_addr .= $billing_state."\n";
564  $processor->setBillingState($billing_state);
565  }
566 
567  //SET BILLING POSTCODE
568  $billing_postcode = array_get_index($card_info, 'billing_postcode', '');
569  if ($billing_postcode != '') {
570  $billing_addr .= $billing_postcode."\n";
571  $processor->setBillingPostcode($billing_postcode);
572  }
573 
574  //GET THE LIST OF COUNTRY CODE IF NECESSARY
575  if ((array_get_index($card_info, 'billing_country', '') != '') || (array_get_index($card_info, 'delivery_country', '') != '')) {
576  global $standards_lists_countries;
577  require_once SQ_FUDGE_PATH.'/standards_lists/countries.inc';
578  }
579 
580  //SET BILLING COUNTRY
581  $billing_country_code = array_get_index($card_info, 'billing_country', '');
582  if ($billing_country_code != '') {
583  $billing_country = array_get_index($standards_lists_countries, $billing_country_code, strtoupper($billing_country_code));
584  $billing_addr .= $billing_country."\n";
585  $processor->setBillingCountry($billing_country_code);
586  }
587 
588  //SET BILLING PHONE
589  $billing_phone = array_get_index($card_info, 'billing_phone', '');
590  if ($billing_phone != '') {
591  $billing_addr .= 'Phone: '.$billing_phone."\n";
592  $processor->setBillingPhone($billing_phone);
593  }
594 
595  if ($this->attr('delivery_addr_is_billing_addr')) {
596  $delivery_str = 'billing_';
597  } else {
598  $delivery_str = 'delivery_';
599  }
600 
601  //SET DELIVERY FIRST NAMES
602  $delivery_first_names = array_get_index($card_info, $delivery_str.'first_names', '');
603  if ($delivery_first_names != '') {
604  $processor->setDeliveryFirstnames($delivery_first_names);
605  }
606 
607  //SET DELIVERY SURNAME
608  $delivery_surname = array_get_index($card_info, $delivery_str.'surname', '');
609  if ($delivery_surname != '') {
610  $processor->setDeliverySurname($delivery_surname);
611  }
612 
613  $delivery_addr = '';
614  //SET DELIVERY ADDRESS 1
615  $delivery_address1 = trim(array_get_index($card_info, $delivery_str.'address1_'.MIN_LINE_IN_ADDRESS, ''));
616  for ($i = MIN_LINE_IN_ADDRESS + 1; $i <= MAX_LINE_IN_ADDRESS; $i++) {
617  $line = array_get_index($card_info, "{$delivery_str}address1_$i", '');
618  if (trim($line) != '') {
619  $delivery_address1 .= ", $line";
620  }
621  }
622  if ($delivery_address1 != '') {
623  $delivery_addr .= $delivery_address1."\n";
624  $processor->setDeliveryAddress1($delivery_address1);
625  }
626 
627  //SET DELIVERY ADDRESS 2
628  $delivery_address2 = trim(array_get_index($card_info, $delivery_str.'address2_'.MIN_LINE_IN_ADDRESS, ''));
629  for ($i = MIN_LINE_IN_ADDRESS + 1; $i <= MAX_LINE_IN_ADDRESS; $i++) {
630  $line = array_get_index($card_info, "{$delivery_str}address2_$i", '');
631  if (trim($line) != '') {
632  $delivery_address2 .= ", $line";
633  }
634  }
635  if ($delivery_address2 != '') {
636  $delivery_addr .= $delivery_address2."\n";
637  $processor->setDeliveryAddress2($delivery_address2);
638  }
639 
640  //SET DELIVERY CITY
641  $delivery_city = array_get_index($card_info, $delivery_str.'city', '');
642  if ($delivery_city != '') {
643  $delivery_addr .= $delivery_city."\n";
644  $processor->setDeliveryCity($delivery_city);
645  }
646 
647  //SET DELIVERY STATE
648  $delivery_state = array_get_index($card_info, $delivery_str.'state', '');
649  if ($delivery_state != '') {
650  $delivery_addr .= $delivery_state."\n";
651  $processor->setDeliveryState($delivery_state);
652  }
653 
654  //SET DELIVERY POSTCODE
655  $delivery_postcode = array_get_index($card_info, $delivery_str.'postcode', '');
656  if ($delivery_postcode != '') {
657  $delivery_addr .= $delivery_postcode."\n";
658  $processor->setDeliveryPostcode($delivery_postcode);
659  }
660 
661  //SET DELIVERY COUNTRY
662  $delivery_country_code = array_get_index($card_info, $delivery_str.'country', '');
663  if ($delivery_country_code != '') {
664  $delivery_country = array_get_index($standards_lists_countries, $delivery_country_code, strtoupper($delivery_country_code));
665  $delivery_addr .= $delivery_country."\n";
666  $processor->setDeliveryCountry($delivery_country_code);
667  }
668 
669  //SET DELIVERY PHONE
670  $delivery_phone = array_get_index($card_info, $delivery_str.'phone', '');
671  if ($delivery_phone != '') {
672  $delivery_addr .= 'Phone: '.$delivery_phone."\n";
673  $processor->setDeliveryPhone($delivery_phone);
674  }
675 
676 
677  //SET DESCRIPTION
678  $processor->setDescription($this->attr('description'));
679 
680  //SET TRANSACTION TYPE AS "PAYMENT"
681  $processor->setTransactionTypePayment();
682 
683  //SET 3-D SECURE
684  if ($this->attr('threeds_enabled')) {
685  $processor->setThreeDSecure();
686  }
687 
688  //SET AVS/CV2
689  if ($this->attr('avscv2_enabled')) {
690  $processor->setAVSCV2();
691 
692  if (empty($card_info['cv2'])) {
693  $this->_setError(translate('sagepay_card_cv2_not_specified'));
694  }
695 
696  if ($billing_first_names == '') {
697  $this->_setError(translate('sagepay_billing_first_names_not_specified'));
698  }
699  if ($billing_surname == '') {
700  $this->_setError(translate('sagepay_billing_surname_not_specified'));
701  }
702  if ($billing_address1 == '') {
703  $this->_setError(translate('sagepay_billing_address1_not_specified'));
704  }
705  if ($billing_city == '') {
706  $this->_setError(translate('sagepay_billing_city_not_specified'));
707  }
708  if ($billing_postcode == '') {
709  $this->_setError(translate('sagepay_billing_postcode_not_specified'));
710  }
711  if ($billing_country_code == '') {
712  $this->_setError(translate('sagepay_billing_country_not_specified'));
713  }
714  if (($billing_country_code == 'us') && ($billing_state == '')) {
715  $this->_setError(translate('sagepay_billing_state_not_specified'));
716  }
717 
718  if (!$this->attr('delivery_addr_is_billing_addr')) {
719  if ($delivery_first_names == '') {
720  $this->_setError(translate('sagepay_delivery_first_names_not_specified'));
721  }
722  if ($delivery_surname == '') {
723  $this->_setError(translate('sagepay_delivery_surname_not_specified'));
724  }
725  if ($delivery_address1 == '') {
726  $this->_setError(translate('sagepay_delivery_address1_not_specified'));
727  }
728  if ($delivery_city == '') {
729  $this->_setError(translate('sagepay_delivery_city_not_specified'));
730  }
731  if ($delivery_postcode == '') {
732  $this->_setError(translate('sagepay_delivery_postcode_not_specified'));
733  }
734  if ($delivery_country_code == '') {
735  $this->_setError(translate('sagepay_delivery_country_not_specified'));
736  }
737  if (($delivery_country_code == 'us') && ($delivery_state == '')) {
738  $this->_setError(translate('sagepay_delivery_state_not_specified'));
739  }
740  }
741  }
742 
743  //SET GIFT AID PAYMENT
744  $var_name = $this->attr('giftaid_var_name');
745  if (!empty($var_name)) {
746  $gift_aid = $this->_getPassThroughVariable($var_name, FALSE);
747  if ($gift_aid !== FALSE){
748  $gift_aid = strtolower($gift_aid);
749  if (($gift_aid == '1') || ($gift_aid == 'yes') || ($gift_aid == 'true')) {
750  $processor->setGiftAidPayment();
751  }
752  }
753  }
754 
755  //CHECK IF THERE IS ERROR BEFORE SENDING DATA TO SagePay SERVER, RETURN FALSE
756  if ($this->isError()) {
757  return FALSE;
758  }
759 
760  $success = $processor->process();
761 
762  //GET RESPONSE
763  $response = $processor->getResponse();
764 
765  //if success (1 or 2), save the last 4 digits of card number to output later
766  if ($success) {
767  //store the last 4 digits of card number to display it later in Form Ecommerce or Delivery Method through the Session variable SQ_ECOM_RESPONSE
768  $_SESSION['SQ_ECOM_FORMATTED_CARD_NUMBER'] = $this->_getFormattedCardNumber($card_info['number']);
769  //store the billing name, billing address, deliver name and deliver address to store in the Order asset of Form Ecommerce
770  $_SESSION['SQ_ECOM_ORDER_BILLING_NAME'] = "$billing_first_names $billing_surname";
771  $_SESSION['SQ_ECOM_ORDER_BILLING_ADDR'] = $billing_addr;
772  $_SESSION['SQ_ECOM_ORDER_DELIVERY_NAME'] = "$delivery_first_names $delivery_surname";
773  $_SESSION['SQ_ECOM_ORDER_DELIVERY_ADDR'] = $delivery_addr;
774  //build the addresses XML to store in the Ecommerce Order XML
775  $billing_state_str = '';
776  if ($billing_state != '') {
777  $billing_state_str = <<<HEREDOC
778 
779  <state><![CDATA[{$this->_getCDATAAllowedString($billing_state)}]]></state>
780 HEREDOC;
781  }
782 
783  $delivery_state_str = '';
784  if ($delivery_state != '') {
785  $delivery_state_str = <<<HEREDOC
786 
787  <state><![CDATA[{$this->_getCDATAAllowedString($delivery_state)}]]></state>
788 HEREDOC;
789  }
790 
791  $_SESSION['SQ_ECOM_ORDER_PAYMENT_GATEWAY_XML'] = <<<HEREDOC
792 
793  <payment_gateway>
794  <billing_address>
795  <first_names><![CDATA[{$this->_getCDATAAllowedString($billing_first_names)}]]></first_names>
796  <surname><![CDATA[{$this->_getCDATAAllowedString($billing_surname)}]]></surname>
797  <address1><![CDATA[{$this->_getCDATAAllowedString($billing_address1)}]]></address1>
798  <address2><![CDATA[{$this->_getCDATAAllowedString($billing_address2)}]]></address2>
799  <city><![CDATA[{$this->_getCDATAAllowedString($billing_city)}]]></city>$billing_state_str
800  <postcode><![CDATA[{$this->_getCDATAAllowedString($billing_postcode)}]]></postcode>
801  <country><![CDATA[{$this->_getCDATAAllowedString($billing_country)}]]></country>
802  <country_code><![CDATA[{$this->_getCDATAAllowedString($billing_country_code)}]]></country_code>
803  <phone><![CDATA[{$this->_getCDATAAllowedString($billing_phone)}]]></phone>
804  </billing_address>
805  <delivery_address>
806  <first_names><![CDATA[{$this->_getCDATAAllowedString($delivery_first_names)}]]></first_names>
807  <surname><![CDATA[{$this->_getCDATAAllowedString($delivery_surname)}]]></surname>
808  <address1><![CDATA[{$this->_getCDATAAllowedString($delivery_address1)}]]></address1>
809  <address2><![CDATA[{$this->_getCDATAAllowedString($delivery_address2)}]]></address2>
810  <city><![CDATA[{$this->_getCDATAAllowedString($delivery_city)}]]></city>$delivery_state_str
811  <postcode><![CDATA[{$this->_getCDATAAllowedString($delivery_postcode)}]]></postcode>
812  <country><![CDATA[{$this->_getCDATAAllowedString($delivery_country)}]]></country>
813  <country_code><![CDATA[{$this->_getCDATAAllowedString($delivery_country_code)}]]></country_code>
814  <phone><![CDATA[{$this->_getCDATAAllowedString($delivery_phone)}]]></phone>
815  </delivery_address>
816  </payment_gateway>
817 HEREDOC;
818 
819  }
820 
821  //if $success = 2, redirect user for card holder verification
822  if ($success === 2) {
823  $this->_redirect_info = $response;
824  } else {
825  //success = 1 or FALSE
826  $this->_setTransactionResult($success, $response);
827  }
828 
829  return $success;
830 
831  }//end processPayment()
832 
833 
843  function authorizePayment($md, $pares)
844  {
845  $processor = new SagePay_Processor($this->attr('protocol'), $this->attr('vendor'), $this->attr('timeout'), $this->attr('run_mode'));
846 
847  $success = $processor->authorize($_SESSION['SQ_ECOM_REF_NO'], $md, $pares);
848 
849  //get response
850  $response = $processor->getResponse();
851 
852  $this->_setTransactionResult($success, $response);
853 
854  return $success;
855 
856  }//end authorizePayment()
857 
858 
868  private function _setTransactionResult($success, $response)
869  {
870  if ($success === FALSE) {
871  $this->_setError($response['STATUS']);
872  } else { //success = 1
873  if ($this->attr('run_mode') != 'Live') {
874  $response['STATUS'] = '!!!ATTENTION!!! '.strtoupper($this->attr('run_mode')).' MODE (transaction not performed) -- '.$response['STATUS'];
875  }
876 
877  $card_no = '';
878  if (isset($_SESSION['SQ_ECOM_FORMATTED_CARD_NUMBER'])) {
879  $card_no = $_SESSION['SQ_ECOM_FORMATTED_CARD_NUMBER'];
880  unset($_SESSION['SQ_ECOM_FORMATTED_CARD_NUMBER']);
881  }
882 
883  $response['CARDNO'] = $card_no;
884  $response['AMOUNT'] = $_SESSION['SQ_ECOM_AMOUNT'];
885 
886  $billing_name = '';
887  if (isset($_SESSION['SQ_ECOM_ORDER_BILLING_NAME'])) {
888  $billing_name = $_SESSION['SQ_ECOM_ORDER_BILLING_NAME'];
889  unset($_SESSION['SQ_ECOM_ORDER_BILLING_NAME']);
890  }
891  $response['BILLING_NAME'] = $billing_name;
892 
893  $billing_addr = '';
894  if (isset($_SESSION['SQ_ECOM_ORDER_BILLING_ADDR'])) {
895  $billing_addr = $_SESSION['SQ_ECOM_ORDER_BILLING_ADDR'];
896  unset($_SESSION['SQ_ECOM_ORDER_BILLING_ADDR']);
897  }
898  $response['BILLING_ADDR'] = $billing_addr;
899 
900  $delivery_name = '';
901  if (isset($_SESSION['SQ_ECOM_ORDER_DELIVERY_NAME'])) {
902  $delivery_name = $_SESSION['SQ_ECOM_ORDER_DELIVERY_NAME'];
903  unset($_SESSION['SQ_ECOM_ORDER_DELIVERY_NAME']);
904  }
905  $response['DELIVERY_NAME'] = $delivery_name;
906 
907  $delivery_addr = '';
908  if (isset($_SESSION['SQ_ECOM_ORDER_DELIVERY_ADDR'])) {
909  $delivery_addr = $_SESSION['SQ_ECOM_ORDER_DELIVERY_ADDR'];
910  unset($_SESSION['SQ_ECOM_ORDER_DELIVERY_ADDR']);
911  }
912  $response['DELIVERY_ADDR'] = $delivery_addr;
913 
914  $addresses_xml = '';
915  if (isset($_SESSION['SQ_ECOM_ORDER_PAYMENT_GATEWAY_XML'])) {
916  $addresses_xml = $_SESSION['SQ_ECOM_ORDER_PAYMENT_GATEWAY_XML'];
917  unset($_SESSION['SQ_ECOM_ORDER_PAYMENT_GATEWAY_XML']);
918  }
919  $response['PAYMENT_GATEWAY_XML'] = $addresses_xml;
920 
921  $_SESSION['SQ_ECOM_RESPONSE'] = $response;
922  }
923 
924  }//end _setTransactionResult()
925 
926 
935  private function _getFormattedCardNumber($card_number)
936  {
937  $card_no = $card_number;
938  $card_len = strlen($card_no);
939  if ($card_len == 16) {
940  $card_no = '****-****-****-'.substr($card_no, -4);
941  } else {
942  $card_no = str_pad(substr($card_no, -4), $card_len, '*', STR_PAD_LEFT);
943  }
944 
945  return $card_no;
946 
947  }//end _getFormattedCardNumber()
948 
949 
958  function returnToCaller($state='SUCCESS', $is_in_frame = FALSE)
959  {
960  $back_url = NULL;
961 
962  if ($state == 'SUCCESS') {
963  $back_url = array_get_index($_SESSION, 'SQ_ECOM_SUCCESS_URL');
964  } else if ($state == 'CANCEL') {
965  $back_url = array_get_index($_SESSION, 'SQ_ECOM_CANCEL_URL');
966  }
967 
968  unset($_SESSION['SQ_ECOM_SUCCESS_URL']);
969  unset($_SESSION['SQ_ECOM_CANCEL_URL']);
970 
971  if (is_null($back_url)) {
972  if ($is_in_frame) {
973  $this->_redirectParent($this->getURL().'?unknown_referer=1');
974  } else {
975  trigger_error('Unknown caller reference');
976  exit;
977  }
978  } else {
979  if ($is_in_frame) {
980  $this->_redirectParent($back_url);
981  }else {
982  header('Location: '.$back_url);
983  exit;
984  }
985  }
986 
987  }//end returnToCaller()
988 
989 
998  private function _redirectParent($url)
999  {
1000  $string = <<<HEREDOC
1001 <script type="text/javascript">
1002  if (parent != self) {
1003  parent.location = "{$url}";
1004  }
1005 </script>
1006 HEREDOC;
1007 
1008  echo $string;
1009  exit;
1010 
1011  }//end _redirectParent()
1012 
1013 
1021  {
1022  $card = $this->getPrefix().'_card';
1023  $string = '<input name="'.$card.'[name]" autocomplete="off" />';
1024  return $string;
1025 
1026  }//end getCardNameKeywordReplacement()
1027 
1028 
1036  {
1037  $prefix = $this->getPrefix();
1038  $card = $prefix.'_card';
1039 
1040  // set variables for simulator and test modes
1041  if ($this->attr('run_mode') != 'Live') {
1042  $test_card_numbers = SagePay_Processor::getTestCardNumbers();
1043  $card_number = '<select name="'.$card.'[number]">';
1044  foreach ($test_card_numbers as $number => $label) {
1045  $card_number .= '<option value="'.$number.'" >'.$label.'</option>';
1046  }
1047  $card_number .= '</select>';
1048  } else {
1049  $card_number = '<input name="'.$card.'[number]" autocomplete="off" />';
1050  }
1051 
1052  return $card_number;
1053 
1054  }//end getCardNumberKeywordReplacement()
1055 
1056 
1064  {
1065  $card = $this->getPrefix().'_card';
1066 
1067  $string = '<input name="'.$card.'[start_month]" size="2" autocomplete="off" />';
1068 
1069  return $string;
1070 
1071  }//end getCardStartMonthKeywordReplacement()
1072 
1073 
1081  {
1082  $card = $this->getPrefix().'_card';
1083 
1084  $string = '<select name="'.$card.'[start_month]">';
1085  $string .= '<option value="" >--</option>';
1086  for ($i = 1; $i <= 12; $i++) {
1087  $month = sprintf('%02s', $i);
1088  $string .= '<option value="'.$month.'" >'.$month.'</option>';
1089  }
1090  $string .= '</select>';
1091 
1092  return $string;
1093 
1094  }//end getCardStartMonthSelectKeywordReplacement()
1095 
1096 
1104  {
1105  $card = $this->getPrefix().'_card';
1106 
1107  $string = '<input name="'.$card.'[start_year]" size="2" autocomplete="off" />';
1108 
1109  return $string;
1110 
1111  }//end getCardStartYearKeywordReplacement()
1112 
1113 
1121  {
1122  $card = $this->getPrefix().'_card';
1123 
1124  $string = '<select name="'.$card.'[start_year]">';
1125  $string .= '<option value="" >----</option>';
1126  $year = date('Y') - $period;
1127  for ($i = 0; $i <= $period; $i++) {
1128  $string .= '<option value="'.substr($year, -2).'" >'.$year.'</option>';
1129  $year++;
1130  }
1131  $string .= '</select>';
1132 
1133  return $string;
1134 
1135  }//end getCardStartYearSelectKeywordReplacement()
1136 
1137 
1145  {
1146  $card = $this->getPrefix().'_card';
1147 
1148  $string = '<input name="'.$card.'[expiry_month]" size="2" autocomplete="off" />';
1149 
1150  return $string;
1151 
1152  }//end getCardExpiryMonthKeywordReplacement()
1153 
1154 
1162  {
1163  $card = $this->getPrefix().'_card';
1164 
1165  $string = '<select name="'.$card.'[expiry_month]">';
1166  $string .= '<option value="" >--</option>';
1167  for ($i = 1; $i <= 12; $i++) {
1168  $month = sprintf('%02s', $i);
1169  $string .= '<option value="'.$month.'" >'.$month.'</option>';
1170  }
1171  $string .= '</select>';
1172 
1173  return $string;
1174 
1175  }//end getCardExpiryMonthSelectKeywordReplacement()
1176 
1177 
1185  {
1186  $card = $this->getPrefix().'_card';
1187 
1188  $string = '<input name="'.$card.'[expiry_year]" size="2" autocomplete="off" />';
1189 
1190  return $string;
1191 
1192  }//end getCardExpiryYearKeywordReplacement()
1193 
1194 
1202  {
1203  $card = $this->getPrefix().'_card';
1204 
1205  $string = '<select name="'.$card.'[expiry_year]">';
1206  $string .= '<option value="" >----</option>';
1207  $year = date('Y');
1208  for ($i = 0; $i <= $period; $i++) {
1209  $string .= '<option value="'.substr($year, -2).'" >'.$year.'</option>';
1210  $year++;
1211  }
1212  $string .= '</select>';
1213 
1214  return $string;
1215 
1216  }//end getCardExpiryYearSelectKeywordReplacement()
1217 
1218 
1226  {
1227  $card = $this->getPrefix().'_card';
1228 
1229  $string = '<input name="'.$card.'[issue_number]" size="4" autocomplete="off" />';
1230 
1231  return $string;
1232 
1233  }//end getCardIssueNumberKeywordReplacement()
1234 
1235 
1243  {
1244  $card = $this->getPrefix().'_card';
1245 
1246  $string = '<input name="'.$card.'[cv2]" size="4" autocomplete="off" />';
1247 
1248  return $string;
1249 
1250  }//end getCardCv2KeywordReplacement()
1251 
1252 
1260  {
1261  $card = $this->getPrefix().'_card';
1262 
1263  $available_card_types = SagePay_Processor::getCardTypes();
1264 
1265  $selected_card_types = explode('|', $this->attr('supported_card_types'));
1266 
1267  ob_start();
1268  echo '<select name="'.$card.'[type]">';
1269  foreach ($selected_card_types as $type) {
1270  echo '<option value="'.$type.'">'.$available_card_types[$type].'</option>';
1271  }
1272 
1273  echo '</select>';
1274 
1275  return ob_get_clean();
1276 
1277  }//end getCardTypeKeywordReplacement()
1278 
1279 
1287  {
1288  ob_start();
1289  $card = $this->getPrefix().'_card';
1290  text_box($card.'[billing_first_names]', $this->_getDefaultInputFromPassThroughAttribute('firstname_var_name'));
1291 
1292  return ob_get_clean();
1293 
1294  }//end getBillingFirstNamesKeywordReplacement()
1295 
1296 
1304  {
1305  ob_start();
1306  $card = $this->getPrefix().'_card';
1307  text_box($card.'[billing_surname]', $this->_getDefaultInputFromPassThroughAttribute('surname_var_name'));
1308 
1309  return ob_get_clean();
1310 
1311  }//end getBillingSurnameKeywordReplacement()
1312 
1313 
1322  function getBillingAddress1KeywordReplacement($line = MIN_LINE_IN_ADDRESS)
1323  {
1324  ob_start();
1325  $card = $this->getPrefix().'_card';
1326  text_box($card."[billing_address1_$line]", $this->_getDefaultInputFromPassThroughAttribute('addr1_var_name', $line));
1327 
1328  return ob_get_clean();
1329 
1330  }//end getBillingAddress1KeywordReplacement()
1331 
1332 
1341  function getBillingAddress2KeywordReplacement($line = MIN_LINE_IN_ADDRESS)
1342  {
1343  ob_start();
1344  $card = $this->getPrefix().'_card';
1345  text_box($card."[billing_address2_$line]", $this->_getDefaultInputFromPassThroughAttribute('addr2_var_name', $line));
1346 
1347  return ob_get_clean();
1348 
1349  }//end getBillingAddress2KeywordReplacement()
1350 
1351 
1359  {
1360  ob_start();
1361  $card = $this->getPrefix().'_card';
1362  text_box($card.'[billing_city]', $this->_getDefaultInputFromPassThroughAttribute('city_var_name'));
1363 
1364  return ob_get_clean();
1365 
1366  }//end getBillingCityKeywordReplacement()
1367 
1368 
1376  {
1377  ob_start();
1378  $card = $this->getPrefix().'_card';
1379  text_box($card.'[billing_postcode]', $this->_getDefaultInputFromPassThroughAttribute('postcode_var_name'));
1380 
1381  return ob_get_clean();
1382 
1383  }//end getBillingPostcodeKeywordReplacement()
1384 
1385 
1393  {
1394  global $standards_lists_countries;
1395  require_once SQ_FUDGE_PATH.'/standards_lists/countries.inc';
1396 
1397  ob_start();
1398  $card = $this->getPrefix().'_card';
1399  combo_box($card.'[billing_country]', $standards_lists_countries, FALSE, $this->_getDefaultInputFromPassThroughAttribute('country_var_name'));
1400 
1401  return ob_get_clean();
1402 
1403  }//end getBillingCountryKeywordReplacement()
1404 
1405 
1413  {
1414  $card = $this->getPrefix().'_card';
1415  $string = '<input name="'.$card.'[billing_state]" />';
1416  return $string;
1417 
1418  }//end getBillingStateKeywordReplacement()
1419 
1420 
1428  {
1429  $card = $this->getPrefix().'_card';
1430  $string = '<input name="'.$card.'[billing_phone]" autocomplete="off" />';
1431  return $string;
1432 
1433  }//end getBillingPhoneKeywordReplacement()
1434 
1435 
1443  {
1444  ob_start();
1445  $card = $this->getPrefix().'_card';
1446  $this->_delivery_textbox($card.'[delivery_first_names]', $this->_getDefaultInputFromPassThroughAttribute('firstname_var_name'));
1447 
1448  return ob_get_clean();
1449 
1450  }//end getDeliveryFirstNamesKeywordReplacement()
1451 
1452 
1460  {
1461  ob_start();
1462  $card = $this->getPrefix().'_card';
1463  $this->_delivery_textbox($card.'[delivery_surname]', $this->_getDefaultInputFromPassThroughAttribute('surname_var_name'));
1464 
1465  return ob_get_clean();
1466 
1467  }//end getDeliverySurnameKeywordReplacement()
1468 
1469 
1478  function getDeliveryAddress1KeywordReplacement($line = MIN_LINE_IN_ADDRESS)
1479  {
1480  ob_start();
1481  $card = $this->getPrefix().'_card';
1482  $this->_delivery_textbox($card."[delivery_address1_$line]", $this->_getDefaultInputFromPassThroughAttribute('addr1_var_name', $line));
1483 
1484  return ob_get_clean();
1485 
1486  }//end getDeliveryAddress1KeywordReplacement()
1487 
1488 
1497  function getDeliveryAddress2KeywordReplacement($line = MIN_LINE_IN_ADDRESS)
1498  {
1499  ob_start();
1500  $card = $this->getPrefix().'_card';
1501  $this->_delivery_textbox($card."[delivery_address2_$line]", $this->_getDefaultInputFromPassThroughAttribute('addr2_var_name', $line));
1502 
1503  return ob_get_clean();
1504 
1505  }//end getDeliveryAddress2KeywordReplacement()
1506 
1507 
1515  {
1516  ob_start();
1517  $card = $this->getPrefix().'_card';
1518  $this->_delivery_textbox($card.'[delivery_city]', $this->_getDefaultInputFromPassThroughAttribute('city_var_name'));
1519 
1520  return ob_get_clean();
1521 
1522  }//end getDeliveryCityKeywordReplacement()
1523 
1524 
1532  {
1533  ob_start();
1534  $card = $this->getPrefix().'_card';
1535  $this->_delivery_textbox($card.'[delivery_postcode]', $this->_getDefaultInputFromPassThroughAttribute('postcode_var_name'));
1536 
1537  return ob_get_clean();
1538 
1539  }//end getDeliveryPostcodeKeywordReplacement()
1540 
1541 
1549  {
1550  ob_start();
1551  $card = $this->getPrefix().'_card';
1552  $name = $card.'[delivery_country]';
1553  $value = $this->_getDefaultInputFromPassThroughAttribute('country_var_name');
1554  if ($this->attr('hide_delivery_addr')) {
1555  hidden_field($name, $value);
1556  } else {
1557  global $standards_lists_countries;
1558  require_once SQ_FUDGE_PATH.'/standards_lists/countries.inc';
1559 
1560  combo_box($name, $standards_lists_countries, FALSE, $value);
1561  }
1562 
1563  return ob_get_clean();
1564 
1565  }//end getDeliveryCountryKeywordReplacement()
1566 
1567 
1575  {
1576  $card = $this->getPrefix().'_card';
1577  $string = '<input name="'.$card.'[delivery_state]" />';
1578  return $string;
1579 
1580  }//end getDeliveryStateKeywordReplacement()
1581 
1582 
1590  {
1591  $card = $this->getPrefix().'_card';
1592  $string = '<input name="'.$card.'[delivery_phone]" />';
1593  return $string;
1594 
1595  }//end getDeliveryPhoneKeywordReplacement()
1596 
1597 
1605  {
1606  $amount = array_get_index($_SESSION,'SQ_ECOM_AMOUNT', 0);
1607 
1608  return $amount;
1609 
1610  }//end getTransactionAmountKeywordReplacement()
1611 
1612 
1620  {
1621  if ($this->isError()) {
1622  return '<span class="payment-gateway-transaction-error">'.$this->getErrorMessage().'</span>';
1623  }
1624 
1625  return '';
1626 
1627  }//end getProcessingErrorKeywordReplacement()
1628 
1629 
1637  {
1638  $button_text = $this->attr('submit_text');
1639  if (empty($button_text)) $button_text = 'Submit';
1640 
1641  return '<input type="submit" value="'.$button_text.'" />';
1642 
1643  }//end getSubmitButtonKeywordReplacement()
1644 
1645 
1653  {
1654  $button_text = $this->attr('reset_text');
1655  if (empty($button_text)) $button_text = 'Reset';
1656 
1657  return '<input type="reset" value="'.$button_text.'" />';
1658 
1659  }//end getResetButtonKeywordReplacement()
1660 
1661 
1669  {
1670  $button_text = $this->attr('cancel_text');
1671  if (empty($button_text)) $button_text = 'Cancel';
1672 
1673  return '<input type="submit" name="'.$this->getPrefix().'_action" value="'.$button_text.'" />';
1674 
1675  }//end getCancelButtonKeywordReplacement()
1676 
1677 
1685  {
1686  $string = <<<HEREDOC
1687 <form name="PARequestForm" action="{$this->_redirect_info['ACS_URL']}" method="POST">
1688  <input type="hidden" name="PaReq" value="{$this->_redirect_info['PAREQ_MESSAGE']}">
1689  <input type="hidden" name="TermUrl" value="{$this->getURL()}">
1690  <input type="hidden" name="MD" value="{$this->_redirect_info['MD']}">
1691 </form>
1692 <iframe name="ACSframe" width="390" height="400" frameborder="0">
1693  <b>Your browser does not support iframes</b>
1694 </iframe>
1695 <script type="text/javascript">
1696  window.onload = function()
1697  {
1698  document.PARequestForm.target = "ACSframe";
1699  document.PARequestForm.submit();
1700  }
1701 </script>
1702 HEREDOC;
1703 
1704  return $string;
1705 
1706  }//end getCardHolderVerificationFormKeywordReplacement()
1707 
1708 
1716  private function _setError($err_message)
1717  {
1718  $this->_tmp['is_error'] = TRUE;
1719  //we need to split the error message here because SagePay error has the following format:
1720  //3153 : The Card AddressLine1 is required., 3156 : The Card City field is required., 5022 : The Postcode value is required.
1721  $errs = explode(',', $err_message);
1722  foreach ($errs as $err_str) {
1723  $err_details = explode(':', $err_str, 2);
1724  if (isset($err_details[1]) && !empty($err_details[1])) {
1725  $this->_tmp['error_message'][] = trim($err_details[1]);
1726  } else {
1727  $this->_tmp['error_message'][] = $err_details[0];
1728  }
1729  }
1730 
1731  }//end _setError()
1732 
1733 
1742  private function _isValidDate($month, $year)
1743  {
1744  $valid = FALSE;
1745 
1746  $two_digits_pattern = '/^\d{2}$/';
1747  //month and year must have 2 digit pattern mm/yy
1748  if (preg_match($two_digits_pattern, $month) && preg_match($two_digits_pattern, $year)) {
1749  //month must be in 1 and 12
1750  if ((0 < $month) && ($month < 13)) {
1751  $valid = TRUE;
1752  }
1753  }
1754 
1755  return $valid;
1756 
1757  }//end _isValidDate()
1758 
1759 
1768  private function _isValidIssueNumber($issue_no)
1769  {
1770  $valid = FALSE;
1771 
1772  $pattern = '/^\d{1,2}$/';
1773  //issue number must be one or two digits long
1774  if (preg_match($pattern, $issue_no)) {
1775  $valid = TRUE;
1776  }
1777 
1778  return $valid;
1779 
1780  }//end _isValidIssueNumber()
1781 
1782 
1792  private function _isValidCV2($cv2, $card_type)
1793  {
1794  $valid = FALSE;
1795 
1796  if ($card_type == 'AMEX') {
1797  $digit_no = 4;
1798  } else {
1799  $digit_no = 3;
1800  }
1801  $pattern = '/^\d{'.$digit_no.'}$/';
1802  //cv2 must be three or four (AMEX card only) digits long
1803  if (preg_match($pattern, $cv2)) {
1804  $valid = TRUE;
1805  }
1806 
1807  return $valid;
1808 
1809  }//end _isValidCV2()
1810 
1811 
1820  private function _getPassThroughVariable($var_name, $default)
1821  {
1822  if (is_null($this->_pass_through_vars)) {
1823  $this->_pass_through_vars = array_get_index($_SESSION, 'SQ_ECOM_PASS_THROUGH_VARS', Array());
1824  }
1825 
1826  return array_get_index($this->_pass_through_vars, $var_name, $default);
1827 
1828  }//end _getPassThroughVariable()
1829 
1830 
1840  private function _getDefaultInputFromPassThroughAttribute($attr_name, $line = '')
1841  {
1842  $result = '';
1843  $var_name = $this->attr($attr_name).$line;
1844  if (!empty($var_name)) {
1845  $result = $this->_getPassThroughVariable($var_name, '');
1846  }
1847 
1848  return $result;
1849 
1850  }//end _getDefaultInputFromPassThroughAttribute()
1851 
1852 
1860  private function _getCDATAAllowedString($text)
1861  {
1862  //CDATA section can not contain a nested CDATA and the closed string ]]>
1863  $search = Array('<![CDATA[', ']]>');
1864  $replace = Array('&lt;![CDATA[', ']]&gt;');
1865 
1866  return str_replace($search, $replace, $text);
1867 
1868  }//end _getCDATAAllowedString()
1869 
1870 
1880  function _delivery_textbox($name, $value)
1881  {
1882  if ($this->attr('hide_delivery_addr')) {
1883  hidden_field($name, $value);
1884  } else {
1885  text_box($name, $value);
1886  }
1887 
1888  }//end getDeliveryFirstNamesKeywordReplacement()
1889 
1890 
1897  public function isError()
1898  {
1899  return array_get_index($this->_tmp, 'is_error', FALSE);
1900 
1901  }//end isError()
1902 
1903 
1910  public function getErrorMessage()
1911  {
1912  $err_message = '';
1913  $errors = array_get_index($this->_tmp, 'error_message', Array());
1914  foreach ($errors as $error) {
1915  $err_message .= "<li>$error </li>";
1916  }
1917 
1918  return '<ul>'.$err_message.'</ul>';
1919 
1920  }//end getErrorMessage()
1921 
1922 
1923 }//end class
1924 
1925 ?>