UNPKG

finnish-bank-utils

Version:

A micro Javascript library for validating, creating and formatting Finnish IBAN bank account numbers and reference numbers. Can parse payment details from Finnish virtual barcodes.

2 lines (1 loc) 9.44 kB
(function(global,factory){if(typeof define==="function"&&define.amd){define("FinnishBankUtils",["module"],factory)}else if(typeof exports!=="undefined"){factory(module)}else{var mod={exports:{}};factory(mod);global.FinnishBankUtils=mod.exports}})(this,function(module){"use strict";var _typeof=typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"?function(obj){return typeof obj}:function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj};var _slicedToArray=function(){function sliceIterator(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"])_i["return"]()}finally{if(_d)throw _e}}return _arr}return function(arr,i){if(Array.isArray(arr)){return arr}else if(Symbol.iterator in Object(arr)){return sliceIterator(arr,i)}else{throw new TypeError("Invalid attempt to destructure non-iterable instance")}}}();function _toConsumableArray(arr){if(Array.isArray(arr)){for(var i=0,arr2=Array(arr.length);i<arr.length;i++){arr2[i]=arr[i]}return arr2}else{return Array.from(arr)}}var REF_NUMBER_MULTIPLIERS=[7,3,1],FINNISH_REF_NUMBER_REGEX=/^(\d{4,20}|RF\d{6,22})$/i,FINNISH_IBAN_REGEX=/^FI\d{16}$/,FINNISH_VIRTUAL_BAR_CODE_REGEX=/^[45]\d{53}$/,FINNISH_DATE_REGEX=/^(\d\d?)\.(\d\d?)\.(\d{4})$/,IBAN_OFFSET_FROM_ASCIICODE=-55;function removeAllWhiteSpaces(str){return str.replace(/\s+/g,"")}function removeLeadingZeros(str){return str.replace(/^0+/,"")}function lettersToNumbers(str){return[].concat(_toConsumableArray(str)).map(function(char){if(/\D/.test(char)){return String(char.charCodeAt(0)+IBAN_OFFSET_FROM_ASCIICODE)}return char}).join("")}function reverseString(str){return[].concat(_toConsumableArray(str)).reverse().join("")}function removeStringFromEnd(str,strToRemove){if(str.substr(-strToRemove.length)===strToRemove){return str.substr(0,str.length-strToRemove.length)}return str}function leftPadString(str,char,pad){return(char.repeat(pad)+str).substr(-Math.max(str.length,pad))}function randomNumberWithLength(length){var randomNumber="";for(var i=0;i<length;i++){randomNumber+=Math.floor(Math.random()*9)+1}return parseInt(randomNumber,10)}function modForLargeNumber(base,divisor){var dividend="";for(var i=0;i<base.length;i++){dividend=parseInt(dividend+base[i],10);if(dividend>=divisor){var remainder=dividend%divisor;if(i==base.length-1){return remainder}else{dividend=remainder}}}return parseInt(dividend,10)}function luhnMod10(value){var sum=0;for(var i=0;i<value.length;i++){var multiplier=i%2===0?2:1;var add=multiplier*parseInt(value[i],10);if(add>=10){add-=9}sum+=add}var mod10=sum%10;return mod10===0?mod10:10-mod10}function isValidFinnishBBAN(accountNumber){accountNumber=removeAllWhiteSpaces(accountNumber);var localAccountNumberWithoutCheckSum=accountNumber.substr(4,13),luhnChecksumChar=parseInt(accountNumber.substr(17,1),10);return luhnMod10(localAccountNumberWithoutCheckSum)===luhnChecksumChar}function isValidIBAN(iban){iban=removeAllWhiteSpaces(iban.toUpperCase());var prefixAndChecksum=iban.substr(0,4),number=iban.substr(4);return modForLargeNumber(lettersToNumbers(number+prefixAndChecksum),97)===1}function isValidFinnishDate(string){if(!string||typeof string!="string"||!FINNISH_DATE_REGEX.test(string)){return false}var _string$match$slice$m=string.match(FINNISH_DATE_REGEX).slice(1,4).map(Number),_string$match$slice$m2=_slicedToArray(_string$match$slice$m,3),day=_string$match$slice$m2[0],month=_string$match$slice$m2[1],year=_string$match$slice$m2[2],date=new Date(year,month-1,day);return year==date.getFullYear()&&month-1==date.getMonth()&&day==date.getDate()}function sliceVirtualBarCode(barCode){var version=Number(barCode.substr(0,1));var slices=void 0;if(version===4){slices=[1,16,6,2,3,20,2,2,2]}else if(version===5){slices=[1,16,6,2,0,23,2,2,2]}var index=0;return slices.map(function(length){var slice=barCode.substr(index,length);index+=length;return slice})}var FinnishBankUtils={isValidFinnishRefNumber:function isValidFinnishRefNumber(refNumber){if(!refNumber||typeof refNumber!=="string"||!FINNISH_REF_NUMBER_REGEX.test(removeAllWhiteSpaces(refNumber.toUpperCase()))){return false}refNumber=removeAllWhiteSpaces(refNumber.toUpperCase());if(/^RF/.test(refNumber)){if(!isValidIBAN(refNumber)){return false}refNumber=refNumber.substr(4)}else{refNumber=removeLeadingZeros(refNumber)}var reversedRefNumber=reverseString(refNumber),providedChecksumNumber=parseInt(reversedRefNumber.charAt(0));refNumber=reversedRefNumber.substr(1);var checksum=0,checksumNumber=void 0;for(var i=0;i<refNumber.length;i++){checksum+=REF_NUMBER_MULTIPLIERS[i%REF_NUMBER_MULTIPLIERS.length]*parseInt(refNumber.charAt(i))}checksumNumber=10-checksum%10;if(checksumNumber===10){checksumNumber=0}return checksumNumber===providedChecksumNumber},isValidFinnishIBAN:function isValidFinnishIBAN(accountNumber){if(!accountNumber||typeof accountNumber!=="string"||!FINNISH_IBAN_REGEX.test(removeAllWhiteSpaces(accountNumber.toUpperCase()))){return false}return isValidFinnishBBAN(accountNumber)&&isValidIBAN(accountNumber)},formatFinnishRefNumber:function formatFinnishRefNumber(refNumber){var separator=arguments.length>1&&arguments[1]!==undefined?arguments[1]:" ";if(this.isValidFinnishRefNumber(refNumber)){refNumber=removeAllWhiteSpaces(refNumber.toUpperCase());if(/^RF/.test(refNumber)){refNumber=refNumber.substr(0,4)+removeLeadingZeros(refNumber.substr(4));return removeStringFromEnd(refNumber.replace(/.{4}/g,"$&"+separator),separator)}else{refNumber=removeLeadingZeros(refNumber);return reverseString(removeStringFromEnd(reverseString(refNumber).replace(/.{5}/g,"$&"+separator),separator))}}},formatFinnishIBAN:function formatFinnishIBAN(accountNumber){var separator=arguments.length>1&&arguments[1]!==undefined?arguments[1]:" ";if(this.isValidFinnishIBAN(accountNumber)){accountNumber=removeAllWhiteSpaces(accountNumber.toUpperCase());return removeStringFromEnd(accountNumber.replace(/.{4}/g,"$&"+separator),separator)}},generateFinnishRefNumber:function generateFinnishRefNumber(initial){var refNumber=typeof initial==="string"?removeAllWhiteSpaces(initial):randomNumberWithLength(9).toString(),reversedRefNumber=reverseString(refNumber);var checksum=0,checksumNumber=void 0;for(var i=0;i<reversedRefNumber.length;i++){checksum+=REF_NUMBER_MULTIPLIERS[i%REF_NUMBER_MULTIPLIERS.length]*parseInt(reversedRefNumber.charAt(i))}checksumNumber=10-checksum%10;if(checksumNumber===10){checksumNumber=0}return refNumber+checksumNumber},generateFinnishIBAN:function generateFinnishIBAN(){var defaultCheckDigit="00",danskeBankOffice="800026",countryCodeInDigits=lettersToNumbers("FI"),bankAccount=randomNumberWithLength(7),localAccountNumber=danskeBankOffice+bankAccount+luhnMod10(danskeBankOffice+bankAccount),accountNumberCandidate=localAccountNumber+countryCodeInDigits+defaultCheckDigit,checkDigit=98-modForLargeNumber(accountNumberCandidate,97),checkChars=checkDigit>=10?checkDigit.toString():"0"+checkDigit;return"FI"+checkChars+localAccountNumber},parseFinnishVirtualBarCode:function parseFinnishVirtualBarCode(barCode){if(!barCode||typeof barCode!="string"||!FINNISH_VIRTUAL_BAR_CODE_REGEX.test(barCode)){return false}var _sliceVirtualBarCode=sliceVirtualBarCode(barCode),_sliceVirtualBarCode2=_slicedToArray(_sliceVirtualBarCode,9),version=_sliceVirtualBarCode2[0],iban=_sliceVirtualBarCode2[1],euros=_sliceVirtualBarCode2[2],cents=_sliceVirtualBarCode2[3],reserve=_sliceVirtualBarCode2[4],reference=_sliceVirtualBarCode2[5],year=_sliceVirtualBarCode2[6],month=_sliceVirtualBarCode2[7],day=_sliceVirtualBarCode2[8];version=Number(version);iban=this.formatFinnishIBAN("FI"+iban);var sum=Number(euros)+Number(cents)/100;if(version===5){reference="RF"+reference.substr(0,2)+removeLeadingZeros(reference.substr(2))}reference=this.formatFinnishRefNumber(reference);var date=void 0;day=Number(day);month=Number(month);if(day>0&&month>0){date=day+"."+month+".20"+year}return{iban:iban,sum:sum,reference:reference,date:date}},formatFinnishVirtualBarCode:function formatFinnishVirtualBarCode(object){if(!object||(typeof object==="undefined"?"undefined":_typeof(object))!="object"||!this.isValidFinnishIBAN(object.iban)||typeof object.sum!="number"||object.sum<0||object.sum>999999.99||object.sum!=Number(object.sum.toFixed(2))||!this.isValidFinnishRefNumber(object.reference)||object.date!=undefined&&!isValidFinnishDate(object.date)){return false}var iban=removeAllWhiteSpaces(object.iban),euros=Math.floor(object.sum),cents=object.sum*100-euros*100,reference=removeAllWhiteSpaces(object.reference),day=0,month=0,year=0,version=/^RF/.test(reference)?5:4;if(object.date){var _object$date$match$sl=object.date.match(FINNISH_DATE_REGEX).slice(1,4).map(Number);var _object$date$match$sl2=_slicedToArray(_object$date$match$sl,3);day=_object$date$match$sl2[0];month=_object$date$match$sl2[1];year=_object$date$match$sl2[2]}if(version==5){reference=reference.replace(/^RF/,"");reference=reference.substr(0,2)+leftPadString(reference.substr(2),"0",21)}return String(version)+iban.replace(/^FI/,"")+leftPadString(String(euros),"0",6)+leftPadString(String(cents),"0",2)+leftPadString(reference,"0",23)+leftPadString(String(year).substr(-2),"0",2)+leftPadString(String(month),"0",2)+leftPadString(String(day),"0",2)}};module.exports=Object.freeze(FinnishBankUtils)});