Мгновенное обновление PayPal CallbackURL не вызывается в режиме реального времени

Я работаю над интеграцией PayPal Express Checkout в существующее веб-приложение, для которого я уже настроил Google Checkout и Amazon Payments (как SimplePay, так и CBA). Так что я не новичок в этом.

Все, в том числе мгновенный обратный вызов обновления, прекрасно работает в настройках, которые используют параметры песочницы. Обратный вызов отлично работает как по HTTP, так и по HTTPS в песочнице. Но как только я переключаюсь на учетные данные Live, пользовательский интерфейс PayPal перестает использовать CallbackURL и возвращается к использованию (откат) стоимости доставки, отправленной в SetExpressCheckout. Очевидно, что налоги вообще не рассчитываются.

Я использую последнюю версию PayPal PHP SDK (версия 106.0). Единственные настройки, которые изменяются для переключения настроек из Песочницы в Live:

  • UserName
  • пароль
  • Подпись
  • режим (от sandbox в live)

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

Обновление 16.09.2013: Кажется, это проблема, связанная с HTTPS. Песочница также не работает на HTTPS, но при обращении к URL обратного вызова из браузера не возникает ошибка SSL. Сертификат действителен и вполне приемлем для других поставщиков платежей, которые мы используем на сайте: Google Wallet и Amazon Payments.

3 ответа

Решение

Эта проблема была исправлена ​​с помощью: 1. Установка CallbackTimeout на 6 2. Использование SSL-сертификата, который принят PayPal. В нашем случае сертификат был выдан "Go Daddy Root Secure Certificate - G2", который не был принят системой PayPal.

У меня была эта проблема с сертификатом Godaddy UCC, но у меня не было проблемы с сертификатом не UCC. Поэтому мне пришлось написать прокси, чтобы перенаправить запрос в нужное место.

Однако в последнее время это тоже не удалось с моим сертификатом Godaddy, поэтому они, кажется, менее разрешительный, чем более разрешительный. Это даже терпит неудачу с сертификатом EV.

Это не имеет никакого смысла. Все, что делает URL-адрес обратного вызова, - это тарифы на доставку! Насколько безопасным должен быть этот процесс? Это нелепо! Никакое решение, кроме изменения сертификата, которое я даже не могу гарантировать, будет работать.

Мне удалось заставить его работать с бесплатным сертификатом от startcom.org (слышал о безопасности сейчас подкаст).

Их веб-сайт ужасен, но PayPal, кажется, в порядке со своим сертификатом, где они не в порядке с сертификатом Godaddy - оба 4096 бит. Плюс это бесплатно:-) Хотя только год хорош.

Как только я перешел на этот сертификат, он работал нормально.

Для PayPal было определенно что-то недопустимое в отношении выданного сертификата GoDadaddy/Starfield.

Также есть сервис ngrokкоторый я нашел очень полезным, чтобы позволить мне проверить на месте. Это позволяет вам настроить туннельный прокси, который доступен снаружи. Даже не касаясь настроек брандмауэра, вы можете создать такой адрес, как http://83def5f1.ngrok.io это доступно через PayPal и перенаправляет трафик на ваш локальный компьютер, позволяя вам устанавливать точки останова.


Страница прокси

(Совершенно не связано с нгрок)

Я предпочел не использовать этот сертификат для своих живых сайтов (плюс у меня есть несколько разных сайтов на сертификатах UCC, которые я не хотел менять), поэтому я создал прокси-страницу, которая перенаправляет запрос на нужный сервер. Затем я просто отправляю следующее в PayPal

"https://example.com/paypalproxy.aspx?callbackUrl=" + HttpUtility.UrlEncode(callbackUrl)

(Куда callbackUrl ваш обычный URL обратного вызова, который вы отправляете в PayPal)

Прокси-сервер является страницей ASPX - его не нужно компилировать, просто поместив на веб-сайт.NET IIS.

Вы можете проверить, чтобы увидеть последний запрос / ответ, вызывающий его с ?debug=Y

<%@ Page language="c#" AutoEventWireup="true" %>
<%@ Import Namespace="System.IO"%>
<Script runat="server" language="C#">

private static string _lastURL;
private static string _lastRequest = "";
private static string _lastResponse = "";
private static DateTime? _lastTime;
private static int _lastDurationMs;

    private void Page_Load(object sender, System.EventArgs e)
    {
        // no cache
        Response.Cache.SetCacheability(HttpCacheability.NoCache);

            var sw = new System.Diagnostics.Stopwatch();
            var wc = new System.Net.WebClient();
            sw.Start();

            var callbackUrl = Request.Params["callbackUrl"];
            var debugMode = Request.Params["debug"] == "Y";

            if (debugMode) 
            {
               Response.ContentType = "text/text";
               Response.Write(_lastTime + "\n");
               Response.Write("LastURL = ["+_lastURL+"]\n\n");
               Response.Write("LastDuration = [" + _lastDurationMs +"]\n\n");
               Response.Write("REQUEST: \n[\n  "+_lastRequest.Replace("&", "&\n  ")+"\n]\n\n");
               Response.Write("RESPONSE: \n[\n  "+_lastResponse.Replace("&", "&\n  ")+"\n]");
               Response.End();
           return;
            }

            _lastDurationMs = -1;
        _lastURL = Request.Params["callbackUrl"];
            _lastTime = DateTime.Now;

            if (callbackUrl.Contains("dev."))
            {
                throw new ApplicationException("Callback shouldn't be to a dev machine!");
            }

            if (callbackUrl.Contains("https") == false)
            {
                throw new ApplicationException("Callback must be https");
            }

            var newUri = callbackUrl + "?" + Request.Form.ToString();

            var str = wc.DownloadString(newUri);

            _lastRequest = Request.Form.ToString();
            _lastResponse = str;
            _lastDurationMs = (int)sw.ElapsedMilliseconds;

            Response.Write(str);
            Response.End();

    }

</Script>
Другие вопросы по тегам