简体   繁体   中英

Trouble connecting DB using Paypal's IPN, C#

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
    }

 }
}

The IPN handler (or any other IPN implementation) doesn't work when this is present in the payment_status.Equals("Completed") branch:

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();
            }

The IPN handler and implementations do work when this sql command code isn't there but I obviously need it to update the db.

I have put this code in all of the other if branches ("Denied", "In-Progress, "Canceled_Reversal") and it has no effect so I know the IPN is looking inside the correct "Completed" branch and not these others.

Does anyone know a specific paypal reason why this is happening or see any issues with the code here?

btw, I know I'm trying to pass "completed" into the memPhone (which is a varchar) and that doesn't make sense. I'm just using it to test if the SQL is working because both are strings.

I can't debug it in Visual Studio unfortunately

Yes, you can. You can mock the request as simple or as complete as you want it to be so you can step through your code internally. You can "save" the original payload somewhere (or even just email it to yourself) and then mock it. There are other tools - eg

  • use PayPal's IPN simulator - though this will not be as good as working with the actual data you are receiving...

  • alternative to the above process you can probably use Requestb.in or similar services so you can have a snapshot of the raw data to use and mock the request.

Once you have the raw data you can mock the POST anyway you choose (eg curl to your local box running app in debug mode).

Sample IPN Simulator POST to Requestb.in . Snapshot below if the sample link has expired (after 48 hours as of this post):

Request.bin示例


Generally speaking, based only on above post/comments, your issue is centered on your SQL process. As suggested, you should try/catch because your answer to the suggestion seems to be just your assumption. Your catch could simply email you the exception message and then you have more detail (and maybe not have to go through all the above mocking).

Hth...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM