Avatar of Ecnalyr
Ecnalyr
 asked on

Difficulty confirming Instant Payment Notification (IPN) from Paypal within an MVC3 Application

I am trying to get Paypal's IPN service working within my app.

When I use the Paypal Sandbox IPN Simulator set to the transaction type of, "Web Accept," Paypal says the message went through just fine  (and if I mess up the code in my Action that handles the IPN, Paypal says there was a server error, so this seems to be communicating correctly).

However, it doesn't appear to actually be doing anything.  If I navigate to my IPN action in a browser `myapp.com/Paypal/IPN`, I receive a response from paypal that says `INVALID` (as expected) and this is written to my output via `Debug.Write`.  When I click "Send IPN" in Paypal's simulator, I get no debug messages at all, although my IPN action is full of `Debug.Write` lines.  (Do calls made from outside your local environment simply not allow `Debug.Write` output?)

For reference, here is the majority of my IPN Action (I've removed various logic for clarity's sake):

    public ActionResult IPN()
    {
        Debug.Write("entering ipn action ");
        var formVals = new Dictionary<string, string>();
        formVals.Add("cmd", "_notify-validate");

        string response = GetPayPalResponse(formVals, true);
        Debug.Write("IPN Response received: " + response + " <-- That was response. . . ");

        if (response == "VALID")
        {
            Debug.Write("Response Was Verified");
        }

        else
        {
            Debug.Write("RESPONSE WAS NOT VERIFIED");
        }

        return this.View();
    }


    string GetPayPalResponse(Dictionary<string, string> formVals, bool useSandbox)
    {
        string paypalUrl = useSandbox
                                ? "https://www.sandbox.paypal.com/cgi-bin/webscr"
                                : "https://www.paypal.com/cgi-bin/webscr";

        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(paypalUrl);
            
        //Set values for the request back
        req.Method = "POST";
        req.ContentType = "application/x-www-form-urlencoded";

        byte[] param = Request.BinaryRead(Request.ContentLength);
        string strRequest = Encoding.ASCII.GetString(param);

        StringBuilder sb = new StringBuilder();
        sb.Append(strRequest);

        foreach (string key in formVals.Keys)
        {
            sb.AppendFormat("&{0}={1}", key, formVals[key]);
        }
        strRequest += sb.ToString();
        req.ContentLength = strRequest.Length;

        string response = "";
        using (StreamWriter streamOut = new StreamWriter(req.GetRequestStream(), System.Text.Encoding.ASCII))
        {
            streamOut.Write(strRequest);
            streamOut.Close();
            using (StreamReader streamIn = new StreamReader(req.GetResponse().GetResponseStream()))
            {
                response = streamIn.ReadToEnd();
            }
        }
        return response;
    }

Open in new window


Am I correct in understanding that if Paypal is actually submitting a request to my IPN action, I should receive the `Debug.Write` messages the same as when I visit the IPN action within my browser?

It does not appear to me that anything actually happens when Paypal sends the IPN simulated message to my web application, but Paypal says things are ok and Paypal somehow knows if I intentionally make the IPN action have an error when it is caused (so it appears to actually be calling the action somehow).

Can anyone help me understand what I am not understanding here?

I just want my user's to be able to pay using Paypal's standard payment method with a 'buy now' button and be able to change a database value from `false` to 'true' when the payment is confirmed to have been received.

Thank you for your time.

Note: Another way I tested this was to have the action change something in my database if it was called (I simply did something like `MyEntity.Value = new value` then `db.SaveAll();`.  This change to my database was made if I navigated directly to the action within my browser, but no change occurs when I had the paypal IPN simulator 'ping' the action.
ASP.NETC#.NET ProgrammingPayPal

Avatar of undefined
Last Comment
Ecnalyr

8/22/2022 - Mon
Dale Burrell

Use trace.axd to see data you are receiving from Paypal on an IPN post and you will be able to see if its posting to the correct URL and what data it is posting which should get you part-way to working out what is happening.

You appear to send the data you receive back to Paypal again, is that to verify the IPN post?
Ecnalyr

ASKER
You appear to send the data you receive back to Paypal again, is that to verify the IPN post?
Yes that is to verify the IPN post.

I have not used trace.axd before, I will look into setting that up now.

Sorry for the short reply, thought it would be good to update as I am working.
Ecnalyr

ASKER
Ok, running trace like this:

<trace enabled="true" requestLimit="100" pageOutput="false" traceMode="SortByTime" localOnly="false" />

Open in new window


It behaves as if nothing happens when I run the Paypal IPN Simulator or if I browse to my web page using a device that is off my local network.

Note that I do see details change when I visit the pages on my local computer:

8	7/8/2012 6:25:01 PM	paypal/ipn	200	GET	View Details
9	7/8/2012 6:25:02 PM	paypal/themes/ui-lightness/jquery-ui-1.8.19.custom.css	404	GET	View Details
10	7/8/2012 6:25:02 PM	favicon.ico	404	GET	View Details
11	7/8/2012 6:25:52 PM	favicon.ico	404	GET	View Details
12	7/8/2012 6:26:09 PM	home/paypaltest	200	GET	View Details

Open in new window

I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
Dale Burrell

So you are using an externally available domain name? And the DNS is correctly configured to allow external access?
Ecnalyr

ASKER
Yes, I very easily can navigate to the web app in question and use it from a remote computer.
Dale Burrell

OK, and when you access the web app from a remote computer do those requests show up in trace.axd?
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
Ecnalyr

ASKER
No they do not.

- also, none of my Debug.Write functions write anything to my Output window in Visual Studio.

- If you think it'd be helpful, I could link you to the most recent commit on GitHub
Dale Burrell

So you have VS connected as a remote debugger?

Thats very strange, I don't know of any way to filter what trace.axd shows, unless you have a module which catches certain requests? Or unless external requests are passed to a duplicate server running the same web app? Try accessed trace.axd on the same machine you are making the request from.

It sounds like from what you are saying that the external requests return the results you would expect - is there any chance your network could be caching pages and therefore external requests are hitting the cache instead of the server?

You should be able to see each and every request in trace.axd, but I can't think of anything further to help you on that front.

If you are unable to get trace.axd displaying all requests the next best thing would be to catch the begin request event in global.asax and manually write every request to a txt log file - that way you are in control and know whats happening.

Very weird! Good luck!
Ecnalyr

ASKER
I got the debugger to start debugging by attaching the debugger to : "w3wp.exe"

It appears that Paypal is indeed making it to my page and responding with "VERIFIED" at this point.  Not sure what this means for me.  Will update.
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
ASKER CERTIFIED SOLUTION
Ecnalyr

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
Ecnalyr

ASKER
It worked.