0

我在我的网站上使用 PayPal Adaptive Payments(并行),我遇到了一个奇怪的问题,即来自同一发件人的两个不同浏览器选项卡中的两次付款。之前有人问过类似的问题,但没有人在那里回答。

重现问题的场景

  1. 用户打开网站的第一个浏览器选项卡并开始向第一个卖家付款。
  2. 出现带有登录按钮的 PayPal 灯箱。
  3. 用户打开网站的第二个浏览器选项卡并开始向第二个卖家付款。
  4. 再次出现带有登录按钮的 PyaPal 灯箱。
  5. 用户返回到第一个浏览器选项卡并登录到 PayPal。
  6. 第一个浏览器选项卡中登录 PayPal 后,用户会看到第二个卖家的付款详细信息。
  7. 在第二个浏览器选项卡中登录 PayPal 后,用户会看到第二个卖家的付款详细信息。

似乎 PayPal 自适应付款仅支持来自一位发件人的一笔交易。

这个怎么运作

该网站使用 Ruby on Rails,我使用paypal_adaptive gem通过 PayPal 付款。付款流程非常简单:

  1. 用户点击网站上的购买按钮。客户端发出 AJAX 请求,由 Ruby on Rails 中的支付控制器处理。
  2. 在控制器中,应用程序使用 paypal_adaptive gem 向 PayPal API 发出支付请求并接收一个 PayKey(参见下面的代码)。
  3. 服务器使用 PayKey 响应客户端,客户端以 PayPal 形式使用它通过 PayPal 的灯箱开始付款过程(请参见下面的代码)。

而已。之后我什么都控制不了(支付过程通过 PayPal 的外部网页)。

补充说明

  1. 我确信在上面列出的测试场景中,支付请求的数据在服务器端是不同的。
  2. 除了 PayPal 的灯箱之外,我还尝试了不同的 PayPal 对话框选项:迷你浏览器和弹出窗口。这些选项不会影响此错误,并且仍然可以重现。

客户端代码

<script src="https://www.paypalobjects.com/js/external/dg.js" type="text/javascript"></script>

<form action="https://www.sandbox.paypal.com/webapps/adaptivepayment/flow/pay" class="paypal-hidden-form" target="PPDGFrame">
  <button id="paypal-submit"></button>
  <input id="type" type="hidden" name="expType" value="light">
  <!-- Insert PayKey here and click on the form's submit button using jQuery after server's response. -->
  <input id="paypal-key" type="hidden" name="paykey" value="">
</form>

<!-- Paypal -->
<script type="text/javascript" charset="utf-8">
    var dgFlow = new PAYPAL.apps.DGFlow({ trigger: "paypal-submit", expType: "light" });
    function MyEmbeddedFlow(embeddedFlow) {
        this.embeddedPPObj = embeddedFlow;
        this.paymentSuccess = function(paymentStatus) {
            this.embeddedPPObj.closeFlow();
            // More UI code here...
        };
        this.paymentCanceled = function() {
            this.embeddedPPObj.closeFlow();
            // More UI code here...
        };
    }
    var myEmbeddedPaymentFlow = new MyEmbeddedFlow(dgFlow);
</script>

服务器代码

# Make a Pay request to PayPal API.
paypal_payment_thread = Thread.new do
  # Some preparation code goes here...

  pay_request = PaypalAdaptive::Request.new
  process_guid = SecureRandom.uuid

  # Construct Pay API request data.
  data = {
    :returnUrl => "#{PAYPAL_RETURN_URL}?process_guid=#{process_guid}",
    :cancelUrl => "#{PAYPAL_CANCEL_URL}?process_guid=#{process_guid}",
    :requestEnvelope => {
      :errorLanguage => "en_US"
    },
    :currencyCode => "USD",
    :receiverList => {
      :receiver => [{
        # seller_paypal value is different for two payments.
        # But in fact we do the last payment for both payments.
        :email => seller_paypal,
        :amount => ORDER_SELLER_AMOUNT,
        :paymentType => "DIGITALGOODS"
      }, {
        :email => PAYPAL_MARKETPLACE_EMAIL,
        :amount => ORDER_MARKETPLACE_AMOUNT,
        :paymentType => "DIGITALGOODS"
      }]
    },
    :actionType => "PAY",
    :ipnNotificationUrl => PAYPAL_NOTIFY_URL,
    :reverseAllParallelPaymentsOnError => "true",
    :trackingId => process_guid
  }

  # Make a Pay API request.
  pay_response = pay_request.pay(data)

  if pay_response.success?
    # Everything is ok. Update database here...
  else
    raise Exceptions::PaypalPaymentError
  end
end

我已经删除了一些不重要的代码,只是为了清楚它是如何工作的。

在此先感谢您的帮助!

4

1 回答 1

1

看起来这是设计使然。我在PayPal 的一位员工的网站上尝试了相同的测试,并且可以在那里重现。

PayPal 的支持回答了我使用 Lightbox 的问题。但是,正如我在帖子中描述的那样,我尝试了迷你浏览器和弹出选项,但没有任何效果。

此外,PayPal 的支持人员回答我这是设计使然,并建议我与技术支持人员联系。也许它对其他人有用。

嗨迈克尔,谢谢,是的,我也能够复制它。然而,重要的是要了解 PayPal 不是为同时处理 2 个支付流程而设计的。如果您想进一步了解,可以联系我们的技术支持:https ://ppmts.custhelp.com/ 他们有其他工具可以调试,也许可以让您更好地了解技术问题。

最后,我使用 HTML5 本地存储中的特殊标志和检测 PayPal 窗口dgFlow.isOpen()的对象方法阻止了同时付款。PAYPAL.apps.DGFlow在窗口关闭时,我使用onunloadonbeforeunload事件重置此标志window

我关闭这个问题。谢谢。

于 2013-10-30T15:58:14.767 回答