Использование PHP с последовательным уведомлением Google (IPN)

Я пытаюсь понять, как заставить это работать с PHP. У меня есть рабочий IPN для PayPal, который содержит менее 20 строк кода для получения нужных мне данных. Я пытался читать документы Google, но они либо слишком специфичны, либо слишком общие. Есть пример кода, который составляет около 1300 строк в 5 файлах, и я не могу понять это. Мне просто нужна горстка варов от завершенной транзакции, ничего больше. Возможно ли сделать это с помощью нескольких строк кода (и я имею в виду без "включаемых" файлов стоимостью 1300 строк) или процесс Google Checkout действительно такой громоздкий?

2 ответа

Решение

Я получил его на работу, и вот скелет моего кода, который можно использовать для обработки HTTP-уведомлений / ответов. Это было очевидно получено из примера tntu выше. (Спасибо!)

//incoming data is in the var $_POST['serial-number']
//"send" the response to acknowledge the serial number that google talks about all over but never explains how
echo "_type=notification-acknowledgment&serial-number=".$_POST['serial-number'];

//now we need to call google's server and ask for this transaction's data:
//you'll need to change your merchant id in the $url and $mid vars, and your merchant key in the $mky var
$url = "https://sandbox.google.com/checkout/api/checkout/v2/reportsForm/Merchant/1234567890?_type=notification-history-request&serial-number=" . $_REQUEST['serial-number'];
$mid = "1234567890"; 
$mky = "ABCDEFGHIJK";
$aut = base64_encode($mid . ":" . $mky);

$arr = parse_url($url);
$ssl = "";
if($arr['scheme'] == "https") $ssl = "ssl://";

$post  = "POST " . $arr['path'] . " HTTP/1.1\r\n";
$post .= "Host: " . $arr['host'] . "\r\n";
$post .= "Authorization: Basic " . $aut . "\r\n";
$post .= "Content-Type: application/xml; charset=UTF-8\r\n";
$post .= "Accept: application/xml; charset=UTF-8\r\n";
$post .= "Content-Length: " . strlen($arr['query']) . "\r\n";
$post .= "Connection: Close\r\n";
$post .= "\r\n";
$post .= $arr['query'];

//now we actually make the request by opening a socket and calling Google's server
$f = fsockopen($ssl . $arr['host'], 443, $errno, $errstr, 30);

if(!$f){
    //something failed in the opening of the socket, we didn't contact google at all, you can do whatever you want here such as emailing yourself about it and what you were trying to send, etc
    @mail("troubleshooting@yourdomain.com","Google IPN - HTTP ERROR ",$errstr . " (" . $errno . ")\n\n\n".$arr['query']);
}else{
    //the socket was opened, send the request for the order data: 
    fputs($f, $post); // you're sending
    while(!feof($f)) { $response .= @fgets($f, 128); } //google replies and you store it in $response
    fclose($f); //close the socket, we're done talking to google's server

    $spl=strpos($response,"_type="); //parse the type because parse_str won't catch it
    if ($spl!==false){
        $spl2=strpos($response,"&",$spl);
        $ordertype=substr($response,($spl+6),($spl2-$spl)-6);
    }//$ordertype will tell you which type of notification is being sent, new-order-notification, risk-information-notification, etc
    $subresponse=substr($response,$spl2+1); //put the rest of it into an array for easy access
    parse_str($subresponse,$order);//you can now access google's response in $order[] vars
    //IMPORTANT: dots in Google's field names are replaced by underscore, for example:
    // $order['google-order-number'] and $order['buyer-billing-address_address1'] NOT $order['buyer-billing-address.address1']
    //order field names are shown here: 
    //https://developers.google.com/checkout/developer/Google_Checkout_HTML_API_Notification_API#order_summary

     //this is the point where you will want to use the data contained in $order[] to create a new record in your database or whatever.
    //NOTE: be sure to store and check for duplicates using the google-order-number because you will get multiple notifications from google regarding the same order

    if (strtoupper($order['order-summary_financial-order-state']) == "CHARGEABLE"){
        //CHARGEABLE is what indicates it is safe to create a login for the user (if you are delivering digital goods) 
        // insert into db, and/or email user with key or download url
    }
}

Вот немного кода, который я начал. Еще не закончен. Работает отлично. Все, что вам нужно сделать, это взять данные, которые Google отправляет обратно, и этот код записывает в файл, и использовать его для вставки в вашу таблицу продаж, отправки уведомления о получении платежа клиенту и так далее. Хитрость заключается в том, что когда Google отправляет вам сообщение, вы должны перезвонить с заголовком авторизации, иначе он не примет это во внимание.

function post2google($url, $timeout = 30, $port = 80, $buffer = 128) {
  $mid = "123456789";
  $mky = "qwertyuiop";
  $aut = base64_encode($mid . ":" . $mky);

  $arr = parse_url($url);

  $ssl = "";
  if($arr['scheme'] == "https") $ssl = "ssl://";

  $post  = "POST " . $arr['path'] . " HTTP/1.1\r\n";
  $post .= "Host: " . $arr['host'] . "\r\n";

  $post .= "Authorization: Basic " . $aut . "\r\n";
  $post .= "Content-Type: application/xml; charset=UTF-8\r\n";
  $post .= "Accept: application/xml; charset=UTF-8\r\n";

  $post .= "Content-Length: " . strlen($arr['query']) . "\r\n";
  $post .= "Connection: Close\r\n";
  $post .= "\r\n";
  $post .= $arr['query'];

  $f = fsockopen($ssl . $arr['host'], $port, $errno, $errstr, $timeout);

  if(!$f)
    return $errstr . " (" . $errno . ")";

  else{
    fputs($f, $post);
    while(!feof($f)) { $echo .= @fgets($f, $buffer); }
    fclose($f);

    return $echo;
  }
}
$re =  post2google("https://checkout.google.com/api/checkout/v2/reportsForm/Merchant/123456789?_type=notification-history-request&serial-number=" . $_REQUEST['serial-number'], 3, 443);

$re = str_replace("&", "\n", $re) . "\n\n--\n\n";

file_put_contents("gpn.txt", $re, FILE_APPEND);
Другие вопросы по тегам