【问题标题】:Trouble connecting DB using Paypal's IPN, C#使用 Paypal 的 IPN、C# 连接数据库时遇到问题
【发布时间】:2015-02-24 17:03:54
【问题描述】:
public partial class ipn : System.Web.UI.Page
{
string connectionString = ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString();
String fname, lname, mc_gross, Pmtcurrency, Payer_email;
string receiver_email, payment_date, payment_status;
string txn_type, amount;
string payer_id, txn_id;
string Verify_sign;
string result;


protected void Page_Load(object sender, EventArgs e)
{
    //Post back to either sandbox or live
    string strSandbox = "https://www.sandbox.paypal.com/cgi-bin/webscr";
    string strLive = "https://www.paypal.com/cgi-bin/webscr";
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(strSandbox);

    //Set values for the request back
    req.Method = "POST";
    req.ContentType = "application/x-www-form-urlencoded";
    byte[] param = Request.BinaryRead(HttpContext.Current.Request.ContentLength);
    string strRequest = Encoding.ASCII.GetString(param);
    string ipnPost = strRequest;
    strRequest += "&cmd=_notify-validate";
    req.ContentLength = strRequest.Length;

    //Send the request to PayPal and get the response
    StreamWriter streamOut = new StreamWriter(req.GetRequestStream(), System.Text.Encoding.ASCII);
    streamOut.Write(strRequest);
    streamOut.Close();
    StreamReader streamIn = new StreamReader(req.GetResponse().GetResponseStream());
    string strResponse = streamIn.ReadToEnd();
    streamIn.Close();

    // logging ipn messages... be sure that you give write
    // permission to process executing this code
    string logPathDir = ResolveUrl("Messages");
    string logPath = string.Format("{0}\\{1}.txt",
                     Server.MapPath(logPathDir), DateTime.Now.Ticks);
    File.WriteAllText(logPath, ipnPost);

    if (strResponse == "VERIFIED")
    {
       result = "VERIFIED";

        fname = Convert.ToString(HttpContext.Current.Request.Form["first_name"]); 
        lname = Convert.ToString(HttpContext.Current.Request.Form["last_name"]); 
        mc_gross = Convert.ToString(HttpContext.Current.Request.Form["mc_gross"]); 

        Pmtcurrency = Convert.ToString(HttpContext.Current.Request.Form["mc_currency"]); 

        Payer_email = Convert.ToString(HttpContext.Current.Request.Form["payer_email"]); 
        Payer_email = Payer_email.Replace("%40", "@");

        txn_id = Convert.ToString(HttpContext.Current.Request.Form["txn_id"]); 
        payer_id = Convert.ToString(HttpContext.Current.Request.Form["payer_id"]); 
        amount = Convert.ToString(HttpContext.Current.Request.Form["payment_gross"]); ;

        payment_date = Convert.ToString(HttpContext.Current.Request.Form["payment_date"]); ;
        payment_date = payment_date.Replace("%3A", ":");
        payment_date = payment_date.Replace("+", " ");
        payment_date = payment_date.Replace("%2C", " ");

        txn_type = Convert.ToString(HttpContext.Current.Request.Form["txn_type"]); // 'cart'

        Verify_sign = "ipn";

        payment_status = Convert.ToString(HttpContext.Current.Request.Form["payment_status"]); ;

        receiver_email = Convert.ToString(HttpContext.Current.Request.Form["receiver_email"]); 
        receiver_email = receiver_email.Replace("%40", "@");

        if (payment_status.Equals("Completed"))
        {
            /*
                using (SqlConnection connection = new SqlConnection(connectionString))
                using (SqlCommand command = connection.CreateCommand())
                {
                    command.CommandText = "UPDATE table SET memPhone = @memPhone WHERE uName='testName'";
                    command.Parameters.AddWithValue("@memPhone", payment_status);  

                    connection.Open();
                    command.ExecuteNonQuery();
                    connection.Dispose();
                }
            */

        }
        else if (payment_status.Equals("Denied") || payment_status.Equals("Failed") || payment_status.Equals("Refunded") || payment_status.Equals("Reversed") || payment_status.Equals("Voided"))
        {

        }
        else if (payment_status.Equals("In-Progress") || payment_status.Equals("Pending") || payment_status.Equals("Processed"))
        {

        }
        else if (payment_status.Equals("Canceled_Reversal"))
        {

        }
        else
        {

        }
    }
    else if (strResponse == "INVALID")
    {
        //log for manual investigation
    }
    else
    {
        //log response/ipn data for manual investigation
    }

 }
}

当它出现在 payment_status.Equals("Completed") 分支中时,IPN 处理程序(或任何其他 IPN 实现)不起作用:

using (SqlConnection connection = new SqlConnection(connectionString))
            using (SqlCommand command = connection.CreateCommand())
            {
                command.CommandText = "UPDATE table SET memPhone = @memPhone WHERE uName='testname'";
                command.Parameters.AddWithValue("@memPhone", payment_status);  

                connection.Open();
                command.ExecuteNonQuery();
                connection.Dispose();
            }

当这个 sql 命令代码不存在时,IPN 处理程序和实现确实可以工作,但我显然需要它来更新数据库。

我已将此代码放入所有其他 if 分支(“Denied”、“In-Progress”、“Canceled_Reversal”)中,但它没有任何效果,所以我知道 IPN 正在查看正确的“Completed”分支而不是这些其他人。

是否有人知道发生这种情况的特定贝宝原因或在此处查看代码的任何问题?

顺便说一句,我知道我正在尝试将“已完成”传递给 memPhone(这是一个 varchar),这没有任何意义。我只是用它来测试 SQL 是否正常工作,因为两者都是字符串。

【问题讨论】:

  • 当您调试代码string connectionString = ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString(); 时,您会从该值得到什么,根据您所拥有的string connectionString = ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString;,您不需要调用Dispose,因为它包含在里面的using(){} 以及当您执行command.ExecuteNonQuery 时您会得到什么,您基于代码假设这不会出错.. 将调用包装在try{}catch{} 周围,告诉我们错误消息是什么(如果有)
  • 我的字符串 connectionString 是如何工作的,不是问题。我在其他每一页上都成功地做到了这一点。我通常确实有 try{} catch{} 但我把它拿出来是因为它可以防止错误,如果它不起作用,我希望它出错。我将删除 dispose。
  • 那么你不需要 .ToString();最后.. 因为这一行将返回一个字符串string connectionString = ConfigurationManager.ConnectionStrings["LocalSqlServer"]
  • 我确实需要 .ToString 因为 System.Configuration.ConnectionStringSettings 不是字符串,需要转换。如果删除它会报错。
  • 这就是我建议在最后使用 .ConnectionString 的方法。无论哪种方式都不是问题。进行一些适当的错误处理,以便您可以报告当前问题。

标签: c# asp.net paypal


【解决方案1】:

很遗憾,我无法在 Visual Studio 中调试它

是的,你可以。您可以将请求模拟为您希望的简单或完整,以便您可以在内部单步执行您的代码。您可以将原始有效负载“保存”到某个地方(甚至只是通过电子邮件将其发送给自己),然后对其进行模拟。还有其他工具 - 例如

  • 使用PayPal's IPN simulator - 虽然这不如使用您收到的实际数据...

  • 除了上述过程之外,您还可以使用Requestb.in 或类似服务,这样您就可以获得原始数据的快照以使用和模拟请求。

获得原始数据后,您可以选择任何方式模拟 POST(例如,curl 以调试模式运行应用程序的本地盒子)。

示例 IPN 模拟器 POST 到 Requestb.in。如果示例链接已过期(截至发帖 48 小时后),请在下方截图:


一般来说,仅基于上述post/cmets,您的问题集中在您的SQL进程上。正如建议的那样,您应该try/catch,因为您对该建议的回答似乎只是您的假设。您的catch 可以简单地将异常消息通过电子邮件发送给您,然后您就可以了解更多详细信息(也许不必经历上述所有模拟)。

第...

【讨论】:

    猜你喜欢
    • 2019-10-01
    • 2019-12-16
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    相关资源
    最近更新 更多