You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP实现PayPal IPN返回INVALID问题求助

解决PayPal IPN监听器的连接与验证问题

嘿,我来帮你搞定这个IPN的问题!从你的描述来看,核心问题主要出在沙箱环境的端点地址使用错误以及fsockopen的调用方式上,咱们一步步来修正:

首先明确正确的PayPal IPN端点

PayPal在2018年后确实更新了IPN的端点,现在沙箱和生产环境的正确地址是:

  • 沙箱环境:ipnpb.sandbox.paypal.com(端口443,SSL加密)
  • 生产环境:ipnpb.paypal.com(端口443,SSL加密)

你之前的错误在于:

  • 用https://www.sandbox.paypal.com或者带完整路径的URL作为fsockopen的主机参数——fsockopen只需要主机名,不能带协议前缀(https://)或路径
  • 混淆了沙箱和生产环境的地址,用生产地址www.paypal.com测试沙箱IPN,自然会返回INVALID

修正后的fsockopen代码实现

这里给你调整好的沙箱环境IPN验证代码,注释里标注了生产环境的切换方式:

<?php
// 发送200响应,避免PayPal重复发送通知
header('HTTP/1.1 200 OK');

// 构造验证请求参数
$resp = 'cmd=_notify-validate';
foreach ($_POST as $parm => $var) {
    $var = urlencode(stripslashes($var));
    $resp .= "&$parm=$var";
}

// 沙箱环境配置(生产环境把主机换成ipnpb.paypal.com即可)
$host = 'ssl://ipnpb.sandbox.paypal.com';
$port = 443;
$errno = '';
$errstr = '';

// 建立SSL连接
$fh = fsockopen($host, $port, $errno, $errstr, 30);

if (!$fh) {
    // 连接失败,记录错误信息到日志
    error_log("IPN连接失败: $errstr ($errno)");
} else {
    // 构造HTTP请求头
    $httphead = "POST /cgi-bin/webscr HTTP/1.1\r\n";
    $httphead .= "Host: ipnpb.sandbox.paypal.com\r\n"; // 生产环境换成ipnpb.paypal.com
    $httphead .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $httphead .= "Content-Length: " . strlen($resp) . "\r\n";
    $httphead .= "Connection: Close\r\n\r\n";

    // 发送验证请求
    fputs($fh, $httphead . $resp);

    // 读取PayPal响应
    while (!feof($fh)) {
        $readresp = fgets($fh, 1024);
        $trimmedResp = trim($readresp);
        
        if ($trimmedResp === "VERIFIED") {
            // IPN验证通过,处理业务逻辑(比如更新订单状态)
            error_log("IPN验证成功");
        } elseif ($trimmedResp === "INVALID") {
            // IPN验证失败,记录日志并排查原因
            error_log("IPN验证失败");
        }
    }
    fclose($fh);
}
?>

额外的排查建议

  1. 强制使用沙箱环境:测试时确保所有配置(包括IPN模拟器、你的代码端点)都指向沙箱,不要和生产环境混着用
  2. 改用cURL替代fsockopen:有些服务器会禁用fsockopen,cURL的兼容性更好,这里给你简化的cURL版本:
    <?php
    header('HTTP/1.1 200 OK');
    $resp = 'cmd=_notify-validate' . '&' . file_get_contents('php://input');
    
    $ch = curl_init('https://ipnpb.sandbox.paypal.com/cgi-bin/webscr');
    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $resp);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
    
    $response = curl_exec($ch);
    if (trim($response) === 'VERIFIED') {
        // 验证通过
    } else {
        // 验证失败
    }
    curl_close($ch);
    ?>
    
  3. 检查服务器日志:连接失败时,把$errno和$errstr的值记录到日志,能帮你快速定位是防火墙、SSL配置还是网络问题
  4. 验证IPN模拟器的参数:确保模拟器里填写的回调URL是公开可访问的,并且能接收POST请求

内容的提问来源于stack exchange,提问作者Parapluie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:57:41