本文介绍了贝宝IPN和fsockopen的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我不能使用cURL,无法更改的Web主机上安装的版本不支持TLS.

Well I can't use cURL, the version installed on my web host that can't be changed doesn't support TLS.

我现在正在尝试使用fsockopen来查看我是否能够使用IPN.

I'm trying to use fsockopen now to see if i'll be able to use IPN.

它只是挂起,浏览器抛出连接超时.

It just hangs and browser throws connection timeout.

PHP 7,open_ssl已启用

PHP 7, open_ssl is enabled

<?php
    header('HTTP/1.1 200 OK');

    $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'];

    $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 = trim(fgets ($fp, 1024));

    if (strcmp ($res, "VERIFIED") == 0) {  // Response contains VERIFIED - process notification

      file_put_contents('./log_'.date("j.n.Y").'.txt', 'VERIFIED', FILE_APPEND);
    }
    else if (strcmp ($res, "INVALID") == 0) { Response contains INVALID - reject notification
        file_put_contents('./log_'.date("j.n.Y").'.txt', 'INVALID', FILE_APPEND);
    }
  }
  //close
  fclose($fp);
?>

UPDATE

UPDATE

所以我当前的代码似乎有问题.我使用以下内容查看是否可以与PayPal通话.

So it appears to be an issue with my current code. I used the following to see if I could talk to PayPal.

<?php

$site = "sandbox.paypal.com";//works
$port = 443;

$fp = fsockopen($site, $port, $errno, $errstr, 30);

if(!$fp){
  echo "<b>The port is NOT open!</b>";
}else{
  echo "<b>The port is open!</b>";
  fclose($fp);
}

?>

结果为The port is open!

更新2

UPDATE 2

好吧,我现在使用以下代码从IPN模拟器获取响应.我遇到的其他问题是我无法使用侦听器的FQDN并放弃了http://.

Ok I'm now getting the response from the IPN Simulator using the below code. The other issues I was having was I failed to use the FQDN of my listener and left off http://.

所以现在下一个问题是$res = trim($res);始终为空,但我的post变量不是.这是因为它是一个沙箱吗?

So now the next problem is $res = trim($res); is always blank but my post variables aren't. Is this because it's a sandbox?

<?php
    $debug            = 1;
    $sandbox          = 1;

    header('HTTP/1.1 200 OK');

    $item_name        = $_POST['item_name'];
    $item_number      = $_POST['item_number'];
    $payment_status   = $_POST['payment_status'];
    if ($_POST['mc_gross'] != null) {
        $payment_amount   = $_POST['mc_gross'];
    } else {
        $payment_amount   = $_POST['mc_gross1'];
    }
    $payment_currency = $_POST['mc_currency'];
    $txn_id           = $_POST['txn_id'];
    $receiver_email   = $_POST['receiver_email'];
    $payer_email      = $_POST['payer_email'];
    $payment_date     = $_POST['payment_date'];
    $first_name       = $_POST['first_name'];
    $last_name        = $_POST['last_name'];
    $item_name        = $_POST['item_name'];

    $sandbox_url      = "sandbox.paypal.com";
    $prod_url         = "paypal.com";
    $verfiy_email     = "you email address the payment should be made to";

    if ($sandbox) {
        $url = $sandbox_url;
    } else {
        $url = $prod_url;
    }

    if ($debug) {
        error_log(date('[Y-m-d H:i e] '). "IPN URL: " . $url . PHP_EOL, 3, LOG_FILE);
    }

    $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

        if ($debug) {
            error_log(date('[Y-m-d H:i e] '). "POST Data: " . $key . " - " . $value . PHP_EOL, 3, LOG_FILE);
        }
    }

    //post back to PayPal system to validate (replaces old headers)
    $header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
    $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $header .= "Host: www." . $url . "\r\n";
    $header .= "Connection: close\r\n";
    $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
    $fp = fsockopen ('sandbox.paypal.com', 443, $errno, $errstr, 30);

    //error connecting to paypal
    if (!$fp) {
        error_log(date('[Y-m-d H:i e] '). "Can't connect to PayPal to validate IPN message: " . $errno . " - " . $errstr . PHP_EOL, 3, LOG_FILE);
    }

    //successful connection
    if ($fp) {
        fputs ($fp, $header . $req);

        while (!feof($fp)) {
            $res = fgets ($fp, 1024);
            $res = trim($res); //NEW & IMPORTANT

            if ($debug) {
                error_log(date('[Y-m-d H:i e] '). "DEBUG: Validation - " . $res . PHP_EOL, 3, LOG_FILE);
                error_log(date('[Y-m-d H:i e] '). "DEBUG: Payment Status - " . $payment_status . PHP_EOL, 3, LOG_FILE);
                error_log(date('[Y-m-d H:i e] '). "DEBUG: Receiver Email - " . $receiver_email . PHP_EOL, 3, LOG_FILE);
                error_log(date('[Y-m-d H:i e] '). "DEBUG: Verify Email - " . $verfiy_email . PHP_EOL, 3, LOG_FILE);
            }

            //I don't see this
            if (strcmp($res, "VERIFIED") == 0) {
                //insert order into database
                if ($debug) {
                    error_log(date('[Y-m-d H:i e] '). "Response Message: " . "VERIFIED" . PHP_EOL, 3, LOG_FILE);
                }
            }

            //I don't see this
            if (strcmp ($res, "INVALID") == 0) {
                //insert into DB in a table for bad payments for you to process later
                if ($debug) {
                    error_log(date('[Y-m-d H:i e] '). "Response Message: " . "INVALID" . PHP_EOL, 3, LOG_FILE);
                }
            }

            if (strcasecmp ($payment_status, "Completed") == 0 && strcasecmp($receiver_email, $verfiy_email) == 0) {
                if ($debug) {
                    error_log(date('[Y-m-d H:i e] '). "Response Message: " . "Payment VERIFIED" . PHP_EOL, 3, LOG_FILE);
                }
            } else {
                if ($debug) {
                    error_log(date('[Y-m-d H:i e] '). "Response Message: " . "Payment INVALID" . PHP_EOL, 3, LOG_FILE);
                }
            }
        }

        fclose($fp);
    }
?>

推荐答案

我遇到了相同的问题,沙箱返回的结果为空.我的代码类似于Tsukasa提供的Update 2.

I encountered the same issue, where the sandbox was returning an empty result. My code was similar to the Update 2 provided by Tsukasa.

我不得不将sandbox.paypal.com更改为ipnbp.sandbox.paypal.com,并以ssl作为前缀. fsocket调用看起来像:

I had to change sandbox.paypal.com to ipnbp.sandbox.paypal.com, and prefix it with ssl. The fsocket call looks like:

$fp = fsockopen ('ssl://ipnbp.sandbox.paypal.com', 443, $errno, $errstr, 30);

这篇关于贝宝IPN和fsockopen的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 23:57