views:

304

answers:

2

I have seen the XML response from google checkout when an order is processed here.

I have also seen the google responsehandlerdemo.php file which I've copied below.

I cannot figure out where I am supposed to insert the code that I will use to update the inventory levels on my shop. Can someone point me there? I also am not quite sure how to find out what was ordered when I recieve a respohnse.

<?php



   chdir("..");
   require_once('library/googleresponse.php');
   require_once('library/googlemerchantcalculations.php');
   require_once('library/googleresult.php');
   require_once('library/googlerequest.php');

   define('RESPONSE_HANDLER_ERROR_LOG_FILE', 'googleerror.log');
   define('RESPONSE_HANDLER_LOG_FILE', 'googlemessage.log');
   $merchant_id = "";  // Your Merchant ID
   $merchant_key = "";  // Your Merchant Key
   $server_type = "sandbox";  // change this to go live
   $currency = 'USD';  // set to GBP if in the UK

   $Gresponse = new GoogleResponse($merchant_id, $merchant_key);

   $Grequest = new GoogleRequest($merchant_id, $merchant_key, $server_type, $currency);

   //Setup the log file
   $Gresponse->SetLogFiles(RESPONSE_HANDLER_ERROR_LOG_FILE, 
                                    RESPONSE_HANDLER_LOG_FILE, L_ALL);

   // Retrieve the XML sent in the HTTP POST request to the ResponseHandler
   $xml_response = isset($HTTP_RAW_POST_DATA)?
                $HTTP_RAW_POST_DATA:file_get_contents("php://input");
   if (get_magic_quotes_gpc()) {
   $xml_response = stripslashes($xml_response);
   }
   list($root, $data) = $Gresponse->GetParsedXML($xml_response);
   $Gresponse->SetMerchantAuthentication($merchant_id, $merchant_key);

   $status = $Gresponse->HttpAuthentication();
   if(! $status) {
   die('authentication failed');
   }

   /* Commands to send the various order processing APIs
   * Send charge order : $Grequest->SendChargeOrder($data[$root]
   *    ['google-order-number']['VALUE'], <amount>);
   * Send process order : $Grequest->SendProcessOrder($data[$root]
   *    ['google-order-number']['VALUE']);
   * Send deliver order: $Grequest->SendDeliverOrder($data[$root]
   *    ['google-order-number']['VALUE'], <carrier>, <tracking-number>,
   *    <send_mail>);
   * Send archive order: $Grequest->SendArchiveOrder($data[$root]
   *    ['google-order-number']['VALUE']);
   *
   */

  switch ($root) {
  case "request-received": {
  break;
}
case "error": {
  break;
}
case "diagnosis": {
  break;
}
case "checkout-redirect": {
  break;
}
case "merchant-calculation-callback": {
  // Create the results and send it
  $merchant_calc = new GoogleMerchantCalculations($currency);

  // Loop through the list of address ids from the callback
  $addresses = get_arr_result($data[$root]['calculate']['addresses']['anonymous-address']);
  foreach($addresses as $curr_address) {
    $curr_id = $curr_address['id'];
    $country = $curr_address['country-code']['VALUE'];
    $city = $curr_address['city']['VALUE'];
    $region = $curr_address['region']['VALUE'];
    $postal_code = $curr_address['postal-code']['VALUE'];

    // Loop through each shipping method if merchant-calculated shipping
    // support is to be provided
    if(isset($data[$root]['calculate']['shipping'])) {
      $shipping = get_arr_result($data[$root]['calculate']['shipping']['method']);
      foreach($shipping as $curr_ship) {
        $name = $curr_ship['name'];
        //Compute the price for this shipping method and address id
        $price = 12; // Modify this to get the actual price
        $shippable = "true"; // Modify this as required
        $merchant_result = new GoogleResult($curr_id);
        $merchant_result->SetShippingDetails($name, $price, $shippable);

        if($data[$root]['calculate']['tax']['VALUE'] == "true") {
          //Compute tax for this address id and shipping type
          $amount = 15; // Modify this to the actual tax value
          $merchant_result->SetTaxDetails($amount);
        }

        if(isset($data[$root]['calculate']['merchant-code-strings']
            ['merchant-code-string'])) {
          $codes = get_arr_result($data[$root]['calculate']['merchant-code-strings']
              ['merchant-code-string']);
          foreach($codes as $curr_code) {
            //Update this data as required to set whether the coupon is valid, the code and the amount
            $coupons = new GoogleCoupons("true", $curr_code['code'], 5, "test2");
            $merchant_result->AddCoupons($coupons);
          }
         }
         $merchant_calc->AddResult($merchant_result);
      }
    } else {
      $merchant_result = new GoogleResult($curr_id);
      if($data[$root]['calculate']['tax']['VALUE'] == "true") {
        //Compute tax for this address id and shipping type
        $amount = 15; // Modify this to the actual tax value
        $merchant_result->SetTaxDetails($amount);
      }
      $codes = get_arr_result($data[$root]['calculate']['merchant-code-strings']
          ['merchant-code-string']);
      foreach($codes as $curr_code) {
        //Update this data as required to set whether the coupon is valid, the code and the amount
        $coupons = new GoogleCoupons("true", $curr_code['code'], 5, "test2");
        $merchant_result->AddCoupons($coupons);
      }
      $merchant_calc->AddResult($merchant_result);
    }
  }
  $Gresponse->ProcessMerchantCalculations($merchant_calc);
  break;
}
case "new-order-notification": {
  $Gresponse->SendAck();
  break;
}
case "order-state-change-notification": {
  $Gresponse->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 'REVIEWING': {
      break;
    }
    case 'CHARGEABLE': {
      //$Grequest->SendProcessOrder($data[$root]['google-order-number']['VALUE']);
      //$Grequest->SendChargeOrder($data[$root]['google-order-number']['VALUE'],'');
      break;
    }
    case 'CHARGING': {
      break;
    }
    case 'CHARGED': {
      break;
    }
    case 'PAYMENT_DECLINED': {
      break;
    }
    case 'CANCELLED': {
      break;
    }
    case 'CANCELLED_BY_GOOGLE': {
      //$Grequest->SendBuyerMessage($data[$root]['google-order-number']['VALUE'],
      //    "Sorry, your order is cancelled by Google", true);
      break;
    }
    default:
      break;
  }

  switch($new_fulfillment_order) {
    case 'NEW': {
      break;
    }
    case 'PROCESSING': {
      break;
    }
    case 'DELIVERED': {
      break;
    }
    case 'WILL_NOT_DELIVER': {
      break;
    }
    default:
      break;
  }
  break;
}
case "charge-amount-notification": {
  //$Grequest->SendDeliverOrder($data[$root]['google-order-number']['VALUE'],
  //    <carrier>, <tracking-number>, <send-email>);
  //$Grequest->SendArchiveOrder($data[$root]['google-order-number']['VALUE'] );
  $Gresponse->SendAck();
  break;
}
case "chargeback-amount-notification": {
  $Gresponse->SendAck();
  break;
}
case "refund-amount-notification": {
  $Gresponse->SendAck();
  break;
}
case "risk-information-notification": {
  $Gresponse->SendAck();
  break;
}
default:
  $Gresponse->SendBadRequestStatus("Invalid or not supported Message");
  break;
  }
 /* In case the XML API contains multiple open tags
    with the same value, then invoke this function and
    perform a foreach on the resultant array.
    This takes care of cases when there is only one unique tag
    or multiple tags.
    Examples of this are "anonymous-address", "merchant-code-string"
    from the merchant-calculations-callback API
 */
 function get_arr_result($child_node) {
   $result = array();
   if(isset($child_node)) {
     if(is_associative_array($child_node)) {
       $result[] = $child_node;
     }
   else {
    foreach($child_node as $curr_node){
      $result[] = $curr_node;
    }
  }
}
return $result;
}

   /* Returns true if a given variable represents an associative array */
  function is_associative_array( $var ) {
    return is_array( $var ) && !is_numeric( implode( '', array_keys( $var ) ) );
  }
?>

I am presuming that I want to do it in the block below, but I'm really just not sure at all how to go about parsing the XML, something I've never done with PHP before.

  case "new-order-notification": {
       $Gresponse->SendAck();
       break;"
  }
+1  A: 

I don't do a whole lot of PHP but are you using an XML parser?

I can't quite tell from your code but if you're not it would make your life a little easier.

http://php.net/manual/en/book.xml.php

John at CashCommons
Well this is google's sample code... and it appeares to be parsing the XML internally: $Gresponse->GetParsedXML($xml_response)I'm just not sure how to specify the tags I'm looking for and get the values of said tags using PHPs parser.
Chris Sobolewski
+1  A: 

Seems like you're on the right track: You'd want to decrement the inventory when an order is received, so elsewhere you can display immediately that the item is out of stock if your inventory goes to zero.

As for your other question, looks like each bracket level of the $data[$root] array gets you down another level in the XML structure, as in the merchant-callback-calculation case of your sample code.

The whole response appears to be in $data, so I'd just look at the example response and poke around for what you're looking for that way. Maybe use some echo statements to see what comes up for ['VALUE'] at different places.

Totally a heuristic answer but hope it helps. ;)

John at CashCommons
You have, if nothing else, echoed what I was thinking but not necessarily confident enough to poke with without hearing it from someone else. So thanks very much for that.
Chris Sobolewski