17 require_once dirname(__FILE__).
'/../../payment_gateway/payment_gateway.inc';
18 require_once dirname(__FILE__).
'/utransact_processor.inc';
39 private $_processor = null;
48 parent::__construct($assetid);
65 if (!parent::_createAdditional($link))
return FALSE;
78 private function _loadProcessor()
81 $this->_processor =
new UTransact_Processor(
82 $this->
attr(
'username'),
83 $this->
attr(
'password'),
84 $this->
attr(
'bgas_webservice_url'),
85 $this->
attr(
'transactions_webservice_url'),
86 $this->
attr(
'services_webservice_url')
103 if (is_null($default_content)) {
104 $default_content = translate(
'default_bodycopy_content');
107 $GLOBALS[
'SQ_SYSTEM']->am->includeAsset(
'bodycopy');
109 $copy_link = Array(
'asset' => &$this,
'link_type' => SQ_LINK_TYPE_2,
'is_dependant' => 1,
'is_exclusive' => 1);
111 $bodycopy->setAttrValue(
'name',
'Display Format');
112 $args = Array(
'content' => $default_content);
113 if ($bodycopy->create($copy_link, $args)) {
114 $child_bodycopy = $GLOBALS[
'SQ_SYSTEM']->am->getLink($bodycopy->id, SQ_LINK_TYPE_2,
'bodycopy_div');
115 $GLOBALS[
'SQ_SYSTEM']->am->releaseLock($child_bodycopy[
'minorid'],
'attributes');
132 $page_links = parent::_getAllowedLinks();
133 $page_links[SQ_LINK_TYPE_2][
'bodycopy'] = Array(
'card' => 2,
'exclusive' => TRUE);
154 $keywords = parent::getAvailableKeywords();
156 $keywords[
'credit_card_number'] =
'Credit Card Number';
157 $keywords[
'credit_card_expiry_year'] =
'Credit Card Expiry Year';
158 $keywords[
'credit_card_expiry_month'] =
'Credit Card Expiry Month';
159 $keywords[
'credit_card_name'] =
'Name on card';
160 $keywords[
'credit_card_ccv'] =
'Credit Card CCV field';
161 $keywords[
'credit_card_type_selector'] =
'Credit Card selector';
163 $keywords[
'transaction_amount'] =
'Total transaction amount';
164 $keywords[
'transaction_gst'] =
'GST percent set at gateway (Not set for transaction)';
166 $keywords[
'submit_button'] =
'Submit Button';
167 $keywords[
'cancel_button'] =
'Cancel Button';
168 $keywords[
'reset_button'] =
'Reset Button';
170 $keywords[
'processing_error'] =
'Processing Error (empty if no error)';
190 $vars[
'keywords'] = array_merge($vars[
'keywords'], $keywords);
203 $amount = array_get_index($_SESSION,
'SQ_ECOM_AMOUNT', 0);
205 $card_info = array_get_index($_REQUEST, $this->
getPrefix().
'_card', FALSE);
206 $action = array_get_index($_REQUEST, $this->
getPrefix().
'_action', FALSE);
208 if ($action ==
'Cancel') {
209 unset($_SESSION[
'UTRANSACT_TRANSACTION_HANDLE']);
212 }
else if (empty($amount)) {
213 unset($_SESSION[
'UTRANSACT_TRANSACTION_HANDLE']);
214 unset($_SESSION[
'SQ_ECOM_AMOUNT']);
215 unset($_SESSION[
'SQ_ECOM_GST']);
221 }
else if ($card_info) {
226 unset($_SESSION[
'UTRANSACT_TRANSACTION_HANDLE']);
227 unset($_SESSION[
'SQ_ECOM_AMOUNT']);
228 unset($_SESSION[
'SQ_ECOM_GST']);
231 if (isset($_SESSION[
'SQ_ECOM_PAYMENT_COMPLETED_BROADCASTER_ASSETID'])) {
233 $broadcaster = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($_SESSION[
'SQ_ECOM_PAYMENT_COMPLETED_BROADCASTER_ASSETID']);
234 if (!empty($broadcaster)) {
237 $response = array_get_index($_SESSION,
'SQ_ECOM_RESPONSE', FALSE);
239 $_POST[
'transaction_reference'] = array_get_index($response,
'REFERENCE',
'');
240 $_POST[
'transaction_time'] = array_get_index($response,
'TIME',
'');
241 $_POST[
'transaction_status'] = array_get_index($response,
'STATUS',
'');
242 $_POST[
'transaction_card_number'] = array_get_index($response,
'CARDNO',
'');
243 $_POST[
'transaction_amount'] = array_get_index($response,
'AMOUNT', 0) + array_get_index($response,
'GST', 0);
244 $_POST[
'transaction_invoice'] = array_get_index($response,
'INVOICE_NUMBER',
'');
247 $GLOBALS[
'SQ_SYSTEM']->broadcastTriggerEvent(
'trigger_event_ecommerce_payment_completed', $broadcaster);
260 if (empty($this->_processor)) {
261 $this->_loadProcessor();
264 if ($this->_processor) {
267 $transaction_handle = $this->_processor->getTransactionHandle();
269 if (!$transaction_handle) {
270 $this->_setError(
'Cannot obtain the transaction handle from the payment gateway. Please submit the payment form again or contact the administrator');
275 $_SESSION[
'UTRANSACT_TRANSACTION_HANDLE'] = $transaction_handle;
278 $this->_setError(
"Cannot load payment processor. Please contact the administrator.");
295 if (is_null($bodycopy))
return;
297 $keywords = $bodycopy->getKeywords();
298 $replacements = Array();
299 foreach ($keywords as $word) {
302 $bodycopy->setKeywordReplacements($replacements);
305 $datapath = sq_web_path(
'data').
'/asset_types/payment_gateway_utransact/files';
309 <script src=
"<?php echo $datapath; ?>/loader.js"></script>
311 var Loader =
new Loader(
'<?php echo $card; ?>',
'#FFFFFF',
'Processing Transaction...',
'<?php echo $datapath; ?>/loader.gif');
314 <form method=
"post" action=
"<?php echo $this->getURL(); ?>" onsubmit=
"Loader.show();">
316 $bodycopy->printBody();
330 $link = $GLOBALS[
'SQ_SYSTEM']->am->getLink($this->
id, SQ_LINK_TYPE_2,
'bodycopy', TRUE,
'',
'major');
331 if (empty($link))
return NULL;
332 $bodycopy = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($link[
'minorid'], $link[
'minor_type_code']);
348 if (!$card_info)
return FALSE;
350 $amount = $_SESSION[
'SQ_ECOM_AMOUNT'];
351 if (empty($amount)) {
352 $this->_setError(translate(
'utransact_amount_not_specified'));
356 if (!$this->
attr(
'username')) {
357 $this->_setError(translate(
"utransact_account_username_not_specified"));
359 if (!$this->
attr(
'password')) {
360 $this->_setError(translate(
"utransact_account_password_not_specified"));
362 if (!$this->
attr(
'bgas_webservice_url')) {
363 $this->_setError(translate(
"url_to_bgas_webservice_not_specified"));
365 if (!$this->
attr(
'transactions_webservice_url')) {
366 $this->_setError(translate(
"url_to_transactions_webservice_not_specified"));
368 if (!$this->
attr(
'services_webservice_url')) {
369 $this->_setError(translate(
"url_to_services_webservice_not_specified"));
377 if (empty($this->_processor)) {
378 $this->_loadProcessor();
380 if (empty($this->_processor)) {
381 $this->_setError(
"Cannot load processor");
392 $reference_no = md5(session_id().time());
393 $this->_processor->setTransactionReferenceNo($reference_no);
395 $_SESSION[
'SQ_ECOM_REF_NO'] = $this->_processor->getTransactionReferenceNo();
397 $pending_order_id = array_get_index($_SESSION[
'sq_local_cart_contents'],
'pending_order_id', NULL);
398 if (!$pending_order_id) {
399 $this->_setError(
"Order asset not found in session.");
402 $pending_order = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($pending_order_id);
403 $pending_order->setAttrValue(
'ecom_ref_no', $_SESSION[
'SQ_ECOM_REF_NO']);
404 $pending_order->appendAuditLog(translate(
'utransact_ecom_ref_num_recorded_before_processing'));
407 if (!empty($card_info[
'number'])) {
408 $card_info[
'number'] = str_replace(Array(
' ',
"\t"),
'', $card_info[
'number']);
409 $this->_processor->setCreditCard($card_info[
'number']);
411 $this->_setError(translate(
"utransact_card_number_not_specified"));
415 if (!empty($card_info[
'name'])) {
416 $this->_processor->setCardHolderName($card_info[
'name']);
418 $this->_setError(translate(
"utransact_card_name_not_specified"));
422 if ($this->_isValidMonth(array_get_index($card_info,
'month',
'')) && $this->_isValidYear(array_get_index($card_info,
'year',
''))) {
423 $this->_processor->setCardExpiryMonth($card_info[
'month']);
424 $this->_processor->setCardExpiryYear($card_info[
'year']);
426 $this->_setError(translate(
"utransact_expiry_date_invalid"));
430 if($this->
attr(
'display_ccv')){
431 if (!empty($card_info[
'ccv']) && $this->_isValidCV2($card_info[
'ccv'])) {
432 $this->_processor->setCreditCardCV2($card_info[
'ccv']);
434 $this->_setError(translate(
"utransact_card_cv2_invalid"));
439 if ($this->
attr(
'merchant_id') !=
'') {
440 $this->_processor->setMerchantId($this->
attr(
'merchant_id'));
444 if ($this->
attr(
'payment_model') !=
'') {
445 $this->_processor->setPaymentModel($this->
attr(
'payment_model'));
449 $purchaser_info = $this->_getPurchaserInfo();
451 $this->_processor->setFirstName(isset($purchaser_info[
'firstname']) ? $purchaser_info[
'firstname'] :
'');
452 $this->_processor->setSurname(isset($purchaser_info[
'surname']) ? $purchaser_info[
'surname'] :
'');
453 $this->_processor->setEmail(isset($purchaser_info[
'email']) ? $purchaser_info[
'email'] :
'');
454 $this->_processor->setAddressLine1(isset($purchaser_info[
'address1']) ? $purchaser_info[
'address1'] :
'');
455 $this->_processor->setAddressLine2(isset($purchaser_info[
'address2']) ? $purchaser_info[
'address2'] :
'');
456 $this->_processor->setSuburb(isset($purchaser_info[
'suburb']) ? $purchaser_info[
'suburb'] :
'');
457 $this->_processor->setCity(isset($purchaser_info[
'city']) ? $purchaser_info[
'city'] :
'');
458 $this->_processor->setPostcode(isset($purchaser_info[
'postcode']) ? $purchaser_info[
'postcode'] :
'');
462 $session_cart = isset($_SESSION[
'sq_local_cart_contents'][
'cart_contents']) ? $_SESSION[
'sq_local_cart_contents'][
'cart_contents'] : Array();
464 if (empty($session_cart)) {
465 $this->_setError(translate(
"utransact_shopping_cart_empty"));
468 foreach($session_cart as $product_assetid => $item) {
469 $item[
'additional_info'] =
"IS DONATION: ".($item[
'is_donation'] ?
'YES' :
'NO');
471 $item[
"application_username"] = isset($item[
"application_username"]) ? $item[
"application_username"] :
'';
472 $item[
"description"] = isset($item[
"description"]) ? $item[
"description"] :
'';
473 $item[
"financial_values"] = isset($item[
"financial_values"]) ? $item[
"financial_values"] :
'';
476 $refund_expiry_date = ($item[
"refund_type"] ===
'Expires') ? date(
"Y-m-d\TH:i:s", strtotime(
"+7 days")) :
'';
478 $this->_processor->addCartItem(
479 $item[
"application_username"],
481 $item[
"description"],
483 $item[
"refund_type"],
486 $item[
"product_code"],
487 $item[
"financial_code"],
488 $item[
"financial_values"],
489 $item[
"additional_info"]
500 $success = $this->_processor->process();
503 $response = $this->_processor->getResponse();
505 $this->_setTransactionResult($success, $response, $card_info);
523 private function _setTransactionResult($success, $response, $card_info)
526 $this->_tmp[
'is_error'] = TRUE;
527 $this->_tmp[
'error_message'] = Array($response[
'MESSAGE']);
529 $status = $response[
'STATUS'];
533 $cardlength = strlen($card_info[
'number']);
534 if ($cardlength < 16) {
535 for ($i = 0; $i < $cardlength - 4; $i++) {
538 $cardno .= substr($card_info[
'number'], $i);
540 $cardno =
'****-****-****-'.substr($card_info[
'number'],12);
543 $response[
'CARDNO'] = $cardno;
544 $response[
'TIME'] = array_get_index($response,
'DATE', date(
'r'));
545 $response[
'TRANSACTION'] = array_get_index($response,
'INVOICE_NUMBER',
'');
547 $_SESSION[
'SQ_ECOM_RESPONSE'] = $response;
559 private function _getPurchaserInfo()
561 $purchaser_data = isset($_SESSION[
'order_extra_information']) ? $_SESSION[
'order_extra_information'] :
'';
562 if (empty($purchaser_data)) {
563 $this->_setError(translate(
"utransact_purchaser_info_not_in_session"));
567 $purchaser_data = unserialize($purchaser_data);
570 $checkout_fields = Array(
581 $purchaser_info = Array();
582 foreach($checkout_fields as $field => $required) {
583 $form_qid = trim($this->
attr(
'map_'.$field.
'_assetid'));
586 if (!preg_match(
'/^[0-9]+?:(.*)$/',$form_qid, $match) && $required) {
587 $this->_setError(translate(
"utransact_form_question_id_not_set", ucfirst($field)));
591 $shadow_qid = isset($match[1]) ? trim($match[1]) : 0;
592 $purchaser_info[$field] = isset($purchaser_data[$shadow_qid]) ? $purchaser_data[$shadow_qid] :
'';
594 if ($required && !$purchaser_info[$field]) {
595 $this->_setError(translate(
"utransact_form_question_id_not_set", ucfirst($field)));
601 return $purchaser_info;
614 private function _isValidMonth($month)
616 $month_of_year = Array(
'JAN',
'FEB',
'MAR',
'APR',
'MAY',
'JUN',
'JUL',
'AUG',
'SEP',
'OCT',
'NOV',
'DEC');
617 return (in_array(strtoupper($month), $month_of_year));
630 private function _isValidYear($year)
632 return preg_match(
'/^\d{4}$/', $year);
645 private function _isValidCV2($cv2)
647 return preg_match(
'/^\d{3,4}$/', $cv2);
660 private function _setError($err_message)
662 $this->_tmp[
'is_error'] = TRUE;
663 $this->_tmp[
'error_message'][] = $err_message;
676 return array_get_index($this->_tmp,
'is_error', FALSE);
689 $this->_tmp[
'error_message'] = Array();
690 $this->_tmp[
'is_error'] = FALSE;
707 if ($state ==
'SUCCESS') {
708 $back_url = array_get_index($_SESSION,
'SQ_ECOM_SUCCESS_URL');
709 unset($_SESSION[
'SQ_ECOM_SUCCESS_URL']);
711 }
else if ($state ==
'CANCEL') {
712 $back_url = array_get_index($_SESSION,
'SQ_ECOM_CANCEL_URL');
713 unset($_SESSION[
'SQ_ECOM_CANCEL_URL']);
716 if (is_null($back_url)) {
717 trigger_error(
'Unknown caller reference');
719 header(
'Location: '.$back_url);
735 $errors = array_get_index($this->_tmp,
'error_message', Array());
737 foreach ($errors as $error) {
738 $err_message .=
"<li>$error </li>";
741 return '<ul>'.$err_message.
'</ul>';
756 if (!$from_gateway && isset($_SESSION[
'SQ_ECOM_GST'])) {
757 return $_SESSION[
'SQ_ECOM_GST'];
760 if (empty($this->_processor)) {
761 $this->_loadProcessor();
763 if (empty($this->_processor)) {
764 $this->_setError(
"Cannot load processor");
770 $_SESSION[
'SQ_ECOM_GST'] = $this->_processor->getTransactionGstRate();
772 return $_SESSION[
'SQ_ECOM_GST'];
786 $card = $prefix.
'_card';
788 $card_number =
'<input name="'.$card.
'[number]" autocomplete="off" />';
804 $string =
'<input name="'.$card.
'[name]" autocomplete="off" />';
818 if (!$this->
attr(
'display_ccv'))
return '';
821 $string =
'CV2 <input name="'.$card.
'[ccv]" size="4" autocomplete="off" />';
835 if (empty($this->_processor)) {
836 $this->_loadProcessor();
838 if (empty($this->_processor)) {
839 $this->_setError(
"Cannot load processor");
846 $card_types = $this->_processor->getCardTypes();
849 echo
'<select name="'.$card.
'[type]">';
850 foreach ($card_types as $type) {
851 echo
'<option value="'.$type.
'">'.$type.
'</option>';
855 return ob_get_clean();
871 return array_get_index($_SESSION,
'SQ_ECOM_AMOUNT', 0);
885 return $gst_rate ? ($gst_rate*100) :
'GST NOT SET!';
901 $string =
'<input name="'.$card.
'[year]" size="2" autocomplete="off" />';
918 $string =
'<input name="'.$card.
'[month]" size="2" autocomplete="off" />';
933 return '<span class="payment-gateway-transaction-error">'.$this->getErrorMessage().
'</span>';
949 $button_text = $this->
attr(
'submit_text');
950 if (empty($button_text)) $button_text =
'Submit';
951 return '<input type="submit" value="'.$button_text.
'" />';
964 $button_text = $this->
attr(
'reset_text');
965 if (empty($button_text)) $button_text =
'Reset';
966 return '<input type="reset" value="'.$button_text.
'" />';
979 $button_text = $this->
attr(
'cancel_text');
980 if (empty($button_text)) $button_text =
'Cancel';
981 return '<input type="submit" name="'.$this->getPrefix().
'_action" value="'.$button_text.
'" />';
994 if (empty($this->_processor)) {
995 $this->_loadProcessor();
998 if ($this->_processor) {
999 return $this->_processor->getTransactionHandle();