Parsing Credit Card data from magnetic stripe reader using javascript - javascript

Ok, So I have an html form that is displayed like so:
<span style='required'>*</span> - Indicates required field.
<div class='fields'>Swiped Information</div>
<input type=text name='swiped' id='swiped'>
</div>
<div class='fields'>First Name</div>
<input type=text name='first_name' id='first_name'><span style='required'>*</span>
</div>
<div class='fields'>Last Name</div>
<input type=text name='last_name' id='last_name'><span style='required'>*</span>
</div>
<div class='fields'>Expiration</div>
<input type=text size=8 name='expiration' id='expiration'><span style='required'>*</span>(MMYY)
</div>
<div class='fields'>CVV Code</div>
<input type=text size=8 name='cvv' id='cvv'><span style='required'>*</span>
</div>
<div class='fields'>Credit Card Number</div>
<input type=text name='card' id='card'><span style='required'>*</span>
</div>
<hr>
<div class='buttons'></div>
<a onclick="readCard();" style="cursor:pointer; color:red;">Swipe Credit Card</a>
</div>
My knowledge of this kind of stuff is very poor. I have a basic little Credit Card Reader that plugs into my computer via USB. I am wanting to be able to swipe a credit card and have my website parse the information into the form fields that are above.
I have added an onclick=readCard(); event to a link below my form and when that is pushed java script is initiated to put focus on the Swiped Information field which will store the string of data from the magnetic stripe reader.
function readCard () {
document.getElementById('swiped').focus();
}
My thoughts would be that the employee would hit "Swipe Credit Card" which would make the Swiped Card Information field have focus and would fill that field with the string, then the javascript would break that information up into pieces and fill the form accordingly.
I have searched high and low to try and find a solution and the closest I could come was a tutorial that used asp.net as the language and I can't do that. Either PHP or JavaScript. Thanks in advance.
All I need to do is break that long string up into multiple and display the appropriate parts in the html form.
P.S. I'm not worried about form validation ATM, I will be taking care of that after I manage to make it fill the form fields! Thanks!
UPDATE:
I created a JSFiddle although the java script I put in doesn't appear to be working.
http://jsfiddle.net/r8FJX/
UPDATE:
As per the comments below, I have added an example of the data sent from my card reader to the computer. I went in and replaced every number in the string with randomly typed fake numbers and replaced my name with a fake one. (Sorry scammers!)
%B6545461234613451^DOE/JOHN^00000000000000000000000?;6545461234613451=984651465116111?
I am assuming this how the code above is laid out, I can't find any documentation:
%Bcardnumber^lastname/firstname^expDate?;cardnumber=expDate?

Option 1)
var card_data = "%B6545461234613451^DOE/JOHN^00000000000000000000000?;6545461234613451=984651465116111?"
var details1 = card_data.split("^");
var card_number = details1[0];
card_number = card_number.substring(2);
var names = details1[1].split("/");
var first_name = names[1];
var last_name = names[0];
var details2 = details1[2].split(";");
details2 = details2[1].split("=");
var exp_date = details2[1];
exp_date = exp_date.substring(0, exp_date.length - 1);
exp_date = exp_date.substring(2, 3) + "/" + exp_date.substring(0,1);
Option 2)
var pattern=new RegExp("^\%B(\d+)\^(\w+)\/(\w+)\^\d+\?;\d+=(\d\d)(\d\d)\d+$");
var match = pattern.exec(card_data);
card_number = match[1];
first_name = match[3];
last_name = match[2];
exp_date = match[5] + "/" + match[4];
Then Do:
document.getElementById("first_name").value = first_name;
document.getElementById("last_name").value = last_name;
document.getElementById("card").value = card_number;
document.getElementById("expiry").value = exp_date;

I had success with the follow for expiration date:
exp_date = exp_date.substring(2, 4) + "/" + exp_date.substring(1, 3);

Just For Future viewers like myself that was searching. The expiry needed to be adjusted. This will make the expiry look like... 10/18. Not 10/81 like I was getting...
Below shows the corrected formatted date of ex: 10/18 not 10/81 or 1/1
exp_date = exp_date.substring(2, 4) + "/" + exp_date.substring(0,2);

(For future people trying to parse USB credit card reader data)
There are two (sometimes 3) tracks of data, they are separated with ?. The expiry date is duplicated on the first track and the second track. If you want to read enough data to charge a credit card you can ignore the Track 2 data (everything from the ; onwards).
The CVC is not stored on the magnetic stripe data. You'll have to disable the CVC check in your payment processor. With Stripe you can do it at https://dashboard.stripe.com/radar/rules.
let parse = readerData => {
let card = readerData.match(/%B([0-9]+)\^([A-Z /.]+)\/([A-Z /.]*)\^([0-9]{2})([0-9]{2})/);
let lastName = card[2].trim();
// 'LASTNAME/FIRSTNAME.MR' is possible
let firstName = card[3].trim().split('.')[0];
let fullName = `${firstName} ${lastName}`;
return {
exp_month: card[5],
exp_year: card[4],
number: card[1],
name: fullName,
};
}
parse('%B6545461234613451^DOE/JOHN^21040000000000000000000?;this part does not matter')
// {exp_month: "04", exp_year: "21", number: "6545461234613451", name: "JOHN DOE"}
If you're using Stripe.js v2 you can pass the object returned by parse() directly to Stripe.card.createToken().
I've seen LASTNAME/FIRSTNAME MIDDLENAME in sample data, this code should turn that into FIRST MIDDLE LAST.
Read https://en.wikipedia.org/wiki/Magnetic_stripe_card#Financial_cards for more info.
I don't know if doing this is legal. Newer USB credit card readers encrypt the data they read (you have to send the data to their api (and pay them) to decrypt it).
If you're having issues with the regex try https://regex101.com/ for debugging it.

Related

JS - Prevent append to be added multiple times

I have a form that has a mobile field. On submit button I put an event to add a value to the mobile field (it adds the country region code automatically which is a fixed value of "11"), so when the user clicks on Submit, the JS adds the "11" value to the mobile so the this field goes to the data base like this "1155555555" (the user just typed "55555555").
Ok, the problem is that if the user left an empty field (all fields are required), and clicks on Submit, the form won´t be sent but it will add the value "11" to the mobile field no matter what, and when the user fills up the empty field and click on Submit for the second time, it will add AGAIN the value "11", so the mobile goes like "111155555555", and so on and so forth.
Basically, what I need is to prevent this function from happening multiple times. It has to happen only once. How do I achieve this using JS?
HTML:
<input id="mobile" name="MOBILE" type="tel"><input type="number" value="11" id="front" class="hide">
<button type="submit" onclick="append11()">SUBMIT</button>
JS:
function append11(){
var mobilenumber = document.getElementById("mobile");
var front = document.getElementById("front").value;
mobilenumber.value=front+mobilenumber.value;
alert(mobilevalue.value);
}
Why you don't append the 11 in the function?
Like:
function append11(){
var mobilenumber = document.getElementById("mobile");
mobilenumber.value="11"+mobilenumber.value;
alert(mobilevalue.value);
}
I think you should heed the comment responses to your original question. Your approach has some risks.
But I'll assume you're a beginner who's just trying to learn how to do something like what you're asking about, so the javascript below applies a few principles you might consider.
function isNumberValid9(num) {
console.log(num, num.length);
//check string length and pattern
//this could be combined into a single regex, e.g.: mobileValue.match("^[0-9]{9}$")
var isValid9 = num.length === 9 && num.match("^[0-9]+$");
console.log(isValid9); //display the value about to be returned
return isValid9;
}
/* Conditionally prepend "11" */
function maybeAppend11() {
var mobilenumber = document.getElementById("mobile");
var mobileValue = mobilenumber.value;
//only prepend "11" if the number matches your expected pattern and length
if (isNumberValid9(mobileValue)) {
var front = document.getElementById("front").value;
mobilenumber.value = front + mobileValue;
}
alert(mobilenumber.value);
}
<input id="mobile" name="MOBILE" type="tel" value="555555555"><input type="number" value="11" id="front" class="hide">
<button type="submit" onclick="maybeAppend11()">SUBMIT</button>

How to clone and append a child inside a "for-function" - pure javascript

here at work our helpdesk-members have to write a lot of support tickets and send them via Mail to the IT.
It takes a lot of time, because the common way to do the task is to search for an already send ticket and to rewrite it by hand.
Although I'm fairly new to javascript, I managed to write a so called "ticket-generator". It contains the input fields, stores the input in localstorage and generates at the end the complete text, inserts it in an outlook mail-body and we are ready to hit the "send" button within seconds.
My problem now:
I'd like to let people choose how many predefined input-fields they need, if they want to write multiple tickets at once.
This is where I'm stuck:
The html:
<form id="ticketform">
<input id="projectselection" name="projectselection1" list="projects" placeholder="Choose project...">
<datalist id="projects">
<option value="Project1"></option>
<option value="Project2"></option>
<option value="Project3"></option>
</datalist>
<br>
<input id="numberoftickets" type="number" placeholder=" Choose the number of tickets...">
</form>
<button id="newForm" onclick="newnew()">DO IT!</button>
<div id="dynamicInput">
</div>
The script:
function newnew() {
let inputNumberoftickets = document.getElementById("numberoftickets").value;
localStorage.setItem("selectionNumberoftickets", inputNumberoftickets);
let original = document.getElementById("projectselection");
let clone = original.cloneNode(true);
let y = inputNumberoftickets;
let formform = document.getElementById("ticketformular");
let text = "";
for (i = 1; i <= y; i++) {
document.getElementById("dynamicInput").innerHTML = text += 'Ticket ' + i + "<br>" +
original.setAttribute("id", ticketformular + i) +
document.getElementById("dynamicInput").appendChild(clone) + "<br>";
This is the result i get:
Ticket 1
undefined[object HTMLInputElement]
Ticket 2
undefined[object HTMLInputElement]
Ticket 3
undefined[object HTMLInputElement]
Did a lot of research but somehow I'm complete stuck.
Even when I set the project input in local storage to define the
field i got no output.
Thanks in advance.
Wish you a nice day.

How to put the variable field names into the hidden fields on a FormAssembly form

We have two form tools for lead capture at my org and I'm trying to create a spreadsheet which uses the same formula to create the UTM parameter links to track our marketing campaigns with Google Analytics.
Example formula
=SUBSTITUTE(IF(LEFT(G4,1)="[","--",CONCATENATE(G4,IF(ISERROR(FIND("?",G4,1))=TRUE,CONCATENATE("?"),CONCATENATE("&")),IF(C4="","","estate="),IF(C4="","",C4),IF(A4="","","&utm_campaign="),IF(A4="","",A4),"&utm_medium=",H4,"&utm_source=",D4,IF(E4<>"-",CONCATENATE("&utm_content=",E4),),IF(E4<>"-",CONCATENATE("",$F$2),)))," ","%20")
On our Pardot pages I've applied the details outlined in https://jennamolby.com/how-to-use-utm-parameters-to-capture-lead-source-in-pardot/ and have these hidden fields populating correctly.
My trouble is with the FormAssembly form. I can change the above formula to include the FormAssembly ID's, ie tfa_199 replaces utm_medium and this works fine but then I would need my spreadsheet users to know which form tool is being used on that landing page. Is there a way to apply the same formula to both form tools and then using JavaScript populate the values for these hidden fields?
I've tried switching the Pardot JavaScript with the FormAssembly labels to no luck.
Sample link
https://www.tfaforms.com/4757457/?tfa_98=Test%20Estate%20X999&tfa_197=Fonzi&tfa_199=social&tfa_200=Facebook&tfa_198=Feed
// Parse the URL
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
// Give the URL parameters variable names
var source = getParameterByName('utm_source');
var medium = getParameterByName('utm_medium');
var campaign = getParameterByName('utm_campaign');
var term = getParameterByName('utm_term');
var content = getParameterByName('utm_content');
var estate = getParameterByName('estate');
// Put the variable names into the hidden fields in the form"
document.querySelector("tfa_200 input").value = source;
document.querySelector("tfa_199 input").value = medium;
document.querySelector("tfa_197 input").value = campaign;
document.querySelector("tfa_201 input").value = term;
document.querySelector("tfa_201 input").value = content;
document.querySelector("tfa_196 input").value = estate;
</script>
The ideal result is regardless of whether the form is a Pardot or FormAssembly the hidden fields populate the same using the same formula.
Have you tried this:
https://stackblitz.com/edit/js-hgrwkn
If your input fields have Ids:
<input type="text" id="utm_source" name="tfa_200"/>
and your hidden fields:
<input type="hidden" id="tfa_200" name="utm_source"/>
then:
<script>
document.getElementById('tfa_200').value =
document.getElementById('utm_source').name;
</script>
Then document.getElementById('tfa_200').name will contain utm_source.

JavaScript simple login from an array

I have very little experience with JavaScript and can't figure out how to get this to work, it may be a very small fix or it may be something major I have absolutely no clue...
I am trying to just create a really simple login for my assignment, security is not an issue as it is not required in the brief. The event of the user clicking the submit button should either grant or deny the user entry into the site. I have commented throughout the code so hopefully this will be a quick job to spot whatever is going wrong.
It possibly may be the "&" i included in the IF statement, I wasn't entirely sure if it would work in JavaScript or not. Or it may possibly be the calling of the users input, as I am not sure if I did that right either; i.e pass = password (from the form)
JavaScript:
<script>
function loadpage() {
var user = username; //assigns user input to variable
var pass = password; //^^
var storedus = ["Jordan", "Marzia", "Ryan"]; //array of acceptable usernames
var storedps = ["123", "cat", "seven"]; //array of acceptable passwords
if (user = storedus & pass = storedps) //condition must include both an acceptable username and password to >>
{
window.location.href = "home.html"; // >> proceed to next the portal page(home.html)
}
else
{
window.alert("An invalid username or password was entered."); //if the users input was not acceptable then display a popup informing them so.
}
}
</script>
HTML table and form:
<table style="position: absolute; left: 35%; top: 20%;"> <!- table to layout the form to take the users username and password to allow them to
gain entry into the site-!>
<form>
<tr><td><h2>Sign in</h2></td></tr>
<tr><td>Username*: </td><td><input type="username*" name="username" required></td></tr>
<tr><td>Password*: </td><td><input type="password*" name="password" required></td></tr>
<tr><td><input type="submit" name="signin" onclick="loadpage()"</td></tr>
</form>
</table>
Thank you in advance for your help!
You are trying to compare an array with what I'd guess to be a string. Instead, you should loop through the array and compare the values with the username and password.
var usernames = [
'Script47',
'SomeUsernname'
];
var passwords = [
'somePassword',
'password'
];
var username = 'Script47';
var password = 'somePassword'
for (var i = 0; i < usernames.length; i++) {
if (username == usernames[i] && password == passwords[i]) {
alert('Successful!');
break;
} else {
alert('Failed!')
}
}
Notice how I am using &&.
Example
JSFiddle

How to display calculated values in IE9

I'm working on an online form for attendees of a conference to fill out. Each person enters the amount of minutes they attended for a certain session. The minutes convert to Credit Hours in a form field like so:
<div class="col3">
<form onsubmit="return false" oninput="document.getElementById('MK1').innerHTML = (Math.floor((MC06.value/50) * 2) / 2).toFixed(1)">
<input name="MC06" id="MC06" onkeyup="disableField06()" type="number" min="0" max="50" placeholder="0-75 minutes" step="any" />
</div>
<div class="col1">
<output name="MK1" id="MK1">0</output>
</form>
</div>
In case you're wondering, the disableField function disables another session for the same time slot. No problems there. No problems with the placeholder either, thanks to a script I found here.
The hours for Subject Category (MK in this case) are collected in a function when the user clicks the Submit button:
var MK1 = document.getElementById("MK1").value;
var MK2 = document.getElementById("MK2").value;
var MK3 = document.getElementById("MK3").value;
var MK4 = document.getElementById("MK4").value;
var MK5 = document.getElementById("MK5").value;
var MK6 = document.getElementById("MK6").value;
document.getElementById("MK").value = parseFloat(MK1) + parseFloat(MK2) + parseFloat(MK3) + parseFloat(MK4) + parseFloat(MK5) + parseFloat(MK6);
Finally, the subjects and their total hours per attendant are displayed in a table at the bottom.
<div class="table-row">
<div class="col2">Marketing: </div>
<div class="col4"><input type = "text" id = "MK" name = "MK"></div>
</div>
This works fine in Chrome, but in IE9 (the company browser) I get NaN. How can I fix this?
I fixed it.
I changed the code for lines like
var MK1 = document.getElementById("MK1").value;
to
var MK1 = document.getElementById("MK1").innerHTML;
That worked for the data called back from the input fields. The code that totals all the subjects' credit hours together still returned NaN. I changed those lines back to .value, and it worked! Looks like IE9 has a narrower scope for .value than other browsers.

Categories

Resources