如何调试PayPalCoreSDK IPN验证失败?

时间:2014-09-11 20:28:56

标签: c# asp.net asp.net-mvc paypal paypal-ipn

我正在使用PayPal自己的.NET库来验证IPN,特别是IPNMessage.cs PayPalCoreSDK 1.5.0通过NuGet(2014-09-09发布)提供。

以下是我使用它的方式:

[HttpPost]
public ActionResult Ipn()
{
    try
    {
        byte[] bytes = Request.BinaryRead(Request.ContentLength);
        IPNMessage message = new IPNMessage(bytes);

        string description = string.Format("PayPal IPN {0} {1} {2}",
            message.IpnValue("txn_id"),
            message.IpnValue("payment_type"),
            message.IpnValue("payment_status"));

        Trace.TraceInformation(description + " Received");

        if (message.Validate())
        {
            Trace.TraceInformation(description + " Valid");
            // do work here
        }
        else
        {
            Trace.TraceError(description + " Invalid");
        }
    }
    catch (Exception e)
    {
        Trace.TraceError("PayPal IPN Exception: " + e.Message);
    }

    return null;
}

我的日志告诉我(txnId已更改):

Application: 2014-09-11T19:52:40  PID[11584] Information PayPal IPN ABC536DEFP96XYZ3U instant Completed Received
Application: 2014-09-11T19:52:40  PID[11584] Error       PayPal IPN ABC536DEFP96XYZ3U instant Completed Invalid

IPN本身充满了我期待的所有键/值。当我登录PayPal并查看即时付款通知(IPN)历史记录部分时,我看到IPN具有匹配的交易ID,其状态为“已发送”。我刚刚从false返回Validate(),因此PayPal不得回复“已验证”。没有异常被抛出,我该如何调试呢?

2 个答案:

答案 0 :(得分:2)

原来我的应用程序甚至无法与PayPal通信。

PayPalCoreSDK在app.config / web.config中需要以下内容:

<configuration>
  <configSections>
    <section name="paypal" type="PayPal.Manager.SDKConfigHandler, PayPalCoreSDK" />
  </configSections>
  <paypal>
    <settings>
      <add name="mode" value="sandbox" /> <!-- "live" or "sandbox" -->
    </settings>
  </paypal>
</configuration>

归功于James Dibble

答案 1 :(得分:1)

要扩展您自己的答案 - 是的,他们是API中的完整白痴。

IPN消息实际上包含一个标志,无论消息是否为沙箱 - 所以它应该能够自己解决这个问题而不需要显式配置集。或者至少应该给出错误。

或者你可以像这样提供配置(我有一个config对象,这只是一个简单的结构)

var message = new PayPal.IPNMessage(new Dictionary<string, string>()
            {
                { "account1.apiUsername", config.APIUsername },
                { "account1.apiPassword", config.APIPassword },
                { "account1.apiSignature", config.APISignature },

                { "mode", config.IsLiveMode ? "live" : "sandbox" }
            }, bytes);

(我很确定这里实际上并不需要帐户用户信息)


想知道为什么不出错?...

我实际上进入source code for IPNMessage看看发生了什么。以下调用检索validate()方法中的URL。它会在您的配置中查找它并在失败时抛出异常(这就是我们想要的)。

不幸的是,它被包装在一个try块中,它实际上只应该捕获运行时错误 - 但是它会掩盖配置错误,只会为false返回一个无用的validate()

string ipnEndpoint = GetIPNEndpoint();