Index: branches/5.1.x/add_to_cart.php =================================================================== --- branches/5.1.x/add_to_cart.php (revision 13703) +++ branches/5.1.x/add_to_cart.php (nonexistent) @@ -1,20 +0,0 @@ -<?php -/** -* @version $Id$ -* @package In-Commerce -* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. -* @license Commercial License -* This software is protected by copyright law and international treaties. -* Unauthorized reproduction or unlicensed usage of the code of this program, -* or any portion of it may result in severe civil and criminal penalties, -* and will be prosecuted to the maximum extent possible under the law -* See http://www.in-portal.org/commercial-license for copyright notices and details. -*/ - -define('FULL_PATH', realpath(dirname(__FILE__))); -include_once(FULL_PATH.'/core/kernel/startup.php'); - -$application =& kApplication::Instance(); -$application->Init(); - -$application->Redirect('in-commerce/checkout/shop_cart', array('pass'=>'p,ord', 'ord_event' => 'OnAddToCart', 'p_id' => $application->GetVar('product'))); \ No newline at end of file Property changes on: branches/5.1.x/add_to_cart.php ___________________________________________________________________ Deleted: cvs2svn:cvs-rev ## -1 +0,0 ## -1.3 \ No newline at end of property Deleted: svn:executable ## -1 +0,0 ## -* \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -Id \ No newline at end of property Index: branches/5.1.x/units/gateways/gw_classes/notify_scripts/google_checkout_notify.php =================================================================== --- branches/5.1.x/units/gateways/gw_classes/notify_scripts/google_checkout_notify.php (revision 13703) +++ branches/5.1.x/units/gateways/gw_classes/notify_scripts/google_checkout_notify.php (revision 13704) @@ -1,51 +1,51 @@ <?php /** * @version $Id$ * @package In-Commerce * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license Commercial License * This software is protected by copyright law and international treaties. * Unauthorized reproduction or unlicensed usage of the code of this program, * or any portion of it may result in severe civil and criminal penalties, * and will be prosecuted to the maximum extent possible under the law * See http://www.in-portal.org/commercial-license for copyright notices and details. */ - define('FULL_PATH', realpath(dirname(__FILE__).'/../../../../../')); - define('REL_PATH', 'in-commerce/units/gateways/gw_classes/notify_scripts'); + define('FULL_PATH', realpath(dirname(__FILE__) . '/../../../../../..')); + define('REL_PATH', 'modules/in-commerce/units/gateways/gw_classes/notify_scripts'); define('ADMIN', 1); include_once(FULL_PATH.'/core/kernel/startup.php'); $application =& kApplication::Instance(); $application->Init(); $sql = 'SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes AS pt LEFT JOIN '.TABLE_PREFIX.'Gateways AS g ON g.GatewayId = pt.GatewayId WHERE g.ClassName = "kGWGoogleCheckout"'; $payment_type_id = $application->Conn->GetOne($sql); $application->SetVar('payment_type_id', $payment_type_id); // keep, because kGWGoogleCheckout::processNewOrderNotification relies on this $order =& $application->recallObject('ord', null, Array ('skip_autoload' => true)); /* @var $order OrdersItem */ $gw_data = $order->getGatewayData($application->GetVar('payment_type_id')); $application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] ); $gateway_object =& $application->recallObject( $gw_data['ClassName'] ); $transaction_status = $gateway_object->processNotification($gw_data['gw_params']); $sql = 'UPDATE '.$order->TableName.' SET TransactionStatus = '.$transaction_status.' WHERE '.$order->IDField.' = '.$order->GetID(); $application->Conn->Query($sql); $order->SetDBField('TransactionStatus', $transaction_status); if ($transaction_status == 1) { $dummy_var = '10'; $application->SetVar('ord_id', $order->GetID()); // used in OrdersEventHandler::UpdateOrderItem $application->HandleEvent($dummy_var, 'ord:OnCompleteOrder'); } $application->Done(); \ No newline at end of file Index: branches/5.1.x/units/gateways/gw_classes/notify_scripts/sella_error.php =================================================================== --- branches/5.1.x/units/gateways/gw_classes/notify_scripts/sella_error.php (revision 13703) +++ branches/5.1.x/units/gateways/gw_classes/notify_scripts/sella_error.php (revision 13704) @@ -1,31 +1,31 @@ <?php /** * @version $Id$ * @package In-Commerce * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license Commercial License * This software is protected by copyright law and international treaties. * Unauthorized reproduction or unlicensed usage of the code of this program, * or any portion of it may result in severe civil and criminal penalties, * and will be prosecuted to the maximum extent possible under the law * See http://www.in-portal.org/commercial-license for copyright notices and details. */ - define('FULL_PATH', realpath(dirname(__FILE__).'/../../../../../')); - define('REL_PATH', 'in-commerce/units/gateways/gw_classes/notify_scripts'); + define('FULL_PATH', realpath(dirname(__FILE__) . '/../../../../../..')); + define('REL_PATH', 'modules/in-commerce/units/gateways/gw_classes/notify_scripts'); define('ADMIN', 1); include_once(FULL_PATH.'/core/kernel/startup.php'); $application =& kApplication::Instance(); $application->Init(); $application->SetVar('sella_error', 1); $application->SetVar('payment_type_id', $application->Conn->GetOne( 'SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes AS pt LEFT JOIN '.TABLE_PREFIX.'Gateways AS g ON g.GatewayId = pt.GatewayId WHERE g.ClassName = '.$application->Conn->qstr('kSellaGuestPayGW'))); - include(FULL_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file + include(MODULES_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file Index: branches/5.1.x/units/gateways/gw_classes/notify_scripts/sella_ok.php =================================================================== --- branches/5.1.x/units/gateways/gw_classes/notify_scripts/sella_ok.php (revision 13703) +++ branches/5.1.x/units/gateways/gw_classes/notify_scripts/sella_ok.php (revision 13704) @@ -1,31 +1,31 @@ <?php /** * @version $Id$ * @package In-Commerce * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license Commercial License * This software is protected by copyright law and international treaties. * Unauthorized reproduction or unlicensed usage of the code of this program, * or any portion of it may result in severe civil and criminal penalties, * and will be prosecuted to the maximum extent possible under the law * See http://www.in-portal.org/commercial-license for copyright notices and details. */ - define('FULL_PATH', realpath(dirname(__FILE__).'/../../../../../')); - define('REL_PATH', 'in-commerce/units/gateways/gw_classes/notify_scripts'); + define('FULL_PATH', realpath(dirname(__FILE__) . '/../../../../../..')); + define('REL_PATH', 'modules/in-commerce/units/gateways/gw_classes/notify_scripts'); define('ADMIN', 1); - include_once(FULL_PATH.'/core/kernel/startup.php'); + include_once(FULL_PATH . '/core/kernel/startup.php'); $application =& kApplication::Instance(); $application->Init(); $application->SetVar('sella_ok', 1); $application->SetVar('payment_type_id', $application->Conn->GetOne( 'SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes AS pt LEFT JOIN '.TABLE_PREFIX.'Gateways AS g ON g.GatewayId = pt.GatewayId WHERE g.ClassName = '.$application->Conn->qstr('kSellaGuestPayGW'))); - include(FULL_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file + include(MODULES_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file Index: branches/5.1.x/units/gateways/gw_classes/notify_scripts/paybox_notify.php =================================================================== --- branches/5.1.x/units/gateways/gw_classes/notify_scripts/paybox_notify.php (revision 13703) +++ branches/5.1.x/units/gateways/gw_classes/notify_scripts/paybox_notify.php (revision 13704) @@ -1,32 +1,30 @@ <?php /** * @version $Id$ * @package In-Commerce * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license Commercial License * This software is protected by copyright law and international treaties. * Unauthorized reproduction or unlicensed usage of the code of this program, * or any portion of it may result in severe civil and criminal penalties, * and will be prosecuted to the maximum extent possible under the law * See http://www.in-portal.org/commercial-license for copyright notices and details. */ - define('FULL_PATH', realpath(dirname(__FILE__).'/../../../../../')); - define('REL_PATH', 'in-commerce/units/gateways/gw_classes/notify_scripts'); - if (!file_exists(FULL_PATH.'/core/kernel/application.php')) { //way to dectect new ver - define('APPLICATION_CLASS', 'MyApplication'); - } + define('FULL_PATH', realpath(dirname(__FILE__) . '/../../../../../..')); + define('REL_PATH', 'modules/in-commerce/units/gateways/gw_classes/notify_scripts'); + define('ADMIN', 1); include_once(FULL_PATH.'/core/kernel/startup.php'); $application =& kApplication::Instance(); $application->Init(); $application->SetVar('payment_type_id', $application->Conn->GetOne( 'SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes AS pt LEFT JOIN '.TABLE_PREFIX.'Gateways AS g ON g.GatewayId = pt.GatewayId WHERE g.ClassName = '.$application->Conn->qstr('kPayboxGW'))); - include(FULL_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file + include(MODULES_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file Index: branches/5.1.x/units/gateways/gw_classes/notify_scripts/multicards_notify.php =================================================================== --- branches/5.1.x/units/gateways/gw_classes/notify_scripts/multicards_notify.php (revision 13703) +++ branches/5.1.x/units/gateways/gw_classes/notify_scripts/multicards_notify.php (revision 13704) @@ -1,32 +1,30 @@ <?php /** * @version $Id$ * @package In-Commerce * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license Commercial License * This software is protected by copyright law and international treaties. * Unauthorized reproduction or unlicensed usage of the code of this program, * or any portion of it may result in severe civil and criminal penalties, * and will be prosecuted to the maximum extent possible under the law * See http://www.in-portal.org/commercial-license for copyright notices and details. */ - define('FULL_PATH', realpath(dirname(__FILE__).'/../../../../../')); - define('REL_PATH', 'in-commerce/units/gateways/gw_classes/notify_scripts'); - if (!file_exists(FULL_PATH.'/core/kernel/application.php')) { //way to dectect new ver - define('APPLICATION_CLASS', 'MyApplication'); - } + define('FULL_PATH', realpath(dirname(__FILE__) . '/../../../../../..')); + define('REL_PATH', 'modules/in-commerce/units/gateways/gw_classes/notify_scripts'); + define('ADMIN', 1); - include_once(FULL_PATH.'/core/kernel/startup.php'); + include_once(FULL_PATH . '/core/kernel/startup.php'); $application =& kApplication::Instance(); $application->Init(); $application->SetVar('payment_type_id', $application->Conn->GetOne( 'SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes AS pt LEFT JOIN '.TABLE_PREFIX.'Gateways AS g ON g.GatewayId = pt.GatewayId WHERE g.ClassName = '.$application->Conn->qstr('kMultiCardsGW'))); - include(FULL_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file + include(MODULES_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file Index: branches/5.1.x/units/gateways/gw_classes/notify_scripts/verisign_pflink_notify.php =================================================================== --- branches/5.1.x/units/gateways/gw_classes/notify_scripts/verisign_pflink_notify.php (revision 13703) +++ branches/5.1.x/units/gateways/gw_classes/notify_scripts/verisign_pflink_notify.php (revision 13704) @@ -1,29 +1,29 @@ <?php /** * @version $Id$ * @package In-Commerce * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license Commercial License * This software is protected by copyright law and international treaties. * Unauthorized reproduction or unlicensed usage of the code of this program, * or any portion of it may result in severe civil and criminal penalties, * and will be prosecuted to the maximum extent possible under the law * See http://www.in-portal.org/commercial-license for copyright notices and details. */ - define('FULL_PATH', realpath(dirname(__FILE__).'/../../../../../')); - define('REL_PATH', 'in-commerce/units/gateways/gw_classes/notify_scripts'); + define('FULL_PATH', realpath(dirname(__FILE__) . '/../../../../../..')); + define('REL_PATH', 'modules/in-commerce/units/gateways/gw_classes/notify_scripts'); define('ADMIN', 1); - include_once(FULL_PATH.'/core/kernel/startup.php'); + include_once(FULL_PATH . '/core/kernel/startup.php'); $application =& kApplication::Instance(); $application->Init(); $application->SetVar('payment_type_id', $application->Conn->GetOne( 'SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes AS pt LEFT JOIN '.TABLE_PREFIX.'Gateways AS g ON g.GatewayId = pt.GatewayId WHERE g.ClassName = '.$application->Conn->qstr('kVerisignPfLinkGW'))); - include(FULL_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file + include(MODULES_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file Index: branches/5.1.x/units/gateways/gw_classes/notify_scripts/google_checkout_shippings.php =================================================================== --- branches/5.1.x/units/gateways/gw_classes/notify_scripts/google_checkout_shippings.php (revision 13703) +++ branches/5.1.x/units/gateways/gw_classes/notify_scripts/google_checkout_shippings.php (revision 13704) @@ -1,37 +1,37 @@ <?php /** * @version $Id$ * @package In-Commerce * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license Commercial License * This software is protected by copyright law and international treaties. * Unauthorized reproduction or unlicensed usage of the code of this program, * or any portion of it may result in severe civil and criminal penalties, * and will be prosecuted to the maximum extent possible under the law * See http://www.in-portal.org/commercial-license for copyright notices and details. */ - define('FULL_PATH', realpath(dirname(__FILE__).'/../../../../../')); - define('REL_PATH', 'in-commerce/units/gateways/gw_classes/notify_scripts'); + define('FULL_PATH', realpath(dirname(__FILE__) . '/../../../../../..')); + define('REL_PATH', 'modules/in-commerce/units/gateways/gw_classes/notify_scripts'); define('ADMIN', 1); - include_once(FULL_PATH.'/core/kernel/startup.php'); + include_once(FULL_PATH . '/core/kernel/startup.php'); $application =& kApplication::Instance(); $application->Init(); $sql = 'SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes AS pt LEFT JOIN '.TABLE_PREFIX.'Gateways AS g ON g.GatewayId = pt.GatewayId WHERE g.ClassName = "kGWGoogleCheckout"'; $payment_type_id = $application->Conn->GetOne($sql); $order =& $application->recallObject('ord', null, Array ('skip_autoload' => true)); /* @var $order OrdersItem */ $gw_data = $order->getGatewayData($payment_type_id); $application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] ); $gateway_object =& $application->recallObject( $gw_data['ClassName'] ); /* @var $gateway_object kGWGoogleCheckout */ $gateway_object->processNotification($gw_data['gw_params'], 'shippings'); $application->Done(); \ No newline at end of file Index: branches/5.1.x/units/gateways/gw_classes/notify_scripts/atosorigin_notify.php =================================================================== --- branches/5.1.x/units/gateways/gw_classes/notify_scripts/atosorigin_notify.php (revision 13703) +++ branches/5.1.x/units/gateways/gw_classes/notify_scripts/atosorigin_notify.php (revision 13704) @@ -1,29 +1,29 @@ <?php /** * @version $Id$ * @package In-Commerce * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license Commercial License * This software is protected by copyright law and international treaties. * Unauthorized reproduction or unlicensed usage of the code of this program, * or any portion of it may result in severe civil and criminal penalties, * and will be prosecuted to the maximum extent possible under the law * See http://www.in-portal.org/commercial-license for copyright notices and details. */ - define('FULL_PATH', realpath(dirname(__FILE__).'/../../../../../')); - define('REL_PATH', 'in-commerce/units/gateways/gw_classes/notify_scripts'); + define('FULL_PATH', realpath(dirname(__FILE__) . '/../../../../../..')); + define('REL_PATH', 'modules/in-commerce/units/gateways/gw_classes/notify_scripts'); define('ADMIN', 1); - include_once(FULL_PATH.'/core/kernel/startup.php'); + include_once(FULL_PATH . '/core/kernel/startup.php'); $application =& kApplication::Instance(); $application->Init(); $application->SetVar('payment_type_id', $application->Conn->GetOne( 'SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes AS pt LEFT JOIN '.TABLE_PREFIX.'Gateways AS g ON g.GatewayId = pt.GatewayId WHERE g.ClassName = '.$application->Conn->qstr('kAtosOriginGW'))); - include(FULL_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file + include(MODULES_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file Index: branches/5.1.x/units/gateways/gw_classes/notify_scripts/sella_notify.php =================================================================== --- branches/5.1.x/units/gateways/gw_classes/notify_scripts/sella_notify.php (revision 13703) +++ branches/5.1.x/units/gateways/gw_classes/notify_scripts/sella_notify.php (revision 13704) @@ -1,29 +1,29 @@ <?php /** * @version $Id$ * @package In-Commerce * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license Commercial License * This software is protected by copyright law and international treaties. * Unauthorized reproduction or unlicensed usage of the code of this program, * or any portion of it may result in severe civil and criminal penalties, * and will be prosecuted to the maximum extent possible under the law * See http://www.in-portal.org/commercial-license for copyright notices and details. */ - define('FULL_PATH', realpath(dirname(__FILE__).'/../../../../../')); - define('REL_PATH', 'in-commerce/units/gateways/gw_classes/notify_scripts'); + define('FULL_PATH', realpath(dirname(__FILE__) . '/../../../../../..')); + define('REL_PATH', 'modules/in-commerce/units/gateways/gw_classes/notify_scripts'); define('ADMIN', 1); include_once(FULL_PATH.'/core/kernel/startup.php'); $application =& kApplication::Instance(); $application->Init(); $application->SetVar('payment_type_id', $application->Conn->GetOne( 'SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes AS pt LEFT JOIN '.TABLE_PREFIX.'Gateways AS g ON g.GatewayId = pt.GatewayId WHERE g.ClassName = '.$application->Conn->qstr('kSellaGuestPayGW'))); - include(FULL_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file + include(MODULES_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file Index: branches/5.1.x/units/gateways/gw_classes/atosorigin.php =================================================================== --- branches/5.1.x/units/gateways/gw_classes/atosorigin.php (revision 13703) +++ branches/5.1.x/units/gateways/gw_classes/atosorigin.php (revision 13704) @@ -1,192 +1,192 @@ <?php /** * @version $Id$ * @package In-Commerce * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license Commercial License * This software is protected by copyright law and international treaties. * Unauthorized reproduction or unlicensed usage of the code of this program, * or any portion of it may result in severe civil and criminal penalties, * and will be prosecuted to the maximum extent possible under the law * See http://www.in-portal.org/commercial-license for copyright notices and details. */ require_once GW_CLASS_PATH.'/gw_base.php'; $class_name = 'kAtosOriginGW'; // for automatic installation class kAtosOriginGW extends kGWBase { function InstallData() { $data = array( 'Gateway' => Array('Name' => 'Atos Origin', 'ClassName' => 'kAtosOriginGW', 'ClassFile' => 'atosorigin.php', 'RequireCCFields' => 0), 'ConfigFields' => Array( 'request_binary' => Array('Name' => 'API Request Executable', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), 'response_binary' => Array('Name' => 'API Response Executable', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), 'pathfile' => Array('Name' => 'Pathfile', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), 'merchant_id' => Array('Name' => 'Merchant ID', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), 'merchant_country' => Array('Name' => 'Merchant Country Code', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), 'currency_code' => Array('Name' => 'Currency Code', 'Type' => 'text', 'ValueList' => '', 'Default' => '978'), 'shipping_control' => Array('Name' => 'Shipping Control', 'Type' => 'select', 'ValueList' => '3=la_CreditDirect,4=la_CreditPreAuthorize', 'Default' => '3'), ) ); return $data; } /** * Returns payment form submit url * * @param Array $gw_params gateway params from payment type config * @return string */ function getFormAction($gw_params) { return $gw_params['submit_url']; } /** * Processed input data and convets it to fields understandable by gateway * * @param Array $item_data * @param Array $tag_params additional params for gateway passed through tag * @param Array $gw_params gateway params from payment type config * @return Array */ function getHiddenFields($item_data, $tag_params, $gw_params) { $params['pathfile'] = $gw_params['pathfile']; $params['merchant_id'] = $gw_params['merchant_id']; $params['merchant_country'] = $gw_params['merchant_country']; $params['currency_code'] = $gw_params['currency_code']; $params['currency_code'] = $gw_params['currency_code']; $params['normal_return_url'] = $this->Application->HREF($tag_params['return_template'],'',Array('pass'=>'m')); $params['cancel_return_url'] = $this->Application->HREF($tag_params['cancel_template'],'',Array('pass'=>'m')); - $params['automatic_response_url'] = $this->Application->BaseURL('/in-commerce/units/gateways/gw_classes/notify_scripts').'atosorigin_notify.php'; + $params['automatic_response_url'] = $this->getNotificationUrl('units/gateways/gw_classes/notify_scripts/atosorigin_notify.php'); $txt_amount = sprintf("%.2f", $item_data['TotalAmount']); - + $params['amount'] = str_replace( Array('.', ','), '', $txt_amount); $params['caddie'] = $this->Application->GetSID() . ',' . MD5($item_data['OrderId']); $params['order_id'] = $item_data['OrderId']; $params['customer_ip_address'] = $_SERVER['REMOTE_ADDR']; $params['customer_id'] = $item_data['PortalUserId']; $billing_email = $item_data['BillingEmail']; if (!$billing_email) { $billing_email = $this->Conn->GetOne(' SELECT Email FROM '.$this->Application->getUnitOption('u', 'TableName').' WHERE PortalUserId = '.$this->Application->RecallVar('user_id')); } $params['customer_email'] = $billing_email; $params_str = ''; foreach ($params as $key => $val) { $params_str .= ' '.$key . '="'.$val.'"'; } $run_line = $gw_params['request_binary'].' '.$params_str; // $run_line = escapeshellcmd($run_line); // echo $run_line; exec ($run_line, $rets); $ret = $rets[0]; $ret = preg_replace('/^(.*)!!/is', '', $ret); $ret = rtrim($ret, '!'); return '</form>'.$ret.'<form>'; } function NeedPlaceButton($item_data, $tag_params, $gw_params) { return false; } function processNotification($gw_params) { $params['pathfile'] = $gw_params['pathfile']; $params['message'] = $_POST['DATA']; $params_str = ''; foreach ($params as $key => $val) { $params_str .= ' '.$key . '="'.$val.'"'; } $run_line = $gw_params['response_binary'].' '.$params_str; exec ($run_line, $rets); $ret = $rets[0]; $result = $this->parseGWResponce($ret); list ($sid, $auth_code) = explode(',', $result['caddie']); $session =& $this->Application->recallObject('Session'); $session->SID = $sid; $order_id = $this->Conn->GetOne('SELECT OrderId FROM '.TABLE_PREFIX.'Orders WHERE md5(OrderId) = '.$this->Conn->qstr($auth_code)); $this->Application->SetVar('ord_id', $order_id); $order =& $this->Application->recallObject('ord'); $order->Load($order_id); return $result['response_code'] === '00' ? 1 : 0; } function parseGWResponce($str) { $response = explode ("!", $str); $result = Array ( 'code' => $response[1], 'error' => $response[2], 'merchant_id' => $response[3], 'merchant_country' => $response[4], 'amount' => $response[5], 'transaction_id' => $response[6], 'payment_means' => $response[7], 'transmission_date' => $response[8], 'payment_time' => $response[9], 'payment_date' => $response[10], 'response_code' => $response[11], 'payment_certificate' => $response[12], 'authorisation_id' => $response[13], 'currency_code' => $response[14], 'card_number' => $response[15], 'cvv_flag' => $response[16], 'cvv_response_code' => $response[17], 'bank_response_code' => $response[18], 'complementary_code' => $response[19], 'complementary_info' => $response[20], 'return_context' => $response[21], 'caddie' => $response[22], 'receipt_complement' => $response[23], 'merchant_language' => $response[24], 'language' => $response[25], 'customer_id' => $response[26], 'order_id' => $response[27], 'customer_email' => $response[28], 'customer_ip_address' => $response[29], 'capture_day' => $response[30], 'capture_mode' => $response[31], 'data' => $response[32], ); $this->parsed_responce = $result; return $result; } function getGWResponce() { return serialize($this->parsed_responce); } function getErrorMsg() { $msg = $this->parsed_responce['error']; if (!$msg) { if ($this->parsed_responce['response_code'] != '00') { $msg = 'Transaction failed'; } } return $msg; } } \ No newline at end of file Index: branches/5.1.x/units/gateways/gw_classes/google_checkout.php =================================================================== --- branches/5.1.x/units/gateways/gw_classes/google_checkout.php (revision 13703) +++ branches/5.1.x/units/gateways/gw_classes/google_checkout.php (revision 13704) @@ -1,931 +1,931 @@ <?php /** * @version $Id$ * @package In-Commerce * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license Commercial License * This software is protected by copyright law and international treaties. * Unauthorized reproduction or unlicensed usage of the code of this program, * or any portion of it may result in severe civil and criminal penalties, * and will be prosecuted to the maximum extent possible under the law * See http://www.in-portal.org/commercial-license for copyright notices and details. */ require_once GW_CLASS_PATH.'/gw_base.php'; $class_name = 'kGWGoogleCheckout'; // for automatic installation class kGWGoogleCheckout extends kGWBase { var $gwParams = Array (); function InstallData() { $data = array( 'Gateway' => Array('Name' => 'Google Checkout', 'ClassName' => 'kGWGoogleCheckout', 'ClassFile' => 'google_checkout.php', 'RequireCCFields' => 0), 'ConfigFields' => Array( 'submit_url' => Array('Name' => 'Submit URL', 'Type' => 'text', 'ValueList' => '', 'Default' => 'https://checkout.google.com/api/checkout/v2'), 'merchant_id' => Array('Name' => 'Google merchant ID', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), 'merchant_key' => Array('Name' => 'Google merchant key', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), 'shipping_control' => Array('Name' => 'Shipping Control', 'Type' => 'select', 'ValueList' => '3=la_CreditDirect,4=la_CreditPreAuthorize', 'Default' => 3), ) ); return $data; } /** * Returns payment form submit url * * @param Array $gw_params gateway params from payment type config * @return string */ function getFormAction($gw_params) { return $gw_params['submit_url'].'/checkout/Merchant/'.$gw_params['merchant_id']; } /** * Processed input data and convets it to fields understandable by gateway * * @param Array $item_data current order fields * @param Array $tag_params additional params for gateway passed through tag * @param Array $gw_params gateway params from payment type config * @return Array */ function getHiddenFields($item_data, $tag_params, $gw_params) { $ret = Array(); $this->gwParams = $gw_params; $cart_xml = $this->getCartXML($item_data); $ret['cart'] = base64_encode($cart_xml); $ret['signature'] = base64_encode( $this->CalcHmacSha1($cart_xml, $gw_params) ); return $ret; } function getCartXML($cart_fields) { // 1. prepare shopping cart content $sql = 'SELECT * FROM '.TABLE_PREFIX.'OrderItems oi LEFT JOIN '.TABLE_PREFIX.'Products p ON p.ProductId = oi.ProductId WHERE oi.OrderId = '.$cart_fields['OrderId']; $order_items = $this->Conn->Query($sql); $ml_formatter =& $this->Application->recallObject('kMultiLanguage'); /* @var $ml_formatter kMultiLanguage */ $cart_xml = Array (); foreach ($order_items as $order_item) { $cart_xml[] = ' <item> <item-name>'.htmlspecialchars($order_item['ProductName']).'</item-name> <item-description>'.htmlspecialchars($order_item[$ml_formatter->LangFieldName('DescriptionExcerpt')]).'</item-description>'. $this->getPriceXML('unit-price', $order_item['Price']).' <quantity>'.$order_item['Quantity'].'</quantity> </item>'; } $cart_xml = '<items>'.implode("\n", $cart_xml).'</items>'; // 2. add order identification info (for google checkout notification) $cart_xml .= ' <merchant-private-data> <session_id>'.$this->Application->GetSID().'</session_id> <order_id>'.$cart_fields['OrderId'].'</order_id> </merchant-private-data>'; // 3. add all shipping types (with no costs) $sql = 'SELECT Name FROM '.TABLE_PREFIX.'ShippingType WHERE Status = '.STATUS_ACTIVE; $shipping_types = $this->Conn->GetCol($sql); $shipping_xml = ''; foreach ($shipping_types as $shipping_name) { $shipping_xml .= ' <merchant-calculated-shipping name="'.htmlspecialchars($shipping_name).'"> <price currency="USD">0.00</price> </merchant-calculated-shipping>'; } $use_ssl = substr($this->gwParams['submit_url'], 0, 8) == 'https://' ? true : null; - $shipping_url = $this->Application->BaseURL('/in-commerce/units/gateways/gw_classes/notify_scripts', $use_ssl).'google_checkout_shippings.php'; + $shipping_url = $this->getNotificationUrl('units/gateways/gw_classes/notify_scripts/google_checkout_shippings.php', $use_ssl); $shipping_xml = '<merchant-checkout-flow-support> <shipping-methods>'.$shipping_xml.'</shipping-methods> <merchant-calculations> <merchant-calculations-url>'.$shipping_url.'</merchant-calculations-url> </merchant-calculations> </merchant-checkout-flow-support>'; $xml = '<checkout-shopping-cart xmlns="http://checkout.google.com/schema/2"> <shopping-cart>'.$cart_xml.'</shopping-cart> <checkout-flow-support>'.$shipping_xml.'</checkout-flow-support> </checkout-shopping-cart>'; return $xml; } /** * Returns price formatted as xml tag * * @param string $tag_name * @param float $price * @return string */ function getPriceXML($tag_name, $price) { $currency = $this->Application->RecallVar('curr_iso'); return '<'.$tag_name.' currency="'.$currency.'">'.sprintf('%.2f', $price).'</'.$tag_name.'>'; } /** * Calculates the cart's hmac-sha1 signature, this allows google to verify * that the cart hasn't been tampered by a third-party. * * {@link http://code.google.com/apis/checkout/developer/index.html#create_signature} * * @param string $data the cart's xml * @return string the cart's signature (in binary format) */ function CalcHmacSha1($data, $gw_params) { $key = $gw_params['merchant_key']; $blocksize = 64; $hashfunc = 'sha1'; if (mb_strlen($key) > $blocksize) { $key = pack('H*', $hashfunc($key)); } $key = str_pad($key, $blocksize, chr(0x00)); $ipad = str_repeat(chr(0x36), $blocksize); $opad = str_repeat(chr(0x5c), $blocksize); $hmac = pack( 'H*', $hashfunc( ($key^$opad).pack( 'H*', $hashfunc( ($key^$ipad).$data ) ) ) ); return $hmac; } /** * Returns XML request, that GoogleCheckout posts to notification / shipping calculation scripts * * @return string */ function getRequestXML() { $xml_data = $GLOBALS['HTTP_RAW_POST_DATA']; if ($this->Application->isDebugMode()) { $fp = fopen(FULL_PATH.'/xml_request.html', 'a'); fwrite($fp, '--- '.adodb_date('Y-m-d H:i:s').' ---'."\n".$xml_data); fclose($fp); } return $xml_data; // for debugging /*return '<order-state-change-notification xmlns="http://checkout.google.com/schema/2" serial-number="c821426e-7caa-4d51-9b2e-48ef7ecd6423"> <google-order-number>434532759516557</google-order-number> <new-financial-order-state>CHARGEABLE</new-financial-order-state> <new-fulfillment-order-state>NEW</new-fulfillment-order-state> <previous-financial-order-state>REVIEWING</previous-financial-order-state> <previous-fulfillment-order-state>NEW</previous-fulfillment-order-state> <timestamp>2007-03-19T15:06:29.051Z</timestamp> </order-state-change-notification>';*/ } /** * Processes notifications from google checkout * * @param Array $gw_params * @return int */ function processNotification($gw_params) { // parse xml & get order_id from there, like sella pay $this->gwParams = $gw_params; $xml_helper =& $this->Application->recallObject('kXMLHelper'); /* @var $xml_helper kXMLHelper */ $root_node =& $xml_helper->Parse( $this->getRequestXML() ); /* @var $root_node kXMLNode */ $this->Application->XMLHeader(); define('DBG_SKIP_REPORTING', 1); $order_approvable = false; switch ($root_node->Name) { case 'MERCHANT-CALCULATION-CALLBACK': $xml_responce = $this->getShippingXML($root_node); break; case 'NEW-ORDER-NOTIFICATION': case 'RISK-INFORMATION-NOTIFICATION': case 'ORDER-STATE-CHANGE-NOTIFICATION': // http://code.google.com/apis/checkout/developer/Google_Checkout_XML_API_Notification_API.html#new_order_notifications list ($order_approvable, $xml_responce) = $this->getNotificationResponceXML($root_node); break; } echo $xml_responce; if ($this->Application->isDebugMode()) { $fp = fopen(FULL_PATH.'/xml_responce.html', 'a'); fwrite($fp, '--- '.adodb_date('Y-m-d H:i:s').' ---'."\n".$xml_responce."\n"); fclose($fp); } return $order_approvable ? 1 : 0; } /** * Processes notification * * @param kXMLNode $root_node */ function getNotificationResponceXML(&$root_node) { // we can get notification type by "$root_node->Name" $order_approvable = false; switch ($root_node->Name) { case 'NEW-ORDER-NOTIFICATION': $order_approvable = $this->processNewOrderNotification($root_node); break; case 'RISK-INFORMATION-NOTIFICATION': $order_approvable = $this->processRiskInformationNotification($root_node); break; case 'ORDER-STATE-CHANGE-NOTIFICATION': $order_approvable = $this->processOrderStateChangeNotification($root_node); break; } // !!! globally set order id, so gw_responce.php will not fail in setting TransactionStatus // 1. receive new order notification // put address & payment type in our order using id found in merchant-private-data (Make order status: Incomplete) // 2. receive risk information // don't know what to do, just mark order some how (Make order status: Incomplete) // 3. receive status change notification to CHARGEABLE (Make order status: Pending) // only mark order status // 4. admin approves order // make api call, that changes order state (fulfillment-order-state) to PROCESSING or DELIVERED (see manual) // 5. admin declines order // make api call, that changes order state (fulfillment-order-state) to WILL_NOT_DELIVER // Before you ship the items in an order, you should ensure that you have already received the new order notification for the order, // the risk information notification for the order and an order state change notification informing you that the order's financial // state has been updated to CHARGEABLE return Array ($order_approvable, '<notification-acknowledgment xmlns="http://checkout.google.com/schema/2" serial-number="'.$root_node->Attributes['SERIAL-NUMBER'].'" />'); } /** * Returns shipping calculations and places part of shipping address into order (1st step) * * http://code.google.com/apis/checkout/developer/Google_Checkout_XML_API_Merchant_Calculations_API.html#Returning_Merchant_Calculation_Results * * @param kXMLNode $node * @return string */ function getShippingXML(&$root_node) { // 1. extract data from xml $search_nodes = Array ( 'SHOPPING-CART:MERCHANT-PRIVATE-DATA', 'CALCULATE:ADDRESSES:ANONYMOUS-ADDRESS', 'CALCULATE:SHIPPING', ); foreach ($search_nodes as $search_string) { $found_node =& $root_node; /* @var $found_node kXMLNode */ $search_string = explode(':', $search_string); foreach ($search_string as $search_node) { $found_node =& $found_node->FindChild($search_node); } $node_data = Array (); $sub_node =& $found_node->firstChild; /* @var $sub_node kXMLNode */ do { if ($found_node->Name == 'SHIPPING') { $node_data[] = $sub_node->Attributes['NAME']; } else { $node_data[$sub_node->Name] = $sub_node->Data; } } while ( ($sub_node =& $sub_node->NextSibling()) ); switch ($found_node->Name) { case 'MERCHANT-PRIVATE-DATA': $order_id = $node_data['ORDER_ID']; $session_id = $node_data['SESSION_ID']; break; case 'ANONYMOUS-ADDRESS': $address_info = $node_data; $address_id = $found_node->Attributes['ID']; break; case 'SHIPPING': $process_shippings = $node_data; break; } } // 2. update shipping address in order $order =& $this->Application->recallObject('ord', null, Array ('skip_autoload' => true)); /* @var $order OrdersItem */ $order->Load($order_id); $shipping_address = Array ( 'ShippingCity' => $address_info['CITY'], 'ShippingState' => $address_info['REGION'], 'ShippingZip' => $address_info['POSTAL-CODE'], ); $cs_helper =& $this->Application->recallObject('CountryStatesHelper'); /* @var $cs_helper kCountryStatesHelper */ $shipping_address['ShippingCountry'] = $cs_helper->getCountryIso($address_info['COUNTRY-CODE'], true); $order->SetDBFieldsFromHash($shipping_address); $order->Update(); // 3. get shipping rates based on given address $shipping_types_xml = ''; $shipping_types = $this->getOrderShippings($order); // add available shipping types foreach ($shipping_types as $shipping_type) { $shipping_name = $shipping_type['ShippingName']; $processable_shipping_index = array_search($shipping_name, $process_shippings); if ($processable_shipping_index !== false) { $shipping_types_xml .= '<result shipping-name="'.htmlspecialchars($shipping_name).'" address-id="'.$address_id.'"> <shipping-rate currency="USD">'.sprintf('%01.2f', $shipping_type['TotalCost']).'</shipping-rate> <shippable>true</shippable> </result>'; // remove available shipping type from processable list unset($process_shippings[$processable_shipping_index]); } } // add unavailable shipping types foreach ($process_shippings as $shipping_name) { $shipping_types_xml .= '<result shipping-name="'.htmlspecialchars($shipping_name).'" address-id="'.$address_id.'"> <shipping-rate currency="USD">0.00</shipping-rate> <shippable>false</shippable> </result>'; } $shipping_types_xml = '<?xml version="1.0" encoding="UTF-8"?> <merchant-calculation-results xmlns="http://checkout.google.com/schema/2"> <results>'.$shipping_types_xml.'</results> </merchant-calculation-results>'; return $shipping_types_xml; } /** * Places all information from google checkout into order (2nd step) * * @param kXMLNode $root_node */ function processNewOrderNotification(&$root_node) { // 1. extract data from xml $search_nodes = Array ( 'SHOPPING-CART:MERCHANT-PRIVATE-DATA', 'ORDER-ADJUSTMENT:SHIPPING:MERCHANT-CALCULATED-SHIPPING-ADJUSTMENT', 'BUYER-ID', 'GOOGLE-ORDER-NUMBER', 'BUYER-SHIPPING-ADDRESS', 'BUYER-BILLING-ADDRESS', ); $user_address = Array (); foreach ($search_nodes as $search_string) { $found_node =& $root_node; /* @var $found_node kXMLNode */ $search_string = explode(':', $search_string); foreach ($search_string as $search_node) { $found_node =& $found_node->FindChild($search_node); } $node_data = Array (); if ($found_node->Children) { $sub_node =& $found_node->firstChild; /* @var $sub_node kXMLNode */ do { $node_data[$sub_node->Name] = $sub_node->Data; } while ( ($sub_node =& $sub_node->NextSibling()) ); } switch ($found_node->Name) { case 'MERCHANT-PRIVATE-DATA': $order_id = $node_data['ORDER_ID']; $session_id = $node_data['SESSION_ID']; break; case 'MERCHANT-CALCULATED-SHIPPING-ADJUSTMENT': $shpipping_info = $node_data; break; case 'BUYER-ID': $buyer_id = $found_node->Data; break; case 'GOOGLE-ORDER-NUMBER': $google_order_number = $found_node->Data; break; case 'BUYER-SHIPPING-ADDRESS': $user_address['Shipping'] = $node_data; break; case 'BUYER-BILLING-ADDRESS': $user_address['Billing'] = $node_data; break; } } // 2. update shipping address in order $order =& $this->Application->recallObject('ord', null, Array ('skip_autoload' => true)); /* @var $order OrdersItem */ $order->Load($order_id); if (!$order->isLoaded()) { return false; } // 2.1. this is 100% notification from google -> mark order with such payment type $order->SetDBField('PaymentType', $this->Application->GetVar('payment_type_id')); $this->parsed_responce = Array ( 'GOOGLE-ORDER-NUMBER' => $google_order_number, 'BUYER-ID' => $buyer_id ); // 2.2. save google checkout order information (maybe needed for future notification processing) $order->SetDBField('GWResult1', serialize($this->parsed_responce)); $order->SetDBField('GoogleOrderNumber', $google_order_number); // 2.3. set user-selected shipping type $shipping_types = $this->getOrderShippings($order); foreach ($shipping_types as $shipping_type) { if ($shipping_type['ShippingName'] == $shpipping_info['SHIPPING-NAME']) { $order->SetDBField('ShippingInfo', serialize(Array (1 => $shipping_type))); // minimal package number is 1 $order->SetDBField('ShippingCost', $shipping_type['TotalCost']); // set total shipping cost break; } } // 2.4. set full shipping & billing address $address_mapping = Array ( 'CONTACT-NAME' => 'To', 'COMPANY-NAME' => 'Company', 'EMAIL' => 'Email', 'PHONE' => 'Phone', 'FAX' => 'Fax', 'ADDRESS1' => 'Address1', 'ADDRESS2' => 'Address2', 'CITY' => 'City', 'REGION' => 'State', 'POSTAL-CODE' => 'Zip', ); $cs_helper =& $this->Application->recallObject('CountryStatesHelper'); /* @var $cs_helper kCountryStatesHelper */ foreach ($user_address as $field_prefix => $address_details) { foreach ($address_mapping as $src_field => $dst_field) { $order->SetDBField($field_prefix.$dst_field, $address_details[$src_field]); } if (!$order->GetDBField($field_prefix.'Phone')) { $order->SetDBField($field_prefix.'Phone', '-'); // required field } $order->SetDBField( $field_prefix.'Country', $cs_helper->getCountryIso($address_details['COUNTRY-CODE'], true) ); } $order->SetDBField('OnHold', 1); $order->SetDBField('Status', ORDER_STATUS_PENDING); $order->Update(); // unlink order, that GoogleCheckout used from shopping cart on site $sql = 'DELETE FROM '.TABLE_PREFIX.'SessionData WHERE VariableName = "ord_id" AND VariableValue = '.$order->GetID(); $this->Conn->Query($sql); // simulate visiting shipping screen $sql = 'UPDATE '.TABLE_PREFIX.'OrderItems SET PackageNum = 1 WHERE OrderId = '.$order->GetID(); $this->Conn->Query($sql); return false; } /** * Saves risk information in order record (3rd step) * * @param kXMLNode $root_node */ function processRiskInformationNotification(&$root_node) { // 1. extract data from xml $search_nodes = Array ( 'GOOGLE-ORDER-NUMBER', 'RISK-INFORMATION', ); foreach ($search_nodes as $search_string) { $found_node =& $root_node; /* @var $found_node kXMLNode */ $search_string = explode(':', $search_string); foreach ($search_string as $search_node) { $found_node =& $found_node->FindChild($search_node); } $node_data = Array (); if ($found_node->Children) { $sub_node =& $found_node->firstChild; /* @var $sub_node kXMLNode */ do { $node_data[$sub_node->Name] = $sub_node->Data; } while ( ($sub_node =& $sub_node->NextSibling()) ); } switch ($found_node->Name) { case 'GOOGLE-ORDER-NUMBER': $google_order_number = $found_node->Data; break; case 'RISK-INFORMATION': $risk_information = $node_data; unset( $risk_information['BILLING-ADDRESS'] ); break; } } // 2. update shipping address in order $order =& $this->Application->recallObject('ord', null, Array ('skip_autoload' => true)); /* @var $order OrdersItem */ $order->Load($google_order_number, 'GoogleOrderNumber'); if (!$order->isLoaded()) { return false; } // 2.1. save risk information in order $this->parsed_responce = unserialize($order->GetDBField('GWResult1')); $this->parsed_responce = array_merge_recursive($this->parsed_responce, $risk_information); $order->SetDBField('GWResult1', serialize($this->parsed_responce)); $order->Update(); return false; } /** * Perform PREAUTH/SALE type transaction direct from php script wihtout redirecting to 3rd-party website * * @param Array $item_data * @param Array $gw_params * @return bool */ function DirectPayment($item_data, $gw_params) { $this->gwParams = $gw_params; if ($gw_params['shipping_control'] == SHIPPING_CONTROL_PREAUTH) { // when shipping control is Pre-Authorize -> do nothing and charge when admin approves order return true; } $this->_chargeOrder($item_data); return false; } /** * Issue charge-order api call * * @param Array $item_data * @return bool */ function _chargeOrder($item_data) { $charge_xml = ' <charge-order xmlns="http://checkout.google.com/schema/2" google-order-number="'.$item_data['GoogleOrderNumber'].'"> <amount currency="USD">'.sprintf('%.2f', $item_data['TotalAmount']).'</amount> </charge-order>'; $root_node =& $this->executeAPICommand($charge_xml); $this->parsed_responce = unserialize($item_data['GWResult1']); if ($root_node->Name == 'REQUEST-RECEIVED') { $this->parsed_responce['FINANCIAL-ORDER-STATE'] = 'CHARGING'; return true; } return false; } /** * Perform SALE type transaction direct from php script wihtout redirecting to 3rd-party website * * @param Array $item_data * @param Array $gw_params * @return bool */ function Charge($item_data, $gw_params) { $this->gwParams = $gw_params; if ($gw_params['shipping_control'] == SHIPPING_CONTROL_DIRECT) { // when shipping control is Direct Payment -> do nothing and auto-charge on notification received return true; } $this->_chargeOrder($item_data); $order =& $this->Application->recallObject('ord.-item', null, Array ('skip_autoload' => true)); /* @var $order OrdersItem */ $order->Load($item_data['OrderId']); if (!$order->isLoaded()) { return false; } $order->SetDBField('OnHold', 1); $order->Update(); return false; } /** * Executes API command for order and returns result * * @param string $command_xml * @return kXMLNode */ function &executeAPICommand($command_xml) { $submit_url = $this->gwParams['submit_url'].'/request/Merchant/'.$this->gwParams['merchant_id']; $curl_helper =& $this->Application->recallObject('CurlHelper'); /* @var $curl_helper kCurlHelper */ $xml_helper =& $this->Application->recallObject('kXMLHelper'); /* @var $xml_helper kXMLHelper */ $curl_helper->SetPostData($command_xml); $auth_options = Array ( CURLOPT_USERPWD => $this->gwParams['merchant_id'].':'.$this->gwParams['merchant_key'], ); $curl_helper->setOptions($auth_options); $xml_responce = $curl_helper->Send($submit_url); $root_node =& $xml_helper->Parse($xml_responce); /* @var $root_node kXMLNode */ return $root_node; } /** * Marks order as pending, when it's google status becomes CHARGEABLE (4th step) * * @param kXMLNode $root_node */ function processOrderStateChangeNotification(&$root_node) { // 1. extract data from xml $search_nodes = Array ( 'GOOGLE-ORDER-NUMBER', 'NEW-FINANCIAL-ORDER-STATE', 'PREVIOUS-FINANCIAL-ORDER-STATE', ); $order_state = Array (); foreach ($search_nodes as $search_string) { $found_node =& $root_node; /* @var $found_node kXMLNode */ $search_string = explode(':', $search_string); foreach ($search_string as $search_node) { $found_node =& $found_node->FindChild($search_node); } switch ($found_node->Name) { case 'GOOGLE-ORDER-NUMBER': $google_order_number = $found_node->Data; break; case 'NEW-FINANCIAL-ORDER-STATE': $order_state['new'] = $found_node->Data; break; case 'PREVIOUS-FINANCIAL-ORDER-STATE': $order_state['old'] = $found_node->Data; break; } } // 2. update shipping address in order $order =& $this->Application->recallObject('ord', null, Array ('skip_autoload' => true)); /* @var $order OrdersItem */ $order->Load($google_order_number, 'GoogleOrderNumber'); if (!$order->isLoaded()) { return false; } $state_changed = ($order_state['old'] != $order_state['new']); if ($state_changed) { $order_charged = ($order_state['new'] == 'CHARGED') && ($order->GetDBField('Status') == ORDER_STATUS_PENDING); $this->parsed_responce = unserialize($order->GetDBField('GWResult1')); $this->parsed_responce['FINANCIAL-ORDER-STATE'] = $order_state['new']; $order->SetDBField('GWResult1', serialize($this->parsed_responce)); if ($order_charged) { // when using Pre-Authorize $order->SetDBField('OnHold', 0); } $order->Update(); if ($order_charged) { // when using Pre-Authorize $order_eh =& $this->Application->recallObject('ord_EventHandler'); /* @var $order_eh OrdersEventHandler */ $order_eh->SplitOrder( new kEvent('ord:OnMassOrderApprove'), $order); } } // update order record in "google_checkout_notify.php" only when such state change happens $order_chargeable = ($order_state['new'] == 'CHARGEABLE') && $state_changed; if ($order_chargeable) { if ($this->gwParams['shipping_control'] == SHIPPING_CONTROL_PREAUTH) { $order->SetDBField('OnHold', 0); $order->Update(); } $process_xml = '<process-order xmlns="http://checkout.google.com/schema/2" google-order-number="'.$order->GetDBField('GoogleOrderNumber').'"/>'; $root_node =& $this->executeAPICommand($process_xml); } return $order_chargeable; } /** * Retrieves shipping types available for given order * * @param OrdersItem $order * @return Array */ function getOrderShippings(&$order) { $weight_sql = 'IF(oi.Weight IS NULL, 0, oi.Weight * oi.Quantity)'; $query = ' SELECT SUM(oi.Quantity) AS TotalItems, SUM('.$weight_sql.') AS TotalWeight, SUM(oi.Price * oi.Quantity) AS TotalAmount, SUM(oi.Quantity) - SUM(IF(p.MinQtyFreePromoShipping > 0 AND p.MinQtyFreePromoShipping <= oi.Quantity, oi.Quantity, 0)) AS TotalItemsPromo, SUM('.$weight_sql.') - SUM(IF(p.MinQtyFreePromoShipping > 0 AND p.MinQtyFreePromoShipping <= oi.Quantity, '.$weight_sql.', 0)) AS TotalWeightPromo, SUM(oi.Price * oi.Quantity) - SUM(IF(p.MinQtyFreePromoShipping > 0 AND p.MinQtyFreePromoShipping <= oi.Quantity, oi.Price * oi.Quantity, 0)) AS TotalAmountPromo FROM '.TABLE_PREFIX.'OrderItems oi LEFT JOIN '.TABLE_PREFIX.'Products p ON oi.ProductId = p.ProductId WHERE oi.OrderId = '.$order->GetID().' AND p.Type = 1'; $shipping_totals = $this->Conn->GetRow($query); $this->Application->recallObject('ShippingQuoteEngine'); $quote_engine_collector =& $this->Application->recallObject('ShippingQuoteCollector'); /* @var $quote_engine_collector ShippingQuoteCollector */ $shipping_quote_params = Array( 'dest_country' => $order->GetDBField('ShippingCountry'), 'dest_state' => $order->GetDBField('ShippingState'), 'dest_postal' => $order->GetDBField('ShippingZip'), 'dest_city' => $order->GetDBField('ShippingCity'), 'dest_addr1' => '', 'dest_addr2' => '', 'dest_name' => 'user-' . $order->GetDBField('PortalUserId'), 'packages' => Array( Array( 'package_key' => 'package1', 'weight' => $shipping_totals['TotalWeight'], 'weight_unit' => 'KG', 'length' => '', 'width' => '', 'height' => '', 'dim_unit' => 'IN', 'packaging' => 'BOX', 'contents' => 'OTR', 'insurance' => '0' ), ), 'amount' => $shipping_totals['TotalAmount'], 'items' => $shipping_totals['TotalItems'], 'limit_types' => serialize(Array ('ANY')), 'promo_params' => Array ( 'items' => $shipping_totals['TotalItemsPromo'], 'amount' => $shipping_totals['TotalAmountPromo'], 'weight' => $shipping_totals['TotalWeightPromo'], ), ); return $quote_engine_collector->GetShippingQuotes($shipping_quote_params); } /** * Returns gateway responce from last operation * * @return string */ function getGWResponce() { return serialize($this->parsed_responce); } /** * Informs payment gateway, that order has been shipped * * http://code.google.com/apis/checkout/developer/Google_Checkout_XML_API_Order_Level_Shipping.html#Deliver_Order * * @param Array $item_data * @param Array $gw_params * @return bool */ function OrderShipped($item_data, $gw_params) { $this->gwParams = $gw_params; $shipping_info = unserialize($item_data['ShippingInfo']); if (getArrayValue($shipping_info, 'Code')) { $traking_carrier = '<carrier>'.$item_data['Code'].'</carrier>'; } if ($item_data['ShippingTracking']) { $tracking_data = '<tracking-data>'.$traking_carrier.' <tracking-number>'.$item_data['ShippingTracking'].'</tracking-number> </tracking-data>'; } $ship_xml = ' <deliver-order xmlns="http://checkout.google.com/schema/2" google-order-number="'.$item_data['GoogleOrderNumber'].'"> '.$traking_data.' <send-email>true</send-email> </deliver-order>'; $root_node =& $this->executeAPICommand($ship_xml); } /** * Informs payment gateway, that order has been declined * * @param Array $item_data * @param Array $gw_params * @return bool */ function OrderDeclined($item_data, $gw_params) { } } \ No newline at end of file Index: branches/5.1.x/units/gateways/gw_classes/worldpay.php =================================================================== --- branches/5.1.x/units/gateways/gw_classes/worldpay.php (revision 13703) +++ branches/5.1.x/units/gateways/gw_classes/worldpay.php (revision 13704) @@ -1,112 +1,112 @@ <?php /** * @version $Id$ * @package In-Commerce * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license Commercial License * This software is protected by copyright law and international treaties. * Unauthorized reproduction or unlicensed usage of the code of this program, * or any portion of it may result in severe civil and criminal penalties, * and will be prosecuted to the maximum extent possible under the law * See http://www.in-portal.org/commercial-license for copyright notices and details. */ require_once GW_CLASS_PATH.'/gw_base.php'; $class_name = 'kGWWorldPay'; // for automatic installation class kGWWorldPay extends kGWBase { function InstallData() { $data = array( 'Gateway' => Array('Name' => 'Worldpay', 'ClassName' => 'kGWWorldPay', 'ClassFile' => 'worldpay.php', 'RequireCCFields' => 0), 'ConfigFields' => Array( 'submit_url' => Array('Name' => 'Submit URL', 'Type' => 'text', 'ValueList' => '', 'Default' => 'https://select.worldpay.com/wcc/purchase'), 'instId' => Array('Name' => 'Installation ID', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), 'callback_pw' => Array('Name' => 'Callback Password', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), ) ); return $data; } /** * Returns payment form submit url * * @param Array $gw_params gateway params from payment type config * @return string */ function getFormAction($gw_params) { return $gw_params['submit_url']; } /** * Processed input data and convets it to fields understandable by gateway * * @param Array $item_data * @param Array $tag_params additional params for gateway passed through tag * @param Array $gw_params gateway params from payment type config * @return Array */ function getHiddenFields($item_data, $tag_params, $gw_params) { $ret = Array(); $ret['instId'] = $gw_params['instId']; $ret['cartId'] = $item_data['OrderNumber']; if (!$this->IsTestMode()) { $ret['amount'] = sprintf('%.2f', $item_data['TotalAmount']); // the total amount to be billed, in decimal form, without a currency symbol. (8 characters, decimal, 2 characters: Example: 99999999.99) } else { $ret['testMode'] = 100; // 100 - success, 101 - failure $ret['amount'] = 1; } $ret['currency'] = 'USD'; $ret['desc'] = 'Order #'.$item_data['OrderNumber']; $ret['name'] = $item_data['BillingTo']; $ret['address'] = $item_data['BillingAddress1']; if ($item_data['BillingAddress2']) { $ret['address'] .= ' '.$item_data['BillingAddress2']; } $ret['postcode'] = $item_data['BillingZip']; $cs_helper =& $this->Application->recallObject('CountryStatesHelper'); /* @var $cs_helper kCountryStatesHelper */ $ret['country'] = $cs_helper->getCountryIso( $item_data['BillingCountry'] ); $ret['tel'] = $item_data['BillingPhone']; $ret['fax'] = $item_data['BillingFax']; $ret['email'] = $item_data['BillingEmail']; $ret['fixContact'] = 1; // contact-info not editable ? $return_params = Array ('pass' => 'm', 'sid' => $this->Application->GetSID(), 'admin' => 1); $ret['MC_return_page'] = $this->Application->HREF($tag_params['return_template'], '', $return_params); $ret['MC_cancel_return_page'] = $this->Application->HREF($tag_params['cancel_template'], '', $return_params); + $ret['MC_callback'] = $this->getNotificationUrl() . '?sid='.$this->Application->GetSID().'&admin=1&order_id='.$item_data['OrderId']; - $ret['MC_callback'] = $this->Application->BaseURL('/in-commerce').'gw_notify.php?sid='.$this->Application->GetSID().'&admin=1&order_id='.$item_data['OrderId']; return $ret; } function processNotification($gw_params) { // http://support.worldpay.com/kb/integration_guides/junior/integration/help/appendicies/sjig_10100.html // SubmitURL: https://select.worldpay.com/wcc/purchase // for Notification to work do this in gateway Admin Console: // Callback URL: <WPDISPLAY ITEM=MC_callback> // Callback enabled? [x] // Use callback response?[x] $transaction_verified = ($this->Application->GetVar('callbackPW') == $gw_params['callback_pw']); if (!$transaction_verified) { return 0; } $transaction_status = $this->Application->GetVar('transStatus') == 'Y' ? 1 : 0; echo curl_post($this->Application->GetVar($transaction_status ? 'MC_return_page' : 'MC_cancel_return_page'), '', null, 'GET'); return $transaction_status; } } \ No newline at end of file Index: branches/5.1.x/units/gateways/gw_classes/paypal.php =================================================================== --- branches/5.1.x/units/gateways/gw_classes/paypal.php (revision 13703) +++ branches/5.1.x/units/gateways/gw_classes/paypal.php (revision 13704) @@ -1,260 +1,261 @@ <?php /** * @version $Id$ * @package In-Commerce * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license Commercial License * This software is protected by copyright law and international treaties. * Unauthorized reproduction or unlicensed usage of the code of this program, * or any portion of it may result in severe civil and criminal penalties, * and will be prosecuted to the maximum extent possible under the law * See http://www.in-portal.org/commercial-license for copyright notices and details. */ require_once GW_CLASS_PATH.'/gw_base.php'; class kGWPayPal extends kGWBase { /** * Returns payment form submit url * * @param Array $gw_params gateway params from payment type config * @return string */ function getFormAction($gw_params) { return $gw_params['submit_url']; } /** * Processed input data and convets it to fields understandable by gateway * * @param Array $item_data * @param Array $tag_params additional params for gateway passed through tag * @param Array $gw_params gateway params from payment type config * @return Array */ function getHiddenFields($item_data, $tag_params, $gw_params) { $ret = Array(); $ret['item_name'] = 'Order #'.$item_data['OrderNumber']; $ret['item_number'] = 'order:'.$item_data['OrderNumber']; $selected_cur = $this->Application->RecallVar('curr_iso'); $available = explode(',', $gw_params['currency_code']); $target = in_array($selected_cur, $available) ? $selected_cur : $available[0]; if( !$this->IsTestMode() ) { $currency_iso = $gw_params['currency_code']; $ret['amount'] = $this->ConvertCurrency($item_data['SubTotal'], $target); $ret['shipping'] = $this->ConvertCurrency($item_data['ShippingCost'], $target); $ret['tax'] = $this->ConvertCurrency($item_data['VAT'], $target); } else { $ret['amount'] = 1; $ret['shipping'] = 0; $ret['tax'] = 0; } $ret['quantity'] = 1; $ret['cancel_return'] = $this->Application->HREF($tag_params['cancel_template'],'',Array('pass'=>'m')); $ret['return'] = $this->Application->HREF($tag_params['return_template'],'',Array('pass'=>'m')); $ret['no_note'] = 1; // customer is not prompted for notes $ret['no_shipping'] = 1; // customer is not prompted for shipping address $ret['rm'] = 2; // return method - POST $ret['currency_code'] = $target; $ret['invoice'] = $item_data['OrderNumber']; $ret['business'] = $gw_params['business_account']; // prepopulated fields $ret['address_override'] = 1; // override user's stored address $ret['email'] = $item_data['BillingEmail']; list($first_name, $last_name) = explode(' ', $item_data['BillingTo']); $ret['first_name'] = $first_name; $ret['last_name'] = $last_name; $ret['address1'] = $item_data['BillingAddress1']; $ret['address2'] = $item_data['BillingAddress2']; $ret['city'] = $item_data['BillingCity']; $ret['state'] = $item_data['BillingState']; $ret['zip'] = $item_data['BillingZip']; $cs_helper =& $this->Application->recallObject('CountryStatesHelper'); /* @var $cs_helper kCountryStatesHelper */ $ret['country'] = $cs_helper->getCountryIso( $item_data['BillingCountry'] ); - $ret['notify_url'] = $this->Application->BaseURL('/in-commerce').'gw_notify.php?sid='.$this->Application->GetSID().'&admin=1&order_id='.$item_data['OrderId']; + $ret['notify_url'] = $this->getNotificationUrl() . '?sid=' . $this->Application->GetSID() . '&admin=1&order_id=' . $item_data['OrderId']; + $ret['cmd'] = '_xclick'; // act as "Buy Now" PayPal button return $ret; } function getSubscriptionFields($item_data, $tag_params, $gw_params) { $ret = Array(); $ret['item_name'] = $item_data['item_name']; $ret['item_number'] = $item_data['item_number']; $ret['a1'] = $item_data['a1']; $ret['p1'] = $item_data['p1']; $ret['t1'] = $item_data['t1']; $ret['a2'] = $item_data['a2']; $ret['p2'] = $item_data['p2']; $ret['t2'] = $item_data['t2']; $ret['p3'] = $item_data['p3']; $ret['t3'] = $item_data['t3']; $ret['src'] = $item_data['src']; $ret['sra'] = $item_data['sra']; $ret['srt'] = $item_data['srt']; $ret['custom'] = $item_data['OrderId']; $currency_iso = $gw_params['currency_code']; $ret['a3'] = $this->ConvertCurrency($item_data['a3'], $currency_iso);; $ret['tax'] = $this->ConvertCurrency($item_data['VAT'], $currency_iso); if( $this->Application->isDebugMode() ) { } else { } // $ret['quantity'] = 1; $ret['cancel_return'] = $this->Application->HREF($tag_params['cancel_template'],'',Array('pass'=>'m')); $ret['return'] = $this->Application->HREF($tag_params['return_template'],'',Array('pass'=>'m')); $ret['no_note'] = 1; // customer is not prompted for notes $ret['no_shipping'] = 1; // customer is not prompted for shipping address $ret['rm'] = 2; // return method - POST $ret['currency_code'] = $gw_params['currency_code']; $ret['invoice'] = $item_data['OrderNumber']; $ret['business'] = $gw_params['business_account']; // prepopulated fields $ret['address_override'] = 1; // override user's stored address $ret['email'] = $item_data['BillingEmail']; list($first_name, $last_name) = explode(' ', $item_data['BillingTo']); $ret['first_name'] = $first_name; $ret['last_name'] = $last_name; $ret['address1'] = $item_data['BillingAddress1']; $ret['address2'] = $item_data['BillingAddress2']; $ret['city'] = $item_data['BillingCity']; $ret['state'] = $item_data['BillingState']; $ret['zip'] = $item_data['BillingZip']; $cs_helper =& $this->Application->recallObject('CountryStatesHelper'); /* @var $cs_helper kCountryStatesHelper */ $ret['country'] = $cs_helper->getCountryIso( $item_data['BillingCountry'] ); - $ret['notify_url'] = $this->Application->BaseURL('/in-commerce').'gw_notify.php?sid='.$this->Application->GetSID().'&admin=1&order_id='.$item_data['OrderId'].'&payment_type_id='.$tag_params['payment_type_id']; + $ret['notify_url'] = $this->getNotificationUrl() . '?sid='.$this->Application->GetSID().'&admin=1&order_id='.$item_data['OrderId'].'&payment_type_id='.$tag_params['payment_type_id']; $ret['cmd'] = '_xclick-subscriptions'; // act as "Buy Now" PayPal button $real_ret = array(); foreach ($ret as $key => $val) { if ($val == '') continue; $real_ret[$key] = $val; } return $real_ret; } function processNotification($gw_params) { $payment_status = $_POST['payment_status']; // save payment_status for later proceeding $_POST['cmd'] = '_notify-validate'; // status, of that PayPal server really has sent such notification to us $status_map = Array('INVALID' => 0, 'VERIFIED' => 1); $n_status = curl_post($gw_params['submit_url'], $_POST); // INVALID, VERIFIED $n_status = $status_map[$n_status]; $success = ($n_status == 1) && ($payment_status == 'Completed') ? 1:0 ; // 1:0 is on purpose, false will result an SQL error ! if (!$success) return; $type = $_POST['txn_type']; switch ($type) { case 'subscr_signup': break; case 'subscr_cancel': break; case 'subscr_failed': break; case 'subscr_payment': $field_values = $this->Conn->GetRow('SELECT * FROM '.TABLE_PREFIX.'OrderItems WHERE OrderItemId = '.$_POST['item_number']); $this->Application->HandleEvent($an_event, 'p:OnSubscriptionApprove', array('field_values' => $field_values)); $success = 0; //this will eliminate OnCompleteOrder in gw_notify! $org_order = $this->Application->recallObject('ord.-original', 'ord', Array('skip_autoload' => true)); $org_order->Load($field_values['OrderId']); $order = $this->Application->recallObject('ord.-paypal', 'ord'); $order->SetDBFieldsFromHash($org_order->FieldValues); $order->SetDBField('SubTotal', $field_values['Price']); $order->SetDBField('OriginalAmout', $field_values['Price']); $order->SetDBField('OrderDate', adodb_mktime()); $order->UpdateFormattersSubFields(); $dup_item = false; if ($org_order->GetDBField('Status') >= ORDER_STATUS_PROCESSED) { $sql = 'SELECT MAX(SubNumber) FROM '.TABLE_PREFIX.'Orders WHERE Number = '.$org_order->GetDBField('Number'); $num = $this->Conn->GetOne($sql) + 1; $order->SetDBField('SubNumber', $num); $dup_item = true; } else { $sql = 'SELECT MAX(Number) FROM '.TABLE_PREFIX.'Orders'; $num = $this->Conn->GetOne($sql) + 1; $order->SetDBField('Number', $num); $order->SetDBField('SubNumber', 0); } $order->SetDBField('PaymentType', $this->Application->GetVar('payment_type_id')); $info = array( 'BillingTo' => $_POST['first_name'].' '.$_POST['last_name'], 'BillingCompany' => 'n/a (PayPal)', 'BillingPhone' => 'n/a (PayPal)', 'BillingFax' => '', 'BillingEmail' => $_POST['payer_email'], 'BillingAddress1' => 'n/a (PayPal)', 'BillingCity' => 'n/a (PayPal)', 'BillingState' => 'n/a (PayPal)', 'BillingZip' => 'n/a (PayPal)', 'BillingCountry' => '???', ); $order->SetFieldsFromHash($info); $order->SetDBField('Status', ORDER_STATUS_PROCESSED); $order->Create(); if ($dup_item) { $query = 'INSERT INTO '.TABLE_PREFIX.'OrderItems (OrderId, ProductId, ProductName, Quantity, QuantityReserved, FlatPrice, Price, BackOrderFlag, Weight, ShippingTypeId, ItemData, OptionsSalt) SELECT '.$order->GetId().' AS OrderId, ProductId, ProductName, Quantity, QuantityReserved, FlatPrice, Price, BackOrderFlag, Weight, ShippingTypeId, ItemData, OptionsSalt FROM '.TABLE_PREFIX.'OrderItems WHERE OrderItemId = '.$field_values['OrderItemId']; } else { $query = 'UPDATE '.TABLE_PREFIX.'OrderItems SET OrderId = %s WHERE OrderItemId = %s'; $query = sprintf($query, $order->GetId(), $field_values['OrderItemId']); } $this->Conn->Query($query); break; case 'subscr_eot': break; case 'subscr_modify': break; } return $success; } } \ No newline at end of file Index: branches/5.1.x/units/gateways/gw_classes/gw_base.php =================================================================== --- branches/5.1.x/units/gateways/gw_classes/gw_base.php (revision 13703) +++ branches/5.1.x/units/gateways/gw_classes/gw_base.php (revision 13704) @@ -1,261 +1,270 @@ <?php /** * @version $Id$ * @package In-Commerce * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license Commercial License * This software is protected by copyright law and international treaties. * Unauthorized reproduction or unlicensed usage of the code of this program, * or any portion of it may result in severe civil and criminal penalties, * and will be prosecuted to the maximum extent possible under the law * See http://www.in-portal.org/commercial-license for copyright notices and details. */ defined('FULL_PATH') or die('restricted access!'); class kGWBase extends kBase { /** * Connection to database * * @var kDBConnection */ var $Conn = null; /** * gateway received responce * * @var string */ var $gw_responce = ''; var $parsed_responce = Array(); function kGWBase() { parent::kBase(); $this->Conn =& $this->Application->GetADODBConnection(); } /** * Returns payment form submit url * * @return string */ function getFormAction($gw_params) { return $this->Application->ProcessParsedTag('m', 'FormAction', Array() ); } /** * Processed input data and convets it to fields understandable by gateway * * @param Array $item_data * @param Array $tag_params additional params for gateway passed through tag * @param Array $gw_params gateway params from payment type config * @return Array */ function getHiddenFields($item_data, $tag_params, $gw_params) { return Array( 'events[ord]' => 'OnCompleteOrder', 'success_template' => $tag_params['return_template'], 'failure_template' => $tag_params['cancel_template']); } function NeedPlaceButton($item_data, $tag_params, $gw_params) { return true; } /** * Process notification about payment from payment gateway * */ function processNotification() { } /** * Perform PREAUTH/SALE type transaction direct from php script wihtout redirecting to 3rd-party website * * @param Array $item_data * @param Array $gw_params * @return bool */ function DirectPayment($item_data, $gw_params) { return true; } /** * Perform SALE type transaction direct from php script wihtout redirecting to 3rd-party website * * @param Array $item_data * @param Array $gw_params * @return bool */ function Charge($item_data, $gw_params) { return true; } /** * Informs payment gateway, that order has been shipped * * @param Array $item_data * @param Array $gw_params * @return bool */ function OrderShipped($item_data, $gw_params) { } /** * Informs payment gateway, that order has been declined * * @param Array $item_data * @param Array $gw_params * @return bool */ function OrderDeclined($item_data, $gw_params) { } /** * Returns gateway responce from last operation * * @return string */ function getGWResponce() { return $this->gw_responce; } /** * Parse previosly saved gw responce into associative array * * @param string $gw_responce * @return Array */ function parseGWResponce($gw_responce, $gw_params) { return $this->gw_responce; } /** * Returns true if we should use testing mode * * @return bool */ function IsTestMode() { return defined('DEBUG_MODE') && constOn('DBG_PAYMENT_GW'); } /** * Convery primary currency to selected (if they are the same, converter will just return) * * @param double $value * @param string $iso * @param bool $format_value * @return double */ function ConvertCurrency($value, $iso, $format_value = true) { $converter =& $this->Application->recallObject('kCurrencyRates'); $value = $converter->Convert($value, 'PRIMARY', $iso); return $format_value ? sprintf('%.2f', $value) : $value; } function InstallData() { return array(); } function Install() { if ($this->IsInstalled()) { return; } $data = $this->InstallData(); if (!$data) { return ; } // 1. create gateway record $fields_hash = Array (); $gw_fields = Array ('Name', 'ClassName', 'ClassFile', 'RequireCCFields'); foreach ($gw_fields as $gw_field) { $fields_hash[$gw_field] = $data['Gateway'][$gw_field]; } $this->Conn->doInsert($fields_hash, TABLE_PREFIX.'Gateways'); $gw_id = $this->Conn->getInsertID(); // 2. create DISABLED payment type, that uses this gateway (used for storing configuration properties of gateway) $payment_type =& $this->Application->recallObject('pt.-item', null, Array ('skip_autoload' => true)); /* @var $payment_type kDBItem */ $payment_type->Clear(); $fields_hash = Array ( 'Name' => $data['Gateway']['Name'], 'Description' => $data['Gateway']['Name'], 'BuiltIn' => 1, 'GatewayId' => $gw_id, ); $payment_type->SetDBFieldsFromHash($fields_hash); $created = $payment_type->Create(); if (!$created) { return ; } // 3. create gateway configuration fields foreach ($data['ConfigFields'] as $field => $properties) { $fields_hash = Array ( 'SystemFieldName' => $field, 'GatewayId' => $gw_id, 'FieldName' => $properties['Name'], 'ElementType' => $properties['Type'], 'ValueList' => $properties['ValueList'], ); $this->Conn->doInsert($fields_hash, TABLE_PREFIX.'GatewayConfigFields'); $fld_id = $this->Conn->getInsertID(); // 4. set default value for configuration property of gateway $fields_hash = Array ( 'GWConfigFieldId' => $fld_id, 'PaymentTypeId' => $payment_type->GetID(), 'Value' => $properties['Default'], ); $this->Conn->doInsert($fields_hash, TABLE_PREFIX.'GatewayConfigValues'); } } function IsInstalled() { $data = $this->InstallData(); if (!$data) { return true; } $sql = 'SELECT GatewayId FROM '.TABLE_PREFIX.'Gateways WHERE ClassName = '.$this->Conn->qstr($data['Gateway']['ClassName']); return $this->Conn->GetOne($sql); } function getErrorMsg() { return ''; } function gettestccnumbers() { return array(); } + function getNotificationUrl($script = 'gw_notify.php', $use_ssl = null) + { + // custom path can be: units/gateways/gw_classes/notify_scripts/google_checkout_shippings.php' + + $ret = MODULES_PATH . '/in-commerce/' . $script; + $ret = preg_replace('/^' . preg_quote(FULL_PATH . '/', '/') . '/', $this->Application->BaseURL('', $use_ssl), $ret); + + return str_replace(DIRECTORY_SEPARATOR, '/', $ret); + } } \ No newline at end of file Index: branches/5.1.x/units/gateways/gw_classes/ideal_nl.php =================================================================== --- branches/5.1.x/units/gateways/gw_classes/ideal_nl.php (revision 13703) +++ branches/5.1.x/units/gateways/gw_classes/ideal_nl.php (revision 13704) @@ -1,159 +1,158 @@ <?php /** * @version $Id$ * @package In-Commerce * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license Commercial License * This software is protected by copyright law and international treaties. * Unauthorized reproduction or unlicensed usage of the code of this program, * or any portion of it may result in severe civil and criminal penalties, * and will be prosecuted to the maximum extent possible under the law * See http://www.in-portal.org/commercial-license for copyright notices and details. */ /* http://www.ideal.nl/ gateway class */ require_once GW_CLASS_PATH.'/gw_base.php'; $class_name = 'kGWiDEALnl'; // for automatic installation class kGWiDEALnl extends kGWBase { function InstallData() { $data = array( 'Gateway' => Array('Name' => 'iDEAL.nl', 'ClassName' => 'kGWiDEALnl', 'ClassFile' => 'ideal_nl.php', 'RequireCCFields' => 0), 'ConfigFields' => Array( 'partner_id' => Array('Name' => 'Partner ID', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), 'request_url' => Array('Name' => 'Request URL', 'Type' => 'text', 'ValueList' => '', 'Default' => 'http://www.mollie.nl/xml/ideals'), 'shipping_control' => Array('Name' => 'Shipping Control', 'Type' => 'select', 'ValueList' => '3=la_CreditDirect,4=la_CreditPreAuthorize', 'Default' => '3'), ) ); return $data; } /** * Processed input data and convets it to fields understandable by gateway * * @param Array $item_data * @param Array $tag_params additional params for gateway passed through tag * @param Array $gw_params gateway params from payment type config * @return Array */ function getHiddenFields($item_data, $tag_params, $gw_params) { $this->Application->StoreVar('gw_success_template',$tag_params['return_template']); $this->Application->StoreVar('gw_cancel_template',$tag_params['cancel_template']); $banks_query = $gw_params['request_url'].'?a=banklist'; $banks = curl_post($banks_query, null, null, 'GET'); $parser =& $this->Application->recallObject('kXMLHelper'); /* @var $parser kXMLHelper */ $bank_data =& $parser->Parse($banks); $bank_data->FindChild('response'); $banks = array(); foreach ($bank_data->Children as $a_child) { if ($a_child->Name != 'BANK') continue; $banks[$a_child->FindChildValue('bank_id')] = $a_child->FindChildValue('bank_name'); } $ret = $this->Application->Phrase('lu_Select_iDEAL_bank').': <select name="ideal_nl_bank_id">'; foreach ($banks as $id => $name) { $ret .= '<option value="'.$id.'">'.$name.'</option>'; } $ret .= '</select>'; $ret .= '<input type="hidden" name="events[ord]" value="OnCompleteOrder" />'."\n"; return $ret; } function DirectPayment($item_data, $gw_params) { $fields = array(); $fields['a'] = 'fetch'; $fields['partnerid'] = $gw_params['partner_id']; $txt_amount = sprintf("%.2f", $item_data['TotalAmount']); - $fields['amount'] = str_replace( Array('.', ','), '', $txt_amount); + $fields['amount'] = str_replace( Array('.', ','), '', $txt_amount); $fields['bank_id'] = $this->Application->GetVar('ideal_nl_bank_id'); $fields['description'] = 'Invoice #'.$item_data['OrderNumber']; - - $fields['returnurl'] = $this->Application->BaseURL('/in-commerce').'gw_notify.php?order_id='.$item_data['OrderId']; - $fields['reporturl'] = $this->Application->BaseURL('/in-commerce').'gw_notify.php?mode=report&order_id='.$item_data['OrderId']; + $fields['returnurl'] = $this->getNotificationUrl() . '?order_id='.$item_data['OrderId']; + $fields['reporturl'] = $this->getNotificationUrl() . '?mode=report&order_id='.$item_data['OrderId']; $transaction_xml = curl_post($gw_params['request_url'], $fields, null, 'GET'); $parser =& $this->Application->recallObject('kXMLHelper'); /* @var $parser kXMLHelper */ $trans_data =& $parser->Parse($transaction_xml); $transaction_id = $trans_data->FindChildValue('transaction_id'); $url = $trans_data->FindChildValue('url'); if ($transaction_id && $url) { $this->Application->Redirect('external:'.$url); } else { $error_msg = $trans_data->FindChildValue('message'); $this->parsed_responce['XML'] = $transaction_xml; $this->Application->SetVar('failure_template', $this->Application->RecallVar('gw_cancel_template')); $this->parsed_responce['MESSAGE'] = $error_msg ? $error_msg : 'Unknown gateway error ('.htmlspecialchars($transaction_xml).')'; return false; } } function getErrorMsg() { return $this->parsed_responce['MESSAGE']; } function getGWResponce() { return serialize($this->parsed_responce); } function processNotification($gw_params) { // silent mode if ($this->Application->GetVar('mode') == 'report') { $fields = array(); $fields['a'] = 'check'; $fields['partnerid'] = $gw_params['partner_id']; $fields['transaction_id'] = $this->Application->GetVar('transaction_id'); $fields['bank_id'] = $this->Application->GetVar('ideal_nl_bank_id'); $check_xml = curl_post($gw_params['request_url'], $fields, null, 'GET'); $parser =& $this->Application->recallObject('kXMLHelper'); /* @var $parser kXMLHelper */ $trans_data =& $parser->Parse($check_xml); $response = $trans_data->FindChild('order'); foreach ($response->Children as $a_child) { $this->parsed_responce[$a_child->Name] = $a_child->Data; } $this->parsed_responce['XML'] = $check_xml; $result = $trans_data->FindChildValue('payed') == 'true' ? 1:0; return $result; } else { $order =& $this->Application->recallObject('ord'); if ($order->GetDBField('Status') == ORDER_STATUS_INCOMPLETE) { // error $t = $this->Application->RecallVar('gw_cancel_template'); $this->parsed_responce = unserialize($order->GetDBField('GWResult1')); $this->Application->StoreVar('gw_error', $this->getErrorMsg()); $this->Application->Redirect($t, array('pass'=>'m', 'm_cat_id'=>0)); } else { // ok $t = $this->Application->RecallVar('gw_success_template'); $this->Application->Redirect($t, array('pass'=>'m', 'm_cat_id'=>0)); } } } } \ No newline at end of file Index: branches/5.1.x/units/gateways/gw_classes/multicards.php =================================================================== --- branches/5.1.x/units/gateways/gw_classes/multicards.php (revision 13703) +++ branches/5.1.x/units/gateways/gw_classes/multicards.php (revision 13704) @@ -1,122 +1,122 @@ <?php /** * @version $Id$ * @package In-Commerce * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license Commercial License * This software is protected by copyright law and international treaties. * Unauthorized reproduction or unlicensed usage of the code of this program, * or any portion of it may result in severe civil and criminal penalties, * and will be prosecuted to the maximum extent possible under the law * See http://www.in-portal.org/commercial-license for copyright notices and details. */ require_once GW_CLASS_PATH.'/gw_base.php'; $class_name = 'kMultiCardsGW'; // for automatic installation class kMultiCardsGW extends kGWBase { function InstallData() { $data = array( 'Gateway' => Array('Name' => 'Multicards', 'ClassName' => 'kMultiCardsGW', 'ClassFile' => 'multicards.php', 'RequireCCFields' => 0), 'ConfigFields' => Array( 'submit_url' => Array('Name' => 'Submit URL', 'Type' => 'text', 'ValueList' => '', 'Default' => 'https://secure.multicards.com/cgi-bin/order2/processorder1.pl'), 'merchant_id' => Array('Name' => 'Merchant ID', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), 'merchant_url_idx' => Array('Name' => 'Merchant Order Page Id', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), ) ); return $data; } /** * Returns payment form submit url * * @param Array $gw_params gateway params from payment type config * @return string */ function getFormAction($gw_params) { return $gw_params['submit_url']; } /** * Processed input data and convets it to fields understandable by gateway * * @param Array $item_data * @param Array $tag_params additional params for gateway passed through tag * @param Array $gw_params gateway params from payment type config * @return Array */ function getHiddenFields($item_data, $tag_params, $gw_params) { $ret = Array(); $ret['mer_id'] = $gw_params['merchant_id']; $ret['mer_url_idx'] = $gw_params['merchant_url_idx']; $ret['num_items'] = 100; $ret['item1_price'] = $item_data['TotalAmount']; $ret['item1_desc'] = 'Order #'.$item_data['OrderNumber']; $ret['item1_qty'] = 1; // $ret['cancel_return'] = $this->Application->HREF($tag_params['cancel_template'],'',Array('pass'=>'m')); // $ret['return'] = $this->Application->HREF($tag_params['return_template'],'',Array('pass'=>'m')); -// $ret['notify_url'] = $this->Application->BaseURL('/in-commerce').'gw_notify.php?sid='.$this->Application->GetSID().'&admin=1&order_id='.$item_data['OrderId']; +// $ret['notify_url'] = $this->getNotificationUrl() . '?sid='.$this->Application->GetSID().'&admin=1&order_id='.$item_data['OrderId']; // $ret['cmd'] = '_xclick'; // act as "Buy Now" PayPal button $ret['no_note'] = 1; // customer is not prompted for notes $ret['no_shipping'] = 1; // customer is not prompted for shipping address $ret['rm'] = 2; // return method - POST $ret['currency_code'] = $target; $ret['invoice'] = $item_data['OrderNumber']; $ret['business'] = $gw_params['business_account']; // prepopulated fields $billing_email = $item_data['BillingEmail']; if (!$billing_email) { $billing_email = $this->Conn->GetOne(' SELECT Email FROM '.$this->Application->getUnitOption('u', 'TableName').' WHERE PortalUserId = '.$this->Application->RecallVar('user_id')); } $ret['cust_email'] = $billing_email; $ret['cust_name'] = $item_data['BillingTo']; $ret['cust_company'] = $item_data['BillingCompany']; $ret['cust_phone'] = $item_data['BillingPhone']; $ret['cust_address1'] = $item_data['BillingAddress1']; $ret['cust_address2'] = $item_data['BillingAddress2']; $ret['cust_city'] = $item_data['BillingCity']; $ret['cust_state'] = $item_data['BillingState']; $ret['cust_zip'] = $item_data['BillingZip'] ? $item_data['BillingZip'] : '99999'; $ret['cust_country'] = $item_data['BillingCountry']; $ret['user1'] = $this->Application->GetSID().','.MD5($item_data['OrderId']); $url = $this->Application->HREF($tag_params['return_template'], '', array('pass'=>'m')); $ret['user2'] = $url; return $ret; } function processNotification($gw_params) { $this->parsed_responce = $_POST; list ($sid, $auth_code) = explode(',', $this->Application->GetVar('user1')); $session =& $this->Application->recallObject('Session'); $session->SID = $sid; $order_id = $this->Conn->GetOne('SELECT OrderId FROM '.TABLE_PREFIX.'Orders WHERE md5(OrderId) = '.$this->Conn->qstr($auth_code)); $this->Application->SetVar('ord_id', $order_id); $order =& $this->Application->recallObject('ord'); $order->Load($order_id); $url = $this->Application->GetVar('user2'); echo '<!--success--><a href="'.$url.'">'.$this->Application->Phrase('la_multicards_continue').'</a>'; return 1; } } \ No newline at end of file Index: branches/5.1.x/gw_notify.php =================================================================== --- branches/5.1.x/gw_notify.php (revision 13703) +++ branches/5.1.x/gw_notify.php (revision 13704) @@ -1,63 +1,65 @@ <?php /** * @version $Id$ * @package In-Commerce * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license Commercial License * This software is protected by copyright law and international treaties. * Unauthorized reproduction or unlicensed usage of the code of this program, * or any portion of it may result in severe civil and criminal penalties, * and will be prosecuted to the maximum extent possible under the law * See http://www.in-portal.org/commercial-license for copyright notices and details. */ - - define('FULL_PATH', realpath(dirname(__FILE__).'/..')); define('GW_NOTIFY', 1); - define('REL_PATH', 'in-commerce'); - include_once(FULL_PATH.'/core/kernel/startup.php'); - + define('REL_PATH', 'modules/in-commerce'); + define('FULL_PATH', realpath(dirname(__FILE__) . '/../..')); + include_once(FULL_PATH . '/core/kernel/startup.php'); + $application =& kApplication::Instance(); $application->Init(); - /*$fh = fopen(WRITEABLE . '/gw.log', 'a'); + /* + // for debugging payment gateway notifications, don't remove + $fh = fopen(WRITEABLE . '/gw.log', 'a'); fwrite ($fh, "\n\n".date('d/m/y h:i:s').":\n"); foreach ($_REQUEST as $key => $val) { fwrite($fh, "<input type=\"text\" name=\"$key\" value=\"$val\">\n"); } - fclose($fh);*/ - + fclose($fh); + */ + $db =& $application->GetADODBConnection(); $application->setUnitOption('ord','AutoLoad',false); $order =& $application->recallObject('ord'); - + $order_id = $application->GetVar('order_id'); if ($order_id) { $order->Load($order_id); } - + $gw_data = $order->getGatewayData($application->GetVar('payment_type_id')); $application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] ); $gateway_object =& $application->recallObject( $gw_data['ClassName'] ); $transaction_status = $gateway_object->processNotification($gw_data['gw_params']); $sql = 'UPDATE %s SET GWResult1 = %s WHERE %s = %s'; $sql = sprintf($sql, $order->TableName, $db->qstr($gateway_object->getGWResponce()), $order->IDField, $order->GetID() ); $db->Query($sql); $order->SetDBField('GWResult1', $gateway_object->getGWResponce() ); $sql = 'UPDATE %s SET TransactionStatus = %s WHERE %s = %s'; $db->Query( sprintf($sql, $order->TableName, $transaction_status, $order->IDField, $order->GetID()) ); $order->SetDBField('TransactionStatus', $transaction_status); if($transaction_status == 1) { $dummy_var = '10'; $application->HandleEvent($dummy_var, 'ord:OnCompleteOrder'); } else { $application->StoreVar('gw_error', $gateway_object->getErrorMsg()); } $application->Done(); \ No newline at end of file