Search code examples
c#asp.net-core-mvcrazor-pagespayu

Razor Pages ASP.NET C# Core 3.1 MVC: PayU not redirecting to success and failure cshtml page after payment transaction


I am building a web application using the ASP.NET C# Core 3.1 MVC and Razor pages. I am new to Razor pages.

I am integrating PayU payment interface in the application.

"Register.cshtml" form accepts UserFirstName, UserLastName, UserEmailAddress, UserPhoneNumber, ProducType and Amount from user and post the data along with PayU credentials (merchant key, salt) arranged in format - "key|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5|udf6|udf7|udf8|udf9|udf10" to https://test.payu.in

I am able to do the transaction successfully, but the redirection from PayU Payment to ( success and failure cshtml page) RegisterConfirm.cshtml is not happening

Following error appears: -

enter image description here

Following is the code:

appsettings.json

"PayUMoneyKey": {
    "MERCHANT_KEY": "gtKFFx",
    "SALT": "4R38IvwiV57FwVpsgOvTXBdLE4tHUXFW",
    "PAYU_BASE_URL": "https://test.payu.in",
    "action": "",
    "hashSequence": "key|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5|udf6|udf7|udf8|udf9|udf10"
  },

Register,chtml

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    if (ModelState.IsValid)
    {

        string strUserFirstName = UserFirstName;
        string strUserLastName = UserLastName;
        string strUserEmailAddress = UserEmailAddress;
        string strUserPhoneNumber = UserPhoneNumber;
        string strProducType = ProducType;
        string strAmount = Amount;

        returnUrl = returnUrl ?? Url.Content("~/");
        objappdbcont = new AppDbContext();

        try
            {
                
                string[] hashVarsSeq;
                string hash_string = string.Empty;

                Random rnd = new Random();
                string strHash = Generatehash512(rnd.ToString() + DateTime.Now);
                txnid1 = strHash.ToString().Substring(0, 20);
                mkey1 = _configuration.GetSection("PayUMoneyKey").GetSection("MERCHANT_KEY").Value;
                msalt1 = _configuration.GetSection("PayUMoneyKey").GetSection("SALT").Value;
                hashVarsSeq = _configuration.GetSection("PayUMoneyKey").GetSection("hashSequence").Value.Split('|');

                hash_string = "";

                foreach (string hash_var in hashVarsSeq)
                {
                    if (hash_var == "key")
                    {
                        hash_string = hash_string + mkey1;
                        hash_string = hash_string + '|';
                    }
                    else if (hash_var == "txnid")
                    {
                        hash_string = hash_string + txnid1;
                        hash_string = hash_string + '|';
                    }
                    else if (hash_var == "amount")
                    {
                        hash_string = hash_string + Convert.ToDecimal(strAmount).ToString("g29");
                        hash_string = hash_string + '|'; 
                    }
                    else if (hash_var == "email")
                    {
                        hash_string = hash_string + strUserEmailAddress;
                        hash_string = hash_string + '|';
                    }
                    else if (hash_var == "firstname")
                    {
                        hash_string = hash_string + strUserFirstName;
                        hash_string = hash_string + '|';
                    }
                    else if (hash_var == "productinfo")
                    {
                        hash_string = hash_string + strProducType;
                        hash_string = hash_string + '|';
                    }
                    else
                    {
                        hash_string = hash_string + '|';
                    }
                }

                hash_string += msalt1;// appending SALT

                hash1 = Generatehash512(hash_string).ToLower();         //generating hash
                action1 = _configuration.GetSection("PayUMoneyKey").GetSection("PAYU_BASE_URL").Value + "/_payment";// setting URL

            string strUserFirstName = UserFirstName;
            string strUserLastName = UserLastName;
            string strUserEmailAddress = UserEmailAddress;
            string strUserPhoneNumber = UserPhoneNumber;
            string strProducType = ProducType;
            string strAmount = Amount;
            string strDummy = "test";

                System.Collections.Hashtable data = new System.Collections.Hashtable(); // adding values in gash table for data post
                data.Add("hash", hash1);
                data.Add("txnid", txnid1);
                data.Add("key", mkey1);
                data.Add("salt", msalt1);
                string AmountForm = Convert.ToDecimal(strAmount.Trim()).ToString("g29");// eliminating trailing zeros
                data.Add("amount", AmountForm);
                data.Add("firstname", strUserFirstName);
                data.Add("email", strUserEmailAddress);
                data.Add("phone", strUserPhoneNumber);
                data.Add("productinfo", strProducType);
                data.Add("surl", "http://localhost:51600/RegisterConfirm");
                data.Add("furl", "http://localhost:51600/RegisterConfirm");
                data.Add("lastname", strUserLastName);
                data.Add("curl", "");
                data.Add("address1", strDummy);
                data.Add("address2", strDummy);
                data.Add("city", strDummy);
                data.Add("state", strDummy);
                data.Add("country", strDummy);
                data.Add("zipcode", strDummy);
                data.Add("udf1", "");
                data.Add("udf2", "");
                data.Add("udf3", "");
                data.Add("udf4", "");
                data.Add("udf5", "");
                data.Add("pg", "");

                string strForm = PreparePOSTForm(action1, data);

                return Content(strForm, System.Net.Mime.MediaTypeNames.Text.Html);
            }
            catch (Exception ex)
            {}
    }
    return Page();
}



    private string PreparePOSTForm(string url, System.Collections.Hashtable data)      // post form
    {
        //Set a name for the form
        string formID = "PostForm";
        //Build the form using the specified data to be posted.
        StringBuilder strForm = new StringBuilder();
        strForm.Append("<form id=\"" + formID + "\" name=\"" +
                       formID + "\" action=\"" + url +
                       "\" method=\"POST\">");

        foreach (System.Collections.DictionaryEntry key in data)
        {

            strForm.Append("<input type=\"hidden\" name=\"" + key.Key +
                           "\" value=\"" + key.Value + "\">");
        }


        strForm.Append("</form>");
        //Build the JavaScript which will do the Posting operation.
        StringBuilder strScript = new StringBuilder();
        strScript.Append("<script language='javascript'>");
        strScript.Append("var v" + formID + " = document." +
                         formID + ";");
        strScript.Append("v" + formID + ".submit();");
        strScript.Append("</script>");
        //Return the form and the script concatenated.
        //(The order is important, Form then JavaScript)
        return strForm.ToString() + strScript.ToString();
    }

    public string Generatehash512(string text)
    {

        byte[] message = Encoding.UTF8.GetBytes(text);

        UnicodeEncoding UE = new UnicodeEncoding();
        byte[] hashValue;
        SHA512Managed hashString = new SHA512Managed();
        string hex = "";
        hashValue = hashString.ComputeHash(message);
        foreach (byte x in hashValue)
        {
            hex += String.Format("{0:x2}", x);
        }
        return hex;

    }

RegisterConfirm

 public class RegisterConfirmModel : PageModel
    {
     
      public RegisterConfirmModel(
            IConfiguration configuration)
        {
            _configuration = configuration;
        }

      public ActionResult OnGet(Microsoft.AspNetCore.Http.IFormCollection collection)
        {
            try
            {    
                ViewData["Name"] = collection["hash"];    
                return Page();
            }
            catch
            {
                return Page();
            }
        }

Question: How to redirect from PayU Payment to ( success and failure cshtml page) RegisterConfirm.cshtml and retrieve transaction details?


Solution

  • The error "This page isn't working right now" was shown because the request posted from PayU didn't had RequestVerificationToken.

    Request Verification in ASP.NET Razor Pages is a mechanism designed to prevent possible Cross Site Request Forgery attacks, also referred to by the acronyms XSRF and CSRF.

    The Razor pages MVC framework expects the "RequestVerificationToken" as part of the posted request. The framework uses this to prevent possible CSRF attacks. If the request does not have this information, the framework will return the HTTP Error 400 (bad request).

    To solve this issue, either RequestVerificationToken should be in the posted form data or the Razor page should bypass the token check

    1. Include the token in header -

    headers:
    {
        "RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
    },
    

    OR

    2. Bypass the checks by adding the IgnoreAntiforgeryTokenAttribute to the relevant PageModel class (not a handler method):

    [IgnoreAntiforgeryToken(Order = 1001)]    
    

    public class RegisterConfirmModel : PageModel

    When the token check was bypassed the page RegisterConfirm.cshtml was loaded.