【发布时间】:2014-03-19 21:16:06
【问题描述】:
我在 ASP.NET 中实现了一个 IPN 侦听器,但是每当我尝试验证交易时,paypal webscr 脚本都会返回一个 html 文档,而不是 VERIFIED 或 INVALID。这是代码:
private void Validate(Transaction transaction)
{
string content = String.Concat(transaction.IpnMessage, "&cmd=_notify-validate");
byte[] rawContent = Encoding.ASCII.GetBytes(content);
HttpWebRequest request = (HttpWebRequest) HttpWebRequest.Create(postBackUrl);
request.Method = "POST";
request.ProtocolVersion = HttpVersion.Version11;
request.KeepAlive = false;
request.ContentType = "application/x-www-form-urlencoded";
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
writer.Write(rawContent);
transaction.Save();
try
{
WebResponse response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string responseContent = reader.ReadToEnd();
if (responseContent.Equals("VERIFIED"))
this.Approve(transaction);
else
transaction.SetOperation("Rejected", responseContent);
}
catch (Exception ex)
{
transaction.SetOperation("WebError", ex.Message);
}
}
下面是如何根据传入请求构建 Transaction 对象:
public static Transaction FromContext(HttpContext context)
{
StreamReader reader = new StreamReader(context.Request.InputStream);
Transaction result = new Transaction();
string ipnMessage;
reader.BaseStream.Position = 0;
ipnMessage = reader.ReadToEnd();
string[] pairs = ipnMessage.Split('&');
result.data = new Dictionary<string, string>();
foreach (string pair in pairs)
{
if (String.IsNullOrEmpty(pair))
continue;
string[] parts = pair.Split('=');
string field = parts[0];
string value = (parts.Length > 1) ? (parts[1]) : String.Empty;
result.data.Add(HttpContext.Current.Server.UrlDecode(field), HttpContext.Current.Server.UrlDecode(value));
}
result.ID = result.data["txn_id"];
result.IpnMessage = ipnMessage;
if (String.IsNullOrEmpty(result.ID))
throw new ArgumentException("This is not a valid transaction.");
return result;
}
如果我通过 REST 控制台(Google Chrome 扩展程序)发送相同的消息,它可以工作。好吧,有点:它返回无效但应该被验证。我没有使用沙盒,我向自己支付了 5 美分。
顺便说一句,我无法设置流的 Content-Length。如果我这样做了,则会抛出一个异常,说明在发送请求之前我没有向流中写入足够的字节(而我写的正是 rawContent.Length 字节)。
postBackUrl 是https://www.paypal.com/cgi-bin/webscr。我正在通过手动向 Web 处理程序发送 IPN 消息的副本来测试这一点。我从我的 PayPal 帐户 IPN 历史记录中复制了它。我也尝试在前面加上 cmd=_notify-validate 而不是追加,但结果是一样的。
我不知道为什么我会收到一个 HTML 文档作为响应。
【问题讨论】:
标签: asp.net http post paypal paypal-ipn