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

PayPal捐赠返回URL返回空数组问题求助

解决PayPal捐赠return页面无法获取交易数据的问题

我来帮你梳理下问题原因和解决方案:

为什么return页面拿不到数据?

你遇到的情况是PayPal捐赠按钮(_donations命令)的特性导致的:

  • 即使表单用POST方法,且设置了rm=2,PayPal对于捐赠类的请求,默认不会将交易详情通过POST/GET直接传递到return URL。
  • return URL的跳转只是给用户展示一个感谢页面,交易的核心数据需要通过**IPN(Instant Payment Notification)或者PDT(Payment Data Transfer)**来获取。你已经能正常接收IPN,说明IPN配置没问题,但return页面本身不会自动拿到这些数据。

解决方案一:启用PDT获取return页面的交易数据

PDT是PayPal提供的用来在return页面获取交易数据的功能,需要先在账户里启用:

1. 启用PDT并获取令牌

  • 登录你的PayPal账户(沙盒和正式环境要分别设置)
  • 进入【卖家设置】→【网站支付设置】→【付款数据传输】
  • 启用PDT,复制生成的PDT令牌

2. 修改捐赠表单

在现有表单里添加几个隐藏字段:

<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post" target="_top">
  <input type="hidden" name="cmd" value="_donations" />
  <input type="hidden" name="business" value="myEmail@gmail.com" />
  <input type="hidden" name="currency_code" value="USD" />
  <!-- 添加PDT相关字段 -->
  <input type="hidden" name="charset" value="utf-8">
  <input type="hidden" name="custom" value="<?php echo session_id(); ?>"> <!-- 可选:传递自定义标识,比如用户会话ID -->
  <input type="hidden" name="cbt" value="返回我的网站"> <!-- 可选:设置跳转按钮的文本 -->
  <input type="hidden" name="return" value="http://localhost/thankyou.php" id="paypal_return">
  <input type="hidden" name="notify_url" value="https://test.org/ipn_route_for_payment" id="ipn_url">
  <input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" title="PayPal - The safer, easier way to pay online!" alt="Donate with PayPal button" />
  <img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
</form>

3. 修改thankyou.php代码获取PDT数据

替换你当前的PHP代码,通过PayPal的同步接口验证并获取交易数据:

<?php
// 替换成你的PDT令牌(沙盒和正式环境的令牌不同)
$pdt_token = '你的PDT令牌';
$tx_id = $_GET['tx']; // PDT会通过GET传递交易ID参数tx

if (!empty($tx_id)) {
    $ch = curl_init();
    // 沙盒环境用这个URL,正式环境替换为https://www.paypal.com/cgi-bin/webscr
    curl_setopt($ch, CURLOPT_URL, 'https://www.sandbox.paypal.com/cgi-bin/webscr');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
        'cmd' => '_notify-synch',
        'tx' => $tx_id,
        'at' => $pdt_token
    ]));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch);

    if (strpos($response, 'SUCCESS') === 0) {
        // 解析响应数据
        $transaction_data = [];
        $lines = explode("\n", trim($response));
        foreach ($lines as $line) {
            if (strpos($line, '=') !== false) {
                list($key, $value) = explode('=', $line, 2);
                $transaction_data[urldecode($key)] = urldecode($value);
            }
        }
        print_r($transaction_data);
    } else {
        echo '获取交易数据失败,请稍后重试';
    }
} else {
    echo '无效的交易请求';
}
?>

解决方案二:结合IPN存储数据,在return页面查询

因为你已经能正常接收IPN,也可以用这种方式:

1. 修改表单添加自定义标识

在表单里加一个custom字段,用来传递唯一标识(比如用户会话ID):

<input type="hidden" name="custom" value="<?php echo session_id(); ?>">

2. 在IPN处理页面存储交易数据

修改你的ipn_route_for_payment页面,把IPN接收到的交易数据(比如txn_id、mc_gross、custom等)存储到数据库中。

3. 在thankyou.php查询数据

当PayPal跳转回return页面时,会通过GET传递tx参数(交易ID),用这个ID去数据库查询已存储的交易数据:

<?php
session_start();
$tx_id = $_GET['tx'];

if (!empty($tx_id)) {
    // 连接你的数据库(示例用PDO,可根据你的数据库类型调整)
    $pdo = new PDO('mysql:host=localhost;dbname=你的数据库名', '用户名', '密码');
    $stmt = $pdo->prepare('SELECT * FROM paypal_donations WHERE txn_id = ?');
    $stmt->execute([$tx_id]);
    $donation = $stmt->fetch(PDO::FETCH_ASSOC);

    if ($donation) {
        print_r($donation);
    } else {
        echo '捐赠记录暂未同步,请稍后刷新页面';
    }
} else {
    echo '无效的交易请求';
}
?>

补充说明

  • 为什么rm=2没生效?PayPal的_donations命令不支持rm参数的POST返回,这个参数仅适用于普通支付按钮(如_xclick),捐赠按钮的return跳转默认是GET,且不会携带交易详情。
  • 沙盒和正式环境的PDT令牌、接口URL都要分开设置,不能混用。
  • 无论用PDT还是IPN,都要验证数据的真实性,避免伪造请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 08:02:50