<?php

$GLOBALS["schema_url"] = "http://checkout.google.com/schema/2";

function CalcHmacSha1($data) 
{

    $key = $GLOBALS["merchant_key"];
    $blocksize = 64;
    $hashfunc = 'sha1';

    if (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;
}

function ProcessXmlData($xml_data, $params = false) 
{
    require_once 'newedge/classes/XmlFunctions.php';
	//modified function to work with CE standars... a little bit different from Google checkout API
	$xmlresponse = XmlFunctions::xmlize($xml_data);
	$message_recognizer = array_keys($xmlresponse);
	$message_recognizer = $message_recognizer[0];


    switch ($message_recognizer) {
    
        // <request-received> received
        case "request-received":
        	$GLOBALS['logger']->log(4,"Google checkout callback::ProcessRequestReceivedResponse(request-received)");
            ProcessRequestReceivedResponse($xmlresponse);
            break;

        // <error> received
        case "error":
        	$GLOBALS['logger']->log(4,"Google checkout callback::ProcessErrorResponse(error)");
            ProcessErrorResponse($xmlresponse);
            break;

        // <diagnosis> received
        case "diagnosis":
        	$GLOBALS['logger']->log(4,"Google checkout callback::ProcessDiagnosisResponse(diagnosis)");
            ProcessDiagnosisResponse($xmlresponse);
            break;

        // <checkout-redirect> received
        case "checkout-redirect":
        	$GLOBALS['logger']->log(4,"Google checkout callback::ProcessCheckoutRedirect(checkout-redirect)");
            ProcessCheckoutRedirect($xmlresponse, $params);
            break;
            
/************************* asynchronous notification messages **********************/

        // <new-order-notification> received
        case "new-order-notification":
        	$GLOBALS['logger']->log(4,"Google checkout callback::ProcessNewOrderNotification(new-order-notification)");
            ProcessNewOrderNotification($xmlresponse);
            break;

        // <order-state-change-notification> received
        case "order-state-change-notification":
        	$GLOBALS['logger']->log(4,"Google checkout callback::ProcessOrderStateChangeNotification(order-state-change-notification)");
            ProcessOrderStateChangeNotification($xmlresponse);
            break;

        // <charge-amount-notification> received
        case "charge-amount-notification":
        	$GLOBALS['logger']->log(4,"Google checkout callback::ProcessChargeAmountNotification(charge-amount-notification)");
            ProcessChargeAmountNotification($xmlresponse);
            break;

        // <chargeback-amount-notification> received
        case "chargeback-amount-notification":
        	$GLOBALS['logger']->log(4,"Google checkout callback::ProcessChargebackAmountNotification(chargeback-amount-notification)");
            ProcessChargebackAmountNotification($xmlresponse);
            break;
    
        // <refund-amount-notification> received
        case "refund-amount-notification":
        	$GLOBALS['logger']->log(4,"Google checkout callback::ProcessRefundAmountNotification(refund-amount-notification)");
            ProcessRefundAmountNotification($xmlresponse);
            break;

        // <risk-information-notification> received
        case "risk-information-notification":
        	$GLOBALS['logger']->log(4,"Google checkout callback::ProcessRiskInformationNotification(risk-information-notification)");
            ProcessRiskInformationNotification($xmlresponse);
            break;

        /*
         * None of the above: The message is not recognized. 
         * You should not remove this case.
         */
        default:
    }
}

/******** Functions for processing synchronous response messages *********/

function ProcessRequestReceivedResponse($dom_response_obj) 
{
    $GLOBALS['logger']->log(4, 'Google Checkout received the request. The Answer was: '.$dom_response_obj);
}

function ProcessErrorResponse($dom_response_obj) 
{
    $GLOBALS['logger']->log(4, 'Google Checkout returned an error. The Answer was: '.print_r($dom_response_obj, true));
}

function ProcessDiagnosisResponse($dom_response_obj) 
{
    echo htmlentities($dom_response_obj);
}

function ProcessCheckoutRedirect($dom_response_obj, $params) 
{
    $redirect_url = $dom_response_obj ['checkout-redirect']['#']['redirect-url'][0]['#'];
    // just in case this is still needed
    $redirect_url = str_replace('&amp;','&', $redirect_url);
    // the & is dropped by the xml parser...
    $redirect_url = str_replace('shoppingcartshoppingcart', 'shoppingcart&shoppingcart', $redirect_url);
    setcookie('returnToSignup', (isset($params['isSignup']) && $params['isSignup']) ? 1:0, null, '/', false);
    Header("Location: " . $redirect_url);
    $GLOBALS['logger']->log(4, 'Google redirected to: '. $redirect_url);
    exit;
}

/******** Functions for processing asynchronous notification messages *********/

function ProcessNewOrderNotification($dom_response_obj) 
{
    require_once 'modules/billing/models/BillingGateway.php';
    $billingGateway = new BillingGateway($GLOBALS['user'], $GLOBALS['customer']);
    SendNotificationAcknowledgment();
    $orderState = $dom_response_obj['new-order-notification']['#']['financial-order-state'][0]['#'];
    $googleOrderNumber = $dom_response_obj['new-order-notification']['#']['google-order-number'][0]['#'];
    $invoiceNumber = $dom_response_obj['new-order-notification']['#']['shopping-cart'][0]['#']['items'][0]['#']['item'][0]['#']['merchant-private-item-data'][0]['#']['item-note'][0]['#'];
    $invoiceAmount = $dom_response_obj['new-order-notification']['#']['shopping-cart'][0]['#']['items'][0]['#']['item'][0]['#']['unit-price'][0]['#'];

	$billingGateway->setTransaction($invoiceNumber, 'Google Checkout is '.$orderState.' the client\'s credit info.', 1, $googleOrderNumber, $orderState, 'NA',$invoiceAmount); 
	
    $GLOBALS['logger']->log(4,'Order State: '.$orderState. ' Order Number: '.$googleOrderNumber);
}

function ProcessOrderStateChangeNotification($dom_response_obj) 
{    
    require_once 'modules/billing/models/BillingGateway.php';
    $billingGateway = new BillingGateway($GLOBALS['user'], $GLOBALS['customer']);
    SendNotificationAcknowledgment();
	$orderState = $dom_response_obj['order-state-change-notification']['#']['new-financial-order-state'][0]['#'];
    $googleOrderNumber = $dom_response_obj['order-state-change-notification']['#']['google-order-number'][0]['#'];
    $GLOBALS['logger']->log(4,'Order State: '.$orderState. ' Order Number: '.$googleOrderNumber);
    
    $arrayResult = GetTransactionData($googleOrderNumber);
    $invoiceAmount = $arrayResult[0];
    $invoiceId = $arrayResult[1];
	
    switch($orderState){
    	case "CHARGEABLE":
    		$billingGateway->setTransaction($invoiceId, 'Google Checkout said that the client\'s Credit Card now is '.$orderState.'.', 1, $googleOrderNumber, $orderState, 'NA',$invoiceAmount);
    		CreateChargeOrder($googleOrderNumber);
    	break;
    	
    	case "CHARGING":
    		$billingGateway->setTransaction($invoiceId, 'Google Checkout is '.$orderState.' the client\'s Credit Card.', 1, $googleOrderNumber, $orderState, 'NA',$invoiceAmount);
    	break;
    	
    	case "CHARGED":
    	    $cPlugin = new Plugin($invoiceId, "", $GLOBALS['user'], $GLOBALS['customer']);
		    $cPlugin->m_Amount = $invoiceAmount;
			$cPlugin->m_TransactionID = $googleOrderNumber;
			$cPlugin->m_Action = $orderState;
			$cPlugin->m_Last4 = "NA";
    		$cPlugin->PaymentAccepted($invoiceAmount,'Google Checkout has '.$orderState.' the client\'s Credit Card.', $googleOrderNumber);
    		CreateChargeOrder($googleOrderNumber);
    	break;
    	
    	case "PAYMENT_DECLINED":
    		$billingGateway->setTransaction($invoiceId, 'The transaction has been cancelled. the reason is: '.$orderState.', sent by Google Checkout.', 1, $googleOrderNumber, $orderState, 'NA',$invoiceAmount);
    		CreateCancelOrder($googleOrderNumber);
    	break;
    	
    	case "CANCELLED":
    		$billingGateway->setTransaction($invoiceId,'The transaction has been '.$orderState.'.', 1, $googleOrderNumber, $orderState, 'NA',$invoiceAmount);
    	break;
    	
    	case "CANCELLED_BY_GOOGLE":
    		$billingGateway->setTransaction($invoiceId, 'The transaction has been '.$orderState.'.', 1, $googleOrderNumber, $orderState, 'NA',$invoiceAmount);
    		$GLOBALS['logger']->log(4, 'Google cancelled the order. The reason given by Google was: '.$dom_response_obj['order-state-change-notification']['#']['reason'][0]['#']);
    	break;
    	
    	default:
    }
}

function ProcessChargeAmountNotification($dom_response_obj) 
{
    SendNotificationAcknowledgment();
}

function ProcessRefundAmountNotification($dom_response_obj) 
{
    SendNotificationAcknowledgment();
}

function ProcessRiskInformationNotification($dom_response_obj) 
{
    SendNotificationAcknowledgment();
    $googleOrderNumber = $dom_response_obj['risk-information-notification']['#']['google-order-number'][0]['#'];
    $GLOBALS['logger']->log(4,'Order Number: '.$googleOrderNumber);
    CreateChargeOrder($googleOrderNumber);
}

/*the SendNotificationAcknowledgment function, apparently, does nothing*/
function SendNotificationAcknowledgment() 
{
    $schemaUrl = $GLOBALS["schema_url"];
	$acknowledgment = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
        <notification-acknowledgment xmlns=\"$schemaUrl\"/>";

	$GLOBALS['logger']->log(4,'Sending acknowledgment to Google: '.$acknowledgment);

}

/***************************** additional functions *********************************/

/*the CreateChargeOrder function, apparently, does nothing*/
function CreateChargeOrder($googleOrderNumber)
{
	$schemaUrl = $GLOBALS["schema_url"];
	$xmlChargeOrder = "<?xml version = \"1.0\" encoding = \"UTF-8\"?>
							<charge-order xmlns=\"$schemaUrl\" google-order-number = $googleOrderNumber>
							</charge-order>";
	$GLOBALS['logger']->log(4,'Sending charge order to Google: '.$xmlChargeOrder);
}

/*the CreateCancelOrder function, apparently, does nothing*/
function CreateCancelOrder($googleOrderNumber)
{
	$schemaUrl = $GLOBALS["schema_url"];
	$xmlCancelOrder = "<?xml version = \"1.0\" encoding = \"UTF-8 \"?>
							<cancel-order xmlns = \"$schemaUrl\" google-order-number = $googleOrderNumber>
							</cancel-order>";
	$GLOBALS['logger']->log(4,'Sending cancel order to Google: '.$xmlCancelOrder);
}

/*
* This function may be used or modified in the future to cancel or refund some money or so
*/
function GetTransactionData($googleOrderNumber)
{
	$query = "SELECT amount, invoiceid FROM invoicetransaction WHERE transactionid = ?";
	$result = $GLOBALS['db']->query($query, $googleOrderNumber);
	list($invoiceAmount, $invoiceId) = $result->fetch();
	$arrayResult = array($invoiceAmount, $invoiceId);
	return $arrayResult;
}

?>
