PayPal Adaptive Payments: два платежа от одного отправителя на двух вкладках браузера

Я использую адаптивные платежи PayPal (параллельные) на своем веб-сайте, и я столкнулся со странной проблемой с двумя платежами в двух разных вкладках браузера от одного отправителя. Подобный вопрос задавался и раньше, но там никто не ответил.

Сценарий, который воспроизводит проблему

  1. Пользователь открывает первую вкладку браузера веб-сайта и начинает процесс оплаты первого продавца.
  2. Появится лайтбокс PayPal с кнопкой входа в систему.
  3. Пользователь открывает вторую вкладку браузера веб-сайта и начинает процесс оплаты для второго продавца.
  4. Снова появляется лайтбокс PyaPal с кнопкой входа в систему.
  5. Пользователь возвращается на первую вкладку браузера и входит в систему PayPal.
  6. После входа в PayPal на первой вкладке браузера пользователь видит реквизиты платежа для второго продавца.
  7. После входа в PayPal во второй вкладке браузера пользователь видит реквизиты платежа для второго продавца.

Похоже, что PayPal Adaptive Payments поддерживает только одну транзакцию от одного отправителя.

Как это устроено

Сайт работает с Ruby on Rails, и я использую гем paypal_adaptive для платежей через PayPal. Поток платежей довольно прост:

  1. Пользователь нажимает кнопку "Купить" на сайте. Клиент делает AJAX-запрос, который обрабатывается контроллером платежей в Ruby on Rails.
  2. В контроллере приложение отправляет запрос Pay в PayPal API, используя гем paypal_adaptive, и получает 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

Я удалил какой-то неважный код, чтобы понять, как он на самом деле работает.

Заранее спасибо за помощь!

1 ответ

Решение

Похоже, что это дизайн. Я попробовал этот же тест здесь на веб-сайте одного из сотрудников PayPal, и он воспроизводится там.

Поддержка PayPal ответила мне, что проблема в использовании Lightbox. Тем не менее, я пробовал варианты Mini-Browser и Popup, как я описал в своем посте, безрезультатно.

Кроме того, служба поддержки PayPal ответила мне, что это сделано специально, и посоветовала мне обратиться в службу технической поддержки. Может быть, это будет полезно для кого-то еще.

Привет, Майкл, спасибо, да, я также смог воспроизвести это. Однако важно понимать, что PayPal не предназначен для обработки двух потоков платежей одновременно. Если вы хотите получить дополнительную информацию об этом, вы можете обратиться в нашу службу технической поддержки: https://ppmts.custhelp.com/ У них есть другие инструменты для отладки, и они могут помочь вам лучше понять техническую проблему.

Наконец, я заблокировал одновременные платежи, используя специальный флаг в HTML5 Local Storage и dgFlow.isOpen() метод PAYPAL.apps.DGFlow объект для обнаружения окна PayPal. При закрытии окна я сбрасываю этот флаг, используя onunload а также onbeforeunload события window,

Я закрываю этот вопрос. Благодарю.

Другие вопросы по тегам