2014-02-19 39 views
0

我在ASP.NET中實現了IPN監聽器,但每當我嘗試驗證事務時,PayPal webscr腳本都會返回一個html文檔而不是VERIFIED或INVALID。這是代碼:PayPal IPN 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; 
} 

如果我通過REST控制檯發送相同的消息(谷歌瀏覽器擴展程序),它作品。那麼,有點:它返回無效,但應該驗證。我沒有使用沙箱,我向我自己支付了5美分。

順便說一下,我無法設置流的Content-Length。如果我這樣做,會拋出一個異常,說在發送請求之前我沒有寫足夠的字節到流中(而我寫的確實是rawContent.Length字節)。

postBackUrl是https://www.paypal.com/cgi-bin/webscr。我正在通過手動將IPN消息的副本發送到Web處理程序來測試此問題。我從PayPal賬戶IPN歷史記錄中複製了這些信息。我也試着預先安裝cmd = _notify-validate而不是附加它,但結果是一樣的。

我不明白爲什麼我收到一個HTML文件作爲迴應。

回答

0

我不代碼在ASP.NET中,但看docs,我注意到,你的代碼連接以相反的方式響應:

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

該計劃使IpnMessage & CMD = _notify-驗證,它應該是& cmd = _notify-validateIpnMessage。

所以,

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

不知道如果這是唯一的原因,但不妨一試。

此外,請確保在消息和「_notify-validate」之間有一個&。這是我的問題。因此,如果transaction.IpnMessage不以&開頭,請確保包含它。

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

我已經試過了,正如我在前面的段落中所寫的那樣。此外,參數應該被解析,無論他們的位置... – Totem

+0

對不起,我沒有讀過。但我不確定他們是否解析它,我認爲他們是這樣理解的。實際上,該網站(https://developer.paypal.com/webapps/developer/docs/classic/ipn/integration-guide/IPNIntro/)說: 「在您可以信任郵件內容之前,您必須首先驗證該消息是否來自PayPal,要驗證消息,您必須按照收到的確切順序發回內容**,並在命令前加上_notify-validate **「。 您是否嘗試過最後一部分,在驗證之後放入「&」? – SuperGT

+0

我正在發送與休息客戶端相同的消息,它的工作(種)。我收到了無效的驗證碼,但至少我收到了一條消息。 – Totem