drogon982007 2018-12-06 02:06
浏览 39

收到Paypal IPN后无法做任何事情

I am using Paypal's two IPN scripts from github here: https://github.com/paypal/ipn-code-samples/tree/master/php however they aren't working.

I send the test IPN using Paypal's tool here: https://developer.paypal.com/developer/ipnSimulator/ and it says it was succesful: "IPN was sent and the handshake was verified."

However, I can't do what I want after that. I've tried inserting into a database or even just sending a success email. Both of these work fine when done on their own but when I add it to the IPN script nothing happens.

PaypalIPN.php (copied from the github)

<?php
class PaypalIPN
{
/** @var bool Indicates if the sandbox endpoint is used. */
private $use_sandbox = false;
/** @var bool Indicates if the local certificates are used. */
private $use_local_certs = true;
/** Production Postback URL */
const VERIFY_URI = 'https://ipnpb.paypal.com/cgi-bin/webscr';
/** Sandbox Postback URL */
const SANDBOX_VERIFY_URI = 'https://ipnpb.sandbox.paypal.com/cgi- bin/webscr';
/** Response from PayPal indicating validation was successful */
const VALID = 'VERIFIED';
/** Response from PayPal indicating validation failed */
const INVALID = 'INVALID';
/**
 * Sets the IPN verification to sandbox mode (for use when testing,
 * should not be enabled in production).
 * @return void
 */
public function useSandbox()
{
    $this->use_sandbox = true;
}
/**
 * Sets curl to use php curl's built in certs (may be required in some
 * environments).
 * @return void
 */
public function usePHPCerts()
{
    $this->use_local_certs = false;
}
/**
 * Determine endpoint to post the verification data to.
 *
 * @return string
 */
public function getPaypalUri()
{
    if ($this->use_sandbox) {
        return self::SANDBOX_VERIFY_URI;
    } else {
        return self::VERIFY_URI;
    }
}
/**
 * Verification Function
 * Sends the incoming post data back to PayPal using the cURL library.
 *
 * @return bool
 * @throws Exception
 */
public function verifyIPN()
{
    if ( ! count($_POST)) {
        throw new Exception("Missing POST Data");
    }
    $raw_post_data = file_get_contents('php://input');
    $raw_post_array = explode('&', $raw_post_data);
    $myPost = array();
    foreach ($raw_post_array as $keyval) {
        $keyval = explode('=', $keyval);
        if (count($keyval) == 2) {
            // Since we do not want the plus in the datetime string to be encoded to a space, we manually encode it.
            if ($keyval[0] === 'payment_date') {
                if (substr_count($keyval[1], '+') === 1) {
                    $keyval[1] = str_replace('+', '%2B', $keyval[1]);
                }
            }
            $myPost[$keyval[0]] = urldecode($keyval[1]);
        }
    }
    // Build the body of the verification post request, adding the _notify-validate command.
    $req = 'cmd=_notify-validate';
    $get_magic_quotes_exists = false;
    if (function_exists('get_magic_quotes_gpc')) {
        $get_magic_quotes_exists = true;
    }
    foreach ($myPost as $key => $value) {
        if ($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) 
    {
            $value = urlencode(stripslashes($value));
        } else {
            $value = urlencode($value);
        }
        $req .= "&$key=$value";
    }
    // Post the data back to PayPal, using curl. Throw exceptions if errors occur.
    $ch = curl_init($this->getPaypalUri());
    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
    curl_setopt($ch, CURLOPT_SSLVERSION, 6);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    // This is often required if the server is missing a global cert bundle, or is using an outdated one.
    if ($this->use_local_certs) {
        curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . "/cert/cacert.pem");
    }
    curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'User-Agent: PHP-IPN-Verification-Script',
        'Connection: Close',
    ));
    $res = curl_exec($ch);
    if ( ! ($res)) {
        $errno = curl_errno($ch);
        $errstr = curl_error($ch);
        curl_close($ch);
        throw new Exception("cURL error: [$errno] $errstr");
    }
    $info = curl_getinfo($ch);
    $http_code = $info['http_code'];
    if ($http_code != 200) {
        throw new Exception("PayPal responded with http code $http_code");
    }
    curl_close($ch);
    // Check if PayPal verifies the IPN data, and if so, return true.
    if ($res == self::VALID) {
        return true;
    } else {
        return false;
    }
    }
}

This is my IPN handler URL, example_usage.php (also copied from the github, I just added the one line to send an email, which does nothing when I send the test IPN):

<?php namespace Listener;
require('PaypalIPN.php');
use PaypalIPN;
$ipn = new PaypalIPN();
// Use the sandbox endpoint during testing.
$ipn->useSandbox();
$verified = $ipn->verifyIPN();
if ($verified) {
    /*
     * Process IPN
     * A list of variables is available here:
     * 
https://developer.paypal.com/webapps/developer/docs/classic/ipn/integration- 
guide/IPNandPDTVariables/
     */


//THIS IS THE ONLY PART I HAVE ADDED, BUT NOTHING IS HAPPENING
$name = '' //Get name from form input
$email = '' //Get email from form input
$amount = '' //Get amount from hidden form input
$subject = 'New order from' . $name
$message = 'New order. Amount: ' . $amount

//For some reason this isn't being sent, even if I change $subject and $message to my own string.
$sendemail= mail("***@***.com", $subject, $message);

}
// Reply with an empty 200 response to indicate to paypal the IPN was 
received correctly.
header("HTTP/1.1 200 OK");

?>

Does anyone have an idea of what the problem is? Thanks if so

  • 写回答

1条回答 默认 最新

  • duannv2081 2018-12-09 09:34
    关注

    You need to make sure the IPNs are triggering as expected, and are being sent to the URL you expect.

    Follow the steps outlined here and you'll be able to find the problem, which includes:

    1. Local Testing
    2. IPN Simulator
    3. Sandbox Transaction Testing
    4. Deployment
    5. Additional tips for troubleshooting.
    评论

报告相同问题?

悬赏问题

  • ¥100 有人会搭建GPT-J-6B框架吗?有偿
  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名