/**
  * This method is handles the response that will be invoked (from extern/googleNotify) every time
  * a notification or request is sent by the Google Server.
  *
  */
 static function main($xml_response)
 {
     require_once 'Google/library/googleresponse.php';
     require_once 'Google/library/googlemerchantcalculations.php';
     require_once 'Google/library/googleresult.php';
     require_once 'Google/library/xml-processing/xmlparser.php';
     $config = CRM_Core_Config::singleton();
     // Retrieve the XML sent in the HTTP POST request to the ResponseHandler
     if (get_magic_quotes_gpc()) {
         $xml_response = stripslashes($xml_response);
     }
     require_once 'CRM/Utils/System.php';
     $headers = CRM_Utils_System::getAllHeaders();
     if (GOOGLE_DEBUG_PP) {
         CRM_Core_Error::debug_var('RESPONSE', $xml_response, TRUE, TRUE, 'Google');
     }
     // Retrieve the root and data from the xml response
     $xmlParser = new XmlParser($xml_response);
     $root = $xmlParser->GetRoot();
     $data = $xmlParser->GetData();
     $orderNo = $data[$root]['google-order-number']['VALUE'];
     // lets retrieve the private-data
     $privateData = $data[$root]['shopping-cart']['merchant-private-data']['VALUE'];
     $privateData = $privateData ? self::stringToArray($privateData) : '';
     list($mode, $module, $paymentProcessorID) = self::getContext($xml_response, $privateData, $orderNo, $root);
     $mode = $mode ? 'test' : 'live';
     require_once 'CRM/Financial/BAO/PaymentProcessor.php';
     $paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getPayment($paymentProcessorID, $mode);
     $ipn =& self::singleton($mode, $module, $paymentProcessor);
     // Create new response object
     $merchant_id = $paymentProcessor['user_name'];
     $merchant_key = $paymentProcessor['password'];
     $server_type = $mode == 'test' ? "sandbox" : '';
     $response = new GoogleResponse($merchant_id, $merchant_key, $xml_response, $server_type);
     if (GOOGLE_DEBUG_PP) {
         CRM_Core_Error::debug_var('RESPONSE-ROOT', $response->root, TRUE, TRUE, 'Google');
     }
     //Check status and take appropriate action
     $status = $response->HttpAuthentication($headers);
     switch ($root) {
         case "request-received":
         case "error":
         case "diagnosis":
         case "checkout-redirect":
         case "merchant-calculation-callback":
             break;
         case "new-order-notification":
             $response->SendAck();
             $ipn->newOrderNotify($data[$root], $privateData, $module);
             break;
         case "order-state-change-notification":
             $response->SendAck();
             $new_financial_state = $data[$root]['new-financial-order-state']['VALUE'];
             $new_fulfillment_order = $data[$root]['new-fulfillment-order-state']['VALUE'];
             switch ($new_financial_state) {
                 case 'CHARGEABLE':
                     $amount = $ipn->getAmount($orderNo);
                     if ($amount) {
                         $response->SendChargeOrder($data[$root]['google-order-number']['VALUE'], $amount, $message_log);
                         $response->SendProcessOrder($data[$root]['google-order-number']['VALUE'], $message_log);
                     }
                     break;
                 case 'CHARGED':
                 case 'PAYMENT_DECLINED':
                 case 'CANCELLED':
                     $ipn->orderStateChange($new_financial_state, $data[$root], $module);
                     break;
                 case 'REVIEWING':
                 case 'CHARGING':
                 case 'CANCELLED_BY_GOOGLE':
                     break;
                 default:
                     break;
             }
         case "charge-amount-notification":
         case "chargeback-amount-notification":
         case "refund-amount-notification":
         case "risk-information-notification":
             $response->SendAck();
             break;
         default:
             break;
     }
 }
 /**
  * This method is handles the response that will be invoked (from extern/googleNotify) every time
  * a notification or request is sent by the Google Server.
  *
  */
 static function main($xml_response)
 {
     require_once 'Google/library/googleresponse.php';
     require_once 'Google/library/googlerequest.php';
     require_once 'Google/library/googlemerchantcalculations.php';
     require_once 'Google/library/googleresult.php';
     require_once 'Google/library/xml-processing/gc_xmlparser.php';
     $config = CRM_Core_Config::singleton();
     // Retrieve the XML sent in the HTTP POST request to the ResponseHandler
     if (get_magic_quotes_gpc()) {
         $xml_response = stripslashes($xml_response);
     }
     $headers = CRM_Utils_System::getAllHeaders();
     if (GOOGLE_DEBUG_PP) {
         CRM_Core_Error::debug_var('RESPONSE', $xml_response, TRUE, TRUE, 'Google');
     }
     // Retrieve the root and data from the xml response
     $response = new GoogleResponse();
     list($root, $data) = $response->GetParsedXML($xml_response);
     // lets retrieve the private-data & order-no
     $privateData = NULL;
     if (array_key_exists('shopping-cart', $data[$root])) {
         $privateData = $data[$root]['shopping-cart']['merchant-private-data']['VALUE'];
     }
     if (empty($privateData) && array_key_exists('order-summary', $data[$root]) && array_key_exists('shopping-cart', $data[$root]['order-summary'])) {
         $privateData = $data[$root]['order-summary']['shopping-cart']['merchant-private-data']['VALUE'];
     }
     $privateData = $privateData ? self::stringToArray($privateData) : '';
     $orderNo = $data[$root]['google-order-number']['VALUE'];
     $serial = $data[$root]['serial-number'];
     // a dummy object to call get context and a parent function inside it.
     $ipn = new CRM_Core_Payment_GoogleIPN('live', $dummyProcessor);
     list($mode, $module, $paymentProcessorID) = $ipn->getContext($privateData, $orderNo, $root, $response, $serial);
     $mode = $mode ? 'test' : 'live';
     $paymentProcessor = CRM_Core_BAO_PaymentProcessor::getPayment($paymentProcessorID, $mode);
     $merchant_id = $paymentProcessor['user_name'];
     $merchant_key = $paymentProcessor['password'];
     $response->SetMerchantAuthentication($merchant_id, $merchant_key);
     $server_type = $mode == 'test' ? 'sandbox' : 'production';
     $request = new GoogleRequest($merchant_id, $merchant_key, $server_type);
     $ipn = self::singleton($mode, $module, $paymentProcessor);
     if (GOOGLE_DEBUG_PP) {
         CRM_Core_Error::debug_var('RESPONSE-ROOT', $response->root, TRUE, TRUE, 'Google');
     }
     //Check status and take appropriate action
     $status = $response->HttpAuthentication($headers);
     switch ($root) {
         case "request-received":
         case "error":
         case "diagnosis":
         case "checkout-redirect":
         case "merchant-calculation-callback":
             break;
         case "new-order-notification":
             $response->SendAck($serial, FALSE);
             $ipn->newOrderNotify($data[$root], $privateData, $module);
             break;
         case "order-state-change-notification":
             $response->SendAck($serial, FALSE);
             $new_financial_state = $data[$root]['new-financial-order-state']['VALUE'];
             $new_fulfillment_order = $data[$root]['new-fulfillment-order-state']['VALUE'];
             switch ($new_financial_state) {
                 case 'CHARGEABLE':
                     break;
                 case 'CHARGED':
                 case 'PAYMENT_DECLINED':
                 case 'CANCELLED':
                 case 'CANCELLED_BY_GOOGLE':
                     $ipn->orderStateChange($new_financial_state, $data[$root], $privateData, $module);
                     break;
                 case 'REVIEWING':
                 case 'CHARGING':
                     break;
                 default:
                     break;
             }
             break;
         case "authorization-amount-notification":
             $response->SendAck($serial, FALSE);
             $new_financial_state = $data[$root]['order-summary']['financial-order-state']['VALUE'];
             $new_fulfillment_order = $data[$root]['order-summary']['fulfillment-order-state']['VALUE'];
             switch ($new_financial_state) {
                 case 'CHARGEABLE':
                     // For google-handled subscriptions chargeorder needn't be initiated,
                     // assuming auto-charging is turned on.
                     //$request->SendProcessOrder($data[$root]['google-order-number']['VALUE']);
                     //$request->SendChargeOrder($data[$root]['google-order-number']['VALUE'],'');
                     break;
                 case 'CHARGED':
                 case 'PAYMENT_DECLINED':
                 case 'CANCELLED':
                     break;
                 case 'REVIEWING':
                 case 'CHARGING':
                 case 'CANCELLED_BY_GOOGLE':
                     break;
                 default:
                     break;
             }
             break;
         case "charge-amount-notification":
         case "chargeback-amount-notification":
         case "refund-amount-notification":
         case "risk-information-notification":
             $response->SendAck($serial);
             break;
         default:
             break;
     }
 }