如何更好地为第三方卖家集成 Paypal“立即购买”按钮?

Posted

技术标签:

【中文标题】如何更好地为第三方卖家集成 Paypal“立即购买”按钮?【英文标题】:How-to better integrate Paypal "Buy Now" button for 3rd-party sellers? 【发布时间】:2015-10-15 03:36:01 【问题描述】:

我正在努力寻找在我的网站中集成 Paypal“立即购买”按钮的最佳方式,但我对所有各种 Paypal 集成技术(托管按钮、动态按钮、IPN、PDT 和其他各种 API)

我想根据自己的需要集成更好/最简单的解决方案以及安全...

我真的不知道该去哪里...... 非常感谢您的帮助!

上下文:

我拥有一个旨在成为销售数字商品的“市场”的网站。

有些人(我们称他们为 SELLERS)在我的网站上注册为“卖家”并上传他们想要销售的一些数字商品。我为他们销售的每个“产品”生成在线页面。

其他一些人(我们称他们为 BUYERS)也仅在我的网站上注册为“买家”:他们只是想从不同的卖家那里购买这些数字商品。

我的需要:

我想在每个产品页面上集成卖家的paypal按钮,所以他会直接付款。我不想成为付款的中间人。

所以我需要在每个产品页面上集成不同的按钮,具体取决于该产品的卖家。

我还需要为每种产品动态指定不同的价格,具体取决于所售产品(价格将由卖家在我的网站后台确定)

交易完成后(买家付款),我需要在商品页面为该买家解锁商品的下载。事实上,我需要更新我的数据库以将产品与该买家相关联,所以当他稍后回到我的网站时,他总是将他购买的产品“解锁”。

我对按钮的看法:

1/ 动态 html 按钮

<form name="_xclick" action="https://www.paypal.com/fr/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="item_name" value="Digital good 1">
<input type="hidden" name="amount" value="12.99">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="quantity" value="1">
<input type="hidden" name="item_number" value="internal_user_and_product_id">
<input type="hidden" name="business" value="seller@abusiness.com">
<input type="hidden" name="notify_url" value="https://mywebsite.com/paypal-ipn.php">
<input type="image" src="http://www.paypal.com/fr_FR/i/btn/x-click-but01.gif" border="0" name="submit">
</form>

这里似乎只需要询问卖家其 Paypal 业务电子邮件或 ID,并为他和他的产品动态生成一个按钮。我还可以提供我的 IPN 侦听器 URL,以便在收到完整交易后使用通过“item_number”传递的数据为我的数据库中的买家解锁产品。很简单。

但是: - 这不安全(任何人都可以在购买前更改 HTML 中的金额或贝宝 ID) - 如果卖家提供的电子邮件地址不正确(拼写错误)会怎样?(我尝试使用测试按钮和虚假电子邮件地址“djfhsgfshdgfsd@dghe.com”进行购买,但我能够处理付款!!这不是企业 ID 不正确的情况...)

2/ Paypal 托管按钮

<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="PJM2WY8H648ZK">
<input type="hidden" name="item_name" value="Digital good 2">
<input type="hidden" name="quantity" value="1">
<input type="hidden" name="item_number" value="internal_user_and_product_id">
<input type="hidden" name="notify_url" value="https://mywebsite.com/paypal-ipn.php">
<input type="image" src="http://www.paypal.com/fr_FR/i/btn/x-click-but01.gif" border="0" name="submit">
<input type="image" src="https://www.paypalobjects.com/fr_FR/FR/i/btn/btn_buynow_LG.gif" border="0" name="submit">
<img  border="0" src="https://www.paypalobjects.com/fr_FR/i/scr/pixel.gif"  >
</form>

这将避免使用 Paypal 上托管的按钮进行欺诈。

但是: - 我无法动态生成按钮(如金额和货币)。这意味着我必须要求卖家为他们要出售的每件商品自己生成一个托管按钮,并设置正确的价格。这也意味着我将无法在我的网站上显示产品的价格?事实上,如果卖家在他的 Paypal 托管按钮中设置了 2 美元,但在我的后台设置了 1 美元,我将在我的网站上显示 1 美元,而实际价格是 2 美元...

我不确定我可以提供哪些变量来覆盖托管按钮。 我至少需要“notify_url”(IPN 侦听器 URL)和“item_number”(我的产品/买家技术 ID)

下一步...

对于接下来的步骤,我还有很多询问,例如 IPN/PDT 以及我真正能用这些做什么。但我们先回答我可以使用和集成的按钮类型!

【问题讨论】:

【参考方案1】:

您最好的解决方案是不使用 PayPal 按钮。您会想要使用 PayPal Express Checkout 解决方案。这里有一个例子:

http://marshalcurrier.com/paypal/ExpressCheckout/SetDo.php

此过程需要更多编程,但它会解决您的所有问题。金额直接从您的服务器传递到 PayPal,并且无法通过 HTML 进行修改。此外,当您完成付款后,您会立即收到付款确认。这样您就不必依赖 IPN。

这是介绍页面的直接链接:

https://developer.paypal.com/docs/classic/express-checkout/gs_expresscheckout/

这里是上面 Express Checkout 示例链接的代码:

买家邮箱:buyer@clubcovert.com

买家密码:test1234

<a href='http://marshalcurrier.com/paypal/ExpressCheckout/custom/SetDo.php'>RESET</a><br>
<form method='post'><input type="text" name="CHARGE" value="1"/><input type="submit" value="Pay Now"/><form>

<?php
session_start();

$PPUSER = 'marshal_api1.clubcovert.com';
$PPPWD = 'LL6NV7TDRB9RFXQ5';
$PPSIG = 'ANc3YRaMB1Tgm9TediH0gENHB02JAksSKWD08wVNN3w3pwHqdBW8Im6y';
function url()                 //PayPal Payment URL (TEST or LIVE)
    $url = "https://api-3t.sandbox.paypal.com/nvp"; //Test Server
    //$url = "https://api-3t.paypal.com/nvp"; //Live Server
    return $url;

function curlCall($nvp)        // Function for Curl Call to PayPal.
    $url = url();
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_HEADER, FALSE); 
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($nvp) );
    //echo http_build_query($nvp);  //Print String
    curl_setopt($ch, CURLOPT_URL, $url); 
    $server_output = curl_exec($ch);
    mb_parse_str($server_output, $arr);
    return $arr;

if(isset($_POST['CHARGE']))    // SetExpressCheckout Call
    $_SESSION['AMT'] = $_POST['CHARGE'];
    $nvp = array(
        'USER'    => $PPUSER,
        'PWD'   => $PPPWD,
        'SIGNATURE' => $PPSIG,
        'METHOD' => 'SetExpressCheckout',
        'VERSION' => '123',
        'PAYMENTREQUEST_0_PAYMENTACTION' => 'SALE',
        'PAYMENTREQUEST_0_AMT' => $_POST['CHARGE'],
        'PAYMENTREQUEST_0_CURRENCYCODE' => 'USD',
        'RETURNURL' => 'http://marshalcurrier.com/paypal/ExpressCheckout/SetDo.php',
        'CANCELURL' => 'http://marshalcurrier.com/paypal/ExpressCheckout/SetDo.php',
    );
    $arr = curlCall($nvp);
    echo '<br><br>SetExpressCheckout Call to PayPal:<br><pre>';
    print_r ($nvp);
    echo '</pre>';
    echo 'SetExpressCheckout Server Response:<br><pre>';
    print_r ($arr);
    echo '</pre>';
    echo '<a href="https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='.($arr['TOKEN']).'">Go To PayPal</a>';

if(isset($_GET['PayerID']))    // DoExpressCheckoutPayment Call
    if (isset($_SESSION['AMT']))
        $AMT = $_SESSION['AMT'];
    else
        $AMT = null;
    
    $nvp = array(
        'METHOD' => 'DoExpressCheckoutPayment',
        'VERSION' => '123',
        'USER'    => $PPUSER,
        'PWD'   => $PPPWD,
        'SIGNATURE' => $PPSIG,
        'PAYERID' => $_GET['PayerID'],
        'TOKEN' => $_GET['token'],
        'PAYMENTREQUEST_0_PAYMENTACTION' => 'SALE',
        'PAYMENTREQUEST_0_AMT' => $AMT,
        'PAYMENTREQUEST_0_CURRENCYCODE' => 'USD',
    );
    $arr = curlCall($nvp);
    echo '<br><br>DoExpressCheckoutPayment Call to PayPal:<br><pre>';
    print_r ($nvp);
    echo '</pre>';
    echo 'DoExpressCheckoutPayment Server Response:<br><pre>';
    print_r ($arr);
    echo '</pre>';
    unset($_SESSION['AMT']); 

?>

【讨论】:

我在这里唯一要调整的是IPN仍然非常重要。单独的 API 响应无法正确处理诸如需要时间来清除的电子支票、欺诈管理过滤器中捕获的付款等。IPN 将针对这些事件中的每一个触发,因此您可以相应地自动化程序。此外,对于与 PHP 的 Express Checkout 集成,我建议您查看PayPal PHP SDK。您可以在几分钟内完成高级 Express Checkout 集成。 感谢您的回答。我需要更深入地分析这一点。但是您能否向我确认,使用此解决方案,我可以将付款发送给动态卖家?如果我正确理解,用户 ID 需要密码,并且将是我的 paypal API 用户 ID/PWD。我在哪里设置收件人贝宝公司 ID 或电子邮件?我不希望我的每个注册卖家都向我提供他们的 paypal API 用户 ID 和密码,这应该是不可接受的...... 如果您不希望请求买家的 API 信息,那么您可以使用其他选项,但这会使事情变得更加复杂。正如您在原始帖子中提到的,您正在寻找解决问题的最简单方法,因此我建议使用 Express Checkout 选项。我们还提供批量支付选项。这将允许您接受付款(您的 PayPal 帐户)并在一天结束时向您的卖家付款。您将对通过的退款和争议承担责任。 developer.paypal.com/webapps/developer/docs/classic/mass-pay/…【参考方案2】:

在继续搜索大型 Paypal 文档后,我想我找到了我想要的东西:Paypal Adaptive Payments。

根据文档,我可以成为 “应用程序所有者”,它是 “付款发送者”(我的一个买家)和 “收款人”(我的卖家之一)。这完全是我的情况!

您还可以做更复杂的事情,例如发送给多个接收者或进行“链式付款”,并成为买卖双方之间的“主要接收者”,并可选择为此收取费用。

这看起来非常完整和灵活!

我现在需要更深入地了解如何在技术细节上实现这一点,但文档说我不需要向收款人询问 PAypal 信息(他甚至不必拥有 Paypal 帐户,这看起来很奇怪,但确实如此......)

Note [extract from Paypal's documentation]: 
The application owner must have a PayPal Business account.
Senders and receivers can have any PayPal account type. 
Senders and receivers are not required to have PayPal accounts initially.
PayPal prompts a sender to create an account before a payment can be completed.
A receiver must create an account to receive the funds after the payment completes.

【讨论】:

以上是关于如何更好地为第三方卖家集成 Paypal“立即购买”按钮?的主要内容,如果未能解决你的问题,请参考以下文章

PayPal 立即购买按钮 - 强制自动退货(无需通过账户设置)

没有 IPN 的 Paypal 集成

Paypal 自适应支付 IPN 回调:如何返回完整未更改的 ipn 消息

加密贝宝立即购买按钮 html 表单

如何使用 PHP 从 Paypal 立即购买按钮接收回调

如何使用 PayPal 的“立即购买”按钮设置“描述”?