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();
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With