我设法使用来自startcom.org 的免费证书使其工作(在Security Now Podcast 上听说过)。
他们的网站很糟糕,但 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>