如何实现Paypal快速结账以获取IPN消息?

时间:2013-11-19 14:03:55

标签: php codeigniter paypal paypal-ipn paypal-sandbox

我尝试实施Paypal快速结账,但我发现了一个问题。我不知道如何正确实现IPN。这是我的表单代码:

<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">

                <!-- Identify your business so that you can collect the payments. -->
                <input type="hidden" name="business" value="myemail@mydomain.com">

                <!-- Specify a Buy Now button. -->
                <input type="hidden" name="cmd" value="_xclick" />

                <!-- Specify details about the item that buyers will purchase. -->
                <input type="hidden" name="item_name" value="Payment order" />
                <input type="hidden" name="amount" value=7 />
                <input type="hidden" name="currency_code" value="EUR" />
                <input type="hidden" name="notify_url" value="http://mysite/checkout/paypal_ipn" />


                <!-- Display the payment button. -->
                <input type="image" name="submit" border="0" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynow_LG.gif" alt="PayPal - The safer, easier way to pay online">
                <img alt="" border="0" width="1" height="1" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" >

            </form>

当我使用CodeIgniter时,我在Controller中创建了一个函数来处理来自Paypal的响应。这是代码:

function paypal_ipn() {
    header('HTTP/1.1 200 OK');
    // Assign payment notification values to local variables
    $item_name = $_POST['item_name'];
    $item_number = $_POST['item_number'];
    $payment_status = $_POST['payment_status'];
    $payment_amount = $_POST['mc_gross'];
    $payment_currency = $_POST['mc_currency'];
    $txn_id = $_POST['txn_id'];
    $receiver_email = $_POST['receiver_email'];
    $payer_email = $_POST['payer_email'];

    // Build the required acknowledgement message out of the notification just received
    $req = 'cmd=_notify-validate';               // Add 'cmd=_notify-validate' to beginning of the acknowledgement

    foreach ($_POST as $key => $value) {         // Loop through the notification NV pairs
        $value = urlencode(stripslashes($value));  // Encode these values
        $req .= "&$key=$value";                   // Add the NV pairs to the acknowledgement
    }

    // Set up the acknowledgement request headers
    $header = "POST /cgi-bin/webscr HTTP/1.1\r\n";                    // HTTP POST request
    $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";

    // Open a socket for the acknowledgement request
    $fp = fsockopen('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);

    // Send the HTTP POST request back to PayPal for validation
    fputs($fp, $header . $req);

    while (!feof($fp)) {                     // While not EOF
        $res = fgets($fp, 1024);               // Get the acknowledgement response
        if (strcmp($res, "VERIFIED") == 0) {  // Response contains VERIFIED - process notification

            echo "VERIVIED";
        } else if (strcmp($res, "INVALID") == 0) { //Response contains INVALID - reject notification
            // Authentication protocol is complete - begin error handling

            echo "INVALID";
        }
    }
    fclose($fp);  // Close the file
}

我预计买家在Paypal完成付款后,会将其重定向到我在表格中说明的notify_url,如果是VERIFIED或INVALID,我会收到消息。但事实是它留在了Paypal的“谢谢”页面。

我对代码做错了什么,所以无法收到通知。

3 个答案:

答案 0 :(得分:0)

这里的这个章节已经制作了一个IPN类,它可以用我用PayPal沙箱测试它 http://www.micahcarrick.com/paypal-ipn-with-php.html

答案 1 :(得分:0)

这不是IPN的工作原理,IPN是异步的,并且独立于用户。

客户流程:

您网站的购物车 - &gt; Paypal付款 - &gt; Paypal感谢您或重定向到您的订单完成

IPN流程:

等待交易 - &gt; POSTS数据到您的网址 - &gt;您的网站验证数据 - &gt;在DB中插入/更新订单

答案 2 :(得分:0)

@Abaij - 将记录器添加到您的IPN使用者代码,该代码将状态消息写入本地文件。确保它是您的IPN消费者代码中的第一行代码,以便在事先抛出异常时不会错过它。 确保您的站点具有对记录器打算写入的drive \文件夹的写访问权。 使用IPN模拟器也会向您的站点发送测试IPN并查看是否写入了日志。如果你得到一个日志,那么你确认消费者正在被击中。如果是这种情况,那么您还需要进一步了解您是否验证过PayPal是否按预期工作。如果您没有获得日志文件,请检查您的站点从外部世界可以看到端口80。

Br