【问题标题】:Using PHP with Google serial notification (IPN)将 PHP 与 Google 串行通知 (IPN) 结合使用
【发布时间】:2012-09-02 16:18:22
【问题描述】:

我正在尝试弄清楚如何使用 PHP 来实现这一点。我有一个可用的贝宝 IPN,不到 20 行代码就可以获取我需要的数据。我试过阅读谷歌文档,但它们要么太具体,要么太笼统。有一些示例代码,在 5 个文件中大约有 1300 行,我无法理解。我只需要从已完成的事务中返回一些 var,仅此而已。是否可以用几行代码(我的意思是没有价值 1300 行的“包含”文件)来做到这一点,或者 Google Checkout 的过程真的那么庞大吗?

【问题讨论】:

    标签: php notifications checkout


    【解决方案1】:

    这是我开始的一些代码。还没有完成。 它完美地工作。 您需要做的就是获取 Google 发回的数据,并将此代码写入文件并使用它插入到您的销售表中,将收到的付款通知发送给客户等等。 诀窍是,当 Google 向您发送帖子时,您必须使用 Authorization 标头进行回调,否则它不会考虑它。

    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);
    

    【讨论】:

    • 谢谢,如果我能设置一个沙盒帐户,我会尝试并在这里发布我的结果。它不断为我注册一个看似普通的帐户。
    • 更新:我还没有进入沙箱,但确实收到了一个尝试发送通知的不同产品的订单,所以我设置了我的 IPN 处理程序以使用上面的代码和电子邮件我与正在发生的事情。
    • 如果您的身份验证数据正常,它会在 Google 发送通知时做出适当的响应,就是这样。从那时起,您需要查看 Google 发送的数据(如果交易是最终且成功的)并将其插入您的数据库中,这样用户就可以下载他的产品(如果它是数字的)或跟踪它是否是物理的。您也可以向买家发送电子邮件。注意:Google 会发送不止一个通知。一个在下订单时,一个在买家成功收费时。在那个阶段你需要发布产品。
    • 是的,但我遇到的一个主要问题是“查看 Google 发送的数据”,因为我在任何地方都找不到任何说明我在何处/如何访问该数据的信息。我是否查看 POST 变量、REQUEST 变量、圣诞老人的来信等。每个人都认为这只是常识,并说完全相同,“处理来自 Google 的数据”。另一个问题,因为我在 PHP 中的弱点是处理跨服务器通信,是如何构建 Google 想要的响应,以及如何“发送”它。上面的示例似乎适合做这些,并且与我的 paypal IPN 处理程序几乎相同。
    • 我添加了一些行让处理程序通过电子邮件向我发送它在做什么。谷歌尝试再次通知它,这次我收到了显示数据的电子邮件。 (我相信它在 URL 中?但无论如何我可以从 $echo var 访问它,如果没有别的。)我确实有我的商家 ID 和密钥,但谷歌仍然说响应无效。所以现在我有足够的资金将订单放入我的数据库并通过电子邮件通知买家。但另一个奇怪的是,当我已经将它标记为已收费并在我的结帐帐户中发货时,它给了我“financial-order-state=REVIEWING”。
    【解决方案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
        }
    }
    

    【讨论】:

    • 感谢您使用基于我的解决方案回答您自己的问题,甚至没有 +1。
    • 是的,抱歉,我试过了,但在我有 15 个声望点之前它不会让我!
    • @tntu 通过用我发布的代码替换它然后删除这个答案来编辑你的答案会更好吗? (我想至少包括回声、cmets 和解析,以便下一个尝试使用它的人更容易。)我不关心分数,我只是不想让其他人不得不处理我所做的只是为了让 IPN 正常工作。
    猜你喜欢
    • 1970-01-01
    • 2021-04-15
    • 2013-08-15
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多