Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
sagepay_processor.inc
1 <?php
18 define('SAGEPAY_LOG_FILE_PREFIX', 'sagepay_transactions_account_');
19 
20 
32 {
33 
34 
40  private static $_URLS = Array(
41  'Live' => Array(
42  'payment_registration' => 'https://live.sagepay.com/gateway/service/vspdirect-register.vsp',
43  'threeds_callback' => 'https://live.sagepay.com/gateway/service/direct3dcallback.vsp',
44  ),
45  'Test' => Array(
46  'payment_registration' => 'https://test.sagepay.com/gateway/service/vspdirect-register.vsp',
47  'threeds_callback' => 'https://test.sagepay.com/gateway/service/direct3dcallback.vsp',
48  ),
49  'Simulator' => Array(
50  'payment_registration' => 'https://test.sagepay.com/simulator/VSPDirectGateway.asp',
51  'threeds_callback' => 'https://test.sagepay.com/simulator/VSPDirectCallback.asp',
52  ),
53  );
54 
59  private $_post_string;
60 
66  private $_post_urls;
67 
72  private $_merchant_ref;
73 
78  private $_card_number;
79 
84  private $_card_type;
85 
90  private $_tx_type;
91 
96  private $_amount;
97 
102  private $_currency;
103 
108  private $_gift_aid = 'no';
109 
114  private $_timeout;
115 
120  private $_log_file_name;
121 
126  private $_response = NULL;
127 
132  private $_success = FALSE;
133 
138  private static $_TEST_CARD_NUMBERS = Array(
139  '4929000000006' => 'Visa',
140  '4462000000000003' => 'Visa Delta',
141  '4917300000000008' => 'Visa Electron',
142  '5404000000000001' => 'MasterCard',
143  '300000000000000004' => 'Maestro',
144  '5641820000000005' => 'Switch (UK Maestro)',
145  '6334900000000005' => 'Solo',
146  '374200000000004' => 'American Express',
147  '36000000000008' => 'Diners Club',
148  '3569990000000009' => 'JCB',
149  '6304990000000000044' => 'Laser',
150  );
151 
156  private static $_CARD_TYPES = Array(
157  'VISA' => 'Visa',
158  'DELTA' => 'Visa Delta',
159  'UKE' => 'Visa Electron',
160  'MC' => 'MasterCard',
161  'MAESTRO' => 'Maestro',
162  'SOLO' => 'Solo',
163  'AMEX' => 'American Express',
164  'DC' => 'Diners Club',
165  'JCB' => 'JCB',
166  'LASER' => 'Laser',
167  );
168 
169 
179  function __construct($protocol, $vendor, $timeout = 60, $run_mode = 'Simulator')
180  {
181  $this->_post_string = "VPSProtocol=$protocol&Vendor=$vendor";
182  $this->_timeout = $timeout;
183  $this->_post_urls = self::$_URLS[$run_mode];
184  $this->_log_file_name = SAGEPAY_LOG_FILE_PREFIX.$vendor.'_'.strtolower($run_mode);
185 
186  }//end constructor
187 
188 
197  public function setCardName($card_name)
198  {
199  $this->_post_string .= '&CardHolder='.urlencode($card_name);
200 
201  }//end setCardName()
202 
203 
212  public function setCardNumber($card_no)
213  {
214  //get the last 4 digits of card numbers for logging later
215  $this->_card_number = substr($card_no, -4);
216  $this->_post_string .= "&CardNumber=$card_no";
217 
218  }//end setCardNumber()
219 
220 
230  public function setCardExpiryDate($month, $year)
231  {
232  $this->_post_string .= "&ExpiryDate=$month$year";
233 
234  }//end setCardExpiryDate()
235 
236 
246  public function setCardStartDate($month, $year)
247  {
248  $this->_post_string .= "&StartDate=$month$year";
249 
250  }//end setCardStartDate()
251 
252 
261  public function setCardIssueNumber($issue_no)
262  {
263  $this->_post_string .= "&IssueNumber=$issue_no";
264 
265  }//end setCardIssueNumber()
266 
267 
276  public function setCardCV2($cv2)
277  {
278  $this->_post_string .= "&CV2=$cv2";
279 
280  }//end setCardCV2()
281 
282 
289  public function setTransactionTypePayment()
290  {
291  $this->_tx_type = 'PAYMENT';
292  $this->_post_string .= "&TxType=PAYMENT";
293 
294  }//end setTransactionTypePayment()
295 
296 
305  public function setMerchantReference($merchant_ref)
306  {
307  $this->_merchant_ref = $this->_getUniqueReferenceNumber($merchant_ref);
308  $this->_post_string .= '&VendorTxCode='.$this->_merchant_ref;
309 
310  }//end setMerchantReference()
311 
312 
322  public function setAmount($amount, $currency)
323  {
324  $this->_amount = sprintf('%01.2f',$amount);
325  $this->_currency = $currency;
326  $this->_post_string .= '&Amount='.$this->_amount."&Currency=$currency";
327 
328  }//end setAmount()
329 
330 
339  public function setDescription($desc)
340  {
341  $this->_post_string .= '&Description='.urlencode($desc);
342 
343  }//end setDescription()
344 
345 
354  public function setCardType($card_type)
355  {
356  $this->_card_type = $card_type;
357  $this->_post_string .= "&CardType=$card_type";
358 
359  }//end setCardType()
360 
361 
370  public function setBillingFirstnames($first_names)
371  {
372  $this->_post_string .= '&BillingFirstnames='.urlencode($first_names);
373 
374  }//end setBillingFirstnames()
375 
376 
385  public function setBillingSurname($surname)
386  {
387  $this->_post_string .= '&BillingSurname='.urlencode($surname);
388 
389  }//end setBillingSurname()
390 
391 
400  public function setBillingAddress1($address)
401  {
402  $this->_post_string .= '&BillingAddress1='.urlencode($address);
403 
404  }//end setBillingAddress1()
405 
406 
415  public function setBillingAddress2($address)
416  {
417  $this->_post_string .= '&BillingAddress2='.urlencode($address);
418 
419  }//end setBillingAddress2()
420 
421 
430  public function setBillingCity($city)
431  {
432  $this->_post_string .= '&BillingCity='.urlencode($city);
433 
434  }//end setBillingCity()
435 
436 
445  public function setBillingPostcode($postcode)
446  {
447  $this->_post_string .= '&BillingPostCode='.urlencode($postcode);
448 
449  }//end setBillingPostcode()
450 
451 
460  public function setBillingCountry($country)
461  {
462  $this->_post_string .= '&BillingCountry='.urlencode($country);
463 
464  }//end setBillingCountry()
465 
466 
475  public function setBillingState($state)
476  {
477  $this->_post_string .= '&BillingState='.urlencode($state);
478 
479  }//end setBillingState()
480 
481 
490  public function setBillingPhone($phone_no)
491  {
492  $this->_post_string .= '&BillingPhone='.urlencode($phone_no);
493 
494  }//end setBillingPhone()
495 
496 
505  public function setDeliveryFirstnames($first_names)
506  {
507  $this->_post_string .= '&DeliveryFirstnames='.urlencode($first_names);
508 
509  }//end setDeliveryFirstnames()
510 
511 
520  public function setDeliverySurname($surname)
521  {
522  $this->_post_string .= '&DeliverySurname='.urlencode($surname);
523 
524  }//end setDeliverySurname()
525 
526 
535  public function setDeliveryAddress1($address)
536  {
537  $this->_post_string .= '&DeliveryAddress1='.urlencode($address);
538 
539  }//end setDeliveryAddress1()
540 
541 
550  public function setDeliveryAddress2($address)
551  {
552  $this->_post_string .= '&DeliveryAddress2='.urlencode($address);
553 
554  }//end setDeliveryAddress2()
555 
556 
565  public function setDeliveryCity($city)
566  {
567  $this->_post_string .= '&DeliveryCity='.urlencode($city);
568 
569  }//end setDeliveryCity()
570 
571 
580  public function setDeliveryPostcode($postcode)
581  {
582  $this->_post_string .= '&DeliveryPostCode='.urlencode($postcode);
583 
584  }//end setDeliveryPostcode()
585 
586 
595  public function setDeliveryCountry($country)
596  {
597  $this->_post_string .= '&DeliveryCountry='.urlencode($country);
598 
599  }//end setDeliveryCountry()
600 
601 
610  public function setDeliveryState($state)
611  {
612  $this->_post_string .= '&DeliveryState='.urlencode($state);
613 
614  }//end setDeliveryState()
615 
616 
625  public function setDeliveryPhone($phone_no)
626  {
627  $this->_post_string .= '&DeliveryPhone='.urlencode($phone_no);
628 
629  }//end setDeliveryPhone()
630 
631 
638  public function setThreeDSecure()
639  {
640  $this->_post_string .= '&Apply3DSecure=0';
641 
642  }//end setThreeDSecure()
643 
644 
651  public function setAVSCV2()
652  {
653  $this->_post_string .= '&ApplyAVSCV2=0';
654 
655  }//end setAVSCV2()
656 
657 
664  public function setGiftAidPayment()
665  {
666  $this->_gift_aid = 'yes';
667  $this->_post_string .= '&GiftAidPayment=1';
668 
669  }//end setGiftAidPayment()
670 
671 
678  public function process()
679  {
680  //send POST request to the Payment Registration URL
681  $this->_success = $this->_sendRequest($this->_post_urls['payment_registration']);
682 
683  if ($this->_success) {
684  switch ($this->_response['Status']) {
685  case 'OK':
686  $this->_success = 1;
687  break;
688  case '3DAUTH':
689  $this->_success = 2;
690  break;
691  default: //the transaction is denied
692  $this->_success = FALSE;
693  }
694  }
695 
696  return $this->_success;
697 
698  }//end process()
699 
700 
711  public function authorize($merchant_ref, $md, $pares)
712  {
713  //set up parameters for logging
714  $this->_merchant_ref = $merchant_ref;
715  $this->_tx_type = '3-D Secure Authorization Callback';
716 
717  //set authorization parameters
718  $this->_post_string = "MD=$md&PARes=".urlencode($pares);
719 
720  //send POST request to the 3-D Secure Callback URL
721  $this->_success = $this->_sendRequest($this->_post_urls['threeds_callback']);
722 
723  if ($this->_success) {
724  $this->_success = $this->_response['Status'] == 'OK'? 1 : FALSE;
725  }
726 
727  return $this->_success;
728 
729  }//end authorize()
730 
731 
740  private function _sendRequest($url)
741  {
742  $success = TRUE;
743 
744  //log the request of the transaction
745  $this->_logRequest();
746 
747  $options = array(
748  'POST' => 1,
749  'POSTFIELDS' => $this->_post_string,
750  'RETURNTRANSFER' => 1,
751  'TIMEOUT' => $this->_timeout,
752  'SSL_VERIFYPEER' => 1,
753  'SSL_VERIFYHOST' => 2,
754  );
755  $details = fetch_url($url, $options);
756  $response = $details['response'];
757 
758  if ($response === FALSE) {
759  $success = FALSE;
760  $response = Array('CURL_ERROR' => TRUE, 'Status' => 'CURL_ERROR_'.$details['errornumber'], 'StatusDetail' => $details['errorstring']);
761  } else {
762  $lines = explode("\r\n", $response);
763  $response = Array();
764  foreach ($lines as $line) {
765  if (!empty($line)) {
766  $key_val_pairs = explode('=', $line, 2);
767  $response[$key_val_pairs[0]] = $key_val_pairs[1];
768  }
769  }
770  }
771 
772  $this->_response = $response;
773 
774  //log the transaction response
775  $this->_logResponse();
776 
777  return $success;
778 
779  }//end _sendRequest()
780 
781 
790  function getResponse()
791  {
792  $response = Array();
793 
794  switch ($this->_success) {
795  case 1: //payment is accepted
796  $response['TRANSACTION'] = $this->_response['VPSTxId'];
797  $response['TIME'] = time();
798  case FALSE: //error
799  $response['STATUS'] = $this->_response['StatusDetail'];
800  break;
801  case 2: //redirect user to the Access Control Server (ACS) for card holder verification
802  $response['ACS_URL'] = $this->_response['ACSURL'];
803  $response['PAREQ_MESSAGE'] = $this->_response['PAReq'];
804  $response['MD'] = $this->_response['MD'];
805  break;
806  }
807 
808  return $response;
809 
810  }//end getResponse()
811 
812 
819  public function getMerchantReference()
820  {
821  return $this->_merchant_ref;
822 
823  }//end getMerchantReference()
824 
825 
832  public static function getTestCardNumbers()
833  {
834  return self::$_TEST_CARD_NUMBERS;
835 
836  }//end getTestCardNumbers()
837 
838 
845  public static function getCardTypes()
846  {
847  return self::$_CARD_TYPES;
848 
849  }//end getCardTypes()
850 
851 
858  private function _logRequest()
859  {
860  $message = "Request\n";
861  if (empty($this->_card_number)) { //a historic (3-D Secure Callback) request
862  $message .= "Historic reference: {$this->getMerchantReference()}\n";
863 
864  } else { //a non-historic (PAYMENT) request
865  //log 4 last digits of card number
866  $message .= "Card number: {$this->_card_number}\n";
867 
868  //log card type
869  $message .= "Card type: {$this->_card_type}\n";
870 
871  //log merchant reference
872  $message .= "Merchant reference: {$this->getMerchantReference()}\n";
873 
874  //log amount
875  $message .= "Amount: {$this->_amount} {$this->_currency}\n";
876 
877  //gift aid
878  $message .= "Gift Aid Payment: {$this->_gift_aid}\n";
879 
880  }
881 
882  //log trasaction type
883  $message .= "Transaction type: {$this->_tx_type}\n";
884 
885  $this->_log($message);
886 
887  }//end _logRequest()
888 
889 
896  private function _logResponse()
897  {
898  $message = "Response\n";
899  if (array_get_index($this->_response, 'CURL_ERROR', FALSE)) {
900  $message .= 'CURL Error: '.$this->_response['StatusDetail'].' (status = '.$this->_response['Status'].")\n";
901 
902  } else {
903  //log the status
904  $message .= 'Transaction result: '.$this->_response['Status']."\n";
905 
906  //log the status details
907  if (isset($this->_response['StatusDetail'])) {
908  $message .= 'Status details: '.$this->_response['StatusDetail']."\n";
909  }
910 
911  //log the merchant reference so that we can match this response with its request in the log file
912  $message .= "Merchant reference: {$this->getMerchantReference()}\n";
913 
914  //log Sage Pay transaction ID
915  if (isset($this->_response['VPSTxId'])) {
916  $message .= 'Transaction ID: '.$this->_response['VPSTxId']."\n";
917  }
918 
919  //log security key
920  if (isset($this->_response['SecurityKey'])) {
921  $message .= 'Security Key: '.$this->_response['SecurityKey']."\n";
922  }
923 
924  //log authorization code
925  if (isset($this->_response['TxAuthNo'])) {
926  $message .= 'Authorization code: '.$this->_response['TxAuthNo']."\n";
927  }
928 
929  //log 3DS Status
930  if (isset($this->_response['3DSecureStatus'])) {
931  $message .= '3-D Secure Status: '.$this->_response['3DSecureStatus']."\n";
932  }
933 
934  //log CAVV result code
935  if (isset($this->_response['CAVV'])) {
936  $message .= '3-D Secure Result Code: '.$this->_response['CAVV']."\n";
937  }
938 
939  }
940 
941  $this->_log($message);
942 
943  }//end _logResponse()
944 
945 
956  private function _log($message, $level = E_USER_NOTICE, $encode=FALSE)
957  {
958  log_write($message, $this->_log_file_name, $level, $encode);
959 
960  }//end log()
961 
962 
971  private function _getUniqueReferenceNumber($ref_no)
972  {
973  if (strlen($ref_no) > 40) {
974  $ref_no = md5($ref_no);
975  }
976 
977  return $ref_no;
978 
979  }//end _getUniqueReferenceNumber()
980 
981 
982 }//end class
983 
984 ?>