如何在PHP中将PayPal沙箱账户切换至正式账户及回调数据问题
解决PayPal正式环境下付款成功页面无法获取交易数据的问题
看起来你遇到的问题核心是:PayPal的return参数仅负责跳转,默认不会主动将交易详情发送到你的成功页面——不管是沙箱还是正式环境,这点其实是一致的,可能之前沙箱测试时你没注意到数据缺失,或者用了特殊测试场景。要在付款成功后同步获取交易ID、金额等数据,你需要启用并配置付款数据传输(PDT),这是PayPal专为同步返回交易数据到商家页面设计的功能。
下面是具体的解决步骤:
第一步:在PayPal商家后台启用PDT并获取身份令牌
- 登录你的PayPal正式商家账户
- 进入设置 -> 付款设置
- 找到网站付款习惯设置,点击旁边的“更新”
- 找到“付款数据传输”选项,点击“启用”
- 启用后,你会看到一个身份令牌(Identity Token),复制这个令牌,后面会用到
第二步:修改你的PayPal表单代码
需要在原有表单中添加关键参数,告诉PayPal启用PDT并以安全方式返回数据:
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top" class="float-right w_100"> <input type="hidden" name="cmd" value="_xclick"> <input type="hidden" name="business" value="business@awakeningsme.com"> <input type="hidden" name="lc" value="US"> <input type="hidden" name="item_name" value="Awakenings Products"> <input type="hidden" name="item_number" value="<?php echo $pro_id ?>"> <input type="hidden" name="amount" value="<?php echo $total; ?>"> <input type="hidden" name="currency_code" value="USD"> <!-- 添加PDT核心参数 --> <input type="hidden" name="rm" value="2"> <!-- 强制PayPal用POST方式返回数据,更安全 --> <input type="hidden" name="cbt" value="返回我的网站"> <!-- 跳转页面上的按钮自定义文字 --> <input type="hidden" name="return" value="http://mywebsite.com/paypal_success.php"> <input type="hidden" name="cancel_return" value="http://mywebsite.com/paypal_cancel.php"> <input type="hidden" name="button_subtype" value="services"> <input type="hidden" name="no_note" value="0"> <input type="hidden" name="bn" value="PP-BuyNowBF:btn_buynowCC_LG.gif:NonHostedGuest"> <input type="image" src="https://www.paypalobjects.com/webstatic/en_US/i/buttons/buy-logo-large.png" alt="Buy now with PayPal" border="0" name="submit"> </form>
rm=2:指定PayPal使用POST方法将数据发送到你的成功页面,这样你能在paypal_success.php中通过$_POST获取数据;如果想用GET方式,可设为rm=1,但POST安全性更高。
第三步:编写paypal_success.php的验证与数据获取代码
PayPal会将交易参数POST到你的成功页面,但必须验证数据的真实性(防止恶意伪造付款成功请求)。你需要用返回的交易ID加上PDT身份令牌,向PayPal发送验证请求,再解析合法的响应数据。
示例代码:
<?php // 替换为你从PayPal后台获取的PDT身份令牌 $identity_token = "你的PDT身份令牌"; // 获取PayPal发送的交易ID $tx_id = $_POST['tx'] ?? ''; if (empty($tx_id)) { echo "无效的付款请求,请重试。"; exit; } // 构建PayPal验证请求URL $validate_url = "https://www.paypal.com/cgi-bin/webscr?cmd=_notify-synch&tx=$tx_id&at=$identity_token"; // 发送验证请求(使用cURL,确保服务器支持) $ch = curl_init($validate_url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); // 开启SSL验证,防止中间人攻击 $response = curl_exec($ch); curl_close($ch); // 解析验证响应 if (strpos($response, "SUCCESS") === 0) { // 验证成功,提取交易数据 $lines = explode("\n", trim($response)); $transaction_data = []; foreach ($lines as $line) { if (strpos($line, "=") !== false) { list($key, $value) = explode("=", $line, 2); $transaction_data[urldecode($key)] = urldecode($value); } } // 提取你需要的字段 $transaction_id = $transaction_data['txn_id'] ?? '未知'; $amount = $transaction_data['mc_gross'] ?? '0.00'; $item_name = $transaction_data['item_name'] ?? '未知商品'; $item_number = $transaction_data['item_number'] ?? '未知编号'; // 这里可以将数据存入数据库,或展示给用户 echo "<h3>付款成功!</h3>"; echo "<p>交易ID: $transaction_id</p>"; echo "<p>付款金额: $amount USD</p>"; echo "<p>商品名称: $item_name</p>"; echo "<p>商品编号: $item_number</p>"; } else { // 验证失败,可能是伪造请求或网络问题 echo "付款验证失败,请联系客服确认付款状态。"; } ?>
额外注意事项
- 确保你的服务器支持cURL(大部分主流主机都支持);如果不支持,可以用
file_get_contents替代,但需要开启allow_url_fopen配置。 - 正式环境下必须做验证步骤,不要直接信任POST过来的数据,避免恶意伪造付款成功的请求。
- 如果需要处理用户关闭浏览器未跳转回页面的场景,建议同时启用IPN(即时付款通知)——PDT负责同步跳转时的数据返回,IPN负责后台异步通知交易状态,两者可以配合使用。
内容的提问来源于stack exchange,提问作者Kashmiri Ammar
相关产品推荐
相关产品推荐

