设置PayPal返回URL并使其自动返回?

131

这是一个关于以下问题的后续提问: PHP: Easy way to start PayPal checkout?

我的问题是我指定了返回URL。然而,在使用PayPal支付后,我最终到达一个屏幕,上面显示:

您刚刚完成了付款。XXXX,您已经完成了付款。 此次支付的交易ID为:XXXXXXXXXXXX。

我们将向XX@XXXX.com发送确认电子邮件。此交易将显示为PAYPAL。

Go to PayPal account overview
我需要让它不显示此屏幕,并直接转到返回URL。我已经完成以下操作:
  • 设置“返回”变量
  • 将“rm”变量设置为:2(根据指南=“使用POST方法将买家的浏览器重定向到返回URL,并包括所有付款变量”)
实际上,这是我的整个表单:
<form method="post" action="https://www.sandbox.paypal.com/cgi-bin/webscr">
  <input type="hidden" value="_xclick" name="cmd">
  <input type="hidden" value="onlinestore@thegreekmerchant.com" name="business">
  <!-- <input type="hidden" name="undefined_quantity" value="1" /> -->
  <input type="hidden" value="Order at The Greek Merchant:&lt;Br /&gt;Goldfish Flock BLG&lt;br /&gt;" name="item_name">
  <input type="hidden" value="NA" name="item_number">
  <input type="hidden" value="22.16" name="amount">
  <input type="hidden" value="5.17" name="shipping">
  <input type="hidden" value="0" name="discount_amount">        
  <input type="hidden" value="0" name="no_shipping">
  <input type="hidden" value="No comments" name="cn">
  <input type="hidden" value="USD" name="currency_code">
  <input type="hidden" value="http://XXX/XXX/XXX/paypal/return" name="return">
  <input type="hidden" value="2" name="rm">      
  <input type="hidden" value="11255XXX" name="invoice">
  <input type="hidden" value="US" name="lc">
  <input type="hidden" value="PP-BuyNowBF" name="bn">
  <input type="submit" value="Place Order!" name="finalizeOrder" id="finalizeOrder" class="submitButton">
</form>

有什么办法可以让它自动返回?或者,如何将支付结果返回到我的网站,以便我可以更新数据库?什么是IPN?


请注意,您自定义返回参数中输入的主机名必须与您在PayPal账户中配置的相同。 - Andreas
6个回答

203

您需要在PayPal账户中启用自动返回功能,否则它将忽略return字段。

根据文档(更新于2019年1月):

默认情况下,自动返回已关闭。要启用自动返回,请执行以下操作:

  1. 登录到https://www.paypal.comhttps://www.sandbox.paypal.com上的PayPal帐户。 出现“我的账户概述”页面。
  2. 单击右上角的齿轮图标。 出现“个人资料摘要”页面。
  3. 单击左侧列中的“我的销售首选项”链接。
  4. 在“在线销售”部分下,单击“网站偏好设置”行中的“更新”链接。 出现“网站支付偏好设置”页面。
  5. 在“网站支付的自动返回”下,单击“开启”单选按钮以启用自动返回。
  6. 在“Return URL”字段中,输入您想要支付者完成付款后重定向的URL。 注意:PayPal会检查您输入的Return URL。如果URL格式不正确或无法验证,PayPal将不会激活自动返回。
  7. 滚动到页面底部,并单击“保存”按钮。

IPN是即时付款通知。它将为您提供比自动返回更可靠/有用的信息。

IPN文档在此处:https://www.x.com/sites/default/files/ipnguide.pdf

IPN的在线文档: https://developer.paypal.com/docs/classic/ipn/gs_IPN/

一般流程是您在请求中传递一个notify_url参数,并设置一个处理和验证IPN通知的页面,当支付/退款等操作发生时,PayPal会向该页面发送请求来通知您。然后,该IPN处理程序页面将是更新数据库以标记订单已付款的正确位置。


2
请点击此处查看 https://www.paypal.com/cgi-bin/webscr?cmd=p/mer/express_return_summary-outside - NoWar
5
随着Paypal新的网站布局,这不再完全准确。步骤3)点击“我的销售工具”,步骤4)在“在线销售”下点击“网站首选项”。 - Ben
2
IPN应该用于验证PayPal是否正确处理了订单,但是您仍然需要返回URL以向用户显示您已经意识到成功。很多时候,用户无法收到您发送的电子邮件,因此如果他们可以立即访问产品(下载等),那就太好了。 - pcunite
1
@Kevin Stricker,我们如何为两个不同的网站设置返回URL?例如,如果我在两个网站上使用一个Paypal账号,但是按照您的步骤只能添加一个URL作为返回URL。那么我该如何将其用于两个网站? - Gaurav
4
“如果你没有在PayPal账户中启用自动返回功能,那么它将忽略return字段”这句话并不完全准确。无论你是否在卖家的PayPal账户配置中设置了自动返回URL,任何传递给结帐过程中的return URL参数都将被优先使用。但是,如果卖家没有启用自动返回功能,则买家需要手动点击结帐末尾才能被重定向到该URL,而不会自动重定向。” - SubGothius
显示剩余15条评论

45

使用PHP进行直接支付的示例表单。

<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
    <input type="hidden" name="cmd" value="_cart">
    <input type="hidden" name="upload" value="1">
    <input type="hidden" name="business" value="you@youremail.com">

    <input type="hidden" name="item_name_' . $x . '" value="' . $product_name . '">
    <input type="hidden" name="amount_' . $x . '" value="' . $price . '">
    <input type="hidden" name="quantity_' . $x . '" value="' . $each_item['quantity'] . '"> 
    <input type="hidden" name="custom" value="' . $product_id_array . '">
    <input type="hidden" name="notify_url" value="https://www.yoursite.com/my_ipn.php">
    <input type="hidden" name="return" value="https://www.yoursite.com/checkout_complete.php">
    <input type="hidden" name="rm" value="2">
    <input type="hidden" name="cbt" value="Return to The Store">
    <input type="hidden" name="cancel_return" value="https://www.yoursite.com/paypal_cancel.php">
    <input type="hidden" name="lc" value="US">
    <input type="hidden" name="currency_code" value="USD">
    <input type="image" src="http://www.paypal.com/en_US/i/btn/x-click-but01.gif" name="submit" alt="Make payments with PayPal - its fast, free and secure!">
</form>
请仔细查阅notify_url、return、cancel_return字段。
以下是处理PayPal付款后由PayPal请求的IPN(my_ipn.php)的示例代码。
如需有关创建IPN的更多信息,请参见此链接:这里
<?php
// Check to see there are posted variables coming into the script
if ($_SERVER['REQUEST_METHOD'] != "POST")
    die("No Post Variables");
// Initialize the $req variable and add CMD key value pair
$req = 'cmd=_notify-validate';
// Read the post from PayPal
foreach ($_POST as $key => $value) {
    $value = urlencode(stripslashes($value));
    $req .= "&$key=$value";
}
// Now Post all of that back to PayPal's server using curl, and validate everything with PayPal
// We will use CURL instead of PHP for this for a more universally operable script (fsockopen has issues on some environments)
//$url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
$url = "https://www.paypal.com/cgi-bin/webscr";
$curl_result = $curl_err = '';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/x-www-form-urlencoded", "Content-Length: " . strlen($req)));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$curl_result = @curl_exec($ch);
$curl_err = curl_error($ch);
curl_close($ch);

$req = str_replace("&", "\n", $req);  // Make it a nice list in case we want to email it to ourselves for reporting
// Check that the result verifies
if (strpos($curl_result, "VERIFIED") !== false) {
    $req .= "\n\nPaypal Verified OK";
} else {
    $req .= "\n\nData NOT verified from Paypal!";
    mail("you@youremail.com", "IPN interaction not verified", "$req", "From: you@youremail.com");
    exit();
}

/* CHECK THESE 4 THINGS BEFORE PROCESSING THE TRANSACTION, HANDLE THEM AS YOU WISH
  1. Make sure that business email returned is your business email
  2. Make sure that the transaction�s payment status is �completed�
  3. Make sure there are no duplicate txn_id
  4. Make sure the payment amount matches what you charge for items. (Defeat Price-Jacking) */

// Check Number 1 ------------------------------------------------------------------------------------------------------------
$receiver_email = $_POST['receiver_email'];
if ($receiver_email != "you@youremail.com") {
//handle the wrong business url
    exit(); // exit script
}
// Check number 2 ------------------------------------------------------------------------------------------------------------
if ($_POST['payment_status'] != "Completed") {
    // Handle how you think you should if a payment is not complete yet, a few scenarios can cause a transaction to be incomplete
}

// Check number 3 ------------------------------------------------------------------------------------------------------------
$this_txn = $_POST['txn_id'];
//check for duplicate txn_ids in the database
// Check number 4 ------------------------------------------------------------------------------------------------------------
$product_id_string = $_POST['custom'];
$product_id_string = rtrim($product_id_string, ","); // remove last comma
// Explode the string, make it an array, then query all the prices out, add them up, and make sure they match the payment_gross amount
// END ALL SECURITY CHECKS NOW IN THE DATABASE IT GOES ------------------------------------
////////////////////////////////////////////////////
// Homework - Examples of assigning local variables from the POST variables
$txn_id = $_POST['txn_id'];
$payer_email = $_POST['payer_email'];
$custom = $_POST['custom'];
// Place the transaction into the database
// Mail yourself the details
mail("you@youremail.com", "NORMAL IPN RESULT YAY MONEY!", $req, "From: you@youremail.com");
?>
以下图片将有助于您了解 PayPal 流程。 Paypal process flow 如需进一步了解,请参阅以下链接: 希望这能帮到您..:)

1
有人知道这个问题在今天的PayPal API中是否仍然有效吗?我看到这个问题已经两年了。 - Matt Welander
1
“return”和“cancel_return” URL用于向买家提供即时交易反馈,并可以使用PDT变量进行操作。然而,PayPal只会尝试一次,因此不能依赖它们来实现关键订单履行(例如,买家在付款后关闭浏览器但仍在PayPal上)。为此,您可能还需要通过“notify_url”使用可靠的IPN过程进行备份处理,至少处理“已完成”的状态(假设其他任何状态都是失败的,可能需要手动协商)。您的PDT和IPN服务器处理需要确保订单只被填写一次。 - Patanjali
我相信事情已经改变,现在Paypal的success.php只能使用GET变量。请参见此处:https://dev59.com/XqTia4cB1Zd3GeqP_lDY - SolaceBeforeDawn

23

我找到了一种方法:

尝试将这个字段插入到你生成的表单代码中:

<input type='hidden' name='rm' value='2'>

rm表示返回方法;

2 表示 (post)

当用户购买并返回您的网站URL后,那个URL也将得到POST参数。

p.s.如果使用PHP,请尝试在您的返回URL(脚本)中插入var_dump($_POST);,然后进行测试购买,当您返回到您的网站时,您将看到您的URL上获取了哪些变量。


你真的用过这个吗? - Simon Gibbs
这太棒了。只要在PayPal中关闭付款数据传输,那么您就可以获得发送到返回URL的所有帖子设置。 - JulianJ

4

我最近遇到了与这个讨论串类似的问题,现在分享一下。

很长一段时间以来,我的脚本(基本支付表单)都运行良好,将POST变量返回到我的success.php页面,并将IPN数据作为POST变量返回。然而,最近我发现返回页面(success.php)不再接收任何POST变量了。我在沙盒和生产环境中进行了测试,我非常确定PayPal已经更改了一些东西!

notify_url仍然接收正确的IPN数据,使我能够更新数据库,但我无法在返回URL(success.php)页面上显示成功消息。

尽管我尝试了许多组合来切换PayPal网站付款首选项和IPN中的选项,但我必须对我的脚本进行一些更改,以确保我仍然可以处理消息。我通过打开PDT和自动返回并遵循这个出色的指南来完成这个目标。

现在一切都正常工作了,但唯一的问题是返回URL包含所有的PDT变量,这很丑陋!

您可能还会发现这篇文章有帮助


3
我认为Kevin上述所描述的将自动返回值设置为某个值的想法有些奇怪!
比如说,你可能有多个网站使用同一个PayPal账户来处理支付,或者你的一个网站中有多个部分执行不同的购买任务,并在完成付款时需要不同的返回地址。如果我按照上面“使用PHP进行直接支付的示例表单”部分所描述的在我的页面上放置一个按钮,你会看到那里有一行代码:
input type="hidden" name="return" value="https://www.yoursite.com/checkout_complete.php"

为什么要在个人资料部分设置通用的返回值,而不是设置单独的返回值?

此外,由于在个人资料部分只能设置一个值,这意味着(据我所知)您无法在具有多个操作的网站上使用自动返回。

请留下您的评论。


3
每个表格都可以传递返回参数,覆盖在PayPal配置中设置的自动返回网址。 - DropHit
1
是的,就像DropHit所说的那样,这只是默认的自动返回值,以防你忘记将其作为参数传递。如果你将其作为参数传递,它将使用你每个网站的返回URL。 - hamish
这有帮助吗?https://codeseekah.com/2012/02/11/how-to-setup-multiple-ipn-receivers-in-paypal/ - hamish
@DropHit,PDT是否仍然支持每个按钮覆盖的“return”值?这样我就可以拥有不同的返回页面,但仍然可以接收PDT数据吗? - Dai
抱歉回复晚了 - 我不确定它是否有效,但是我的当前集成仍然按预期运行,尽管这并不能保证您的用例与我的一样有效。 - DropHit
正如@Tim Makins所说,我有同样的问题...我有一个结帐页面和许多PayPal帐户...我可以有一个返回URL吗?这个URL会覆盖Merchant的Paypal帐户中的URL吗? - Kiriakos Grhgoriadhs

1
在结账页面上,查找“cancel_return”隐藏表单元素: 将cancel_return表单元素的值设置为您希望返回的URL:

实际上,“取消返回”仅在交易失败时使用。您还必须提供一个“返回”URL来处理成功完成的交易,否则默认的URL将用于它们。 - Patanjali
不是在交易失败时,而是当买家在结账过程中点击“取消并返回[商家名称]”链接以放弃完成订单时。 - SubGothius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接