Asp.net PayPal IPN webscr返回一个html文档

Asp.net PayPal IPN webscr返回一个html文档,asp.net,http,post,paypal,paypal-ipn,Asp.net,Http,Post,Paypal,Paypal Ipn,我正在ASP.NET中实现一个IPN侦听器,但每当我尝试验证一个事务时,paypal webscr脚本都会返回一个html文档,而不是已验证或无效的文档。代码如下: private void Validate(Transaction transaction) { string content = String.Concat(transaction.IpnMessage, "&cmd=_notify-validate"); byte[] rawContent = Encod

我正在ASP.NET中实现一个IPN侦听器,但每当我尝试验证一个事务时,paypal webscr脚本都会返回一个html文档,而不是已验证或无效的文档。代码如下:

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);
    }
}
下面是如何从传入请求构建事务对象:

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;
}
公共静态事务FromContext(HttpContext)
{
StreamReader=新的StreamReader(context.Request.InputStream);
交易结果=新交易();
字符串IPN消息;
reader.BaseStream.Position=0;
ipnMessage=reader.ReadToEnd();
string[]pairs=ipnMessage.Split('&');
result.data=新字典();
foreach(成对的字符串对)
{
if(String.IsNullOrEmpty(pair))
继续;
string[]parts=pair.Split('=');
字符串字段=部件[0];
字符串值=(parts.Length>1)?(parts[1]):string.Empty;
Add(HttpContext.Current.Server.UrlDecode(字段),HttpContext.Current.Server.UrlDecode(值));
}
result.ID=result.data[“txn_ID”];
result.IpnMessage=IpnMessage;
if(String.IsNullOrEmpty(result.ID))
抛出新ArgumentException(“这不是有效的事务”);
返回结果;
}
如果我通过REST控制台(GoogleChrome扩展)发送相同的消息,它就会工作。嗯,有点像:它返回的是无效的,但应该进行验证。我没有使用沙箱,我给自己付了5美分

顺便说一下,我不能设置流的内容长度。如果我这样做了,就会抛出一个异常,说明我在发送请求之前没有向流写入足够的字节(而我只写入了rawContent.Length字节)

postBackUrl为。我通过手动向web处理程序发送IPN消息的副本来测试这一点。我从我的PayPal帐户IPN历史记录中复制了它。我还尝试在cmd=\u notify-validate前面加上前缀,而不是附加它,但结果是一样的


我不明白为什么会收到一个HTML文档作为响应。

我没有在ASP.NET中编写代码,但是查看,我注意到您的代码以相反的方式连接响应:

string content = String.Concat(transaction.IpnMessage, "&cmd=_notify-validate");
它使它成为IpnMessage&cmd=\u notify-validate,而它应该是&cmd=\u notify-validateIpnMessage

所以

不确定这是否是唯一的原因,但试试看

另外,确保消息和“\u notify-validate”之间有一个&in。那是我的问题。因此,如果transaction.IpnMessage不是以&开头,请确保包含它

string content = String.Concat("&cmd=_notify-validate&", transaction.IpnMessage);

正如我在最后几段中所写,我已经试过了。此外,参数应该被解析,不管它们的位置如何……对不起,我没有读到。但我不确定他们是否会解析它,我想他们是按原样读的。事实上,网站()上说:“在你信任邮件内容之前,你必须先验证邮件是否来自PayPal。要验证邮件,你必须按照收到邮件的确切顺序发回邮件内容,并在发送之前使用命令_notify-validate”。您是否尝试了最后一部分,在验证后加上“&”?我正在用rest客户端发送相同的消息,它起了作用(有点)。我收到的是无效信息,而不是验证信息,但至少我收到了一条回复信息。嗯,无效意味着它的格式正确,但Paypal无法识别该信息(即,它从未发送过)。这是意料之中的,除非你让PayPal给你发送一条验证信息。您是否尝试过:string content=string.Concat(&cmd=_notify-validate&),transaction.IpnMessage)??
string content = String.Concat("&cmd=_notify-validate&", transaction.IpnMessage);