6
votes

I had test application integrated with Paypal express checkout and it was running fine. But now there seems some issue. After successful payment on paypal when my IPN handler check for response paypal returns response as html page instead of "VERIFIED" OR "INVALID" and because of this I'm not able to verify the payment. Is there any change in Paypal recently for express checkout? Below is complete code

<form id="Paypal" name="Paypal" action="https://www.sandbox.paypal.com/cgi-bin/webscr"
    method="post">
    @Html.Hidden("cmd", "_xclick")
    @Html.Hidden("business", "[email protected]")
    @Html.Hidden("item_name", "Payment for course registration")
    @Html.Hidden("amount", 100 )
    @Html.Hidden("no_shipping", "1")
    @Html.Hidden("return", "http://localhost:49319/cart/IPN")
    @Html.Hidden("rm", "2")
    @Html.Hidden("notify_url", "http://localhost:49319/cart/IPN")
    @Html.Hidden("cancel_return", "http://localhost:49319/cart/PaymentFailure")
    @Html.Hidden("currency_code", "CAD")
    @Html.Hidden("tax_cart", "1")
    @Html.Hidden("custom", "12")
    <div class="checkout-button">
        <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif"
            align="left" style="margin-right: 7px;" />
    </div>
    </form>

IPN handler code:

 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;

        //for proxy
        //WebProxy proxy = new WebProxy(new Uri("http://urlort#");
        //req.Proxy = proxy;
        //Send the request to PayPal and get the response
        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;

Edit: Here is request string sent to Paypal

CONTEXT=wtgSziM4C5x0SI-9CmKcv2vkSeTLK5P_g6HqzC__YTYkcqziFNcB84p79Ja&myAllTextSubmitID=&cmd=_flow&transaction_subject=12&txn_type=web_accept&payment_date=01%3A59%3A21+May+02%2C+2011+PDT&last_name=User&residence_country=CA&pending_reason=paymentreview&item_name=Payment+for+course+registration&payment_gross=&mc_currency=CAD&business=pramod_1298956597_biz%40sumerusolutions.com&payment_type=instant&protection_eligibility=Ineligible&payer_status=verified&verify_sign=Ag7LtkvrF1u9.1ScLJwRM4btR1G1A16qsCs-xUl6EpI1rE1UWpodXJsc&txn_id=15Y20623GD922445F&payer_email=pramod_1298961722_per%40sumerusolutions.com&tax=0.00&test_ipn=1&first_name=Test&receiver_email=pramod_1298956597_biz%40sumerusolutions.com&quantity=1&payer_id=Z2MRT3Q9L6E28&receiver_id=RT3M59WESZHEE&item_number=&payment_status=Pending&handling_amount=0.00&shipping=0.00&mc_gross=850.00&custom=12&charset=windows-1252&notify_version=3.1&merchant_return_link=click+here&form_charset=UTF-8CONTEXT=wtgSziM4C5x0SI-9CmKcv2vkSeTLK5P_g6HqzC__YTYkcqziFNcB84p79Ja&myAllTextSubmitID=&cmd=_flow&transaction_subject=12&txn_type=web_accept&payment_date=01%3A59%3A21+May+02%2C+2011+PDT&last_name=User&residence_country=CA&pending_reason=paymentreview&item_name=Payment+for+course+registration&payment_gross=&mc_currency=CAD&business=pramod_1298956597_biz%40sumerusolutions.com&payment_type=instant&protection_eligibility=Ineligible&payer_status=verified&verify_sign=Ag7LtkvrF1u9.1ScLJwRM4btR1G1A16qsCs-xUl6EpI1rE1UWpodXJsc&txn_id=15Y20623GD922445F&payer_email=pramod_1298961722_per%40sumerusolutions.com&tax=0.00&test_ipn=1&first_name=Test&receiver_email=pramod_1298956597_biz%40sumerusolutions.com&quantity=1&payer_id=Z2MRT3Q9L6E28&receiver_id=RT3M59WESZHEE&item_number=&payment_status=Pending&handling_amount=0.00&shipping=0.00&mc_gross=850.00&custom=12&charset=windows-1252&notify_version=3.1&merchant_return_link=click+here&form_charset=UTF-8&cmd=_notify-validate

5

5 Answers

5
votes

Ok. After lot of trial and error and posting this issue in paypal forum I got my payment gateway working. Though I'm not really happy with the solution.The solution is use PDT and don't use IPN. The response I got from paypal support was "The Problem is that IPN is an additional Notification system and there is a little delay in it. So it is not 100% the perfect solution for an autoreturn Page."

Paypal suggested me to use PDT and it's working now. I'll put the steps here so that it may help someone who is also facing such issue:

  1. Activate the "AutoReturn" and PDT feature in your PayPal Account. Steps: Login to your PayPal account click on Profile click on Website Payment Preferences set Auto Return to On enter a valid URL in the Return URL text box set Payment Data Transfer to on. Note down the PDT token displayed. scroll to the bottom of the page and click "Save"

  2. Pass below parameters to paypal cmd, business, item_name, amount, return, currency_code, custom.

  3. Change IPN handler code with PDT code, PDT code in my case is as below-

    string authToken, txToken, query; string strResponse;

        authToken = ConfigurationManager.AppSettings["PDTToken"];
    
        //read in txn token from querystring
        txToken = Request.QueryString.Get("tx");
    
    
        query = string.Format("cmd=_notify-synch&tx={0}&at={1}", txToken, authToken);
    
        // Create the request back
        string url = ConfigurationManager.AppSettings["PayPalUrl"];
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
    
        // Set values for the request back
        req.Method = "POST";
        req.ContentType = "application/x-www-form-urlencoded";
        req.ContentLength = query.Length;
    
        // Write the request back IPN strings
        StreamWriter stOut = new StreamWriter(req.GetRequestStream(), System.Text.Encoding.ASCII);
        stOut.Write(query);
        stOut.Close();
    
        // Do the request to PayPal and get the response
        StreamReader stIn = new StreamReader(req.GetResponse().GetResponseStream());
        strResponse = stIn.ReadToEnd();
        stIn.Close();            
    
        // If response was SUCCESS, parse response string and output details
        if (strResponse.StartsWith("SUCCESS"))
        {
    
        }
    
0
votes

You need to show yourself the html which is being returned. It's quite probable that your account was suspended or something and Paypal is responding something to you. Can you show us that HTML ?

0
votes

Firstly, I suggest you go to the Paypal developer support site. Although they can take a short while to respond to your problem, the people there are very experienced with Paypal and I'm sure will be able to give you a answer.

On your particular problem, & in my Paypal experience, I believe that there are two types of Paypal accounts.

The first type of account allows your website to act as a third party - that is:

  • the user submits payment information on your website
  • your website communicates to Paypal, receiving a response
  • you are able to display that response to the user on your website

This is obviously what you are trying to do.

However, I believe there is a second type of Paypal account. This account may be cheaper, have less restrictive requirements / terms & conditions, or just simpler to integrate (otherwise I'm not sure why one would choose it). I believe this account requires your website to redirect the user to Paypal, where they will be given a response.

  • the user submits payment information
  • you redirect them to Paypal
  • they see the payment status or some other message, and can click a link to come back to your (vendor) website.

I could be wrong but this is my recollection of working with Paypal API. I strongly suggest you go to the Paypal developer site, linked above.

0
votes

I am having the same exact issue trying to setup IPN... I have it working when I send an "echeck" from the sandbox it will return VERIFIED, however when I try to do an express checkout it will not return verified or invalid... it returns something totally different than echeck... its very strange.

I am going to try and ask tech support what the difference is with these two services.

0
votes

IPN does work from C#, I was having the same issue as you (getting an HTML page that asks me to login) and then I found that I was missing the following variable in my post back to PayPal

cmd=_notify-validate

as soon as I added that correctly, the request to PayPal worked as expected.

Another thing to make sure of, is you pass the variables back as they were received in the IPN request, just append the above command to the begining of your post back.

I am not using MVC but I am doing this with WCF and it works like a charm.

Hope that helps.