adyen / adyen-cse-web Goto Github PK
View Code? Open in Web Editor NEW[DEPRECATED] Client-side encryption on JavaScript
License: MIT License
[DEPRECATED] Client-side encryption on JavaScript
License: MIT License
Hey,
I want to use options.cvcIgnoreBins = '6703';
to Ignore CVC for BCMC but this options won't remove the disabled
state form the submit button unless you click on the cvc field to fire the event handler.
Do you know why here we only update the validity of field who fired the event handler?
We could update cse.validity
with the result of validate()
, like this ignored fields would also get updated.
cse.validity = cse.encryption.validate(validationData);
if ( validationResult[field] ) {
removeClass( node, 'invalid-' + field );
addClass( node, 'valid-' + field );
} else {
if (!isInitializing || val !== '') {
addClass( node, 'invalid-' + field );
}
removeClass( node, 'valid-' + field );
}
What do you think? Should I create a PR with this change ?
Alex
We have an adyen form that contains a confirmation checkbox (Terms) at the end and I want to be able to enable submit button only when this checkbox is checked.
If I could invalidate form in onvalidate
hook that would be great.
I suggest that in the callback it could be done by simply returning false
if one wants the form to be invalidated.
The following line in adyen.encrypt.js
seems to contain a typo. It (probably unintentionally) uses the bitwise OR operator here on line 1131:
handlers.cvcHandler({target:elementsByName.cvc, originalEvent: ev, type : (ev|{}).type, isInitializing : (ev||{}).isInitializing})
(ev|{}).type
should be (ev||{}).type
- just like the other occurrence a couple characters to the right.
It doesn't produce errors during runtime, but the result of (ev|{}).type
will always be undefined
, not matter the value of ev
.
Hello
Most of the credit card in France displays 2 digits for the expiration year. (18 for 2018)
That's why my form allows to enter 2-digits year instead of 4-digits.
However, passing 2 digits year to the validate function seems to be invalid.
I expect a 2 digits year to passed as well as a 4 digits year.
What's your thoughts ?
Best regards
Hello
In the file addOns.adyen.cardType.js
line 61
Cards.determine("")
and Cards.determine(undefined)
returns "mc".
I think this is not the expected behavior, right ?
If I'm wrong, please explain me why ?
I use this method to detect the cardType and show an icon in the input field depending on the credit card number
Best regards
We use this part of the library to identify card types, and the logspam caused by console.log
inside there is an irritation. Can we please take them out?
I'd like to get a confirmation of supported browsers. IE10 gives an error.
There was an error collecting entropy from the browser:
Error: secure random number generation not supported by this browser
use chrome, FireFox or Internet Explorer 11
So, it's official that Adyen CSE won't work in IE10 and below?
We could maybe add this info to the docs maybe?
I have used the same code here in my product code.
https://docs.adyen.com/developers/risk-management/device-fingerprinting
But it give the DfDo undefined function error. So I change to
When I try to send paymentRequest.additionalData.card.encrypted.json
to https://pal-test.adyen.com/pal/adapter/httppost encrypted with latest js library (0.1.20) I'm getting a response from API 'validation 175 Unable to parse JSON data'
Node.js / NPM error
npm i git://github.com:Adyen/adyen-cse-web.git --save
All I'm doing here is requiring the package, and it throws.
/Users/thomasreggi/Desktop/project/node_modules/adyen-cse-web/js/adyen.encrypt.nodom.js:130
(function(){try{var b=[new Uint8Array(1),new Uint32Array(1),new Int32Array(1)];return}catch(g){}function f(e,a){return this.slice(e,a)}function c(j,e){if(arguments.length<2){e=0}for(var a=0,h=j.length;a<h;++a,++e){this[e]=j[a]&255}}function d(e){var a;if(typeof e==="number"){a=new Array(e);for(var h=0;h<e;++h){a[h]=0}}else{a=e.slice(0)}a.subarray=f;a.buffer=a;a.byteLength=a.length;a.set=c;if(typeof e==="object"&&e.buffer){a.buffer=e.buffer}return a}try{window.Uint8Array=d}catch(g){}try{window.Uint32Array=d}catch(g){}try{window.Int32Array=d}catch(g){}})();(function(){if("btoa" in window){return}var a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";window.btoa=function(g){var e="";var f,d;for(f=0,d=g.length;f<d;f+=3){var k=g.charCodeAt(f)&255;var j=g.charCodeAt(f+1)&255;var h=g.charCodeAt(f+2)&255;var c=k>>2,b=((k&3)<<4)|(j>>4);var m=f+1<d?((j&15)<<2)|(h>>6):64;var l=f+2<d?(h&6
ReferenceError: window is not defined
at /Users/thomasreggi/Desktop/project/node_modules/adyen-cse-web/js/adyen.encrypt.nodom.js:130:591
at /Users/thomasreggi/Desktop/project/node_modules/adyen-cse-web/js/adyen.encrypt.nodom.js:130:981
at Object.<anonymous> (/Users/thomasreggi/Desktop/project/node_modules/adyen-cse-web/js/adyen.encrypt.nodom.js:568:4)
at Module._compile (module.js:541:32)
at Module._extensions..js (module.js:550:10)
at Object.require.extensions.(anonymous function) [as .js] (/Users/thomasreggi/.nvm/versions/node/v6.2.2/lib/node_modules/babel-cli/node_modules/babel-register/lib/node.js:166:7)
at Module.load (module.js:458:32)
at tryModuleLoad (module.js:417:12)
at Function.Module._load (module.js:409:3)
at Module.require (module.js:468:17)
source code:
import adyenEncrypt from 'adyen-cse-web';
......
const cseInstance = adyenEncrypt.createEncryption(PUBLIC_KEY_DEV, options);
postData['adyen-encrypted-data'] = cseInstance.encrypt(cardData);
result:
Object {adyen-encrypted-data: false}
Hello,
Can I require adyen-cse-js and take only the javascript sdk ? Currently, I do something like that :
const adyen = require('adyen-cse-js');
const encryptor = adyen.createEncryption(publicEncryptionKey);
const cseToken = encryptor.encrypt(Object.assign({ generationtime }, card));
Then, my website is loading Roboto font, from your javascript :(
I'm using VueJs with Nuxt, in the same way, when server side rendering append, adyen try to find navigator var, but it's not available. Why this variable is needed ? Maybe the same reason than css is loading :/
Thanks,
Gaël
Sorry for my ignorance, but is there any reason for doing RSA+AES here, instead of pure RSA, given the message size will usually be much smaller than 245 chars? Is this for future proofing, or is it in any way more secure than just doing RSA?
Thanks!
We'd like to enable / disable some buttons right after the CSE library validated the creditcard is correct.
Can you provide some documentation about how to do this? Are there any hooks or events we are able to capture? Can we add a closure to the options array for this?
I'd like to get client side encryption nodom library as npm dependency for our project, so that copy of the file doesn't have to be in our repository.
Can you provide this?
Please help me!
Do you guys have a plan to create an ES6 module of this library?.
In our case, we use Webpack + Babel for compile those modules to ES5.
In our frontend error tracking tool, we see the following error
Unable to get property 'x' of undefined or null reference
with the minimal stacktrace of
at ? line 14, column 29192 (https://checkout.spreadshirt.fr/Public/Checkout2/build/2.38.7/checkout/lib/adyen.encrypt.nodom.min.js:14)
which drills down to the code block
t.accelerationIncludingGravity.x
Additional data:
In adyen.encrypt.nodom.js#L517 you should also allow to pass "generationtime" element. Now if you pass all the arguments to validate function before encrypt function call you will get valid == false.
I'm not sure why this method returns false instead of returning the encrypted data.
I checked every input field and everything seems in order but I have no clue what I'm missing.
I have been trying to use this, but am getting a javascript compiler error. I am using the adyen.encrypt.nodom.js file, and am having a problem with the ".replace" on line 400 (line number includes the current comments). I get the error "val.replace is not a function".
I tried replacing val = val.replace( /\D/g, '' ); with val = ("" + val).replace( /\D/g, '' ); and doing this in one other spot, but then the end result of the encrypted data always seems to be "false". Where am I going wrong?
Hi all!
I'm having this issue but no ideia why.
let cardData = {
cvc:"737",
expiryMonth:"08",
expiryYear:"2018",
generationtime:"2016-10-10T17:01:16.748Z",
holderName:"John Smith",
number:"5555444433331111"
};
let encryptData = cseInstance.encrypt(cardData);
console.log(cseInstance.validate());
The console log returns false but there's no clue why the validation is failing.
Is there any way to enable a verbose mode for the validator?
Thank you,
Hugo
Google PageSpeed is not happy with Adyen Hosted CSE, because content is not gzipped
To prevent accidentally sending unencrypted card data over an insecure connection.
To verify if the card data was successfully encrypted.
And if the current page protocol is https:
if (location.protocol === 'https:') {
// page is secure
}
A developer would provide the url of their request handler and their own additional data to the Adyen cse library, which sends the request to the merchant server.
The Adyen cse library would verify the cardData encryption and the location protocol, before sending the request to the merchant server.
var encrypted_card_data = cseInstance.encrypt(cardData);
var request = {};
// Object with data set by merchant about price, product, session etc:
request.merchantData = custom_merchant_shopper_data;
request.encrypted_card_data = encrypted_card_data;
var server_url = '/shopperhandler';
/* location protocol ( https ) and
card data encryption verified by Adyen before sending request.
*/
cseInstance.send_request(request,server_url);
There seems to be a bug concerning the validation of the card holder name.
In Encryption.prototype.encrypt
the validationObject
does not contain the holderName
key.
Is that correct?
Thanks for your feedback.
I'm working with angularJS and I get an error response, can you try to help me ?
First
The form (an object vm.ayden is created then submitted to my client side controller with vm.adyenSub() ) :
<form ng-submit="vm.adyenSub()" id="adyen-encrypted-form">
<div class="form-group">
<label for="adyen-encrypted-form-number">Card Number</label>
<input type="text" ng-model="vm.adyen.number" class="form-control" id="adyen-encrypted-form-number" value="5555444433331111" size="20" autocomplete="off" data-encrypted-name="number">
</div>
<div class="form-group">
<label for="adyen-encrypted-form-holder-name">Card Holder Name</label>
<input type="text" ng-model="vm.adyen.holderName" class="form-control" id="adyen-encrypted-form-holder-name" value="John Doe" size="20" autocomplete="off" data-encrypted-name="holderName">
</div>
<div class="form-group">
<label for="adyen-encrypted-form-cvc">CVC</label>
<input type="text" ng-model="vm.adyen.cvc" class="form-control" id="adyen-encrypted-form-cvc" value="737" size="4" autocomplete="off" data-encrypted-name="cvc">
</div>
<div class="form-group col-xs-6">
<label for="adyen-encrypted-form-expiry-month">Expiration Month (MM)</label>
<input type="text" ng-model="vm.adyen.expiryMonth" class="form-control" value="06" id="adyen-encrypted-form-expiry-month" size="2" autocomplete="off" data-encrypted-name="expiryMonth">
</div>
<div class="form-group col-xs-6">
<label for="adyen-encrypted-form-expiry-year">Expiration Year (YYYY)</label>
<input type="text" ng-model="vm.adyen.expiryYear" class="form-control" value="2016" id="adyen-encrypted-form-expiry-year" size="4" autocomplete="off" data-encrypted-name="expiryYear">
</div>
<input type="hidden" ng-model="vm.adyen.crypted" id="adyen-encrypted-form-expiry-generationtime" data-encrypted-name="generationtime" />
<button type="submit" class="btn btn-default">Create payment</button>
</form>
Second
My controller handle the data and make a POST to NodeJS, (no unencrypted data travelling to the server )
vm.adyenSub=function(){
var key = "10001|THE KEY PROVIDED BY ADYEN";
var options = {}; // See adyen.encrypt.nodom.html for details
var cseInstance = adyen.encrypt.createEncryption(key, options);
function encryptMyData() {
var postData = {};
var cardData = {
number : vm.adyen.number,
cvc : vm.adyen.cvc,
holderName : vm.adyen.holderName,
expiryMonth : vm.adyen.expiryMonth,
expiryYear : vm.adyen.expiryYear,
generationtime : vm.dateAdyen
};
postData['adyen-encrypted-data'] = cseInstance.encrypt(cardData);
return postData
}
//Here I make the POST to nodeJS with the result of encryptMyData()
$http.post('/companyAPI/checkout/adyen', encryptMyData(), {headers: {Authorization: 'Bearer ' + authentificationService.getToken()}}).success(function (data) {
console.log(data);
}).error(function (data) {
console.log(data)
});
}
THIRD
I successfully send to nodeJS this payload
{ action: 'Payment.authorise',
'paymentRequest.merchantAccount': 'Hic2hMerchant',
'paymentRequest.amount.currency': 'EUR',
'paymentRequest.amount.value': '199',
'paymentRequest.reference': 'TEST-PAYMENT-2016-03-03T13:53:29+01:00',
'paymentRequest.shopperIP': '11.111.111.111',
'paymentRequest.shopperEmail': '[email protected]',
'paymentRequest.shopperReference': 'test-hic2h',
'paymentRequest.fraudOffset': '0',
'paymentRequest.additionalData.card.encrypted.json': 'adyenjs_0_1_16$hUD6rjw3MMVpWmYs+5OQhrBIFnzaF49HKNTUxap0Q/Ita2JbfZi6tTUydP94KDhlT6hFT0Wo5DMZXbrf/eI/H79/E3ARY+vB90pSmWjjrhEDdweFWr7FS+5veBTX/XEE8FyMOBT+g7jsgCn8p+1ZUthbWsgSgH1iOWKqFs5agvkzM1HYlg9T2jV77BWB8PvMD+kLFS3iFay9UBRogaUdFFbvqJqDpbHsJRzqfyL4VGlcbNQGuoXyyPJO+wq3crRBtfnHREMzK9DhMhu7akQcPOPR41nPOAljKd9GkBafEplfH63aYPXJ31A6cOYXYBk0eyczEa/MOYBjXdUozQwJaoGA==$hR9nGIoQbm8eSQNgzPZTU15rbYgvYlkxnjVygu6WJyF7wgwvegGIqdy3/hnP03gYTOp8+NK3MfSI6fHSDDuUDGsF3HMByNXoYwpNyXcp/0yIvF/9iqGnsWZ2JfujHkvsf+NAbsxNDZyTqYVknPLomD0Lg+WkIEKkaiBYb6fzBEy8MZbCVGT4SixltwR/aZgTlBJIThIHal3HuoIiik7gBakZG5PqdVYjucuGzXht8wrz/7hEKmP4jrMR/jPahzxn0R5P0ZBvS+wD5082s5GED23TQ5cttUxW4NxnKSZB5d6EYJgbcSLBKHGPv6gFsfwvvanfFNBzTUXeY1qLXyGiJhQ8WRMReQgAYTjjlQe29cdY6P6gFt0hzfTRfDkAWXY22J5/YNQCSw==' }
then I do :
adyen.test("[email protected]", "myPassword", adyenRequestBody, function(err, response){
res.json({err: err, response: response});
});
And i receive this response :
{err: "Unknown server Error"}
The library provides validation for year field, but it just checks that input is digits. It would be great if you add the ability to check that the card expiration year is greater than or equal to current one (e.g. now 2016 - ... are valid, but 2015 isn't).
This PR (#20) should resolve this issue.
ELO cards that are recognized as Maestro. Test samples:
Card BRADESCO ELO MAIS: 5090510000414209
Card B. BRASIL ELO NANQUIM: 5090685000041697
Carb B. BRASIL ELO NANQUIM: 6516539999924898
ELO cards that are recognized as Discover. Test samples:
Cart BRADESCO ELO GRAFITE: 6550049999924911
As described on the original ticket in the adyen-magento github:
Magento version: 1.9.2.4
Plugin version: 2.9.0
Description
The adyen.encrypt_0_1_16.js
and adyen.encrypt_0_1_18.js
is causing a lot of forced reflows in our checkout. This has apparently been a issue for a long time but just recently got some attention.
The problem occurs when filling in a credit card number, after one or two digits the input field stops responding to any input for about 3 seconds. When recording the issue in the observer I see a function call in the adyen.encrypt_0_1_16.js:204
that eventually calls the getJsFonts
a lot. Chrome indicates this as the most likely cause for performance issues during the recording.
Tried to update to module to 2.9.6 and switching the encrypt js file to 1.18 without any luck. Also removed our theme rewrites on the cc.phtml
with still the same problem.
Hi,im trying to create working prototype in React however there are some issues im unable to solve. I've created java script page with HTML form and it works fine.Any help would be appreciated.
Not sure if im on the right track but I'm trying to apply encryption to the form and then execute form submit.
My form is
<form id="adyen-encrypted-form" action="https://requestb.in/1mrymb71" method="POST" ref="AdyenForm">
The onClick button event for the submit button is:
let options = {};
// Bind encryption options to the form.
let encrypted = window.adyen.createEncryptedForm(this.refs.AdyenForm, options);
this.refs.AdyenForm.submit();
Im not getting any errors and im able to inspect window.adyen therefore it has been loaded successfully.
Line: his.refs.AdyenForm.submit();
submits the form as it should.Problem is that for some reason form is not bound and encrypted as it should. Inspecting object: window.adyen.encrypt.errors
i can see there is a UNABLETOBIND:"CSEB01"
.
Every card parameter except holder name validated with parameter allowEmpty = true passed to validations.createChangeHandler
.
Previously all fields were required.
Using the instructions in the README we ran into several issues getting the package to install using NPM for the v0.1.18 tag.
We eventually resolved this by using
"adyen-cse-js": "git+https://github.com/Adyen/CSE-JS.git#v0.1.18"
Why are the following incomplete credit-card numbers validated true?
cseInstance.validate({ number: '499897' });
// returns: { valid=true, number=true, luhn=true}
cseInstance.validate({ number: '41111' });
// returns: { valid=true, number=true, luhn=true}
According to http://www.validcreditcardnumber.com/ they aren't valid.
Hey guys
I have an eCommerce built with NodeJS using adyen library in the client side and
after add csurf library to protect the forms
the last step in checkout(payment step) could not be completed.
my form has an input hidden like this one:
<form method="POST">
<input type="hidden" id="_csrf" name="_csrf" value="8cvViCIw-yTDZXYgPjA11VOaFCJG6W6Z7Sjk">
....adyen stuff
</form>
i have to setup something in adyen for this form work passing _csrf
in the body?
Thanks!
When I try to use no-dom version as a node module, I get the wrong object.
// package.json
"dependencies": {
"adyen-cse-js": "git+https://github.com/Adyen/CSE-JS.git#v0.1.17"
}
// app.js
import adyenEncrypt from 'adyen-cse-js'
console.log(adyenEncrypt)
// → Object { cipher, hash, keyexchange, mode, misc, codec, exception, bitArray, prng, random, json, encrypt, decrypt }
Every node module has a module
variable as a reference to the object representing the current module.
And I figured out that this variable is used in sjcl
library, and you include this library into your module without any encapsulation.
As a result, when I import your library I get sjcl
library instead.
You may want to wrap this code into closure, and pass an empty object as module
variable:
(function (module) {
// ... current sjcl code on L149
})({});
Also after defining AMD module it would be great to make it obvious what exactly do we want to export:
// L172
if (module && module.exports) {
module.exports = encrypt;
}
Due to require("crypto") in sjcl.js which is included in adyen.encrypt.js files when building a bundle with webpack a whole lot of dependencies are pulled in as a result. Unknowingly people who are using webpack or a similar bundling solution might be getting a bigger bundle as a result. This is unnecessary as the code which is responsible for the require fails silently in the browser.
The relevant line in the sjcl.js repo is here https://github.com/bitwiseshiftleft/sjcl/blob/00bd42dae9ebc3a28708db2053ffa2e88f99ad1e/core/random.js#L485
Adyen is 40KB~ in size parsed which leaves around 50KB~ of unwanted dependencies that start to get bundled with require("crypto").
My short term suggestion would be to remove the require("crypto") line in the adyen.encrypt.js files.
We include this repo as a dependency in our package.json like so:
"adyen-cse-js": "git+https://github.com/Adyen/adyen-cse-web.git#v0.1.20.1",
We are on NPM 5. Very routinely, in Jenkins CI we get this error:
npm WARN checkPermissions Missing write access to
/some/path/to/node_modules/adyen-cse-js
We have hundreds of dependencies in our package.json and we never get this error on any others. When we re-run CI, the problem usually goes away.
I'm not sure if adyen-cse-web
actually has permission problems with contents. I suspect it's rather something to do with the fact that this repo's dependency name does not match is repo name. Would love to get these two consistent. Whether you choose to rename the repo or the dependency name doesn't matter to me; which ever one is easiest and most friction-free.
Thanks!
master
is on Version 0_1_13 according to the commit description, but there is no tag. Bower therefor isn't able to install this new version.
I've been searching the documentation but I couldn't find any information about CORS or JSONP.
Do I need to send any specific headers in my request?
The goal is to send the encrypted card details and payment from the user's browser directly to Adyen servers.
Thank you
edit : typo
Hi,
validate()
method is returning valid true for credit card number: 23422343423443223432
which is really not valid as it doesn't start with numbers of any provider
I already made a github issue in another Adyen repository:
https://github.com/Adyen/client-side-encryption/issues/24
Everything works fine in an Android cordova application, but we get errors on the iOS cordova (multiple devices tested: iOS v9.2 and v9.3) which blocks our entire application (because no payments can be done on iOS)
Support ticket: LPC-669-89689
Please advice.
There is no method on the adyen object for detecting credit card type, which are needed for custom payment form integration with modern frameworks. The method that is currently present requires a DOM form which is not desirable.
Is this planned in any future release?
The version history mentions Add device fingerprinting as part of fraud detection
. Is this functionality exposed in any way to be used for device fingerprinting ?
Invalid CVC input has 'valid' class until onblur event fired on them.
Steps to reproduce:
It would be understandable for user to see that CVC is invalid for AmEx card.
Note: fourDigitCvcForBins has default value - '34,37'
Hello,
I'm a developer, which integrating you library with angular app.
I need to implement lazy loading of you library. As always I wrap code into anonymous function and add definition of empty object with name window, then eval this code after ajax load. But I got exception on line 153. Because of this
function a(c, d, e, b) {
// c is a window (replaced by my fake) object
// because of addEventListener is not defined it is not a function
if (typeof c.addEventListener === "function") {
c.addEventListener(d, e, b)
} else {
// also attachEvent is not defined
if (c.attachEvent) {
c.attachEvent("on" + d, e)
} else {
// there is throw exception, but encrypt is not defined yet, because it defined on line 162
throw new Error(encrypt.errors.UNABLETOBIND + ": Unable to bind " + d + "-event")
}
}
}
I don't understand, why you need to use window object in "nodom" library. May be it is not bug, but looks like. May be you have version of you library which fully nodom?
You guys have renamed your package.json
name property in 5d253b7. Are you in the process of updating the github repo name also? It should match. Are you planning on publishing the library as a package on npm?
When using adyen.nodom.js
it's currently not possible to add a device fingerprint to the encrypted data object.
adyen.nodom.js
doesn't include adyen-hpp.df.js
, so the dfValue
attribute is always set to an empty string here: https://github.com/Adyen/adyen-cse-web/blob/master/js/adyen.encrypt.nodom.js#L471 .
try {
data.dfValue = df();
} catch (e) {
}
Note: df()
is a function returning an empty string)
It would be very useful to be able to get the fingerprint separately and pass is to the encrypt
method (without it being reset to an empty string).
An Elo credit card is falsely detected as a maestro card (adyen-cardtype.js). You can check it by using the number provided in the documentation https://www.adyen.com/home/support/knowledgebase/implementation-articles
Card number 5066 9911 1111 1118
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.