Paypal 自适应支付 : two payments from one sender in two browser tabs

原文 标签 paypal payment-gateway payment paypal-adaptive-payments

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

重现问题的场景

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

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

    它是如何工作的

    该网站使用 Ruby on Rails,我使用 paypal_adaptive gem使用 PayPal 付款。付款流程非常简单:
  • 用户点击网站上的购买按钮。客户端发出 AJAX 请求,由 Ruby on Rails 中的支付 Controller 处理。
  • 在 Controller 中,应用程序使 Pay request使用 paypal_adaptive gem 到 PayPal API 并接收 PayKey(参见下面的代码)。
  • 服务器使用 PayKey 响应客户端,客户端以 PayPal 形式使用它通过 PayPal 的灯箱启动付款流程(请参见下面的代码)。

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

    附加说明
  • 我确信在上面列出的测试场景中,支付请求的数据在服务器端是不同的。
  • 除了 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
    

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

    在此先感谢您的帮助!

    最佳答案

    看起来这是设计使然。我在 the website 上尝试过相同的测试PayPal 的一名员工,它可以在那里重现。

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

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

    Hi Michael, Thanks, yes I was able to reproduce it as well. However it’s important to understand that PayPal is not made for handling 2 payment flows at the same time. If you want to get further on that, you can contact our Technical Support : https://ppmts.custhelp.com/ They have other tools to debug and may be able to give you a better understanding of the technical problem.



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

    我关闭这个问题。谢谢。

    关于 Paypal 自适应支付 : two payments from one sender in two browser tabs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19659524/

    相关文章:

    android - 如何使用 paypal android sdk 中的 payment_id 在 paypal 中获取完整的交易详情

    android - Paypal集成开发中的PaymentActivity.EXTRA_CLIENT_ID是什么

    paypal - 自动将付款发送到银行帐户

    php - Paypal 付款后上传到 Dropbox

    paypal - 检查txn_id以防止欺诈

    PayPal SetExpressCheckout 在实时服务器上失败

    paypal - 使用 paypal api 的地址验证服务

    ruby-on-rails - 无法建立到远程服务器的 SSL 连接

    ios - CFSDK支付网关 'Invalid token sent in request'