diff --git a/README.markdown b/README.md similarity index 88% rename from README.markdown rename to README.md index 65d5086..997faad 100644 --- a/README.markdown +++ b/README.md @@ -32,7 +32,7 @@ Possíveis retornos: * true ou false ### Identificando a bandeira de um cartão -``` javascript +``` javascript moip.creditCard.cardType("5105105105105100"); //return [Object]MASTERCARD moip.creditCard.cardType("4111111111111111"); //return [Object]VISA moip.creditCard.cardType("341111111111111"); //return [Object]AMEX @@ -40,9 +40,12 @@ moip.creditCard.cardType("30569309025904"); //return [Object]DINERS moip.creditCard.cardType("3841001111222233334"); //return [Object]HIPERCARD moip.creditCard.cardType("4514160123456789"); //return [Object]ELO Moip.creditCard.cardType("6370950000000005"); //return [Object]HIPER +Moip.creditCard.cardType("6011020000245045"); //return [Object]DISCOVER +Moip.creditCard.cardType("5078601912345600019"); //return [Object]AURA +Moip.creditCard.cardType("3566007770004971"); //return [Object]JCB moip.creditCard.cardType("9191919191919191"); //return [Object]null -card = moip.creditCard.cardType("5105105105105100"); +card = moip.creditCard.cardType("5105105105105100"); cardIs = card.brand; // MASTERCARD ``` Possíveis retornos: @@ -53,6 +56,9 @@ Object: [brand] * DINERS * HIPERCARD * ELO + * DISCOVER + * AURA + * JCB ### Verificado se a data de expiração do cartão ``` javascript diff --git a/build/moip.js b/build/moip.js index 3325305..1a1668f 100644 --- a/build/moip.js +++ b/build/moip.js @@ -38,7 +38,7 @@ if (digit < 10) { checksum += digit; } else { checksum += (digit-9); } } if ((checksum % 10) === 0) { - return true; + return true; } else { return false; } @@ -65,7 +65,10 @@ return ( eloBins.indexOf(cardNum.substring(0,6)) > -1 || eloBins.indexOf(cardNum.substring(0,5)) > -1 ); - } } + } }, + DISCOVER: { matches: function(cardNum) { return /^6011\d{12}|622\d{13}|64|65\d{14}$/.test(cardNum); } }, + AURA: { matches: function(cardNum) { return /^50\d{17}$/.test(cardNum); } }, + JCB: { matches: function(cardNum) { return /^35\d{14}$/.test(cardNum); } } }, // for non-strict detections looseBrands = { @@ -106,18 +109,21 @@ if (brands.AMEX.matches(creditCardNumber)) { return {brand:'AMEX'}; } if (brands.HIPERCARD.matches(creditCardNumber)) { return {brand:'HIPERCARD'}; } if (brands.DINERS.matches(creditCardNumber)) { return {brand:'DINERS'}; } - + if (brands.DISCOVER.matches(creditCardNumber)) { return {brand:'DISCOVER'}; } + if (brands.AURA.matches(creditCardNumber)) { return {brand:'AURA'}; } + if (brands.JCB.matches(creditCardNumber)) { return {brand:'JCB'}; } + return null; }, isSecurityCodeValid: function(creditCardNumber, csc) { var type = moip.creditCard.cardType(creditCardNumber), digits; - + digits = (type.brand === "AMEX") ? 4 : 3; - + var regExp = new RegExp('[0-9]{' + digits + '}'); - + return (csc.length === digits && regExp.test(csc)); }, @@ -164,7 +170,7 @@ }; moip.creditCard = CreditCard(); - + })(window); (function(window) { diff --git a/build/moip.min.js b/build/moip.min.js index 38a3da0..682d711 100644 --- a/build/moip.min.js +++ b/build/moip.min.js @@ -1,2 +1,2 @@ -/*! Moip.js - build date: 2015-03-04 */ -!function(a){function b(a){return a+="",a.replace(/[\s+|\.|\-]/g,"")}function c(){return this instanceof c?void 0:new c}var d=a.moip||{};a.moip=d,c.prototype={isValid:function(a){var d=c.prototype.cardType(a);if(a=b(a),d){if("HIPERCARD"===d.brand)return!0;for(var e=0,f=2-a.length%2;f<=a.length;f+=2)e+=parseInt(a.charAt(f-1),10);for(f=a.length%2+1;fg?g:g-9}return e%10===0?!0:!1}return!1},cardType:function(a,c){var d={VISA:{matches:function(a){return/^4\d{15}$/.test(a)}},MASTERCARD:{matches:function(a){return/^5[1-5]\d{14}$/.test(a)}},AMEX:{matches:function(a){return/^3[4,7]\d{13}$/.test(a)}},DINERS:{matches:function(a){return/^3[0,6,8]\d{12}$/.test(a)}},HIPERCARD:{matches:function(a){return/^(606282\d{10}(\d{3})?)|(3841\d{15})$/.test(a)}},ELO:{matches:function(a){var b=["50670","50671","50672","50673","50674","50675","50676","50900","50901","50902","50903","50904","50905","50906","50907","401178","401179","431274","438935","451416","457393","457631","457632","504175","506699","506770","506771","506772","506773","506774","506775","506776","506777","506778","509080","509081","509082","509083","627780","636297"];return null===a||16!=a.length?!1:b.indexOf(a.substring(0,6))>-1||b.indexOf(a.substring(0,5))>-1}}},e={VISA:{matches:function(a){return/^4\d{3}\d*$/.test(a)}},MASTERCARD:{matches:function(a){return/^5[1-5]\d{4}\d*$/.test(a)}},AMEX:{matches:function(a){return/^3[4,7]\d{2}\d*$/.test(a)}},DINERS:{matches:function(a){return/^3(?:0[0-5]|[68][0-9])+\d*$/.test(a)}},HIPERCARD:{matches:function(a){return/^(606282|3841\d{2})\d*$/.test(a)}},ELO:{matches:function(a){var b=["50670","50671","50672","50673","50674","50675","50676","50900","50901","50902","50903","50904","50905","50906","50907","401178","401179","431274","438935","451416","457393","457631","457632","504175","506699","506770","506771","506772","506773","506774","506775","506776","506777","506778","509080","509081","509082","509083","627780","636297"];return null===a||a.length<6?!1:b.indexOf(a.substring(0,6))>-1||b.indexOf(a.substring(0,5))>-1}}};return a=b(a),c&&(d=e),d.ELO.matches(a)?{brand:"ELO"}:d.VISA.matches(a)?{brand:"VISA"}:d.MASTERCARD.matches(a)?{brand:"MASTERCARD"}:d.AMEX.matches(a)?{brand:"AMEX"}:d.HIPERCARD.matches(a)?{brand:"HIPERCARD"}:d.DINERS.matches(a)?{brand:"DINERS"}:null},isSecurityCodeValid:function(a,b){var c,e=d.creditCard.cardType(a);c="AMEX"===e.brand?4:3;var f=new RegExp("[0-9]{"+c+"}");return b.length===c&&f.test(b)},isExpiryDateValid:function(a,b){return a=parseInt(a,10),b=parseInt(b,10),1>a||a>12?!1:2!==(b+"").length&&4!==(b+"").length?!1:(2===(b+"").length&&(b=b>80?"19"+b:"20"+b),1e3>b||b>=3e3?!1:!c.prototype.isExpiredDate(a,b))},isExpiredDate:function(a,b){var c=new Date,d=("0"+(c.getMonth()+1)).slice(-2),e=c.getFullYear();if(a=("0"+a).slice(-2),2===b.toString().length){if(b>80)return!0;b="20"+b}var f=e+d,g=b+a;return parseInt(g,10)=g;g++)c[g]=this._calculateInstallmentValue(a.amount,g+1),d[g]=this._calculateAntecipationPercentage(b,a,g,a.amount),e[g]=this._calculateTotalTax(d[g],b),f[g]=this._calculateLiquidValue(a.amount,e[g]);return{amount:a.amount,transaction_tax:b,antecipation_percentage:d,total_tax:e,liquid_value:f,installment_value:c}}return f=this._calculateLiquidValue(a.amount,b),{amount:a.amount,transaction_tax:b,liquid_value:f}},pricingWithInterest:function(a){for(var b=[],c=[],d=[],e=[],f=[],g=[],h=[],i=1;12>=i;i++)b[i-1]=this._calculateInterestRate(a.amount,a.interest_rate,i),c[i-1]=this._calculateAmount(b[i-1],i),d[i-1]=this._calculateTransactionTax(c[i-1],a.transaction_percentage,a.fixed),e[i-1]=this._calculateAntecipationPercentage(d[i-1],a,i-1,c[i-1]),f[i-1]=this._calculateAntecipationPercentageFromAmount(c[i-1],e[i-1]),g[i-1]=this._calculateTotalTax(e[i-1],d[i-1]),h[i-1]=this._calculateLiquidValue(c[i-1],g[i-1]);return{amount:c,transaction_tax:d,antecipation_percentage:f,total_tax:g,liquid_value:h,installment_value:b}},_calculateAntecipationPercentageFromAmount:function(a,b){return parseFloat(100*b/(a/100)).toFixed(2)},_calculateTransactionTax:function(a,b,c){return parseFloat(((a*(b/100)+c)/100).toFixed(2))},_calculateAntecipationPercentage:function(a,b,c,d){return parseFloat((parseFloat(b.antecipation_percentage/100/30*(30+15*c-b.floating))*parseFloat(d/100-a)).toFixed(2))},_calculateTotalTax:function(a,b){return parseFloat((a+b).toFixed(2))},_calculateLiquidValue:function(a,b){return parseFloat((a/100-parseFloat(b)).toFixed(2))},_calculateInstallmentValue:function(a,b){return parseFloat((a/b/100).toFixed(2))},_calculateInterestRate:function(a,b,c){return parseFloat(1===c?a/100:(this._coefficient(b,c)*(a/100)).toFixed(2))},_calculateAmount:function(a,b){return parseFloat(100*(a*b).toFixed(2))},_coefficient:function(a,b){return parseFloat((a/100/(1-1/Math.pow(a/100+1,b))).toFixed(10))}}}(window); \ No newline at end of file +/*! Moip.js - build date: 2015-11-17 */ +!function(a){function b(a){return a+="",a.replace(/[\s+|\.|\-]/g,"")}function c(){return this instanceof c?void 0:new c}var d=a.moip||{};a.moip=d,c.prototype={isValid:function(a){var d=c.prototype.cardType(a);if(a=b(a),d){if("HIPERCARD"===d.brand)return!0;for(var e=0,f=2-a.length%2;f<=a.length;f+=2)e+=parseInt(a.charAt(f-1),10);for(f=a.length%2+1;fg?g:g-9}return e%10===0?!0:!1}return!1},cardType:function(a,c){var d={VISA:{matches:function(a){return/^4\d{15}$/.test(a)}},MASTERCARD:{matches:function(a){return/^5[1-5]\d{14}$/.test(a)}},AMEX:{matches:function(a){return/^3[4,7]\d{13}$/.test(a)}},DINERS:{matches:function(a){return/^3[0,6,8]\d{12}$/.test(a)}},HIPERCARD:{matches:function(a){return/^(606282\d{10}(\d{3})?)|(3841\d{15})$/.test(a)}},ELO:{matches:function(a){var b=["50670","50671","50672","50673","50674","50675","50676","50900","50901","50902","50903","50904","50905","50906","50907","401178","401179","431274","438935","451416","457393","457631","457632","504175","506699","506770","506771","506772","506773","506774","506775","506776","506777","506778","509080","509081","509082","509083","627780","636297"];return null===a||16!=a.length?!1:b.indexOf(a.substring(0,6))>-1||b.indexOf(a.substring(0,5))>-1}},DISCOVER:{matches:function(a){return/^6011\d{12}|622\d{13}|64|65\d{14}$/.test(a)}},AURA:{matches:function(a){return/^50\d{17}$/.test(a)}},JCB:{matches:function(a){return/^35\d{14}$/.test(a)}}},e={VISA:{matches:function(a){return/^4\d{3}\d*$/.test(a)}},MASTERCARD:{matches:function(a){return/^5[1-5]\d{4}\d*$/.test(a)}},AMEX:{matches:function(a){return/^3[4,7]\d{2}\d*$/.test(a)}},DINERS:{matches:function(a){return/^3(?:0[0-5]|[68][0-9])+\d*$/.test(a)}},HIPERCARD:{matches:function(a){return/^(606282|3841\d{2})\d*$/.test(a)}},ELO:{matches:function(a){var b=["50670","50671","50672","50673","50674","50675","50676","50900","50901","50902","50903","50904","50905","50906","50907","401178","401179","431274","438935","451416","457393","457631","457632","504175","506699","506770","506771","506772","506773","506774","506775","506776","506777","506778","509080","509081","509082","509083","627780","636297"];return null===a||a.length<6?!1:b.indexOf(a.substring(0,6))>-1||b.indexOf(a.substring(0,5))>-1}}};return a=b(a),c&&(d=e),d.ELO.matches(a)?{brand:"ELO"}:d.VISA.matches(a)?{brand:"VISA"}:d.MASTERCARD.matches(a)?{brand:"MASTERCARD"}:d.AMEX.matches(a)?{brand:"AMEX"}:d.HIPERCARD.matches(a)?{brand:"HIPERCARD"}:d.DINERS.matches(a)?{brand:"DINERS"}:d.DISCOVER.matches(a)?{brand:"DISCOVER"}:d.AURA.matches(a)?{brand:"AURA"}:d.JCB.matches(a)?{brand:"JCB"}:null},isSecurityCodeValid:function(a,b){var c,e=d.creditCard.cardType(a);c="AMEX"===e.brand?4:3;var f=new RegExp("[0-9]{"+c+"}");return b.length===c&&f.test(b)},isExpiryDateValid:function(a,b){return a=parseInt(a,10),b=parseInt(b,10),1>a||a>12?!1:2!==(b+"").length&&4!==(b+"").length?!1:(2===(b+"").length&&(b=b>80?"19"+b:"20"+b),1e3>b||b>=3e3?!1:!c.prototype.isExpiredDate(a,b))},isExpiredDate:function(a,b){var c=new Date,d=("0"+(c.getMonth()+1)).slice(-2),e=c.getFullYear();if(a=("0"+a).slice(-2),2===b.toString().length){if(b>80)return!0;b="20"+b}var f=e+d,g=b+a;return parseInt(g,10)=g;g++)c[g]=this._calculateInstallmentValue(a.amount,g+1),d[g]=this._calculateAntecipationPercentage(b,a,g,a.amount),e[g]=this._calculateTotalTax(d[g],b),f[g]=this._calculateLiquidValue(a.amount,e[g]);return{amount:a.amount,transaction_tax:b,antecipation_percentage:d,total_tax:e,liquid_value:f,installment_value:c}}return f=this._calculateLiquidValue(a.amount,b),{amount:a.amount,transaction_tax:b,liquid_value:f}},pricingWithInterest:function(a){for(var b=[],c=[],d=[],e=[],f=[],g=[],h=[],i=1;12>=i;i++)b[i-1]=this._calculateInterestRate(a.amount,a.interest_rate,i),c[i-1]=this._calculateAmount(b[i-1],i),d[i-1]=this._calculateTransactionTax(c[i-1],a.transaction_percentage,a.fixed),e[i-1]=this._calculateAntecipationPercentage(d[i-1],a,i-1,c[i-1]),f[i-1]=this._calculateAntecipationPercentageFromAmount(c[i-1],e[i-1]),g[i-1]=this._calculateTotalTax(e[i-1],d[i-1]),h[i-1]=this._calculateLiquidValue(c[i-1],g[i-1]);return{amount:c,transaction_tax:d,antecipation_percentage:f,total_tax:g,liquid_value:h,installment_value:b}},_calculateAntecipationPercentageFromAmount:function(a,b){return parseFloat(100*b/(a/100)).toFixed(2)},_calculateTransactionTax:function(a,b,c){return parseFloat(((a*(b/100)+c)/100).toFixed(2))},_calculateAntecipationPercentage:function(a,b,c,d){return parseFloat((parseFloat(b.antecipation_percentage/100/30*(30+15*c-b.floating))*parseFloat(d/100-a)).toFixed(2))},_calculateTotalTax:function(a,b){return parseFloat((a+b).toFixed(2))},_calculateLiquidValue:function(a,b){return parseFloat((a/100-parseFloat(b)).toFixed(2))},_calculateInstallmentValue:function(a,b){return parseFloat((a/b/100).toFixed(2))},_calculateInterestRate:function(a,b,c){return 1===c?parseFloat(a/100):parseFloat((this._coefficient(b,c)*(a/100)).toFixed(2))},_calculateAmount:function(a,b){return parseFloat(100*(a*b).toFixed(2))},_coefficient:function(a,b){return parseFloat((a/100/(1-1/Math.pow(a/100+1,b))).toFixed(10))}}}(window); \ No newline at end of file diff --git a/src/creditCard.js b/src/creditCard.js index 72ae019..5cf1adf 100644 --- a/src/creditCard.js +++ b/src/creditCard.js @@ -38,7 +38,7 @@ if (digit < 10) { checksum += digit; } else { checksum += (digit-9); } } if ((checksum % 10) === 0) { - return true; + return true; } else { return false; } @@ -65,7 +65,10 @@ return ( eloBins.indexOf(cardNum.substring(0,6)) > -1 || eloBins.indexOf(cardNum.substring(0,5)) > -1 ); - } } + } }, + DISCOVER: { matches: function(cardNum) { return /^6011\d{12}|622\d{13}|64|65\d{14}$/.test(cardNum); } }, + AURA: { matches: function(cardNum) { return /^50\d{17}$/.test(cardNum); } }, + JCB: { matches: function(cardNum) { return /^35\d{14}$/.test(cardNum); } } }, // for non-strict detections looseBrands = { @@ -106,18 +109,21 @@ if (brands.AMEX.matches(creditCardNumber)) { return {brand:'AMEX'}; } if (brands.HIPERCARD.matches(creditCardNumber)) { return {brand:'HIPERCARD'}; } if (brands.DINERS.matches(creditCardNumber)) { return {brand:'DINERS'}; } - + if (brands.DISCOVER.matches(creditCardNumber)) { return {brand:'DISCOVER'}; } + if (brands.AURA.matches(creditCardNumber)) { return {brand:'AURA'}; } + if (brands.JCB.matches(creditCardNumber)) { return {brand:'JCB'}; } + return null; }, isSecurityCodeValid: function(creditCardNumber, csc) { var type = moip.creditCard.cardType(creditCardNumber), digits; - + digits = (type.brand === "AMEX") ? 4 : 3; - + var regExp = new RegExp('[0-9]{' + digits + '}'); - + return (csc.length === digits && regExp.test(csc)); }, @@ -164,5 +170,5 @@ }; moip.creditCard = CreditCard(); - + })(window); diff --git a/test/unit/creditCard.js b/test/unit/creditCard.js index 3e1ddcc..7ee9a06 100644 --- a/test/unit/creditCard.js +++ b/test/unit/creditCard.js @@ -61,7 +61,7 @@ QUnit.test("Diners", function() { this.strictList(valids, moip.creditCard.isValid); }); - + QUnit.test("Amex", function() { var valids = { "valid w/ 16 digits": ["378282246310005", true] @@ -77,7 +77,7 @@ QUnit.test("Hipercard", function(assert) { "valid w/ spaces": ["6062 8256 0763 2328", true] }; - this.strictList(valids, moip.creditCard.isValid); + this.strictList(valids, moip.creditCard.isValid); }); QUnit.test("moip.creditCard.isSecurityCodeValid", function(assert) { @@ -103,9 +103,15 @@ QUnit.test("moip.creditCard.cardType", function(assert) { assert.deepEqual(moip.creditCard.cardType("3841001111222233334"), {"brand": "HIPERCARD"}); assert.deepEqual(moip.creditCard.cardType("6062825607632328"), {"brand": "HIPERCARD"}); - + assert.deepEqual(moip.creditCard.cardType("4514160123456789"), {"brand" : "ELO"}); + assert.deepEqual(moip.creditCard.cardType("6011020000245045"), {"brand" : "DISCOVER"}); + + assert.deepEqual(moip.creditCard.cardType("5078601912345600019"), {"brand" : "AURA"}); + + assert.deepEqual(moip.creditCard.cardType("3566007770004971"), {"brand" : "JCB"}); + assert.equal(moip.creditCard.cardType("2441111111111111"), null); }); @@ -134,7 +140,7 @@ QUnit.test("moip.creditCard.cardType loose check", function(assert) { assert.deepEqual(moip.creditCard.cardType("606282", loose), {"brand": "HIPERCARD"}, "loosely HIPERCARD => 606282"); assert.notDeepEqual(moip.creditCard.cardType("606282"), {"brand": "HIPERCARD"}); - + assert.deepEqual(moip.creditCard.cardType("451416", loose), {"brand" : "ELO"}, "loosely ELO => 451416"); assert.notDeepEqual(moip.creditCard.cardType("451416"), {"brand": "ELO"}); });