Post Redirect to URL with post data
Asked Answered
S

1

6

I am working on a post redirect for a payment provider and trying to pass form data to their secure URL.

I am doing this in kentico 8 by using their custom payment gateway method as shown here https://docs.kentico.com/display/K8/Creating+a+custom+payment+gateway

So in the custom payment class I prepared the data to be passed to the payment provider in a 'Form' format with hidden fields using this tutorial http://www.codeproject.com/Articles/37539/Redirect-and-POST-in-ASP-NET

However I am not able to figure out on how to redirect to the secure URL with the form data?

Here is my code so far.

I have tried Response.Redirect however it is a GET function instead of POST.

using System;
using System.Collections;
using System.Collections.Specialized;
using System.Configuration;
using CMS;
using CMS.Base;
using CMS.EcommerceProvider;
using CMS.Helpers;
using System.Security.Cryptography;
using System.Web;
using System.Web.Security;
using System.Text;
using System.IO;
using System.Net;
using System.Web.UI;


[assembly: RegisterCustomClass("CustomGateway", typeof(CustomGateway))]

public class CustomGateway : CMSPaymentGatewayProvider
{


/// <summary>
/// Process payment.
/// </summary>
public override void ProcessPayment()
{        
    // Get payment gateway url

    string url = "https://epage.payandshop.com/epage.cgi";
    if (url != "")
    {
        NameValueCollection postData = getRealexData();
        RedirectAndPOST(url, postData);
    }
    else
    {
        // Show error message - payment gateway url not found
        ErrorMessage = "Unable to finish payment: Payment gateway url not found.";
        // Update payment result
        PaymentResult.PaymentDescription = ErrorMessage;
        PaymentResult.PaymentIsCompleted = false;
        // Update order payment result in database
        UpdateOrderPaymentResult();
    }
}

public static void RedirectAndPOST(string destinationUrl, NameValueCollection data)
{
    //Prepare the Posting form
    string strForm = PreparePOSTForm(destinationUrl, data);

    HttpContext.Current.Response.Write(strForm);
    HttpContext.Current.Response.End();
}

private static String PreparePOSTForm(string url, NameValueCollection data)
{
    //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 (string key in data)
    {
        strForm.Append("<input type=\"hidden\" name=\"" + key + 
                        "\" value=\"" + data[key] + "\">");
    }

    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 NameValueCollection getRealexData()
{
    //format the date expected by Realex
    string timestamp = RealexDateFormatter.DateFormatForRealex();

    //take the MerchantID and Shared Secret from the web.config
    string merchantid = ConfigurationManager.AppSettings["RealexMerchantID"];
    string secret = ConfigurationManager.AppSettings["RealexSecret"];

    // Order Info
    int orderid = ShoppingCartInfoObj.OrderId;
    string stringorderid = Convert.ToString(orderid);
    string curr = ShoppingCartInfoObj.Currency.CurrencyCode;
    double amount = ShoppingCartInfoObj.TotalPrice;
    amount = Convert.ToInt32(amount);
    string prepareMD5 = timestamp + "." + merchantid + "." + orderid + "." + amount + "." + curr;

    //generate the md5 Hash
    MD5 md5 = new MD5CryptoServiceProvider();

    string temp1 = GetMD5Hash(prepareMD5);
    temp1 = temp1.ToLower();
    string temp2 = temp1 + "." + secret;
    string md5hash = GetMD5Hash(temp2);
    md5hash = md5hash.ToLower();

    NameValueCollection data = new NameValueCollection();

    data.Add("MERCHANT_ID", merchantid);
    data.Add("ORDER_ID", stringorderid);
    data.Add("CURRENCY", curr);
    data.Add("AMOUNT", amount.ToString());
    data.Add("TIMESTAMP", timestamp);
    data.Add("MD5HASH", md5hash);
    data.Add("AUTO_SETTLE_FLAG", "1");

    return data;
}

public static String GetMD5Hash(String TextToHash)
{
    //Check wether data was passed
    if ((TextToHash == null) || (TextToHash.Length == 0))
    {
        return String.Empty;
    }

    //Calculate MD5 hash
    MD5 md5 = new MD5CryptoServiceProvider();

    // Create a new Stringbuilder to collect the bytes 
    // and create a string.
    byte[] data = md5.ComputeHash(Encoding.UTF8.GetBytes(TextToHash));

    StringBuilder sBuilder = new StringBuilder();

    // Loop through each byte of the hashed data  
    // and format each one as a hexadecimal string. 
    for (int i = 0; i < data.Length; i++)
    {
        sBuilder.Append(data[i].ToString("x2"));
    }
    return sBuilder.ToString();
}

}

Susurrous answered 5/8, 2015 at 16:8 Comment(0)
M
3

Take a look at this answer from a similar question. I would recommend using Method 3 in that answer. By creating an asynchronous call, you could wait for a response back and either redirect on a successful response with Response.Redirect(), or notify the user of any errors.

Memoir answered 5/8, 2015 at 19:16 Comment(1)
interesting, but the link is just strictly about sending postdata. The person asking the question was asking about 'redirect'. In a redirect the browser is moved and directed (but the link you sent, was strictly talking about post and receiving responses). The idea of redirecting the browser (with data) is still unanswered.Didier

© 2022 - 2024 — McMap. All rights reserved.