我正在使用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不得回复“已验证”。没有异常被抛出,我该如何调试呢?
答案 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();