Skip to content

Commit cd35c02

Browse files
author
euforic
committed
initial commit
0 parents  commit cd35c02

File tree

4 files changed

+330
-0
lines changed

4 files changed

+330
-0
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.DS_Store
2+
node_modules
3+
npm-debug.log
4+
private_tests

Readme.md

+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
# Banking.js
2+
3+
## The Missing API for your bank.
4+
* Bank statement results in JSON or Valid XML
5+
* Supports all financial institutions (File an issue if yours does not work)
6+
7+
## Installation
8+
9+
```bash
10+
$ npm install banking
11+
```
12+
13+
## Usage
14+
15+
```javascript
16+
var banking = require('banking');
17+
18+
var bankInfo = {
19+
fid: 10898
20+
, fidorg: 'B1'
21+
, url: 'https://yourBanksOfxApiURL.com'
22+
, bankid: 0123456 /* If bank account use your bank routing number otherwise set to null */
23+
, user: username
24+
, pass: password
25+
, accid: 0123456789
26+
, acctype: 'CHECKING' /* CHECKING || SAVINGS || MONEYMRKT || CREDITCARD */
27+
, date_start: 20010125 /* Statement start date YYYYMMDDHHMMSS */
28+
, date_end: 20110125 /* Statement end date YYYYMMDDHHMMSS */
29+
};
30+
31+
//If second param is omitted JSON will be returned by default
32+
33+
banking.getStatement(bankInfo, 'xml', function(res, err)
34+
if(err) console.log(err)
35+
console.log(res);
36+
}
37+
```
38+
## Sample Response
39+
40+
```javascript
41+
{
42+
"OFX": {
43+
"SIGNONMSGSRSV1": {
44+
"SONRS": {
45+
"STATUS": {
46+
"CODE": "0",
47+
"SEVERITY": "INFO",
48+
"MESSAGE": "SUCCESS"
49+
},
50+
"DTSERVER": "20120126212302.454[-8:PST]",
51+
"LANGUAGE": "ENG",
52+
"FI": {
53+
"ORG": "DI",
54+
"FID": "321081669"
55+
}
56+
}
57+
},
58+
"BANKMSGSRSV1": {
59+
"STMTTRNRS": {
60+
"TRNUID": "BiJNgqjvbw5vg18Z5T8kZASgUKmsFnNY",
61+
"STATUS": {
62+
"CODE": "0",
63+
"SEVERITY": "INFO",
64+
"MESSAGE": "SUCCESS"
65+
},
66+
"CLTCOOKIE": "iXus7",
67+
"STMTRS": {
68+
"CURDEF": "USD",
69+
"BANKACCTFROM": {
70+
"BANKID": "321081669",
71+
"ACCTID": "3576960405",
72+
"ACCTTYPE": "CHECKING"
73+
},
74+
"BANKTRANLIST": {
75+
"DTSTART": "20010125120000.000",
76+
"DTEND": "20120126212302.638[-8:PST]",
77+
"STMTTRN": [{
78+
"TRNTYPE": "DEP",
79+
"DTPOSTED": "20110407070000.000",
80+
"DTAVAIL": "20110407070000.000",
81+
"TRNAMT": "1934.65",
82+
"FITID": "156599402",
83+
"NAME": "CLIENT DEPOSIT",
84+
"MEMO": "CLIENT DEPOSIT"
85+
}, {
86+
"TRNTYPE": "DEBIT",
87+
"DTPOSTED": "20110412070000.000",
88+
"DTAVAIL": "20110412070000.000",
89+
"TRNAMT": "-700.00",
90+
"FITID": "156950780",
91+
"NAME": "DOMESTIC WIRE FUNDS-DEBIT CHRIST",
92+
"MEMO": "DOMESTIC WIRE FUNDS-DEBIT CHRISTIAN SULLIVAN"
93+
}, {
94+
"TRNTYPE": "CHECK",
95+
"DTPOSTED": "20110414070000.000",
96+
"DTAVAIL": "20110414070000.000",
97+
"TRNAMT": "-38.20",
98+
"FITID": "157222076",
99+
"CHECKNUM": "10004",
100+
"NAME": "CHECK WITHDRAWAL",
101+
"MEMO": "CHECK WITHDRAWAL"
102+
}, {
103+
"TRNTYPE": "CHECK",
104+
"DTPOSTED": "20110414070000.000",
105+
"DTAVAIL": "20110414070000.000",
106+
"TRNAMT": "-349.79",
107+
"FITID": "157222077",
108+
"CHECKNUM": "10006",
109+
"NAME": "CHECK WITHDRAWAL",
110+
"MEMO": "CHECK WITHDRAWAL"
111+
}]
112+
},
113+
"LEDGERBAL": {
114+
"BALAMT": "1661.41",
115+
"DTASOF": "20120126212302.751[-8:PST]"
116+
},
117+
"AVAILBAL": {
118+
"BALAMT": "2761.41",
119+
"DTASOF": "20120126212302.751[-8:PST]"
120+
}
121+
}
122+
}
123+
}
124+
}
125+
}
126+
```
127+
128+
## TODO
129+
* Retrieve users available accounts with out account numbers
130+
* Add directory of common banks
131+
132+
## More Information
133+
* [Banking Connection Parameters](http://www.ofxhome.com/index.php/home/directory)
134+
* [Offical OFX Home Page](http://www.ofx.net/)
135+
136+
## License
137+
138+
(The MIT License)
139+
140+
Copyright (c) 2010-2012 Christian Sullivan <[email protected]>
141+
142+
Permission is hereby granted, free of charge, to any person obtaining
143+
a copy of this software and associated documentation files (the
144+
'Software'), to deal in the Software without restriction, including
145+
without limitation the rights to use, copy, modify, merge, publish,
146+
distribute, sublicense, and/or sell copies of the Software, and to
147+
permit persons to whom the Software is furnished to do so, subject to
148+
the following conditions:
149+
150+
The above copyright notice and this permission notice shall be
151+
included in all copies or substantial portions of the Software.
152+
153+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
154+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
155+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
156+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
157+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
158+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
159+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

lib/banking.js

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
var parser = require('xml2json')
2+
, request = require('request');
3+
4+
5+
/**
6+
* Unique Id Generator
7+
*
8+
* @param {number} length
9+
* @return {string} radix
10+
* @return {string} uuid
11+
* @api private
12+
*/
13+
function uuid(len,radix) {
14+
var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
15+
var chars = CHARS, uuid = [];
16+
radix = radix || chars.length;
17+
18+
if (len) {
19+
for (var i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix];
20+
} else {
21+
var r;
22+
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
23+
uuid[14] = '4';
24+
25+
for (var i = 0; i < 36; i++) {
26+
if (!uuid[i]) {
27+
r = 0 | Math.random()*16;
28+
uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
29+
}
30+
}
31+
}
32+
33+
return uuid.join('');
34+
};
35+
36+
37+
/**
38+
* Clean OFX Data
39+
*
40+
* @param {string} ofxBody
41+
* @return {object} response head
42+
* @return {xmlstring} callback
43+
* @api private
44+
*/
45+
function cleanOFX(resBody, format, cb) {
46+
if(typeof format !== 'string') cb = format, format = 'json';
47+
48+
var ofx = resBody.split('<OFX>',2);
49+
var headerString = ofx[0].split(/\r|\n/);
50+
var bodyXML = ('<OFX>'+ofx[1]).replace(/>\s+</g, '><').replace(/\s+</g, '<').replace(/>\s+/g, '>').replace(/<([A-Z0-9_]*)+\.+([A-Z0-9_]*)>([^<]+)/g, '<\$1\$2>\$3' ).replace(/<(\w+?)>([^<]+)/g, '<\$1>\$2</\$1>');
51+
var header = {}
52+
53+
for(attrs in headerString){
54+
var headAttributes = headerString[attrs].split(/:/,2);
55+
header[headAttributes[0]] = headAttributes[1];
56+
}
57+
58+
var body = (format === 'json') ? JSON.parse(parser.toJson(bodyXML)) : bodyXML;
59+
console.log(header);
60+
cb(body, null);
61+
};
62+
63+
64+
/**
65+
*
66+
*/
67+
68+
exports.getStatement = function(o, type, cb) {
69+
70+
//TODO join ofxReq and ofxReqCC not sure why I seperated in the first place
71+
//Request for Bank statement
72+
var ofxReq = 'OFXHEADER:100\n'+
73+
'DATA:OFXSGML\nVERSION:102\nSECURITY:NONE\nENCODING:USASCII\nCHARSET:1252\nCOMPRESSION:NONE\nOLDFILEUID:NONE\nNEWFILEUID:'+uuid(32)+'\n\n'+
74+
'<OFX>'+
75+
'<SIGNONMSGSRQV1>'+
76+
'<SONRQ>'+
77+
'<DTCLIENT>'+o.date_end+
78+
'<USERID>'+o.user+
79+
'<USERPASS>'+o.pass+
80+
'<LANGUAGE>ENG'+
81+
'<FI>'+
82+
'<ORG>'+o.fidorg+
83+
'<FID>'+o.fid+
84+
'</FI>'+
85+
'<APPID>QWIN'+
86+
'<APPVER>1700'+
87+
'</SONRQ></SIGNONMSGSRQV1>'+
88+
'<BANKMSGSRQV1>'+
89+
'<STMTTRNRQ>'+
90+
'<TRNUID>'+uuid(32)+
91+
'<CLTCOOKIE>'+uuid(5)+
92+
'<STMTRQ>'+
93+
'<BANKACCTFROM>'+
94+
'<BANKID>'+o.bankid+
95+
'<ACCTID>'+o.accid+
96+
'<ACCTTYPE>'+o.acctype+
97+
'</BANKACCTFROM>'+
98+
'<INCTRAN>'+
99+
'<DTSTART>'+o.date_start+
100+
'<INCLUDE>Y</INCTRAN>'+
101+
'</STMTRQ>'+
102+
'</STMTTRNRQ>'+
103+
'</BANKMSGSRQV1>'+
104+
'</OFX>';
105+
106+
//Request for CreditCard Statement
107+
var ofxReqCC = 'OFXHEADER:100\n'+
108+
'DATA:OFXSGML\nVERSION:102\nSECURITY:NONE\nENCODING:USASCII\nCHARSET:1252\nCOMPRESSION:NONE\nOLDFILEUID:NONE\nNEWFILEUID:'+uuid(32)+'\n\n'+
109+
'<OFX>'+
110+
'<SIGNONMSGSRQV1>'+
111+
'<SONRQ>'+
112+
'<DTCLIENT>'+o.date_end+
113+
'<USERID>'+o.user+
114+
'<USERPASS>'+o.pass+
115+
'<LANGUAGE>ENG'+
116+
'<FI>'+
117+
'<ORG>'+o.fidorg+
118+
'<FID>'+o.fid+
119+
'</FI>'+
120+
'<APPID>QWIN'+
121+
'<APPVER>1700'+
122+
'</SONRQ></SIGNONMSGSRQV1>'+
123+
'<CREDITCARDMSGSRQV1>'+
124+
'<CCSTMTTRNRQ>'+
125+
'<TRNUID>'+uuid(32)+
126+
'<CLTCOOKIE>'+uuid(5)+
127+
'<CCSTMTRQ>'+
128+
'<CCACCTFROM>'+
129+
'<ACCTID>'+o.accid+
130+
'</CCACCTFROM>'+
131+
'<INCTRAN>'+
132+
'<DTSTART>'+o.date_start+
133+
'<INCLUDE>Y</INCTRAN>'+
134+
'</CCSTMTRQ>'+
135+
'</CCSTMTTRNRQ>'+
136+
'</CREDITCARDMSGSRQV1>'+
137+
'</OFX>';
138+
139+
request({
140+
method: 'POST'
141+
, url: o.url
142+
, headers: { 'Content-Type' : 'application/x-ofx' }
143+
, body: (o.acctype == 'CREDITCARD') ? ofxReqCC : ofxReq
144+
, encoding: 'UTF8'
145+
}, function(err,res,body){
146+
if(res.headers['content-type'] !== 'application/x-ofx') return cb(body,'Invalid Response');
147+
cleanOFX(body, type, cb);
148+
});
149+
};

package.json

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "banking"
3+
, "description": "The missing Bank API for getting you statement data"
4+
, "version": "0.1.0"
5+
, "author": "Christian Sullivan <[email protected]>"
6+
, "keywords": ["banking", "ofx", "financial", "bank"]
7+
, "private": false
8+
, "homepage": "http://euforic.github.com/banking.js"
9+
, "dependencies": {
10+
"xml2json": ">=0.2.4"
11+
, "request":">=2.1.1"
12+
}
13+
, "repository": {
14+
"type": "git"
15+
, "url": "http://github.com/euforic/banking.js.git" }
16+
, "main": "lib/banking.js"
17+
, "engines": { "node": ">= 0.6.2" }
18+
}

0 commit comments

Comments
 (0)