Post Redirect to URL with post data - c#

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.

Related

GoogleSmarthome JWT Creation

The documentation is at Using OAuth 2.0 for Server to Server Applications
You will notice in the documentation the disclaimer "don't do this but use the libraries". Unfortunately, there does NOT appear to be .Net Core libraries and I have suggested to the Smarthome program managers that support for .Net Core should be the same as provided for Java, node.js and Python.
However, I'm hunkered down, socially distanced and have some time available so I gave it a shot. There are a lot of moving parts here but to start I downloaded a p12 file instead of a JSON file (as indicated in the documentation) from the Google Console for the account.
The code:
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
namespace MakeJWTTest
{
class Program
{
static void Main(string[] args)
{
string token = MakeJwt();
Console.WriteLine();
Console.WriteLine("The Final JWT: " + token );
}
public static string MakeJwt()
{
string jwt = string.Empty;
string iss = "XXXXXXXXXXXXXXX-v2.iam.gserviceaccount.com";
string scope = "https://www.googleapis.com/auth/homegraph";
string aud = "https://oauth2.googleapis.com/token";
string exp = EpochExpiration();
string iat = EpochCurrentTime();
string jwtHeader = "{\"alg\":\"RS256\",\"typ\":\"JWT\"}";
Console.WriteLine("iss: " + iss);
Console.WriteLine("scope: " + scope);
Console.WriteLine("aud: " + aud);
Console.WriteLine("exp: " + exp);
Console.WriteLine("iat: " + iat);
Console.WriteLine("JWT Header: " + jwtHeader);
string claim = "{\"iss\": \"" + iss + "\",\"scope\": \"" + scope + "\",\"aud\": \"" + aud + "\",\"exp\": " +
exp + ",\"iat\": " + iat + "}";
var encodedHeader = Base64UrlEncoder.Encode(jwtHeader);
Console.WriteLine("Encoded JWT Header: " + encodedHeader);
var encodedClaim = Base64UrlEncoder.Encode(claim);
string claimSet = encodedHeader + "." + encodedClaim;
string sig = Sign(claimSet);
jwt = claimSet + '.' + sig;
return jwt;
}
public static string EpochExpiration()
{
DateTime epoch = DateTime.UnixEpoch;
DateTime now = DateTime.UtcNow;
DateTime expiration = now.AddMinutes(60);
TimeSpan secondsSinceEpoch = expiration.Subtract(epoch);
return secondsSinceEpoch.TotalSeconds.ToString().Substring(0, 10);
}
public static string EpochCurrentTime()
{
DateTime epoch = DateTime.UnixEpoch;
DateTime now = DateTime.UtcNow;
TimeSpan secondsSinceEpoch = now.Subtract(epoch);
return secondsSinceEpoch.TotalSeconds.ToString().Substring(0, 10);
}
public static string Sign( string toSHA256)
{
try
{
byte[] data = Encoding.ASCII.GetBytes(toSHA256);
var certificate = new X509Certificate2(#"XXXXXXXXXXXXXXX-v2-6790af22aa27.p12", "notasecret", X509KeyStorageFlags.Exportable);
RSACryptoServiceProvider key = new RSACryptoServiceProvider();
// byte[] key = certificate.PrivateKey.ExportPkcs8PrivateKey();
key.FromXmlString(certificate.PrivateKey.ToXmlString(true));
//Sign the data
byte[] sig = key.SignData(data, CryptoConfig.MapNameToOID("SHA256"));
return Base64UrlEncoder.Encode(sig);
}
catch { Exception e; return null; }
}
}
}
Run this program and I get:
scope: https://www.googleapis.com/auth/homegraph
aud: https://oauth2.googleapis.com/token
exp: 1586193162
iat: 1586189562
JWT Header: {"alg":"RS256","typ":"JWT"}
Encoded JWT Header: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
The Final JWT: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiAibGltaXRlZG1vYmlsaXR5djJAbGltaXRlZC1tb2JpbGl0eS1zb2x1dGlvbnMtdjIuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iICJzY29wZSI6ICJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9hdXRoL2hvbWVncmFwaCJhdWQiOiAiaHR0cHM6Ly9vYXV0aDIuZ29vZ2xlYXBpcy5jb20vdG9rZW4iZXhwIjogIjE1ODYxOTMxNjIiaWF0IjogMTU4NjE4OTU2Mg.ZOX93iUhirtH2tf95XzLYrGIbTK8kABipfVa6DnD-sAe3WcRfLmLVIAybtHTHxC8frCuZtCeS4XMT-EC69kLy-ks5BWFTnaRwm0TfIeNzIVrGfJUVRchvaJLFM9-wX6svVa4fGHMp8pKttO22BI3sIEisxXx2tw6Ge_8QRZXjSCXD0rg5P-0S-pnd8omkgPv_PhhALqcwd9RTUpcAqcMDoyP7ZxpBSMt1EwySixctKz2y4sRCGC8xaxp5E5VnH3liz3xTNMY5QRNX-tMxVIunh0Qp9v7bkuuvnhrwbcjRPq9qTKlhfIQBmZvaA5-9hzJZOiWWHmCunMec1pZp0bAgQ
Press any key to close this window . . .
I then run this from Powershell using curl:
.\curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.RZVpzWygMLuL-n3GwjW1_yhQhrqDacyvaXkuf8HcJl8EtXYjGjMaW5oiM5cgAaIorrqgYlp4DPF_GuncFqg9uDZrx7pMmCZ_yHfxhSCXru3gbXrZvAIicNQZMFxrEEn4REVuq7DjkTMyCMGCY1dpMa8aWfTQFt3Eh7smLchaZsU' https://oauth2.googleapis.com/token
Which returns:
{"error":"invalid_grant","error_description":"Invalid grant: account not found"}
Could be a bunch of things wrong here. Any thoughts welcomed.
There were two errors in the code:
The JSON string
claim = "{\"iss\": \"" + iss + "\",\"scope\": \"" + scope +
"\",\"aud\": \"" + aud + "\",\"exp\": " +
exp + ",\"iat\": " + iat + "}";
The DateTime needs to be UTC
And now it works.

PayUMoney Integration in MVC and calling using ajax

On button click I want the user to redirect to payumoney gateway and if payment has been done successfully, the data of user to be store in database and redirect user to success page vice a versa..
Currently I am saving data using AJAX call and redirect user on ajax success:function.
AJAX
$('#payNowButton').on("click", function () {
var total = $('#main_total_s5').html();
console.log("Total : " + total);
$.ajax({
url: '/Home/Demo?total=' + total, //Demo method in Home Controller is for payumoney payment gateway.
type: "POST",
data: total,
async: false,
success: function (result) {
window.location.href = result;
if (result > 0) {
PlaceOrder(); //after successful payment, it will call this function to save data in database.
window.location.href = '#Url.Action("Sucess", "Home")';
}
else {
alert("Some error occurred." + result);
}
},
error: function (result) {
window.location.href = '#Url.Action("Failure", "Home")';
}
});
});
Controller
[HttpPost]
public void Demo(OrderCustom orderCustom)
{
string firstName = "";
string amount = "";
string productInfo = "";
string email = "";
string phone = "";
string surl;
string furl;
RemotePost myremotepost = new RemotePost();
string key = "";
string salt = "";
//posting all the parameters required for integration.
myremotepost.Url = "https://secure.payu.in/_payment";
myremotepost.Add("key", "");
string txnid = Generatetxnid();
myremotepost.Add("txnid", txnid);
myremotepost.Add("amount", amount);
myremotepost.Add("productinfo", productInfo);
myremotepost.Add("firstname", firstName);
myremotepost.Add("phone", phone);
myremotepost.Add("email", email);
myremotepost.Add("surl", "http://localhost:/Home/Sucess");//Change the success url here depending upon the port number of your local system.
myremotepost.Add("furl", "http://localhost:/Home/Failure");//Change the failure url here depending upon the port number of your local system.
myremotepost.Add("service_provider", "payu_paisa");
string hashString = key + "|" + txnid + "|" + amount + "|" + productInfo + "|" + firstName + "|" + email + "|||||||||||" + salt;
string hash = Generatehash512(hashString);
myremotepost.Add("hash", hash);
myremotepost.Post();
}
public class RemotePost
{
private System.Collections.Specialized.NameValueCollection Inputs = new System.Collections.Specialized.NameValueCollection();
public string Url = "";
public string Method = "post";
public string FormName = "form1";
public void Add(string name, string value)
{
Inputs.Add(name, value);
}
public void Post()
{
System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.Write("<html><head>");
System.Web.HttpContext.Current.Response.Write(string.Format("</head><body onload=\"document.{0}.submit()\">", FormName));
System.Web.HttpContext.Current.Response.Write(string.Format("<form name=\"{0}\" method=\"{1}\" action=\"{2}\" >", FormName, Method, Url));
for (int i = 0; i < Inputs.Keys.Count; i++)
{
System.Web.HttpContext.Current.Response.Write(string.Format("<input name=\"{0}\" type=\"hidden\" value=\"{1}\">", Inputs.Keys[i], Inputs[Inputs.Keys[i]]));
}
System.Web.HttpContext.Current.Response.Write("</form>");
System.Web.HttpContext.Current.Response.Write("</body></html>");
System.Web.HttpContext.Current.Response.End();
}
}
When I click on button it shows this error :
Error Image
I have faced the same problem yesterday. What I did i, I removed myremotepost.Add("service_provider", "payu_paisa"); and It worked!.
Also check the URL once, if you are doing it on test server then the URL would be https://test.payu.in/_payment
"Key" and "SALT" value cannot be blank, these values will be shared to you by payumoney itself.
string key = "";
string salt = "";
myremotepost.Add("service_provider", "payu_paisa");
This is Mandatory Field, Recently I am contacting with help desk they are asking for some customization. Then it will work

Entity Framework not writing to Database

I'm trying to take a JSON response, deserialize it, and store in a localdb. Everything is working, but its not writing the data to my database. I can't seem to figure out why its not as I'm not getting any errors.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using DataFetcher.DataFieldsInClasses;
using DataFetcher.EF_Models;
using Newtonsoft.Json;
namespace DataFetcher
{
class Program
{
static void Main(string[] args)
{
var teamNames = new TeamsList();
teamNames.teamList.Sort();
for (int i = 0; i < 30; i++)
{
var cities = teamNames.teamList.ElementAt(i);
//URL for each indivual team
string URL = #"http://nhlwc.cdnak.neulion.com/fs1/nhl/league/teamroster/" + cities + "/iphone/clubroster.json";
WebRequest wrGETURL;
wrGETURL = WebRequest.Create(URL);
HttpWebResponse response = wrGETURL.GetResponse() as HttpWebResponse;
StreamReader responseStream = new StreamReader(response.GetResponseStream());
var result = responseStream.ReadToEnd();
//var parsedInformation = JsonConvert.DeserializeObject<RootObject>(result);
foreach (var forwardData in JsonConvert.DeserializeObject<RootObject>(result).forwards)
{
//test output
Console.WriteLine(forwardData.id + " " + " " + forwardData.position + " " + forwardData.name + " " + forwardData.twitterURL + " " + forwardData.height + " " + forwardData.birthdate);
//write to database using EF
using (var _temp_Player = new DataFetcherDBEntities())
{
//var players = _temp_Player.Set<Player>();
_temp_Player.Players.Attach(new Player
{
player_id = forwardData.id,
name = forwardData.name,
age = forwardData.age,
birthdate = forwardData.birthdate,
birthplace = forwardData.birthplace,
weight = forwardData.weight,
height = forwardData.height,
number = forwardData.number,
position = forwardData.position,
imageUrl = forwardData.imageUrl,
twitterURL = forwardData.twitterURL,
twitterHandle = forwardData.twitterHandle
});
_temp_Player.SaveChanges();
}
}
}
Console.ReadKey();
}
}
}
Any tips/ideas?
P.S I'm still learning and self-taught.
*Edit, I copied the localdb to "...DataFetcher\bin\Debug\Databases" and my new error is ""Violation of PRIMARY KEY constraint 'PK__tmp_ms_x__44DA120C6655986D'. Cannot insert duplicate key in object 'dbo.Player'. The duplicate key value is (8473492).\r\nThe statement has been terminated."}"
Which doesn't make sense to me as every player has a unique ID (player_id = forwardData.id)
You need to use _temp_Player.Players.Add instead of Attach.
When you Attach, you need to set the entity state for the EF to detect that it is a new record and insert it into the database during Save Changes.

Error 400 from Google CSE Request

I'm using Visual C# Express 2010 with the Google custom search API and the Newtonsoft.Json.dll. I'm getting a 400 error back from Google. I think I'm not forming the search string (mySearchString) correctly but I can't see the error.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using Newtonsoft.Json;
namespace Test_Console1
{
class Program
{
//Google keys
const string APIKey = "{key}";
const string CSEKey = "{key}";
//base url for the search query
const string GoogleBaseURL = "https://www.googleapis.com/customsearch/v1?";
public static void Main (string[] args)
{
string myQuery = "Action Motivation, Inc. South San Francisco";
int startResult = 0;
int numResults = 10;
string result;
result = submitSearch(makeSearchString(myQuery, startResult, numResults));
Console.WriteLine(result);
string dummy = Console.ReadLine();
}
public static string makeSearchString(string myQuery, int startResult, int numResults)
{
//add keys
string mySearchString = GoogleBaseURL + "key=" + APIKey + "&cx=" + CSEKey + "&q=";
//add query string: replace space+plus sign pattern with just a plus sign
string[] keys = myQuery.Split(' ');
foreach(string key in keys)
{
mySearchString += key +"+"; //append keywords
}
//specify JSON response format
mySearchString += "&alt=json";
//specify starting result number
mySearchString += "&start=" + startResult;
//specify number of results
mySearchString += "&num=" + numResults;
return mySearchString;
}
public static string submitSearch(string mySearchString)
{
//try
//{
Uri url = new Uri(mySearchString);
//url looks like this:
//"https://www.googleapis.com/customsearch/v1?key=AZaaAaAaA0aaAA0ZAZA0aaAA00aaA0aaAaAa0aA&cx=012345678901234567890:aaaaaaaa0aa&q=Action+Motivation,+Inc.+South+San+Francisco+&alt=json&start=0&num=10"
WebRequest myRequest = WebRequest.Create(url);
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
Stream myStream = myResponse.GetResponseStream ();
StreamReader myReader = new StreamReader(myResponse.GetResponseStream(), System.Text.Encoding.UTF8);
string result = myReader.ToString();
//JObject myJo = JObject.Parse(myReader.ReadToEnd());
//int resultcount = (int)myJo.SelectToken("responseData.cursor.estimatedResultCount");
myStream.Close();
myReader.Close();
myResponse.Close();
return result;
//}
//catch (Exception e)
//{
// //debug statement
//}
return null;
}
}
}

I wants some data of My Facebook Account but it not allowing me?

I am using http://lite.facebook.com And i want to get some data from my account.
I am using HttpWebRequest for this.
I am able to login to facebook from my credential using web request And I got profile url from home page html.
Now when i am trying to get list of all friends then its kick me out login page.
for login I am using This Code.
string HtmlData = httpHelper.getHtmlfromUrl(new Uri(FacebookUrls.Lite_MainpageUrl));
lstInput = globussRegex.GetInputControlsNameAndValueInPage(HtmlData);
foreach (string str in lstInput)
{
if (str.Contains("lsd"))
{
int FirstPoint = str.IndexOf("name=\"lsd\"");
if (FirstPoint > 0)
{
TempHtmlData = str.Substring(FirstPoint).Replace("name=\"lsd\"","").Replace("value","");
}
int SecondPoint = TempHtmlData.IndexOf("/>");
if (SecondPoint > 0)
{
Value = TempHtmlData.Substring(0, SecondPoint).Replace("=", "").Replace("\\", "").Replace("\"", "").Replace(" ", "");
}
}
}
string LoginData = "form_present=1&lsd=" + Value + "&email=" + UserName + "&password=" + Password + "";
string ResponseData = httpHelper.postFormData(new Uri(FacebookUrls.Lite_LoginUrl), LoginData);
int FirstProfileTag = ResponseData.IndexOf("/p/");
int SecondProfileTag = ResponseData.IndexOf("\">Profile");
if (FirstProfileTag > 0 && SecondProfileTag > 0)
{
string TempProfileUrl = ResponseData.Substring(FirstProfileTag, SecondProfileTag - FirstProfileTag);
string ProfileUrl = FacebookUrls.Lite_ProfileUrl + TempProfileUrl;
GetUserProfileData(ProfileUrl);
}
And For getting Profile Url And FriendList Url Iam doing This
string HtmlData = httpHelper.getHtmlfromUrl(new Uri(ProfileUrl));
string FriendUrl = "http://lite.facebook.com" + "/p/Pankaj-Mishra/1187787295/friends/";
string HtmlData1 = httpHelper.getHtmlfromUrl(new Uri(FriendUrl));
I got perfect result when i tried for ProfileUrl.
but when i tried for frindUrl its logged out how can i solve this problem
Plz help me.
Stop scraping HTML data and use their API

Categories

Resources