我在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控制台(谷歌浏览器扩展程序)发送相同的消息,它可以正常工作。嗯,有点:它返回INVALID但应该是VERIFIED。我没有使用沙盒,我向自己付了5美分。
顺便说一下,我无法设置流的Content-Length。如果我这样做,会抛出一个异常,说我在发出请求之前没有向流写入足够的字节(当我写完正确的rawContent.Length字节时)。
postBackUrl是https://www.paypal.com/cgi-bin/webscr。我通过手动向Web处理程序发送IPN消息的副本来测试它。我从我的PayPal帐户IPN历史中复制了它。我也尝试在前面添加cmd = _notify-validate而不是附加它,但结果是一样的。
我无法弄清楚为什么我会收到回复的HTML文档。
答案 0 :(得分:0)
我不是在ASP.NET中编写代码,但是查看docs,我注意到您的代码以相反的方式连接响应:
string content = String.Concat(transaction.IpnMessage, "&cmd=_notify-validate");
它应该是IpnMessage&amp; cmd = _notify-validate,当它应该是&amp; cmd = _notify-validateIpnMessage。
所以,
string content = String.Concat("&cmd=_notify-validate", transaction.IpnMessage);
不确定这是否是唯一的原因,但请试一试。
另外,请确保有&amp;在消息和&#34; _notify-validate&#34;之间。这是我的问题。因此,如果transaction.IpnMessage不以&amp;开头,请确保包含它。
string content = String.Concat("&cmd=_notify-validate&", transaction.IpnMessage);