Hello guys, first I'm so sorry if my english is not good, because I am spanish and my english is very poor, and this is my frist time to write a full blog in english. Today I would like to share with all developpers my solution for can work with eWay payments from Windows Form Applications.
I create this solution to easy implementation to create the Token and manage the payment's for the CST STAFF on a company where i am working now. I hope is helpfully for you.
Integrate Web Page in Windows Form
If you already user eWay on your web page, you know it's very easy to use, because you can use all the JAVASCRIPTS and HTML TAGS, but if you are using Windows Form Application to implement the payment or for create a token, you cannot execute diretly this tools.
So, the first step is search how to use a Web From like a Windows Form. You can use System.Windows.Form.WebBrowser and show a web page for make a transaction. But if you need some value from this web page you cannot get directly from the Windows Form.
If you create the web page, you can set a element for later query with a WebBrowser and get the value. But is is like 2 steps and is not my idea. I would like directly from my Windows Form can send the transactino an get the TransactionID or my CustomerToken and continues with my process on the Form.
If you like do in 2 steps, create the HTML file, on a web server or in your local folder, and execute myWebBrowser.Navigate([file route]); after imput the data adn click on Submit and your code show the result on some HTML tag like span or div you can get this value from your Windows Form with myWebBrowser.Document.GetElementById("[Element Id]").InnerText (for a span tag) or myWebBrowser.Document.GetElementById("[Element Id]").InnerHtml (for a div tag). So now you have your data to continues the process.
My transparent solution
But for me, I don't like use 2 steps, because is not good the user have a WebBrowser on the Windows Form. So I prefer abstract to the user and full manage form a independece process. And also I can reuse again from other Windows Form. Of course I need use a WebBroser Control, but no need show on the Form. Because I already write how to do, directly I go to show the code and comment later.
private class EncriptData
{
private System.Windows.Forms.WebBrowser webBrowser = new System.Windows.Forms.WebBrowser(); //createthe web browser object
//share variables
private string number;
private string cvn;
private string number_encripted;
private string cvn_encripted;
//function to call from the Form
public string[] EncriptCreditCard(string Number, string Cvn)
{
//create the webbrowser object
webBrowser.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser_DocumentCompleted);
webBrowser.ScriptErrorsSuppressed = true;
this.number = Number;
this.cvn = Cvn;
string clave;
//MERCHANT CLIENT SIDE ENCRYPTION KEY STRING
#if DEBUG
clave = "[YOUR SANDBOX KEY]";
#else
clave = "[YOUR LIVE KEY]";
#endif
//create the page
string html = @"
< html >
< head >
< script src=""https://secure.ewaypayments.com/scripts/eCrypt.min.js"" >< /script >
< script >
function EncriptData(param) {
var params = param.split(';');
var setValue = document.getElementById('card_number');
setValue.value = params[0];
var setEncrypt = document.getElementById('card_number_encripted');
setEncrypt.innerText = eCrypt.encryptValue(setValue.value);
setValue = document.getElementById('card_cvn');
setValue.value = params[1];
setEncrypt = document.getElementById('card_cvn_encripted');
setEncrypt.innerText = eCrypt.encryptValue(setValue.value);
}
< /script >
< /head >
< body >
< form data-eway-encrypt-key=""" + clave + @""" >
< label>Card Number
< input type=""text"" id=""card_number"" data-eway-encrypt-name=""card_number""/>
< label>CVV
< input type=""text"" id=""card_cvn"" data-eway-encrypt-name=""card_cvn"" />
< /form>
< span id=""card_number_encripted"">
< span id=""card_cvn_encripted"">
< /body>
< /html>";
archivos a = new archivos(); //file management
string web = a.guardaDato("eway.html", html); //create a file HTML
webBrowser.Navigate(web); //execute the page on the web browser control
while (webBrowser.ReadyState != System.Windows.Forms.WebBrowserReadyState.Complete|| //wait until full load the page
(string.IsNullOrEmpty(this.number_encripted) && string.IsNullOrEmpty(this.cvn_encripted))) //if is load but not execute the script wait until get the data
{
System.Windows.Forms.Application.DoEvents();
}
a.borrarArchivo(web); //optional, delete the file after use
a = null;
return new string[] { this.number_encripted, this.cvn_encripted };
}
//get the values for send the transaction
private void webBrowser_DocumentCompleted(object sender, System.Windows.Forms.WebBrowserDocumentCompletedEventArgs e)
{
//repeat until can get the values
int counter = 0;
do
{
if (counter < 100)
{
webBrowser.Document.InvokeScript("EncriptData", new string[] { this.number + ";" + this.cvn }); //execute the javaescript
//get the values encripted
this.number_encripted = webBrowser.Document.GetElementById("card_number_encripted").InnerText;
this.cvn_encripted = webBrowser.Document.GetElementById("card_cvn_encripted").InnerText;
}
else
{
//control the script can't execute
this.number_encripted = "FAIL";
this.cvn_encripted = "FAIL";
}
counter++;
} while ((string.IsNullOrEmpty(this.number_encripted) && string.IsNullOrEmpty(this.cvn_encripted)));
}
}
- Create a WebBrowser Object
- Declare some variables to share
- Function to return the values encripted, get the credit card number and credit CVN, because is the data we need to encript
- Inside the functon create the EventHandler to know when the web document is complete and can execute the excript to encript the data
- Set the values to share with the Event
- Create HTML file
- In the web broser object navigate to the file
- Here we need to wait until the page is already load.
- In the Event Function when the page is loaded call the script to encript the data.
- Set the values to share with the encripted data
- Deldete de temp file
Controls to do
On point 8 is where we need control if the share variables don't have a value is because the script is not complete, or because the page is not full charge. This can be when you execute the page from a live web server, don't create the local file, or because the script fail or don't return a value.
Also in the Event need control the script really execute after charge the page. For that need to repeat the script until get some data. To control unlimited loops, because the page is not charge, for example, I control max 100 loops and set the share variable with "FAIL" for can go out of all the loops.
Get the Customer Token
This is a example to use this function to setup a CustomerTokenID for can make transactions later. With Direct Connection
///
/// Get new Token from the customer
///
/// Customer data object
///
public MyTransaction SetToken(MyCustomer myCustomer)
{
MyTransaction myTransaction = new MyTransaction();
string APIKEY;
string PASSWORD;
string ENDPOINT;
try
{
//using the function to encript a data
EncriptData e = new EncriptData();
string[] encriptCreditCard = e.EncriptCreditCard(myCustomer.CardDetails.Number, myCustomer.CardDetails.CVN);
e = null;
IRapidClient eway = RapidClientFactory.NewRapidClient(APIKEY, PASSWORD, ENDPOINT);
eway.SetVersion(40);
//without token need insert all data for the customer
//create a customer info
Customer customer;
customer = new Customer()
{
Reference = myCustomer.Reference,
FirstName = myCustomer.FirstName,
LastName = myCustomer.LastName,
CompanyName = myCustomer.CompanyName,
Phone = myCustomer.Phone,
Mobile = myCustomer.Mobile,
Email = myCustomer.Email,
Address = new Address()
{
Street1 = myCustomer.Street,
City = myCustomer.City,
State = myCustomer.Street,
PostalCode = myCustomer.PostalCode,
Country = myCustomer.Country
},
CardDetails = new CardDetails()
{
Name = myCustomer.CardDetails.Name,
Number = encriptCreditCard[0],
ExpiryMonth = myCustomer.CardDetails.ExpiryMonth,
ExpiryYear = myCustomer.CardDetails.ExpiryYear,
CVN = encriptCreditCard[1]
}
};
try
{
CreateCustomerResponse getToken = eway.Create(PaymentMethod.Direct, customer);
if (getToken.Errors == null) {
myTransaction.token = getToken.Customer.TokenCustomerID;
myTransaction.result = true;
myTransaction.error = string.Empty;
}
else
{
List errores = getToken.Errors;
myTransaction.error = string.Empty;
myTransaction.token = string.Empty;
myTransaction.result = false;
foreach (string errorCode in errores)
{
myTransaction.error += errorCode + ": " + eWayErrorCode(errorCode) + Environment.NewLine;
}
}
}
catch (Exception ex)
{
myTransaction.token = string.Empty;
myTransaction.result = false;
myTransaction.error = ex.ToString();
}
}
catch (Exception ex)
{
myTransaction.token = string.Empty;
myTransaction.result = false;
myTransaction.error = ex.ToString();
}
return myTransaction;
}
Also available in CodeProject
Happy codding
#CSHARP #windowsforms #APIs