3

我正在将 PayPal Express Checkout 集成到现有的 Web 应用程序中,我已经为其设置了 Google Checkout 和 Amazon Payments(SimplePay 和 CBA)。所以我对此并不陌生。

一切,包括即时更新回调,在使用沙盒设置的设置中都可以正常工作。回调在沙盒中的 HTTP 和 HTTPS 上都可以正常工作。但是,一旦我切换到实时凭据,PayPal UI 就会停止点击 CallbackURL 并回退到使用在 SetExpressCheckout 中发送的(回退)运费。显然,税收根本不计算。

我正在使用最新版本的 PayPal PHP SDK(版本 106.0)。将设置从沙盒切换到实时更改的唯一设置是:

  • 用户名
  • 密码
  • 签名
  • 模式(从sandboxlive

我在 PayPal 的社区帮助论坛上看到了类似的问题,但没有提到解决方案。出于某种原因,我似乎无法在该线程中发帖……也许是因为它已存档。

2013 年 9 月 16 日更新:似乎是与 HTTPS 相关的问题。Sandbox 在 HTTPS 上也不起作用,但从浏览器点击回调 URL 时不会出现 SSL 错误。证书对我们在网站上使用的其他支付供应商有效且完全可以接受:Google Wallet 和 Amazon Payments。

4

3 回答 3

2

此问题已通过以下方式解决: 1. 将 CallbackTimeout 设置为 6 2. 使用 PayPal 接受的 SSL 证书。在我们的案例中,证书是由“Go Daddy Root Secure Certificate - G2”颁发的,PayPal 的系统不接受该证书。

于 2014-01-23T04:50:58.913 回答
0

Godaddy UCC 证书有这个问题,但非 UCC 证书没有这个问题。所以我不得不编写一个代理来将请求重定向到正确的位置。

然而最近我的 Godaddy 证书也失败了,所以他们似乎不那么宽容而不是更加宽容。它甚至无法获得 EV 证书。

这毫无意义。回调 URL 所做的只是提供运费!该需求过程需要有多安全。太荒谬了!除了更改我什至不能保证会起作用的证书之外,目前没有任何解决方案。

于 2014-03-05T07:01:55.707 回答
0

我设法让它使用来自(在Security Now Podcaststartcom.org上听说过)的免费证书。

他们的网站很糟糕,但是 PayPal 似乎对他们的证书没问题,而对 Godaddy 证书却不满意——都是 4096 位。另外它是免费的:-) 虽然只有一年好。

一旦我切换到此证书,它就可以正常工作。

GoDaddy/Starfield 颁发的证书对 PayPal 来说绝对是不可接受的。

我发现还有一项服务ngrok非常有用,可以让我在本地进行测试。它允许您设置可从外部访问的隧道代理。即使不接触防火墙设置,您也可以创建一个http://83def5f1.ngrok.io可通过 PayPal 访问的地址,并将流量重定向到您的本地计算机,从而允许您设置断点。


代理页面

(与 ngrok 完全无关)

我宁愿不将此证书用于我的实时站点(另外,我在 UCC 证书上有几个不同的站点,我不想更改),所以我创建了一个代理页面,将请求重定向到正确的服务器。然后我只需将以下内容发送到 PayPal

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

callbackUrl(您将发送到 PayPal 的常规回调 URL 位于何处)

代理是一个 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>
于 2015-06-09T06:03:49.210 回答