├── .gitattributes
├── .gitignore
├── LICENSE.txt
├── LICENSE_BOL.txt
├── LICENSE_GNU_AGPLv3.txt
├── LICENSE_GNU_APL.txt
├── README.txt
├── client.inc
├── client.php
├── client
├── 202.html
├── 403.html
├── 503.html
├── 511.html
├── btn_1.gif
├── btn_2.gif
├── btn_3.gif
├── btn_4.gif
├── btn_5.gif
├── debug.html
├── form.html
├── home.html
├── icon.ico
├── icon.png
├── rule.css
├── template.html
├── template.js
└── wsofx.gif
├── common.inc
├── common
├── fi.xml
└── ofx.xml
├── index.php
├── index.txt
├── log
└── .gitkeep
├── php.ini
├── php_mac.ini
├── server.inc
├── server.php
├── server
├── auwallet.inc
├── benefit401k.inc
├── btmu.inc
├── chocom.inc
├── dccard.inc
├── esaifu.inc
├── jaccscard.inc
├── jist.inc
├── jpbank.inc
├── kabucom.inc
├── mhbk.inc
├── mobilesuica.inc
├── mufgcard.inc
├── nanaco.inc
├── netbk.inc
├── nrkn.inc
├── osaifuponta.inc
├── rakutensec.inc
├── saisoncard.inc
├── sbisec.inc
├── smbc.inc
├── smbccard.inc
├── smcprepaide.inc
├── surugavisacard.inc
├── viewcard.inc
└── waon.inc
└── start_php.bat
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
19 | *.bat eol=crlf
20 | *.ini eol=crlf
21 | *.xml eol=crlf
22 |
23 | *.inc linguist-language=PHP
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Project ignored files
2 | log/*.log
3 |
4 | # Windows image file caches
5 | Thumbs.db
6 | ehthumbs.db
7 |
8 | # Folder config file
9 | Desktop.ini
10 |
11 | # Recycle Bin used on file shares
12 | $RECYCLE.BIN/
13 |
14 | # Windows Installer files
15 | *.cab
16 | *.msi
17 | *.msm
18 | *.msp
19 |
20 | # Windows shortcuts
21 | *.lnk
22 |
23 | # =========================
24 | # Operating System Files
25 | # =========================
26 |
27 | # OSX
28 | # =========================
29 |
30 | .DS_Store
31 | .AppleDouble
32 | .LSOverride
33 |
34 | # Thumbnails
35 | ._*
36 |
37 | # Files that might appear on external disk
38 | .Spotlight-V100
39 | .Trashes
40 |
41 | # Directories potentially created on remote AFP share
42 | .AppleDB
43 | .AppleDesktop
44 | Network Trash Folder
45 | Temporary Items
46 | .apdisk
47 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | OFXProxyは、GNU AFFERO GENERAL PUBLIC LICENSE Version 3、および
2 | Beatrek Origin Licenseのデュアルライセンスに基づき提供いたします。
3 |
4 | ライセンスの詳細については、./LICENSE_GNU_AGPLv3.txt、および./LICENSE_BOL.txtを
5 | ご参照ください。
6 |
7 |
8 | ./server.*, ./server/*.*:, ./client.*, ./client/*.*:
9 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 | 上記ファイルは、GNU AFFERO GENERAL PUBLIC LICENSE Version 3、および
11 | Beatrek Origin Licenseのデュアルライセンスに基づき提供いたします。
12 |
13 | ライセンスの詳細については、./LICENSE_GNU_AGPLv3.txt、および./LICENSE_BOL.txtを
14 | ご参照ください。
15 |
16 |
17 | ./common.*, ./common/*.*, ./index.*, ./README.txt, ./php*.ini, ./start_php.bat:
18 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19 | 上記ファイルは、GNU All-Permissive License、およびBeatrek Origin Licenseの
20 | デュアルライセンスに基づき提供いたします。
21 |
22 | ライセンスの詳細については、./LICENSE_GNU_APL.txt、および./LICENSE_BOL.txtを
23 | ご参照ください。
24 |
25 |
--------------------------------------------------------------------------------
/LICENSE_BOL.txt:
--------------------------------------------------------------------------------
1 | Beatrek Origin License
2 |
3 | (準拠法)
4 | 本ライセンスの解釈、および適用は、日本国法に準拠するものとします。
5 |
6 | (著作権)
7 | 本ライセンスが適用されるソースコードの著作権は、特に記載のない限り、
8 | 著作者であるアウター・ガイ事務所に帰属するものであり、日本国著作権法、
9 | 国際条約、およびその他の法律によって保護されています。
10 | 明示的に付与されていないすべての権利は、著作者により留保されています。
11 |
12 | (適用の除外)
13 | 本ライセンスが適用されるソースコードのうち、アウター・ガイ事務所以外の
14 | 者が著作者であるソースコード部分については、本ライセンスが適用されない
15 | ものとします。
16 |
17 | (使用、および利用の制限)
18 | 本ライセンスが適用されるソースコードは、著作者が何らの制約を受ける
19 | ことなく、著作者の自己の技術を他に転用する目的で、現状有姿のまま
20 | 供するものであり、お客様が事前に著作者の文書による許諾を得た場合を
21 | 除き、かかる目的、あるいはその他法律によって明示的に認められる範囲を
22 | 超えて、かかるソースコードを、いかなる方法によっても使用、および利用
23 | することはできません。
24 |
25 | (免責)
26 | 著作者は、本ライセンスが適用されるソースコードに関して、明示的、
27 | あるいは黙示的を問わず、一切保証しません。
28 | 著作者は、本ライセンスが適用されるソースコードの使用、または
29 | 使用不能により生じたあらゆる損失および損害について、著作者が予見し、
30 | または予見し得た場合を含め、いかなる場合も一切責任を負わないものと
31 | します。
32 |
33 |
--------------------------------------------------------------------------------
/LICENSE_GNU_APL.txt:
--------------------------------------------------------------------------------
1 | GNU All-Permissive License
2 |
3 | Copying and distribution of this file, with or without modification,
4 | are permitted in any medium without royalty provided the copyright
5 | notice and this notice are preserved. This file is offered as-is,
6 | without any warranty.
7 |
8 |
--------------------------------------------------------------------------------
/README.txt:
--------------------------------------------------------------------------------
1 | OFXProxy:対応金融機関のOFXファイルをダウンロードするサービス
2 |
3 | OFXProxyは、対応金融機関の口座情報をOFXファイルとしてダウンロードできるサービスです。取得した明細データは、OFX対応ソフト・サービスに取り込めます。
4 |
5 | OFXProxyを実行するには、PHPバージョン5.4以降が必要です。
6 |
7 | ソースコード(GitHub)
8 | https://github.com/outerguy/ofxproxy
9 |
10 | プロジェクトサイト(Beatrek)
11 | https://www.beatrek.com/home/ofxproxy.htm
12 |
13 | Beatrek OFX仕様書(Beatrek)
14 | https://www.beatrek.com/home/ofxspec.htm
15 |
16 |
--------------------------------------------------------------------------------
/client.inc:
--------------------------------------------------------------------------------
1 | ", "", "", ""), array($fi["fiid"], $fi["name"], $fi["home"], trim(get_auth($fi))), $str);
30 | }
31 | return $ret;
32 | }
33 |
34 | // 認証情報を生成する
35 | function get_auth($fi) {
36 | $ret = "";
37 |
38 | $forms = explode("|", $fi["form"]);
39 | foreach($forms as $form) {
40 | list($text, $attr) = explode("|", $fi[$form], 2);
41 | $attr = strtolower($attr);
42 | switch($attr) {
43 | case "text":
44 | case "password":
45 | break;
46 | default:
47 | $attr = "text";
48 | break;
49 | }
50 | $ret .= "
" . $text . "\r\n";
51 | $ret .= "\r\n";
52 | }
53 |
54 | return $ret;
55 | }
56 |
57 | // 金融機関一覧を生成する
58 | function get_filist($fis) {
59 | $ret = "";
60 |
61 | foreach($fis as $fi) $ret .= "\r\n";
62 |
63 | return $ret;
64 | }
65 |
66 | ?>
67 |
--------------------------------------------------------------------------------
/client.php:
--------------------------------------------------------------------------------
1 | ", "", "", "\"\""), array(ENV_PRODUCT_CLIENT_VERSION, ENV_PRODUCT_VERSION, ENV_PRODUCT_FAMILY, (ENV_BOOL_DEBUG == true? "true": "false")), $js);
17 |
18 | // レスポンスを返す
19 | header(get_http_status(ENV_NUM_STATUS_SUCCESS));
20 | header("Cache-Control: no-cache");
21 | header("Pragma: no-cache");
22 | header("Content-Type: text/javascript; charset=UTF-8");
23 | header("Content-Length: " . strlen($js));
24 | echo $js;
25 |
26 | ?>
27 |
--------------------------------------------------------------------------------
/client/202.html:
--------------------------------------------------------------------------------
1 | 追加認証
2 | 本人確認のため、より追加認証を求められています。
3 |
4 |
5 |
14 |
--------------------------------------------------------------------------------
/client/403.html:
--------------------------------------------------------------------------------
1 | 認証エラー
2 | ログインできませんでした。
3 | 認証情報の内容を確認した後、再試行してください。
4 |
5 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/client/503.html:
--------------------------------------------------------------------------------
1 | メンテナンスエラー
2 | システムメンテナンス画面が表示されたため、処理を中断しました。
3 | のシステムメンテナンスが終了した後、再試行してください。
4 |
5 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/client/511.html:
--------------------------------------------------------------------------------
1 | 情報取得エラー
2 | 「重要なお知らせ」等の画面が表示されたため、処理を中断しました。
3 | にログインし、画面を確認した後、再試行してください。
4 |
5 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/client/btn_1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/outerguy/ofxproxy/89e0d8a08537897d628bc46ddf862452d39ee2df/client/btn_1.gif
--------------------------------------------------------------------------------
/client/btn_2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/outerguy/ofxproxy/89e0d8a08537897d628bc46ddf862452d39ee2df/client/btn_2.gif
--------------------------------------------------------------------------------
/client/btn_3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/outerguy/ofxproxy/89e0d8a08537897d628bc46ddf862452d39ee2df/client/btn_3.gif
--------------------------------------------------------------------------------
/client/btn_4.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/outerguy/ofxproxy/89e0d8a08537897d628bc46ddf862452d39ee2df/client/btn_4.gif
--------------------------------------------------------------------------------
/client/btn_5.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/outerguy/ofxproxy/89e0d8a08537897d628bc46ddf862452d39ee2df/client/btn_5.gif
--------------------------------------------------------------------------------
/client/debug.html:
--------------------------------------------------------------------------------
1 | 【警告】開発者向け(デバッグ)機能が有効のため、認証情報を含む詳細な記録が残ります。開発者以外の方は、操作しないでください。または、開発者へご相談ください。
2 |
--------------------------------------------------------------------------------
/client/form.html:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/client/home.html:
--------------------------------------------------------------------------------
1 | 
2 | OFXProxyは、対応金融機関の口座情報をOFXファイルとしてダウンロードできるサービスです。生成した電子明細をOFX対応マネー管理ソフトに取り込めます。
3 | 金融機関の非表示設定は、最大60日間、Cookieに保持されます。
4 |
12 | 銀行
13 |
14 | クレジットカード
15 |
16 | 証券
17 |
18 | 前払式帳票
19 |
20 | 金融機関の非表示設定
21 |
24 |
31 | バージョン情報
32 |
33 |
ブラウザーのJavaScriptが無効になっているため、表示できません。
34 |
35 |
--------------------------------------------------------------------------------
/client/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/outerguy/ofxproxy/89e0d8a08537897d628bc46ddf862452d39ee2df/client/icon.ico
--------------------------------------------------------------------------------
/client/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/outerguy/ofxproxy/89e0d8a08537897d628bc46ddf862452d39ee2df/client/icon.png
--------------------------------------------------------------------------------
/client/rule.css:
--------------------------------------------------------------------------------
1 | * {
2 | font-family: "メイリオ", "Meiryo", sans-serif;
3 | }
4 | body {
5 | width: 720px;
6 | border: 0px;
7 | padding: 0px;
8 | margin: 20px;
9 | color: #000000;
10 | background: #FFFFFF;
11 | cursor: default;
12 | }
13 | h1 {
14 | margin: 0px;
15 | color: #993300;
16 | background: transparent;
17 | }
18 | h2 {
19 | border: solid #993300;
20 | border-width: 0px 0px 2px 0px;
21 | margin: 1em 0px 0px 0px;
22 | color: #993300;
23 | background: transparent;
24 | }
25 | h3 {
26 | border: solid #FF9900;
27 | border-width: 2px 2px 0px 2px;
28 | margin: 1em 0px 0px 0px;
29 | color: #FFFFFF;
30 | background: #FF9900;
31 | text-indent: 0.5em;
32 | text-align: center;
33 | clear: both;
34 | }
35 | h3 a {
36 | color: #FFFFFF;
37 | background: transparent;
38 | }
39 | h4 {
40 | margin: 1em 0px 0px 0px;
41 | color: #CC6600;
42 | background: transparent;
43 | }
44 | p {
45 | margin: 0px;
46 | }
47 | p#debug {
48 | border: 0px;
49 | padding: 0.5em;
50 | margin: 0px;
51 | color: #FFFFFF;
52 | background: #FF0000;
53 | font-weight: bold;
54 | }
55 | p#wsofx {
56 | float: right;
57 | clear: right;
58 | }
59 | p.product {
60 | border: 0px;
61 | padding: 0px;
62 | margin: 8px 0px 0px 0px;
63 | font-weight: bold;
64 | }
65 | p.product a {
66 | border: 0px;
67 | padding: 0px;
68 | margin: 0px 8px 0px 0px;
69 | }
70 | div#addmsg {
71 | display: none;
72 | }
73 | code {
74 | color: #333333;
75 | background: transparent;
76 | font-family: monospace;
77 | line-height: 110%;
78 | }
79 | form.ofxform {
80 | border: solid 2px #FF9900;
81 | border-radius: 0px 0px 10px 10px;
82 | padding: 0px 0px 5px 0px;
83 | margin: 0px;
84 | color: #CC6600;
85 | background: #FFFFCC;
86 | }
87 | form.ofxform dl {
88 | padding: 0px 10px 0px 10px;
89 | }
90 | form.ofxform dt {
91 | float: left;
92 | clear: both;
93 | width: 160px;
94 | padding: 0.1em 0px 0.1em 0px;
95 | font-size: 80%;
96 | text-align: left;
97 | }
98 | form.ofxform dt:after {
99 | content: ":";
100 | }
101 | form.ofxform dd {
102 | margin-left: 160px;
103 | padding: 0.1em 0px 0.1em 10px;
104 | color: #000000;
105 | background: transparent;
106 | }
107 | form.ofxform dd input.ofxinput {
108 | width: 180px;
109 | }
110 | form.ofxform div.ofximage {
111 | float: right;
112 | position: relative;
113 | top: -45px;
114 | left: -10px;
115 | width: 320px;
116 | height: 40px;
117 | }
118 | form.ofxform div.ofximage input {
119 | cursor: pointer;
120 | }
121 | a img {
122 | border: 0px;
123 | }
124 |
--------------------------------------------------------------------------------
/client/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | OFXProxy
19 |
20 |
21 |
22 |
23 |
24 | OFXProxy
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/client/template.js:
--------------------------------------------------------------------------------
1 | /*
2 | template.js: 画面・機能を制御する
3 | Copyright (C) 2012-2015 OFFICE OUTERGUY. All rights reserved.
4 | mailto:contact@beatrek.com
5 | Dual-licensed under the GNU AGPLv3 and Beatrek Origin License.
6 | */
7 |
8 | // グローバル変数・定数を定義する
9 | var debug = "";
10 | var ver = ".";
11 | var family = "";
12 | var flag_ofxform = false;
13 |
14 | (function() {
15 | // 起動時にロード機能を呼び出す
16 | with(self.window) if(addEventListener) {
17 | addEventListener("load", fnc_load, true);
18 | } else if(attachEvent) {
19 | attachEvent("onload", fnc_load);
20 | } else {
21 | onload = fnc_load;
22 | }
23 |
24 | // Cookieを読み込む
25 | load_cookie_ofxform();
26 |
27 | // Cookieを書き込む
28 | save_cookie_ofxform();
29 |
30 | })();
31 |
32 |
33 | // =========================================================================
34 | // 機能
35 | // =========================================================================
36 |
37 | // ロード機能
38 | function fnc_load() {
39 | // バージョン情報を表示する
40 | var cdf = document.createDocumentFragment();
41 | var tag_body = dom_get_tag("body")[0];
42 | var title = dom_get_tag("title")[0].firstChild.nodeValue;
43 | var tag_div = dom_get_id("ver");
44 | var tag_p, tag_a;
45 |
46 | tag_p = dom_create_tag("p", { "class": "product" });
47 | tag_a = dom_create_tag("a", { "href": "https://github.com/outerguy/ofxproxy", "target": "_blank" });
48 | tag_a.appendChild(dom_create_text(title));
49 | tag_p.appendChild(tag_a);
50 | tag_p.appendChild(dom_create_text("Version " + ver));
51 | cdf.appendChild(tag_p);
52 |
53 | tag_p = dom_create_tag("p");
54 | tag_p.appendChild(dom_create_text("Copyright (C) 2008-2015 OFFICE OUTERGUY. All rights reserved."));
55 | cdf.appendChild(tag_p);
56 |
57 | tag_p = dom_create_tag("p");
58 | tag_p.appendChild(dom_create_text("Portions Copyright (C) 2012-2015 Hiromu2000. All rights reserved."));
59 | cdf.appendChild(tag_p);
60 |
61 | if(tag_div != null) with(tag_div) {
62 | while(hasChildNodes() == true) removeChild(lastChild);
63 | appendChild(cdf);
64 | }
65 |
66 | return;
67 | }
68 |
69 | function exec_ofxform(obj) {
70 | var ret = false;
71 | var fnc = function() {
72 | flag_ofxform = false;
73 |
74 | return;
75 | };
76 | with(obj) {
77 | if(flag_ofxform == true) {
78 | alert("明細のダウンロードを開始するまで、しばらくお待ちください。");
79 | } else {
80 | self.window.setTimeout(fnc, 2000);
81 | flag_ofxform = true;
82 | ret = true;
83 | }
84 | }
85 |
86 | return ret;
87 | }
88 |
89 | function link_ofxform(obj) {
90 | with(obj) target = parentNode.id;
91 |
92 | return true;
93 | }
94 |
95 | function help_ofxform(obj) {
96 | obj.target = "help_ofxform";
97 |
98 | return true;
99 | }
100 |
101 | function load_cookie_ofxform() {
102 | var cookies = self.document.cookie.split("; ");
103 | var i;
104 | for(i = 0; i < cookies.length; i++) {
105 | kvs = cookies[i].split("=", 2);
106 | if(dom_get_id(kvs[0])) {
107 | dom_get_id(kvs[0]).style.display = kvs[1];
108 | dom_get_id(kvs[0] + "_hide").checked = (kvs[1] == "none"? true: false);
109 | }
110 | }
111 |
112 | return;
113 | }
114 |
115 | function save_cookie_ofxform() {
116 | var tag_inputs = dom_get_tag("input");
117 | var expire = new Date();
118 | var i;
119 |
120 | expire.setTime(expire.getTime() + 86400000 * 60);
121 |
122 | for(i in tag_inputs) with(tag_inputs[i]) if(typeof type != "undefined" && type == "checkbox" && id != "all_hide") {
123 | self.document.cookie = id.replace("_hide", "") + "=" + (checked == true? "none": "block") + "; expires=" + expire.toUTCString();
124 | }
125 |
126 | return;
127 | }
128 |
129 |
130 | // =========================================================================
131 | // 関数
132 | // =========================================================================
133 |
134 | // DOMよりタグに合致するエレメントを取得する
135 | function dom_get_tag(name) {
136 | var obj = null;
137 |
138 | with(self.document) if(typeof getElementsByTagName != "undefined") try {
139 | if(typeof name == "string") obj = getElementsByTagName(name);
140 | } catch(e) {
141 | void(e);
142 | }
143 |
144 | return obj;
145 | }
146 |
147 | // DOMよりIDに合致するエレメントを取得する
148 | function dom_get_id(name) {
149 | var obj = null;
150 |
151 | with(self.document) if(typeof getElementById != "undefined") try {
152 | if(typeof name == "string") obj = getElementById(name);
153 | } catch(e) {
154 | void(e);
155 | }
156 |
157 | return obj;
158 | }
159 |
160 | // DOMのテキストを生成する
161 | function dom_create_text(text) {
162 | var obj = null;
163 |
164 | with(self.document) if(typeof createTextNode != "undefined") try {
165 | if(typeof text == "string") obj = createTextNode(dom_convert_escape(text));
166 | } catch(e) {
167 | void(e);
168 | }
169 |
170 | return obj;
171 | }
172 |
173 | // DOMのタグを生成する
174 | function dom_create_tag(name, attrs) {
175 | var obj = null;
176 | var i;
177 |
178 | with(self.document) if(typeof createElement != "undefined") try {
179 | if(typeof name == "string") obj = createElement(name);
180 | } catch(e) {
181 | void(e);
182 | }
183 |
184 | if(typeof attrs != "array") for(i in attrs) try {
185 | obj.setAttribute(i, dom_convert_escape(attrs[i]));
186 | } catch(e) {
187 | void(e);
188 | }
189 |
190 | return obj;
191 | }
192 |
193 | // DOMの特定文字をエスケープする
194 | function dom_convert_escape(str) {
195 | var ret = "";
196 | var buf = "";
197 | var hcs = { "amp": "&", "quot": "\"", "lt": "<", "gt": ">" };
198 | var fnc;
199 | var i;
200 |
201 | if(str.indexOf(hcs["amp"]) == -1) {
202 | ret = str;
203 | } else {
204 | fnc = function() {
205 | return hcs[arguments[1]];
206 | };
207 |
208 | for(i in hcs) buf += "|" + i;
209 | ret = str.replace(new RegExp(hcs["amp"] + "(" + buf.substring(1) + ");", "g"), fnc);
210 | }
211 |
212 | return ret;
213 | }
214 |
--------------------------------------------------------------------------------
/client/wsofx.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/outerguy/ofxproxy/89e0d8a08537897d628bc46ddf862452d39ee2df/client/wsofx.gif
--------------------------------------------------------------------------------
/common.inc:
--------------------------------------------------------------------------------
1 | fi as $fi) {
36 | $id = mb_htmlspecialchars((string)$fi["id"]);
37 | $settings[$id]["fiid"] = mb_htmlspecialchars((string)$id);
38 | $settings[$id]["type"] = mb_htmlspecialchars((string)$fi->type);
39 | $settings[$id]["name"] = mb_htmlspecialchars((string)$fi->name);
40 | $settings[$id]["home"] = mb_htmlspecialchars((string)$fi->home);
41 | if(isset($fi["code"]) == true) $settings[$id]["code"] = mb_htmlspecialchars((string)$fi["code"]);
42 | if(isset($fi->additional) == true) $settings[$id]["additional"] = mb_htmlspecialchars(implode("|", array((string)$fi->additional, (string)$fi->additional["input"], (string)$fi->additional["type"])));
43 | if(isset($fi->help) == true) $settings[$id]["help"] = preg_replace("/^[\r\n]*([\w\W]*?)<\/help>[\r\n]*$/", "\\1", $fi->help->asXML());
44 |
45 | $inputs = array();
46 | foreach($fi->form->input as $input) {
47 | array_push($inputs, mb_htmlspecialchars((string)$input["id"]));
48 | $settings[$id][(string)$input["id"]] = mb_htmlspecialchars(implode("|", array((string)$input, (string)$input["type"])));
49 | }
50 | $settings[$id]["form"] = implode("|", $inputs);
51 |
52 | if(isset($fi->itemlist) == true) foreach($fi->itemlist->item as $item) $settings[$id][(string)$item["id"]] = mb_htmlspecialchars((string)$item);
53 | }
54 |
55 | $ret = ($fiid != "" && isset($settings[$fiid]) == true? $settings[$fiid]: $settings);
56 |
57 | return $ret;
58 | }
59 |
60 | function mb_htmlspecialchars($str) {
61 | return htmlspecialchars($str, ENT_COMPAT | ENT_XML1, "UTF-8");
62 | }
63 |
64 | // $codeに合致するHTTP/1.1ステータスコードの文字列を取得する
65 | function get_http_status($code) {
66 | $status = "Unknown Status-code";
67 | switch((integer)$code) {
68 | // 100
69 | case 100:
70 | $status = "Continue";
71 | break;
72 | case 101:
73 | $status = "Switching Protocols";
74 | break;
75 | case 102:
76 | $status = "Processing";
77 | break;
78 | // 200
79 | case 200:
80 | $status = "OK";
81 | break;
82 | case 201:
83 | $status = "Created";
84 | break;
85 | case 202:
86 | $status = "Accepted";
87 | break;
88 | case 203:
89 | $status = "Non-Authoritative Information";
90 | break;
91 | case 204:
92 | $status = "No Content";
93 | break;
94 | case 205:
95 | $status = "Reset Content";
96 | break;
97 | case 206:
98 | $status = "Partial Content";
99 | break;
100 | case 207:
101 | $status = "Multi-Status";
102 | break;
103 | case 208:
104 | $status = "Already Reported";
105 | break;
106 | case 226:
107 | $status = "IM Used";
108 | break;
109 | // 300
110 | case 300:
111 | $status = "Multiple Choices";
112 | break;
113 | case 301:
114 | $status = "Moved Parmanently";
115 | break;
116 | case 302:
117 | $status = "Found";
118 | break;
119 | case 303:
120 | $status = "See Other";
121 | break;
122 | case 304:
123 | $status = "Not Modified";
124 | break;
125 | case 305:
126 | $status = "Use Proxy";
127 | break;
128 | case 306:
129 | $status = "(Unused)";
130 | break;
131 | case 307:
132 | $status = "Temporary Redirect";
133 | break;
134 | case 308:
135 | $status = "Permanent Redirect";
136 | break;
137 | // 400
138 | case 400:
139 | $status = "Bad Request";
140 | break;
141 | case 401:
142 | $status = "Unautorized";
143 | break;
144 | case 402:
145 | $status = "Payment Required";
146 | break;
147 | case 403:
148 | $status = "Forbidden";
149 | break;
150 | case 404:
151 | $status = "Not Found";
152 | break;
153 | case 405:
154 | $status = "Method Not Allowed";
155 | break;
156 | case 406:
157 | $status = "Not Acceptable";
158 | break;
159 | case 407:
160 | $status = "Proxy Authentication Required";
161 | break;
162 | case 408:
163 | $status = "Request Timeout";
164 | break;
165 | case 409:
166 | $status = "Conflict";
167 | break;
168 | case 410:
169 | $status = "Gone";
170 | break;
171 | case 411:
172 | $status = "Length Required";
173 | break;
174 | case 412:
175 | $status = "Precondition Failed";
176 | break;
177 | case 413:
178 | $status = "Request Entity Too Large";
179 | break;
180 | case 414:
181 | $status = "Request-URI Too Long";
182 | break;
183 | case 415:
184 | $status = "Unsupported Media Type";
185 | break;
186 | case 416:
187 | $status = "Requested Range Not Satisfiable";
188 | break;
189 | case 417:
190 | $status = "Expectation Failed";
191 | break;
192 | case 422:
193 | $status = "Unprocessable Entity";
194 | break;
195 | case 423:
196 | $status = "Locked";
197 | break;
198 | case 424:
199 | $status = "Failed Dependency";
200 | break;
201 | case 426:
202 | $status = "Upgrade Required";
203 | break;
204 | case 428:
205 | $status = "Precondition Required";
206 | break;
207 | case 429:
208 | $status = "Too Many Requests";
209 | break;
210 | case 431:
211 | $status = "Request Header Fields Too Large";
212 | break;
213 | // 500
214 | case 500:
215 | $status = "Internal Server Error";
216 | break;
217 | case 501:
218 | $status = "Not Implemented";
219 | break;
220 | case 502:
221 | $status = "Bad Gateway";
222 | break;
223 | case 503:
224 | $status = "Service Unavailable";
225 | break;
226 | case 504:
227 | $status = "Gateway Timeout";
228 | break;
229 | case 505:
230 | $status = "HTTP Version Not Supported";
231 | break;
232 | case 506:
233 | $status = "Variant Also Negotiates";
234 | break;
235 | case 507:
236 | $status = "Insufficient Storage";
237 | break;
238 | case 508:
239 | $status = "Loop Detected";
240 | break;
241 | case 510:
242 | $status = "Not Extended";
243 | break;
244 | case 511:
245 | $status = "Network Authentication Required";
246 | break;
247 | default:
248 | // 何もしない
249 | break;
250 | }
251 | return "HTTP/1.1 " . (string)$code . " " . $status;
252 | }
253 |
254 | ?>
255 |
--------------------------------------------------------------------------------
/common/ofx.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 |
15 | 0
INFOJPN
16 |
17 |
18 |
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 | ヘルプ\r\n";
48 | $str .= "" . $fis[$fiid]["name"] . "
\r\n";
49 | $str .= str_replace("h3", "h4", $fis[$fiid]["help"]);
50 | $str .= "\r\n";
51 | } else {
52 | // デバッグ機能が有効の場合、デバッグHTMLを取得する
53 | if(ENV_BOOL_DEBUG == true) $str .= file_get_contents(ENV_FILE_DIR_CLIENT . ENV_FILE_TEMPLATE_DEBUG);
54 |
55 | // ホームHTMLを取得する
56 | $str .= file_get_contents(ENV_FILE_DIR_CLIENT . ENV_FILE_TEMPLATE_HOME);
57 |
58 | // 埋め込み文字列を置換する
59 | $str = str_replace(array("", "", "", "", ""), array(trim(get_form($banks)), trim(get_form($creditcards)), trim(get_form($invstmts)), trim(get_form($prepaids)), trim(get_filist($fis))), $str);
60 | }
61 |
62 | $html = str_replace("", trim($str), $html);
63 |
64 | // レスポンスを返す
65 | header(get_http_status(ENV_NUM_STATUS_SUCCESS));
66 | header("Cache-Control: no-cache");
67 | header("Pragma: no-cache");
68 | header("Content-Type: text/html; charset=UTF-8");
69 | header("Content-Length: " . strlen($html));
70 | echo $html;
71 |
72 | ?>
73 |
--------------------------------------------------------------------------------
/index.txt:
--------------------------------------------------------------------------------
1 | PHP関数インデックス
2 |
3 | ■(boolean)env_dlog((string)$html, (string)$tag)
4 | 【説明】
5 | ENV_BOOL_DEBUGがtrueの場合、デバッグログを出力する。
6 |
7 | ■(array)get_fi_settings((string)$fiid = "") {
8 | 【説明】
9 | XMLファイルより$fiidセクションの定義を取得する。
10 |
11 | ■(string)mb_htmlspecialchars((string)$str)
12 | 【説明】
13 | 特殊文字をXHTMLエンティティーを変換する。
14 |
15 | ■(string)sess_encode((string)$str)
16 | 【説明】
17 | $strよりセッション保持用文字列を作成する。
18 |
19 | ■(string)sess_decode((string)$str)
20 | 【説明】
21 | セッション保持用文字列($str)より元データを取得する。
22 |
23 | ■(string)mb_convert_uniqueid((string)$str)
24 | 【説明】
25 | $strより32バイトの一意な文字列を生成する。
26 |
27 | ■(string)mb_convert_uniquename((string)$str)
28 | 【説明】
29 | 文字列を正規化する。
30 |
31 | ■(string)mb_convert_string((string)$str)
32 | 【説明】
33 | 文字エンコーディングをShift_JISからUTF-8へと変換する。
34 |
35 | ■class ofxDOM
36 | Copyright (C) 2012-2017 Hiromu Takahashi All Rights Reserved.
37 | mailto:hiromu2000@hotmail.com
38 |
39 | ■(string)parse_amount((string)$str)
40 | 【説明】
41 | 金額をパースする。
42 |
43 | ■(string)parse_date((string)$str)
44 | 【説明】
45 | 日付をパースする。
46 |
47 | ■(string)parse_param((string)$str)
48 | 【説明】
49 | フォーム経由で送受信されるパラメータをパースする。
50 | ※urlencode()やurldecode()で変換されない文字列も変換する。
51 |
52 | ■(array)parse_tag((string)$html, (string)$tag, (boolean)$recursive)
53 | 【説明】
54 | 指定された開始タグから終了タグまでのHTML、およびタグの属性を取得する。
55 | $recursiveがtrueの場合、タグの入れ子内部も再帰的に取得する。
56 | 【例】
57 | $html = "" . "
";
58 | $tag = "select";
59 | parse_tag($html, $tag) = array(2) {
60 | [0]=>
61 | array(3) {
62 | ["name"]=>
63 | string(3) "abc"
64 | ["class"]=>
65 | string(1) "x"
66 | ["innerHTML"]=>
67 | string(76) ""
68 | }
69 | [1]=>
70 | array(3) {
71 | ["name"]=>
72 | string(3) "def"
73 | ["class"]=>
74 | string(1) "Y"
75 | ["innerHTML"]=>
76 | string(73) ""
77 | }
78 | }
79 |
80 | ■(array)parse_tag_attributes((string)$html, (string)$tag)
81 | 【説明】
82 | 指定されたタグの属性を取得する。
83 | 【例】
84 | $html = "" . "";
85 | $tag = "input";
86 | parse_tag_attributes($html, $tag) = array(2) {
87 | [0]=>
88 | array(3) {
89 | ["type"]=>
90 | string(4) "text"
91 | ["name"]=>
92 | string(3) "abc"
93 | ["value"]=>
94 | string(0) ""
95 | }
96 | [1]=>
97 | array(3) {
98 | ["type"]=>
99 | string(6) "HIDDEN"
100 | ["name"]=>
101 | string(3) "def"
102 | ["value"]=>
103 | string(3) "xyz"
104 | }
105 | }
106 |
107 | ■(integer)parse_tag_search((array)$tags, (string)$key, (string)$value)
108 | 【説明】
109 | 指定されたタグ配列より属性が一致($key=$value)するタグの配列番号を取得する。
110 | 【例】
111 | $tags = array();
112 | $tags[0] = array("type" => "text", "name" => "abc", "value" => "", "innerHTML" => "");
113 | $tags[1] = array("type" => "hidden", "name" => "def", "value" => "xyz", "innerHTML" => "");
114 | $key = "name";
115 | $value = "def";
116 | parse_tag_search($tags, $key, $value) = int(1)
117 |
118 | ■(array)parse_header((string)$http, (string)$head)
119 | 【説明】
120 | $headに一致するHTTPヘッダーの配列を取得する。
121 |
122 | ■(array)parse_uri((string)$uri_next, (array)$uris = array())
123 | 【説明】
124 | $uri_nextを$urisからの絶対・相対パスURIとしてパースする。
125 | PHPの標準関数parse_url()と異なり、クエリーは"query"ではなく、"path"に含めて返却する。
126 | 【例】
127 | $uri_next = "../global.html?lang=en";
128 | $uris = array();
129 | $uris["scheme"] = "http";
130 | $uris["host"] = "www.example.com";
131 | $uris["path"] = "/japan/index.html";
132 | parse_uri($uri_next, $uris) = array(3) {
133 | ["scheme"]=>
134 | string(4) "http"
135 | ["host"]=>
136 | string(15) "www.example.com"
137 | ["path"]=>
138 | string(19) "/global.html?lang=en"
139 | }
140 |
141 | ■(array)parse_csv((string)$csv, (string)$delimiter = ",", (string)$enclosure = "\"")
142 | 【説明】
143 | CSV形式のデータをパースする。
144 |
145 | ■(string)http11((string)$method, (string)$protocol, (string)$host, (integer)$port = 0, (string)$page = "/", (string)$query = "", (string)$basic = "", (string)$cookie = "", (boolean)$autoconv = true, (string)$ua = ENV_PRODUCT_UA, (string)$fr = "", (string)$referer = "")
146 | 【説明】
147 | HTTP/1.1プロトコルでアクセスする。
148 |
149 | ■(string)http11_fread_blocking((resource)$fp, (integer)$len)
150 | 【説明】
151 | Chunkedのデータをfreadで読み込みする際、指定サイズ未満しか取得できない場合があるのを改善する。
152 |
153 | ■(string)update_cookie((array)$memories, (array)$heads, (string)$cookie)
154 | 【説明】
155 | $memoriesに存在するキーを$headsより探し、$cookieの値を更新する。
156 |
157 | ■(string)convert_ofx((string)$ofx)
158 | 【説明】
159 | OFX 1.0.2からOFX 2.1.1へと整形する。
160 |
161 | ■(string)generate_ofx((string)$status, (string)$str = ENV_STR_OFX_NODATA, (string)$cook = "", (string)$akey = "")
162 | 【説明】
163 | テンプレートよりOFX 2.1.1を生成する。
164 |
165 | ■(string)generate_html((string)$settings, (array)$resp)
166 | 【説明】
167 | テンプレートよりHTMLを生成する。
168 |
169 | ■(string)get_http_status((integer)$code)
170 | 【説明】
171 | $codeに合致するHTTP/1.1ステータスコードの文字列を取得する。
172 |
173 |
--------------------------------------------------------------------------------
/log/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/outerguy/ofxproxy/89e0d8a08537897d628bc46ddf862452d39ee2df/log/.gitkeep
--------------------------------------------------------------------------------
/php.ini:
--------------------------------------------------------------------------------
1 | [PHP]
2 | extension_dir = ".\ext";
3 | extension=php_mbstring.dll
4 | extension=php_openssl.dll
5 |
6 | [Date]
7 | date.timezone = "Asia/Tokyo"
8 |
--------------------------------------------------------------------------------
/php_mac.ini:
--------------------------------------------------------------------------------
1 | [Date]
2 | date.timezone = "Asia/Tokyo"
3 |
--------------------------------------------------------------------------------
/server.php:
--------------------------------------------------------------------------------
1 | 0) {
86 | header("Content-Length: " . (string)$n);
87 | echo $content;
88 | }
89 |
90 | ?>
91 |
--------------------------------------------------------------------------------
/server/chocom.inc:
--------------------------------------------------------------------------------
1 | 0) {
32 | $method = "GET";
33 | $uris = parse_uri($locations[0], $uris);
34 | $query = "";
35 | $cookie = chocom_update_cookie($head, $cookie);
36 | list($head, $body) = chocom_http11($method, $uris, $query, $cookie);
37 | }
38 | }
39 |
40 | // ログイン画面を取得する
41 | $as = parse_tag($body, "a");
42 | foreach($as as $a) if(parse_tag_search(parse_tag($a["innerHTML"], "img"), "alt", "会員ログイン") != -1) {
43 | $method = "GET";
44 | $uris = parse_uri($a["href"], $uris);
45 | $query = "";
46 | $cookie = chocom_update_cookie($head, $cookie);
47 | list($head, $body) = chocom_http11($method, $uris, $query, $cookie);
48 | break;
49 | }
50 |
51 | // リダイレクトする
52 | $scripts = parse_tag($body, "script");
53 | foreach($scripts as $script) if(preg_match("/location\.replace\(\'(.*?)\'/i", $script["innerHTML"], $matches) > 0) {
54 | $method = "GET";
55 | $uris = parse_uri($matches[1], $uris);
56 | $query = "";
57 | $cookie = chocom_update_cookie($head, $cookie);
58 | list($head, $body) = chocom_http11($method, $uris, $query, $cookie);
59 | break;
60 | }
61 |
62 | // ログインする
63 | $forms = parse_tag($body, "form");
64 | $c = parse_tag_search($forms, "name", "form1");
65 | if($c != -1) {
66 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
67 | $queries = array();
68 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
69 | $queries["MAILADDR"] = "MAILADDR=" . $user;
70 | $queries["TELEPHONE"] = "TELEPHONE=" . $tel;
71 | $queries["PASSWORD"] = "PASSWORD=" . $pass;
72 |
73 | $method = $forms[$c]["method"];
74 | $uris = parse_uri($forms[$c]["action"], $uris);
75 | $query = implode("&", $queries);
76 | $cookie = chocom_update_cookie($head, $cookie);
77 | list($head, $body) = chocom_http11($method, $uris, $query, $cookie);
78 | }
79 |
80 | if(strpos($body, "ログインすることが出来ませんでした") !== false) {
81 | // システムメンテナンス画面の場合
82 | $resp["status"] = ENV_NUM_STATUS_MAINTENANCE;
83 | $resp["method"] = $method;
84 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
85 | $resp["query"] = $query;
86 | $resp["cookie"] = $cookie;
87 | $resp["head"] = $head;
88 | $resp["body"] = $body;
89 | $resp["ofx"] = generate_ofx($resp["status"]);
90 | } else if(strpos($body, "ご利用履歴") === false) {
91 | // ログイン失敗の場合
92 | $resp["status"] = ENV_NUM_STATUS_FAILURE;
93 | $resp["method"] = $method;
94 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
95 | $resp["query"] = $query;
96 | $resp["cookie"] = $cookie;
97 | $resp["head"] = $head;
98 | $resp["body"] = $body;
99 | $resp["ofx"] = generate_ofx($resp["status"]);
100 | } else {
101 | // ログアウト画面を退避する
102 | $forms = parse_tag($body, "form");
103 | $c = parse_tag_search($forms, "name", "clickChecker");
104 | if($c != -1) {
105 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
106 | $queries = array();
107 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
108 | $queries["clickCounter"] = "clickCounter=1";
109 |
110 | $method_old = $forms[$c]["method"];
111 | $uris_old = parse_uri($forms[$c]["action"], $uris);
112 | $query_old = implode("&", $queries);
113 | }
114 |
115 | $account = array();
116 |
117 | $account["acctname"] = $settings["name"] . ENV_CHR_CONCATENATOR . $user;
118 |
119 | // 支店番号を取得する
120 | if(preg_match("/" . preg_quote("貯金箱番号") . "[\s\t]*([0-9]+)/", $body, $matches) > 0) $account["branchid"] = $matches[1];
121 |
122 | // 口座番号を取得する
123 | if(preg_match("/\.Com\-ID[\s\t]*([0-9]{4}\-[0-9]{4}\-[0-9]{4}\-[0-9]{4}\-[0-9]{4}\-[0-9])/", $body, $matches) > 0) $account["acctid"] = str_replace("-", "", $matches[1]);
124 |
125 | // 残高を取得する
126 | if(preg_match("/" . preg_quote("貯金箱残高") . "[\s\t]*:[\s\t]*([0-9]+)/", $body, $matches) > 0) $account["balance"] = parse_amount($matches[1]);
127 |
128 | // 履歴残高照会画面を取得する
129 | $as = parse_tag($body, "a");
130 | $c = parse_tag_search($as, "innerHTML", "履歴照会");
131 | if($c != -1) {
132 | $method = "GET";
133 | $uris = parse_uri($as[$c]["href"], $uris);
134 | $query = "";
135 | $cookie = chocom_update_cookie($head, $cookie);
136 | list($head, $body) = chocom_http11($method, $uris, $query, $cookie, false); // 文字コードを変換しない
137 | }
138 |
139 | // 履歴表示画面(1ページ目)を取得する
140 | $forms = parse_tag($body, "form");
141 | $c = parse_tag_search($forms, "name", "sForm");
142 | if($c != -1) {
143 | $queries = array();
144 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
145 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
146 | $selects = parse_tag($forms[$c]["innerHTML"], "select");
147 | foreach($selects as $select) {
148 | $options = parse_tag($select["innerHTML"], "option");
149 | foreach($options as $option) if($select["name"] != "" && $option["selected"] == "selected") $queries[$select["name"]] = urlencode($select["name"]) . "=" . urlencode($option["value"]);
150 | }
151 | $queries["yearStart"] = "yearStart=" . (string)(integer)substr(ENV_STR_DATE_PASTDAY, 0, 4);
152 | $queries["monthStart"] = "monthStart=" . (string)(integer)substr(ENV_STR_DATE_PASTDAY, 4, 2);
153 | $queries["dayStart"] = "dayStart=" . (string)(integer)substr(ENV_STR_DATE_PASTDAY, 6, 2);
154 | $queries["yearFinish"] = "yearFinish=" . (string)(integer)substr(ENV_STR_DATE_TODAY, 0, 4);
155 | $queries["monthFinish"] = "monthFinish=" . (string)(integer)substr(ENV_STR_DATE_TODAY, 4, 2);
156 | $queries["dayFinish"] = "dayFinish=" . (string)(integer)substr(ENV_STR_DATE_TODAY, 6, 2);
157 |
158 | $method = $forms[$c]["method"];
159 | $uris = parse_uri($forms[$c]["action"], $uris);
160 | $query = implode("&", $queries);
161 | $cookie = chocom_update_cookie($head, $cookie);
162 | list($head, $body) = chocom_http11($method, $uris, $query, $cookie, false); // 文字コードを変換しない
163 | }
164 |
165 | $account["details"] = chocom_get_details($body);
166 |
167 | // 履歴表示画面(2ページ目以降)を取得する
168 | while(parse_tag_search(parse_tag($body, "a"), "innerHTML", "以前の履歴") != -1) {
169 | $forms = parse_tag($body, "form");
170 | $c = parse_tag_search($forms, "name", "hisForm");
171 | if($c != -1) {
172 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
173 | $queries = array();
174 | foreach($inputs as $input) {
175 | switch($input["name"]) {
176 | case "":
177 | // 何もしない
178 | break;
179 | case "E2BURL":
180 | $forms[$c]["action"] = $input["value"];
181 | // breakしない
182 | default:
183 | $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
184 | break;
185 | }
186 | }
187 | $queries["REQ_PAGE"] = "REQ_PAGE=NEXT";
188 |
189 | $method = $forms[$c]["method"];
190 | $uris = parse_uri($forms[$c]["action"], $uris);
191 | $query = implode("&", $queries);
192 | $cookie = chocom_update_cookie($head, $cookie);
193 | list($head, $body) = chocom_http11($method, $uris, $query, $cookie, false); // 文字コードを変換しない
194 |
195 | $account["details"] = array_merge(chocom_get_details($body), $account["details"]);
196 | }
197 | }
198 |
199 | // 実行時間(タイムアウト)を再設定する
200 | @set_time_limit(ENV_NUM_TIMEOUT);
201 |
202 | // ログアウトする
203 | $method = $method_old;
204 | $uris = $uris_old;
205 | $query = $query_old;
206 | $cookie = chocom_update_cookie($head, $cookie);
207 | list($head, $body) = chocom_http11($method, $uris, $query, $cookie);
208 |
209 | // リダイレクトする
210 | $retry = 0;
211 | while($retry++ < ENV_NUM_HTTP11_RETRY) {
212 | $locations = parse_header($head, "location");
213 | if(count($locations) > 0) {
214 | $method = "GET";
215 | $uris = parse_uri($locations[0], $uris);
216 | $query = "";
217 | $cookie = chocom_update_cookie($head, $cookie);
218 | list($head, $body) = chocom_http11($method, $uris, $query, $cookie);
219 | }
220 | }
221 |
222 | // 実行時間(タイムアウト)を再設定する
223 | @set_time_limit(ENV_NUM_TIMEOUT);
224 |
225 | $bankmsgsrsv1 = "";
226 | $bankmsgsrsv1 .= "";
227 | $bankmsgsrsv1 .= "\r\n";
228 |
229 | // 口座情報を取得する
230 | $bankmsgsrsv1 .= "";
231 | $bankmsgsrsv1 .= "\r\n";
232 | $bankmsgsrsv1 .= "0";
233 | $bankmsgsrsv1 .= "\r\n";
234 | $bankmsgsrsv1 .= "0
INFO";
235 | $bankmsgsrsv1 .= "\r\n";
236 | $bankmsgsrsv1 .= "";
237 | $bankmsgsrsv1 .= "\r\n";
238 | $bankmsgsrsv1 .= "" . ENV_STR_OFX_CURRENCY_JPY . "";
239 | $bankmsgsrsv1 .= "\r\n";
240 | $bankmsgsrsv1 .= "";
241 | $bankmsgsrsv1 .= "" . $settings["code"] . "";
242 | $bankmsgsrsv1 .= "" . $account["branchid"] . "";
243 | $bankmsgsrsv1 .= "" . $account["acctid"] . "";
244 | $bankmsgsrsv1 .= "" . ENV_STR_ACCTTYPE_CHECKING . "";
245 | $bankmsgsrsv1 .= "";
246 | $bankmsgsrsv1 .= "\r\n";
247 | $bankmsgsrsv1 .= chocom_parse_details($account);
248 | $bankmsgsrsv1 .= "";
249 | $bankmsgsrsv1 .= "\r\n";
250 | $bankmsgsrsv1 .= "";
251 | $bankmsgsrsv1 .= "\r\n";
252 |
253 | $bankmsgsrsv1 .= "";
254 | $bankmsgsrsv1 .= "\r\n";
255 |
256 | // OFXファイルを出力する
257 | $resp["status"] = ENV_NUM_STATUS_SUCCESS;
258 | $resp["ofx"] = generate_ofx($resp["status"], $bankmsgsrsv1);
259 | }
260 | return $resp;
261 |
262 | // HTTP/1.1
263 | function chocom_http11($method, $uris, $query = "", $cookie = "", $autoconv = true) {
264 | $ret = "INVALID HOST";
265 | if(preg_match("/\.chocom\.(?:jp|net)$/", $uris["host"]) > 0) $ret = http11(strtoupper($method), $uris["scheme"], $uris["host"], 0, $uris["path"], $query, "", $cookie, $autoconv);
266 | return explode("\r\n\r\n", $ret, 2);
267 | }
268 |
269 | function chocom_update_cookie($head, $cookie) {
270 | return update_cookie(array("AlteonP", "JSESSIONID"), parse_header($head, "set-cookie"), $cookie);
271 | }
272 |
273 | function chocom_get_details($body) {
274 | $rets = array();
275 | $i = 0;
276 | $trs = parse_tag(mb_convert_string($body), "tr");
277 | foreach($trs as $tr) {
278 | $tds = parse_tag($tr["innerHTML"], "td");
279 | if(count($tds) == 6) {
280 | // 利用日付を取得する
281 | $rets[$i]["date"] = parse_date(trim(strip_tags($tds[0]["innerHTML"])));
282 |
283 | // ご利用先を取得する
284 | $name1 = str_replace(" ", "", trim(strip_tags($tds[1]["innerHTML"])));
285 | $name2 = str_replace(" ", "", trim(strip_tags($tds[3]["innerHTML"])));
286 | $rets[$i]["summary"] = ($name1 == "" || $name2 == ""? $name1 . $name2: implode(ENV_CHR_CONCATENATOR, array($name1, $name2)));
287 |
288 | // ご利用金額を取得する
289 | $rets[$i]["amount"] = parse_amount($tds[4]["innerHTML"]);
290 |
291 | $i++;
292 | }
293 | }
294 |
295 | return $rets;
296 | }
297 |
298 | function chocom_parse_details($account) {
299 | $ret = "";
300 | $cds = array();
301 | $cd_date = "";
302 | $cd_num = 0;
303 | foreach($account["details"] as $line) {
304 | $cd = array();
305 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_DIRECTDEBIT;
306 |
307 | // 日付を取得する
308 | $cd["DTPOSTED"] = $line["date"];
309 |
310 | // 通番を生成する
311 | if($cd["DTPOSTED"] == $cd_date) $cd_num++; else $cd_num = 0;
312 |
313 | // トランザクション番号を生成する
314 | $cd["FITID"] = $cd["DTPOSTED"] . "0000000" . sprintf("%05d", $cd_num);
315 |
316 | // 摘要を取得する
317 | $cd["NAME"] = $line["summary"];
318 |
319 | // 金額を取得する
320 | $cd["TRNAMT"] = parse_amount($line["amount"]);
321 | $cd["MEMO"] = ENV_STR_OFX_MEMO;
322 |
323 | array_push($cds, $cd);
324 | $cd_date = $cd["DTPOSTED"];
325 | }
326 | // BANKTRANLIST
327 | $ret .= "";
328 | $ret .= "\r\n";
329 | $ret .= "" . ENV_STR_DATE_PASTDAY . ENV_STR_OFX_TZ . "";
330 | $ret .= "" . ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ . "";
331 | $ret .= "\r\n";
332 |
333 | foreach($cds as $cd) {
334 | $ret .= "";
335 | $ret .= "" . $cd["TRNTYPE"] . "";
336 | $ret .= "" . $cd["DTPOSTED"] . ENV_STR_OFX_TZ . "";
337 | $ret .= "" . $cd["TRNAMT"] . "";
338 | $ret .= "" . $cd["FITID"] . "";
339 | $ret .= "" . $cd["NAME"] . "";
340 | $ret .= "" . $cd["MEMO"] . "";
341 | $ret .= "";
342 | $ret .= "\r\n";
343 | }
344 |
345 | $ret .= "";
346 | $ret .= "\r\n";
347 | $ret .= "";
348 | $ret .= "" . $account["balance"] . "";
349 | $ret .= "" . ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ . "";
350 | $ret .= "";
351 | $ret .= "\r\n";
352 |
353 | // 口座名称を出力する
354 | if($account["acctname"] != "") {
355 | $ret .= "" . $account["acctname"] . "";
356 | $ret .= "\r\n";
357 | }
358 |
359 | return $ret;
360 | }
361 |
362 | ?>
363 |
--------------------------------------------------------------------------------
/server/esaifu.inc:
--------------------------------------------------------------------------------
1 | 0) {
41 | $method = "GET";
42 | $uris = parse_uri($locations[0], $uris);
43 | $query = "";
44 | $cookie = esaifu_update_cookie($head, $cookie);
45 | list($head, $body) = esaifu_http11($method, $uris, $query, $cookie);
46 | }
47 | }
48 |
49 | // ログイン画面を取得する
50 | $as = parse_tag($body, "a");
51 | foreach($as as $a) if(parse_tag_search(parse_tag($a["innerHTML"], "img"), "alt", "会員ログイン)") != -1) {
52 | $method = "GET";
53 | $uris = parse_uri($a["href"], $uris);
54 | $query = "";
55 | $cookie = esaifu_update_cookie($head, $cookie);
56 | list($head, $body) = esaifu_http11($method, $uris, $query, $cookie);
57 | break;
58 | }
59 |
60 | // 画像認証の画像を取得する
61 | $imgs = parse_tag($body, "img");
62 | $c = parse_tag_search($imgs, "id", "siimage");
63 | if($c != -1) {
64 | $imguris = parse_uri($imgs[$c]["src"], $uris);
65 | list($imghead, $imgbody) = esaifu_http11($method, $imguris, $query, $cookie, $uris["scheme"] . "://" . $uris["host"] . $uris["path"] . $query);
66 | $imgsrc = "data:image/png;base64," . base64_encode($imgbody);
67 | }
68 |
69 | // ログインする
70 | $forms = parse_tag($body, "form");
71 | if(count($forms) > 0) {
72 | $inputs = parse_tag($forms[0]["innerHTML"], "input");
73 | $queries = array();
74 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
75 | $queries["user_id"] = "user_id=" . $user;
76 | $queries["password"] = "password=" . $pass;
77 | $queries["image_key"] = "image_key=";
78 |
79 | $method = $forms[0]["method"];
80 | $uris = parse_uri($forms[0]["action"], $uris);
81 | $query = implode("&", $queries);
82 | $cookie = esaifu_update_cookie($head, $cookie);
83 | }
84 |
85 | // セッションを退避する
86 | $sid = 1;
87 | $head = "";
88 | $body = "";
89 | } else if($sid == 1) {
90 | // セッションを復元する
91 | $sid = 0;
92 | $uris = parse_uri($uri);
93 | $query = str_replace("image_key=", "image_key=" . $auth, $query);
94 | list($head, $body) = esaifu_http11($method, $uris, $query, $cookie);
95 |
96 | // リダイレクトする
97 | $forms = parse_tag($body, "form");
98 | $c = parse_tag_search($forms, "id", "form1");
99 | if($c != -1) {
100 | $scripts = parse_tag($body, "script");
101 | foreach($scripts as $script) if(preg_match("/([\'\"])([^\\1]*?)\\1/i", $script["innerHTML"], $matches) > 0) {
102 | $forms[$c]["action"] = $matches[2];
103 |
104 | $method = $forms[$c]["method"];
105 | $uris = parse_uri($forms[$c]["action"], $uris);
106 | // $queryは一つ前のものを使い回す
107 | // $query = implode("&", $queries);
108 | $cookie = esaifu_update_cookie($head, $cookie);
109 | list($head, $body) = esaifu_http11($method, $uris, $query, $cookie);
110 | break;
111 | }
112 | }
113 |
114 | // リダイレクトする
115 | $retry = 0;
116 | while($retry++ < ENV_NUM_HTTP11_RETRY) {
117 | $locations = parse_header($head, "location");
118 | if(count($locations) > 0) {
119 | $method = "GET";
120 | $uris = parse_uri($locations[0], $uris);
121 | $query = "";
122 | $cookie = esaifu_update_cookie($head, $cookie);
123 | list($head, $body) = esaifu_http11($method, $uris, $query, $cookie);
124 | }
125 | }
126 | }
127 |
128 | if($sid > 0) {
129 | // セッションを引き継ぐ
130 | $resp["status"] = ENV_NUM_STATUS_ADDITION;
131 | $resp["aid"] = "image_key";
132 | $resp["additional"] = $imgsrc;
133 | $resp["sid"] = $sid;
134 | $resp["sesscookie"] = sess_encode(implode("\t", array($cookie, ENV_STR_SESSION_PADDING)));
135 | $resp["accesskey"] = sess_encode(implode("\t", array((string)$sid, $method, $uris["scheme"] . "://" . $uris["host"] . $uris["path"], $query, $user, ENV_STR_SESSION_PADDING)));
136 |
137 | $mfachallengetrnrs = "";
138 | $mfachallengetrnrs .= "";
139 | $mfachallengetrnrs .= "";
140 | $mfachallengetrnrs .= "";
141 | $mfachallengetrnrs .= "" . $resp["aid"] . "";
142 | $mfachallengetrnrs .= "" . $resp["additional"] . "";
143 | $mfachallengetrnrs .= "";
144 | $mfachallengetrnrs .= "";
145 | $mfachallengetrnrs .= "";
146 |
147 | $resp["ofx"] = generate_ofx($resp["status"], $mfachallengetrnrs, $resp["sesscookie"], $resp["accesskey"]);
148 | } else if(strpos($body, "eさいふ | メンテナンス中") !== false) {
149 | // システムメンテナンス画面の場合
150 | $resp["status"] = ENV_NUM_STATUS_MAINTENANCE;
151 | $resp["method"] = $method;
152 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
153 | $resp["query"] = $query;
154 | $resp["cookie"] = $cookie;
155 | $resp["head"] = $head;
156 | $resp["body"] = $body;
157 | $resp["ofx"] = generate_ofx($resp["status"]);
158 | } else if(strpos($body, "前回のご利用日時") === false) {
159 | // ログイン失敗の場合
160 | $resp["status"] = ENV_NUM_STATUS_FAILURE;
161 | $resp["method"] = $method;
162 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
163 | $resp["query"] = $query;
164 | $resp["cookie"] = $cookie;
165 | $resp["head"] = $head;
166 | $resp["body"] = $body;
167 | $resp["ofx"] = generate_ofx($resp["status"]);
168 | } else {
169 | $account = array();
170 |
171 | $account["acctname"] = $settings["name"];
172 |
173 | // 支店番号を取得する
174 | $account["branchid"] = "0";
175 |
176 | // 口座番号を取得する
177 | $account["acctid"] = $user;
178 |
179 | // 残高を取得する
180 | $ps = parse_tag($body, "p");
181 | $c = parse_tag_search($ps, "class", "price");
182 | if($c != -1) $account["balance"] = parse_amount(strip_tags($spans[0]["innerHTML"]));
183 |
184 | // 履歴画面を取得する
185 | $as = parse_tag($body, "a");
186 | $c = parse_tag_search($as, "innerHTML", "履歴");
187 | if($c != 1) {
188 | $method = "GET";
189 | $uris = parse_uri($as[$c]["href"], $uris);
190 | $query = "";
191 | $cookie = esaifu_update_cookie($head, $cookie);
192 | list($head, $body) = esaifu_http11($method, $uris, $query, $cookie);
193 | }
194 |
195 | // 履歴画面(1ページ目)を取得する
196 | $forms = parse_tag($body, "form");
197 | if(count($forms) > 0) {
198 | $queries = array();
199 | $inputs = parse_tag($forms[0]["innerHTML"], "input");
200 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
201 | $selects = parse_tag($forms[0]["innerHTML"], "select");
202 | foreach($selects as $select) {
203 | $options = parse_tag($select["innerHTML"], "option");
204 | foreach($options as $option) if($select["name"] != "" && $option["selected"] == "selected") $queries[$select["name"]] = urlencode($select["name"]) . "=" . urlencode($option["value"]);
205 | }
206 | $queries["user_year_from"] = "user_year_from=" . (string)(integer)substr(ENV_STR_DATE_PASTDAY, 0, 4);
207 | $queries["user_month_from"] = "user_month_from=" . (string)(integer)substr(ENV_STR_DATE_PASTDAY, 4, 2);
208 | $queries["user_day_from"] = "user_day_from=" . (string)(integer)substr(ENV_STR_DATE_PASTDAY, 6, 2);
209 | $queries["user_year_to"] = "user_year_to=" . (string)(integer)substr(ENV_STR_DATE_TODAY, 0, 4);
210 | $queries["user_month_to"] = "user_month_to=" . (string)(integer)substr(ENV_STR_DATE_TODAY, 4, 2);
211 | $queries["user_day_to"] = "user_day_to=" . (string)(integer)substr(ENV_STR_DATE_TODAY, 6, 2);
212 |
213 | $method = $forms[0]["method"];
214 | $uris = parse_uri($forms[0]["action"], $uris);
215 | $query = implode("&", $queries);
216 | $cookie = esaifu_update_cookie($head, $cookie);
217 | list($head, $body) = esaifu_http11($method, $uris, $query, $cookie);
218 | }
219 |
220 | $tbody = "";
221 |
222 | // 無限ループする
223 | while(true) {
224 | // 明細を取得する
225 | $tables = parse_tag($body, "table");
226 | $c = parse_tag_search($tables, "class", "only_pc");
227 | if($c != -1) {
228 | $tbodys = parse_tag($tables[$c]["innerHTML"], "tbody");
229 | if(count($tbodys) > 0) $tbody .= $tbodys[0]["innerHTML"];
230 | }
231 |
232 | // 履歴画面(2ページ目以降)を取得する
233 | $as = parse_tag($body, "a");
234 | $found = false;
235 | foreach($as as $a) {
236 | if(trim(strip_tags($a["innerHTML"])) == "次へ") {
237 | $method = "GET";
238 | $uris = parse_uri($a["href"], $uris);
239 | $query = "";
240 | $cookie = esaifu_update_cookie($head, $cookie);
241 | list($head, $body) = esaifu_http11($method, $uris, $query, $cookie);
242 |
243 | $found = true;
244 | break;
245 | }
246 | }
247 |
248 | // 見つからない場合、ループを抜ける
249 | if($found == false) break;
250 | }
251 |
252 | $account["details"] = esaifu_get_details($tbody);
253 |
254 | // 実行時間(タイムアウト)を再設定する
255 | @set_time_limit(ENV_NUM_TIMEOUT);
256 |
257 | // ログアウトする
258 | $as = parse_tag($body, "a");
259 | foreach($as as $a) if(strip_tags($a["innerHTML"]) == "ログアウト") {
260 | $method = "GET";
261 | $uris = parse_uri($a["href"], $uris);
262 | $query = "";
263 | $cookie = esaifu_update_cookie($head, $cookie);
264 | list($head, $body) = esaifu_http11($method, $uris, $query, $cookie);
265 | break;
266 | }
267 |
268 | // リダイレクトする
269 | $retry = 0;
270 | while($retry++ < ENV_NUM_HTTP11_RETRY) {
271 | $locations = parse_header($head, "location");
272 | if(count($locations) > 0) {
273 | $method = "GET";
274 | $uris = parse_uri($locations[0], $uris);
275 | $query = "";
276 | $cookie = esaifu_update_cookie($head, $cookie);
277 | list($head, $body) = esaifu_http11($method, $uris, $query, $cookie);
278 | }
279 | }
280 |
281 | // 実行時間(タイムアウト)を再設定する
282 | @set_time_limit(ENV_NUM_TIMEOUT);
283 |
284 | $bankmsgsrsv1 = "";
285 | $bankmsgsrsv1 .= "";
286 | $bankmsgsrsv1 .= "\r\n";
287 |
288 | // 口座情報を取得する
289 | $bankmsgsrsv1 .= "";
290 | $bankmsgsrsv1 .= "\r\n";
291 | $bankmsgsrsv1 .= "0";
292 | $bankmsgsrsv1 .= "\r\n";
293 | $bankmsgsrsv1 .= "0
INFO";
294 | $bankmsgsrsv1 .= "\r\n";
295 | $bankmsgsrsv1 .= "";
296 | $bankmsgsrsv1 .= "\r\n";
297 | $bankmsgsrsv1 .= "" . ENV_STR_OFX_CURRENCY_JPY . "";
298 | $bankmsgsrsv1 .= "\r\n";
299 | $bankmsgsrsv1 .= "";
300 | $bankmsgsrsv1 .= "" . $settings["code"] . "";
301 | $bankmsgsrsv1 .= "" . $account["branchid"] . "";
302 | $bankmsgsrsv1 .= "" . $account["acctid"] . "";
303 | $bankmsgsrsv1 .= "" . ENV_STR_ACCTTYPE_CHECKING . "";
304 | $bankmsgsrsv1 .= "";
305 | $bankmsgsrsv1 .= "\r\n";
306 | $bankmsgsrsv1 .= esaifu_parse_details($account);
307 | $bankmsgsrsv1 .= "";
308 | $bankmsgsrsv1 .= "\r\n";
309 | $bankmsgsrsv1 .= "";
310 | $bankmsgsrsv1 .= "\r\n";
311 |
312 | $bankmsgsrsv1 .= "";
313 | $bankmsgsrsv1 .= "\r\n";
314 |
315 | // OFXファイルを出力する
316 | $resp["status"] = ENV_NUM_STATUS_SUCCESS;
317 | $resp["ofx"] = generate_ofx($resp["status"], $bankmsgsrsv1);
318 | }
319 | return $resp;
320 |
321 | // HTTP/1.1
322 | function esaifu_http11($method, $uris, $query = "", $cookie = "", $referer = "") {
323 | $ret = "INVALID HOST";
324 | if(preg_match("/\.mun-prepaid\.com$/", $uris["host"]) > 0) $ret = http11(strtoupper($method), $uris["scheme"], $uris["host"], 0, $uris["path"], $query, "", $cookie, true, ENV_PRODUCT_UA, "", $referer);
325 | return explode("\r\n\r\n", $ret, 2);
326 | }
327 |
328 | function esaifu_update_cookie($head, $cookie) {
329 | return update_cookie(array("cookie_use_ok", "sslCookieUseOk", "vp_partner_id", "vp_session", "Nicos_pmk"), parse_header($head, "set-cookie"), $cookie);
330 | }
331 |
332 | function esaifu_get_details($body) {
333 | $rets = array();
334 | $i = 0;
335 | $trs = parse_tag($body, "tr");
336 | foreach($trs as $tr) {
337 | $tds = parse_tag($tr["innerHTML"], "td");
338 | if(count($tds) == 7) {
339 | // 利用日付を取得する
340 | $dt = explode(" ", $tds[1]["innerHTML"]);
341 | $rets[$i]["date"] = parse_date(trim(strip_tags($dt[0])));
342 |
343 | // ご利用種別、ご利用内容、およびお取引IDを取得する
344 | $buf = trim(strip_tags($tds[2]["innerHTML"]));
345 | switch($buf) {
346 | case "ご利用(予約)":
347 | $name = $buf;
348 | $memo = implode(ENV_CHR_CONCATENATOR, array(str_replace("カード下4桁 ", "", trim(strip_tags($tds[3]["innerHTML"]))), trim(strip_tags($tds[6]["innerHTML"]))));
349 | break;
350 | case "ご利用(確定)":
351 | list($name, $memo) = explode("
", $tds[3]["innerHTML"], 2);
352 | $name = trim(strip_tags($name));
353 | $memo = implode(ENV_CHR_CONCATENATOR, array(str_replace("カード下4桁 ", "", trim(strip_tags($memo))), trim(strip_tags($tds[6]["innerHTML"]))));
354 | break;
355 | default:
356 | $name = trim(strip_tags($tds[3]["innerHTML"]));
357 | $memo = $buf;
358 | break;
359 | }
360 | $rets[$i]["summary"] = $name;
361 | $rets[$i]["memo"] = $memo;
362 |
363 | // ご利用金額を取得する
364 | $rets[$i]["amount"] = parse_amount(strip_tags($tds[4]["innerHTML"]));
365 |
366 | $i++;
367 | }
368 | }
369 |
370 | return $rets;
371 | }
372 |
373 | function esaifu_parse_details($account) {
374 | $ret = "";
375 | $cds = array();
376 | $cd_date = "";
377 | $cd_num = 0;
378 | foreach($account["details"] as $line) {
379 | $cd = array();
380 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_DIRECTDEBIT;
381 |
382 | // 日付を取得する
383 | $cd["DTPOSTED"] = $line["date"];
384 |
385 | // 通番を生成する
386 | if($cd["DTPOSTED"] == $cd_date) $cd_num++; else $cd_num = 0;
387 |
388 | // トランザクション番号を生成する
389 | $cd["FITID"] = $cd["DTPOSTED"] . "0000000" . sprintf("%05d", $cd_num);
390 |
391 | // 摘要を取得する
392 | $cd["NAME"] = $line["summary"];
393 |
394 | // 金額を取得する
395 | $cd["TRNAMT"] = parse_amount($line["amount"]);
396 | $cd["MEMO"] = ($line["memo"] != ""? $line["memo"]: ENV_STR_OFX_MEMO);
397 |
398 | array_push($cds, $cd);
399 | $cd_date = $cd["DTPOSTED"];
400 | }
401 | // BANKTRANLIST
402 | $ret .= "";
403 | $ret .= "\r\n";
404 | $ret .= "" . ENV_STR_DATE_PASTDAY . ENV_STR_OFX_TZ . "";
405 | $ret .= "" . ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ . "";
406 | $ret .= "\r\n";
407 |
408 | foreach($cds as $cd) {
409 | $ret .= "";
410 | $ret .= "" . $cd["TRNTYPE"] . "";
411 | $ret .= "" . $cd["DTPOSTED"] . ENV_STR_OFX_TZ . "";
412 | $ret .= "" . $cd["TRNAMT"] . "";
413 | $ret .= "" . $cd["FITID"] . "";
414 | $ret .= "" . $cd["NAME"] . "";
415 | $ret .= "" . $cd["MEMO"] . "";
416 | $ret .= "";
417 | $ret .= "\r\n";
418 | }
419 |
420 | $ret .= "";
421 | $ret .= "\r\n";
422 | $ret .= "";
423 | $ret .= "" . $account["balance"] . "";
424 | $ret .= "" . ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ . "";
425 | $ret .= "";
426 | $ret .= "\r\n";
427 |
428 | // 口座名称を出力する
429 | if($account["acctname"] != "") {
430 | $ret .= "" . $account["acctname"] . "";
431 | $ret .= "\r\n";
432 | }
433 |
434 | return $ret;
435 | }
436 |
437 | ?>
438 |
--------------------------------------------------------------------------------
/server/jaccscard.inc:
--------------------------------------------------------------------------------
1 | 0) {
76 | $method = "GET";
77 | $uris = parse_uri($locations[0], $uris);
78 | $query = "";
79 | $cookie = jaccscard_update_cookie($head, $cookie);
80 | list($head, $body) = jaccscard_http11($method, $uris, $query, $cookie);
81 | }
82 | }
83 |
84 | if(strpos($body, "メンテナンスを行っております") !== false) {
85 | // システムメンテナンス画面の場合
86 | $resp["status"] = ENV_NUM_STATUS_MAINTENANCE;
87 | $resp["method"] = $method;
88 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
89 | $resp["query"] = $query;
90 | $resp["cookie"] = $cookie;
91 | $resp["head"] = $head;
92 | $resp["body"] = $body;
93 | $resp["ofx"] = generate_ofx($resp["status"]);
94 | } else if(strpos($body, "前回ログイン") === false) {
95 | // ログイン失敗の場合
96 | $resp["status"] = ENV_NUM_STATUS_FAILURE;
97 | $resp["method"] = $method;
98 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
99 | $resp["query"] = $query;
100 | $resp["cookie"] = $cookie;
101 | $resp["head"] = $head;
102 | $resp["body"] = $body;
103 | $resp["ofx"] = generate_ofx($resp["status"]);
104 | } else {
105 | $account = array();
106 |
107 | // 実行時間(タイムアウト)を再設定する
108 | @set_time_limit(ENV_NUM_TIMEOUT);
109 |
110 | // ご利用状況の確認画面を取得する
111 | $forms = parse_tag($body, "form");
112 | $c = parse_tag_search($forms, "name", "MainForm");
113 | if($c != -1) {
114 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
115 | $queries = array();
116 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
117 | $queries["_TRANID"] = "_TRANID=JAMY00001_01M"; // ご利用状況の確認
118 |
119 | $method = $forms[$c]["method"];
120 | $uris = parse_uri($forms[$c]["action"], $uris);
121 | $query = implode("&", $queries);
122 | $cookie = jaccscard_update_cookie($head, $cookie);
123 | list($head, $body) = jaccscard_http11($method, $uris, $query, $cookie);
124 | }
125 |
126 | // ご利用代金明細を見る画面を取得する
127 | $forms = parse_tag($body, "form");
128 | $c = parse_tag_search($forms, "name", "MainForm");
129 | if($c != -1) {
130 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
131 | $queries = array();
132 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
133 | $queries["_TRANID"] = "_TRANID=JAST00001_21M"; // ご利用代金明細を見る
134 | $queries["_SUBINDEX"] = "_SUBINDEX=0"; // (カードが複数枚存在する場合)最初のカード
135 |
136 | $method = $forms[$c]["method"];
137 | $uris = parse_uri($forms[$c]["action"], $uris);
138 | $query = implode("&", $queries);
139 | $cookie = jaccscard_update_cookie($head, $cookie);
140 | list($head, $body) = jaccscard_http11($method, $uris, $query, $cookie);
141 | }
142 |
143 | // お支払日を取得する
144 | $trs = parse_tag($body, "tr", true); // 再帰的に取得する
145 | $c = parse_tag_search($trs, "class", "first");
146 | if($c != -1) {
147 | $tds = parse_tag($trs[$c]["innerHTML"], "td");
148 | if(count($tds) >= 1) $account["paydate"] = parse_date(trim(str_replace("\t", "", $tds[0]["innerHTML"])));
149 | }
150 |
151 | // カード名・カード番号を取得する
152 | $dds = parse_tag($body, "dd");
153 | if(count($dds) >= 2) {
154 | $account["acctname"] = implode(ENV_CHR_CONCATENATOR, array($settings["name"], $dds[0]["innerHTML"]));
155 | $account["name"] = $settings["name"];
156 | $account["acctid"] = strip_tags(str_replace("∗", "*", $dds[1]["innerHTML"]));
157 | }
158 |
159 | $body_old = $body;
160 |
161 | // CSVファイルをダウンロードする
162 | $forms = parse_tag($body, "form");
163 | $c = parse_tag_search($forms, "name", "MainForm");
164 | if($c != -1) {
165 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
166 | $queries = array();
167 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
168 | $queries["_TRANID"] = "_TRANID=JAST00016_23C"; // 明細をCSVで保存する
169 |
170 | $method = $forms[$c]["method"];
171 | $uris = parse_uri($forms[$c]["action"], $uris);
172 | $query = implode("&", $queries);
173 | $cookie = jaccscard_update_cookie($head, $cookie);
174 | list($head, $body) = jaccscard_http11($method, $uris, $query, $cookie);
175 |
176 | if(strpos($head, "Content-Type: text/html") === false) {
177 | $creditcardmsgsrsv1 = "";
178 | $creditcardmsgsrsv1 .= "";
179 | $creditcardmsgsrsv1 .= "\r\n";
180 |
181 | $creditcardmsgsrsv1 .= "";
182 | $creditcardmsgsrsv1 .= "\r\n";
183 | $creditcardmsgsrsv1 .= "0";
184 | $creditcardmsgsrsv1 .= "\r\n";
185 | $creditcardmsgsrsv1 .= "0
INFO";
186 | $creditcardmsgsrsv1 .= "\r\n";
187 | $creditcardmsgsrsv1 .= "";
188 | $creditcardmsgsrsv1 .= "\r\n";
189 | $creditcardmsgsrsv1 .= "" . ENV_STR_OFX_CURRENCY_JPY . "";
190 | $creditcardmsgsrsv1 .= "\r\n";
191 | $creditcardmsgsrsv1 .= "";
192 | $creditcardmsgsrsv1 .= "" . $account["acctid"] . "";
193 | $creditcardmsgsrsv1 .= "";
194 | $creditcardmsgsrsv1 .= "\r\n";
195 | $creditcardmsgsrsv1 .= jaccscard_parse_csv($body, $account);
196 | $creditcardmsgsrsv1 .= "";
197 | $creditcardmsgsrsv1 .= "\r\n";
198 | $creditcardmsgsrsv1 .= "";
199 | $creditcardmsgsrsv1 .= "\r\n";
200 |
201 | $creditcardmsgsrsv1 .= "";
202 | $creditcardmsgsrsv1 .= "\r\n";
203 | }
204 |
205 | }
206 |
207 | $body = $body_old;
208 |
209 | // 実行時間(タイムアウト)を再設定する
210 | @set_time_limit(ENV_NUM_TIMEOUT);
211 |
212 | // ログアウトする
213 | $forms = parse_tag($body, "form");
214 | $c = parse_tag_search($forms, "name", "MainForm");
215 | if($c != -1) {
216 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
217 | $queries = array();
218 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
219 | $queries["_TRANID"] = "_TRANID=JALG00012_00M"; // ログアウト
220 |
221 | $method = $forms[$c]["method"];
222 | $uris = parse_uri($forms[$c]["action"], $uris);
223 | $query = implode("&", $queries);
224 | $cookie = jaccscard_update_cookie($head, $cookie);
225 | list($head, $body) = jaccscard_http11($method, $uris, $query, $cookie);
226 | }
227 |
228 | // OFXファイルを出力する
229 | $resp["status"] = ENV_NUM_STATUS_SUCCESS;
230 | if(strpos($creditcardmsgsrsv1, "") === false) {
231 | // 明細が存在しない場合
232 | $resp["ofx"] = generate_ofx($resp["status"]);
233 | } else {
234 | // 明細が存在する場合
235 | $resp["ofx"] = generate_ofx($resp["status"], $creditcardmsgsrsv1);
236 | }
237 | }
238 | return $resp;
239 |
240 | // HTTP/1.1
241 | function jaccscard_http11($method, $uris, $query = "", $cookie = "") {
242 | $ret = "INVALID HOST";
243 | if(preg_match("/\.jaccs\.co\.jp$/", $uris["host"]) > 0) $ret = http11(strtoupper($method), $uris["scheme"], $uris["host"], 0, $uris["path"], $query, "", $cookie);
244 | return explode("\r\n\r\n", $ret, 2);
245 | }
246 |
247 | function jaccscard_update_cookie($head, $cookie) {
248 | return update_cookie(array("JSESSIONID", "[0-9]{17}"), parse_header($head, "set-cookie"), $cookie);
249 | }
250 |
251 | function jaccscard_parse_csv($str, $account) {
252 | $ret = "";
253 | $lines = parse_csv(mb_convert_string($str));
254 | $cds = array();
255 | $cds_balamt = "0";
256 | $cds_paydate = $account["paydate"];
257 | $cds_s = "";
258 | $cds_e = "";
259 | $cd_date = "";
260 | $cd_num = 0;
261 | $ledge_balamt = 0;
262 | $flg = false;
263 |
264 | foreach($lines as $line) {
265 | $cd = array();
266 |
267 | if(count($line) == 2 && $line[0] == "(A)1回・2回・分割・ボーナス払の今回お支払金額小計") {
268 | // 今回お支払金額を取得する
269 | $cds_balamt = (string)((double)parse_amount($line[1]));
270 | } else if(count($line) == 13 && $line[1] == "<<次回以降のお支払明細>>") {
271 | // 次回以降のお支払明細を処理しない
272 | $flg = true;
273 | // break;
274 | } else if(count($line) == 13 && $line[0] != "ご利用年月日" && $line[0] != "" && $flg == false) {
275 | // PAYMENT固定とする
276 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_PAYMENT;
277 |
278 | // 日付を取得する
279 | $cd["DTPOSTED"] = parse_date($line[0]);
280 | if($cds_s == "") $cds_s = $cd["DTPOSTED"];
281 | $cds_e = $cd["DTPOSTED"];
282 |
283 | // 通番を生成する
284 | if($cd["DTPOSTED"] == $cd_date) $cd_num++; else $cd_num = 0;
285 |
286 | // トランザクション番号を生成する
287 | $cd["FITID"] = $cd["DTPOSTED"] . sprintf("%04d", $account["id"]) . substr($account["paydate"], 4, 2) . "0" . sprintf("%05d", $cd_num);
288 |
289 | // 摘要を取得する
290 | $cd["NAME"] = $line[1];
291 |
292 | // 金額を取得する
293 | $cd["TRNAMT"] = (string)(-1 * (double)parse_amount($line[7]));
294 |
295 | // 費目を取得する
296 | $cd["MEMO"] = ($line[12] != "未設定"? $line[12]: ENV_STR_OFX_MEMO);
297 |
298 | // 残高を取得する
299 | $ledge_balamt += (double)$cd["TRNAMT"];
300 |
301 | array_push($cds, $cd);
302 | $cd_date = $cd["DTPOSTED"];
303 | }
304 | }
305 |
306 | $ledge_balamt += (double)$cds_balamt;
307 |
308 | if($cds_s == "") $cds_s = ENV_STR_DATE_TODAY;
309 | if($cds_e == "") $cds_e = ENV_STR_DATE_TODAY;
310 | if($cds_s > $cds_e) $cds_e = $cds_s;
311 |
312 | // クレジットカード支払請求を明細に追加する
313 | $i = count($cds);
314 | $cds[$i]["DTPOSTED"] = $cds_paydate;
315 | $cds[$i]["NAME"] = $account["name"];
316 | $cds[$i]["MEMO"] = ENV_STR_OFX_MEMO;
317 | $cds[$i]["TRNAMT"] = $cds_balamt;
318 | $cds[$i]["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_DIRECTDEBIT;
319 | $cds[$i]["FITID"] = $cds[$i]["DTPOSTED"] . sprintf("%04d", $account["id"]) . substr($account["paydate"], 4, 2) . "100000";
320 |
321 | // BANKTRANLIST
322 | $ret .= "";
323 | $ret .= "\r\n";
324 | $ret .= "" . $cds_s . ENV_STR_OFX_TZ . "";
325 | $ret .= "" . $cds_e . ENV_STR_OFX_TZ . "";
326 | $ret .= "\r\n";
327 |
328 | foreach($cds as $cd) {
329 | $ret .= "";
330 | $ret .= "" . $cd["TRNTYPE"] . "";
331 | $ret .= "" . $cd["DTPOSTED"] . ENV_STR_OFX_TZ . "";
332 | $ret .= "" . $cd["TRNAMT"] . "";
333 | $ret .= "" . $cd["FITID"] . "";
334 | $ret .= "" . $cd["NAME"] . "";
335 | $ret .= "" . $cd["MEMO"] . "";
336 | $ret .= "";
337 | $ret .= "\r\n";
338 | }
339 |
340 | $ret .= "";
341 | $ret .= "\r\n";
342 |
343 | // 支払後残高を出力する
344 | $ret .= "";
345 | $ret .= "" . (string)$ledge_balamt . "";
346 | $ret .= "" . ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ . "";
347 | $ret .= "";
348 | $ret .= "\r\n";
349 |
350 | // カード名称を出力する
351 | if($account["acctname"] != "") {
352 | $ret .= "" . $account["acctname"] . "";
353 | $ret .= "\r\n";
354 | }
355 |
356 | return $ret;
357 | }
358 |
359 | ?>
360 |
--------------------------------------------------------------------------------
/server/mobilesuica.inc:
--------------------------------------------------------------------------------
1 | 0) {
76 | // セッションを引き継ぐ
77 | $resp["status"] = ENV_NUM_STATUS_ADDITION;
78 | $resp["aid"] = "WebCaptcha1__editor";
79 | $resp["additional"] = $imgsrc;
80 | $resp["sid"] = $sid;
81 | $resp["sesscookie"] = sess_encode(implode("\t", array($cookie, ENV_STR_SESSION_PADDING)));
82 | $resp["accesskey"] = sess_encode(implode("\t", array((string)$sid, $method, $uris["scheme"] . "://" . $uris["host"] . $uris["path"], $query, $user, ENV_STR_SESSION_PADDING)));
83 |
84 | $mfachallengetrnrs = "";
85 | $mfachallengetrnrs .= "";
86 | $mfachallengetrnrs .= "";
87 | $mfachallengetrnrs .= "";
88 | $mfachallengetrnrs .= "" . $resp["aid"] . "";
89 | $mfachallengetrnrs .= "" . $resp["additional"] . "";
90 | $mfachallengetrnrs .= "";
91 | $mfachallengetrnrs .= "";
92 | $mfachallengetrnrs .= "";
93 |
94 | $resp["ofx"] = generate_ofx($resp["status"], $mfachallengetrnrs, $resp["sesscookie"], $resp["accesskey"]);
95 | } else if(strpos($body, "SF(電子マネー)利用履歴") === false) {
96 | // ログイン失敗の場合
97 | $resp["status"] = ENV_NUM_STATUS_FAILURE;
98 | $resp["method"] = $method;
99 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
100 | $resp["query"] = $query;
101 | $resp["cookie"] = $cookie;
102 | $resp["head"] = $head;
103 | $resp["body"] = $body;
104 | $resp["ofx"] = generate_ofx($resp["status"]);
105 | } else {
106 | $account = array();
107 |
108 | $account["acctname"] = $settings["name"] . ENV_CHR_CONCATENATOR . $user;
109 |
110 | // 支店番号を取得する
111 | $account["branchid"] = "0";
112 |
113 | // 口座番号を取得する
114 | $account["acctid"] = $user;
115 |
116 | // 残高を取得する
117 | $account["balance"] = 0;
118 |
119 | // SF(電子マネー)利用履歴画面を取得する
120 | $as = parse_tag($body, "a");
121 | foreach($as as $a) if(parse_tag_search(parse_tag($a["innerHTML"], "img"), "alt", "SF(電子マネー)利用履歴") != -1) {
122 | $method = "POST";
123 | if(preg_match("/javascript:[^\']+?\'([^\']+)\'.*?/i", $a["href"], $matches) > 0) $uris = parse_uri($matches[1], $uris);
124 | $query = "";
125 | $cookie = mobilesuica_update_cookie($head, $cookie);
126 | list($head, $body) = mobilesuica_http11($method, $uris, $query, $cookie);
127 | break;
128 | }
129 |
130 | $account["details"] = array();
131 | $tables = parse_tag($body, "table", true); // 再帰的に取得する
132 | foreach($tables as $table) if($table["cellpadding"] == "8") {
133 | $account["details"] = mobilesuica_get_details($table["innerHTML"]);
134 | $detail = array_shift($account["details"]);
135 | $account["balance"] = $detail["amount"];
136 | }
137 |
138 | // SuicaID番号を取得する
139 | $forms = parse_tag($body, "form", true); // 再帰的に取得する
140 | $c = parse_tag_search($forms, "name", "form1");
141 | if($c != -1) {
142 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
143 | $queries = array();
144 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
145 | $selects = parse_tag($forms[$c]["innerHTML"], "select");
146 | foreach($selects as $select) {
147 | $options = parse_tag($select["innerHTML"], "option");
148 | foreach($options as $option) if($select["name"] != "" && $option["selected"] == "selected") $queries[$select["name"]] = urlencode($select["name"]) . "=" . urlencode($option["value"]);
149 | }
150 | $queries["baseVarCopy"] = "baseVarCopy=" . substr($queries["baseVariable"], strpos($queries["baseVariable"], "=") + 1);
151 | if($queries["SEARCH"] != "") unset($queries["SEARCH"]);
152 | if($queries["RETURNMENU"] != "") unset($queries["RETURNMENU"]);
153 |
154 | $method = $forms[$c]["method"];
155 | $uris = parse_uri($forms[$c]["action"], $uris);
156 | $query = implode("&", $queries);
157 | $cookie = mobilesuica_update_cookie($head, $cookie);
158 | list($head, $body) = mobilesuica_http11($method, $uris, $query, $cookie);
159 |
160 | $contentdispositions = parse_header($head, "content-disposition");
161 | if(count($contentdispositions) > 0) {
162 | $account["acctid"] = substr($contentdispositions[0], strpos($contentdispositions[0], "=") + 1, 17);
163 | }
164 |
165 | }
166 |
167 | // 実行時間(タイムアウト)を再設定する
168 | @set_time_limit(ENV_NUM_TIMEOUT);
169 |
170 | // ログアウトする
171 | $method = "POST";
172 | $uris = parse_uri("/ka/lg/LogoutComplete.aspx", $uris);
173 | $query = "";
174 | $cookie = mobilesuica_update_cookie($head, $cookie);
175 | list($head, $body) = mobilesuica_http11($method, $uris, $query, $cookie);
176 |
177 | // 実行時間(タイムアウト)を再設定する
178 | @set_time_limit(ENV_NUM_TIMEOUT);
179 |
180 | $bankmsgsrsv1 = "";
181 | $bankmsgsrsv1 .= "";
182 | $bankmsgsrsv1 .= "\r\n";
183 |
184 | // 口座情報を取得する
185 | $bankmsgsrsv1 .= "";
186 | $bankmsgsrsv1 .= "\r\n";
187 | $bankmsgsrsv1 .= "0";
188 | $bankmsgsrsv1 .= "\r\n";
189 | $bankmsgsrsv1 .= "0
INFO";
190 | $bankmsgsrsv1 .= "\r\n";
191 | $bankmsgsrsv1 .= "";
192 | $bankmsgsrsv1 .= "\r\n";
193 | $bankmsgsrsv1 .= "" . ENV_STR_OFX_CURRENCY_JPY . "";
194 | $bankmsgsrsv1 .= "\r\n";
195 | $bankmsgsrsv1 .= "";
196 | $bankmsgsrsv1 .= "" . $settings["code"] . "";
197 | $bankmsgsrsv1 .= "" . $account["branchid"] . "";
198 | $bankmsgsrsv1 .= "" . $account["acctid"] . "";
199 | $bankmsgsrsv1 .= "" . ENV_STR_ACCTTYPE_CHECKING . "";
200 | $bankmsgsrsv1 .= "";
201 | $bankmsgsrsv1 .= "\r\n";
202 | $bankmsgsrsv1 .= mobilesuica_parse_details($account);
203 | $bankmsgsrsv1 .= "";
204 | $bankmsgsrsv1 .= "\r\n";
205 | $bankmsgsrsv1 .= "";
206 | $bankmsgsrsv1 .= "\r\n";
207 |
208 | $bankmsgsrsv1 .= "";
209 | $bankmsgsrsv1 .= "\r\n";
210 |
211 | // OFXファイルを出力する
212 | $resp["status"] = ENV_NUM_STATUS_SUCCESS;
213 | $resp["ofx"] = generate_ofx($resp["status"], $bankmsgsrsv1);
214 | }
215 | return $resp;
216 |
217 | // HTTP/1.1
218 | function mobilesuica_http11($method, $uris, $query = "", $cookie = "", $referer = "", $autoconv = true) {
219 | $ret = "INVALID HOST";
220 | if(preg_match("/\.mobilesuica\.com$/", $uris["host"]) > 0) $ret = http11(strtoupper($method), $uris["scheme"], $uris["host"], 0, $uris["path"], $query, "", $cookie, $autoconv, ENV_PRODUCT_UA . " MSIE 7.0", "", $referer); // ログイン時にUser-Agentをチェックされる
221 | return explode("\r\n\r\n", $ret, 2);
222 | }
223 |
224 | function mobilesuica_update_cookie($head, $cookie) {
225 | return update_cookie(array("ASP.NET_SessionId", "sc_auth"), parse_header($head, "set-cookie"), $cookie);
226 | }
227 |
228 | function mobilesuica_get_details($body) {
229 | $rets = array();
230 | $trs = parse_tag($body, "tr");
231 | array_shift($trs);
232 | $i = count($trs) - 1;
233 | $prev = "";
234 | $last = "";
235 | foreach($trs as $tr) {
236 | $tds = parse_tag($tr["innerHTML"], "td");
237 | if(count($tds) == 7) {
238 | // 日時を取得する
239 | $dt = trim(str_replace("/", "", strip_tags($tds[0]["innerHTML"])));
240 | if($dt > substr(ENV_STR_DATE_TODAY, 4, 4)) {
241 | $dt = (string)((integer)substr(ENV_STR_DATE_TODAY, 0, 4) - 1) . $dt;
242 | } else {
243 | $dt = substr(ENV_STR_DATE_TODAY, 0, 4) . $dt;
244 | }
245 |
246 | // 取引種別、および場所を取得する
247 | $class1 = mobilesuica_parse_string($tds[1]["innerHTML"]);
248 | $place1 = mobilesuica_parse_string($tds[2]["innerHTML"]);
249 | $class2 = mobilesuica_parse_string($tds[3]["innerHTML"]);
250 | $place2 = mobilesuica_parse_string($tds[4]["innerHTML"]);
251 |
252 | $name = $class1 . $class2;
253 | $memo = $place1;
254 | if($place2 != "") $memo .= "-" . $place2;
255 | if($memo == "") $memo = ENV_STR_OFX_MEMO;
256 |
257 | // 収支を計算する
258 | $amount = mobilesuica_parse_string($tds[6]["innerHTML"]);
259 |
260 | // 残高を取得する
261 | if($last == "") $last = parse_amount(str_replace("¥", "", trim(strip_tags($tds[5]["innerHTML"]))));
262 |
263 | $rets[$i]["date"] = $dt;
264 | $rets[$i]["summary"] = $name;
265 | $rets[$i]["amount"] = $amount;
266 | $rets[$i]["memo"] = $memo;
267 |
268 | $i--;
269 | }
270 | }
271 | $rets[0]["amount"] = $last;
272 |
273 | // 戻り値の配列の先頭が残高となる(明細としては無効)
274 | return array_reverse($rets);
275 | }
276 |
277 | function mobilesuica_parse_string($str) {
278 | return trim(mb_convert_kana(strip_tags($str), "sKV", "UTF-8"));
279 | }
280 |
281 | function mobilesuica_parse_details($account) {
282 | $ret = "";
283 | $cds = array();
284 | $cd_date = "";
285 | $cd_num = 0;
286 | $dtstart = ENV_STR_DATE_PASTDAY;
287 | foreach($account["details"] as $line) {
288 | if($dtstart > $line["date"]) $dtstart = $line["date"];
289 |
290 | $cd = array();
291 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_DIRECTDEBIT;
292 |
293 | // 日付を取得する
294 | $cd["DTPOSTED"] = $line["date"];
295 |
296 | // 通番を生成する
297 | if($cd["DTPOSTED"] == $cd_date) $cd_num++; else $cd_num = 0;
298 |
299 | // トランザクション番号を生成する
300 | $cd["FITID"] = $cd["DTPOSTED"] . "0000000" . sprintf("%05d", $cd_num);
301 |
302 | // 摘要を取得する
303 | $cd["NAME"] = $line["summary"];
304 |
305 | // 金額を取得する
306 | $cd["TRNAMT"] = parse_amount($line["amount"]);
307 | $cd["MEMO"] = ($line["memo"] != ""? $line["memo"]: ENV_STR_OFX_MEMO);
308 |
309 | array_push($cds, $cd);
310 | $cd_date = $cd["DTPOSTED"];
311 | }
312 | // BANKTRANLIST
313 | $ret .= "";
314 | $ret .= "\r\n";
315 | $ret .= "" . $dtstart . ENV_STR_OFX_TZ . "";
316 | $ret .= "" . ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ . "";
317 | $ret .= "\r\n";
318 |
319 | foreach($cds as $cd) {
320 | $ret .= "";
321 | $ret .= "" . $cd["TRNTYPE"] . "";
322 | $ret .= "" . $cd["DTPOSTED"] . ENV_STR_OFX_TZ . "";
323 | $ret .= "" . $cd["TRNAMT"] . "";
324 | $ret .= "" . $cd["FITID"] . "";
325 | $ret .= "" . $cd["NAME"] . "";
326 | $ret .= "" . $cd["MEMO"] . "";
327 | $ret .= "";
328 | $ret .= "\r\n";
329 | }
330 |
331 | $ret .= "";
332 | $ret .= "\r\n";
333 | $ret .= "";
334 | $ret .= "" . $account["balance"] . "";
335 | $ret .= "" . ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ . "";
336 | $ret .= "";
337 | $ret .= "\r\n";
338 |
339 | // 口座名称を出力する
340 | if($account["acctname"] != "") {
341 | $ret .= "" . $account["acctname"] . "";
342 | $ret .= "\r\n";
343 | }
344 |
345 | return $ret;
346 | }
347 |
348 | ?>
349 |
--------------------------------------------------------------------------------
/server/mufgcard.inc:
--------------------------------------------------------------------------------
1 | 0) {
74 | $method = "GET";
75 | $uris = parse_uri($locations[0], $uris);
76 | $query = "";
77 | $cookie = mun_update_cookie($head, $cookie);
78 | list($head, $body) = mun_http11($method, $uris, $query, $cookie);
79 | }
80 | }
81 |
82 | $as = parse_tag($body, "a");
83 | foreach($as as $a) {
84 | switch(trim(strip_tags($a["innerHTML"]))) {
85 | case "ログアウト":
86 | // ログアウト画面を退避する(NEWS+PLUS)
87 | $method_mun = "GET";
88 | $uris_mun = parse_uri($a["href"], $uris);
89 | $query_mun = "";
90 | $cookie_mun = $cookie;
91 | break;
92 | case "WEBサービストップ":
93 | // WEBサービストップ画面を取得する(NEWS+PLUS)
94 | $method = "GET";
95 | $uris = parse_uri($a["href"], $uris);
96 | $query = "";
97 | $cookie = mun_update_cookie($head, $cookie);
98 | list($head, $body) = mun_http11($method, $uris, $query, $cookie);
99 | break;
100 | default:
101 | break;
102 | }
103 | }
104 |
105 | // 以降は各カードブランドの画面に遷移する
106 | $cookie = "";
107 |
108 | // 実行時間(タイムアウト)を再設定する
109 | @set_time_limit(ENV_NUM_TIMEOUT);
110 |
111 | // ログインする
112 | $forms = parse_tag($body, "form");
113 | $c = parse_tag_search($forms, "id", "seamlessForm");
114 | if($c != -1) {
115 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
116 | $queries = array();
117 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
118 |
119 | $method = $forms[$c]["method"];
120 | $uris = parse_uri($forms[$c]["action"], $uris);
121 | $query = implode("&", $queries);
122 | $cookie = mufgcard_updatecookie($head, $cookie);
123 | list($head, $body) = mufgcard_http11($method, $uris["scheme"], $uris["host"], $uris["path"], $query, $cookie);
124 | }
125 |
126 | // リダイレクトする
127 | $retry = 0;
128 | while($retry++ < ENV_NUM_HTTP11_RETRY) {
129 | $locations = parse_header($head, "location");
130 | if(count($locations) > 0) {
131 | $method = "GET";
132 | $uris = parse_uri($locations[0], $uris);
133 | $query = "";
134 | $cookie = mufgcard_updatecookie($head, $cookie);
135 | list($head, $body) = mufgcard_http11($method, $uris["scheme"], $uris["host"], $uris["path"], $query, $cookie);
136 | }
137 | }
138 |
139 | if(strpos($body, "現在サービス停止中") !== false || strpos($body, "システムメンテナンスのため") !== false) {
140 | // システムメンテナンス画面の場合
141 | $resp["status"] = ENV_NUM_STATUS_MAINTENANCE;
142 | $resp["method"] = $method;
143 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
144 | $resp["query"] = $query;
145 | $resp["cookie"] = $cookie;
146 | $resp["head"] = $head;
147 | $resp["body"] = $body;
148 | $resp["ofx"] = generate_ofx($resp["status"]);
149 | } else if(strpos($body, "前回ログイン") === false) {
150 | // ログイン失敗の場合
151 | $resp["status"] = ENV_NUM_STATUS_FAILURE;
152 | $resp["method"] = $method;
153 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
154 | $resp["query"] = $query;
155 | $resp["cookie"] = $cookie;
156 | $resp["head"] = $head;
157 | $resp["body"] = $body;
158 | $resp["ofx"] = generate_ofx($resp["status"]);
159 | } else {
160 | // ログアウト画面を退避する
161 | $uris_old = parse_uri("/inet/dy/logout.html", $uris);
162 |
163 | // 請求額・利用明細照会
164 | $method = "GET";
165 | $uris = parse_uri("/inet/dy/meisaisyokai/index.html", $uris);
166 | $query = "";
167 | $cookie = mufgcard_updatecookie($head, $cookie);
168 | list($head, $body) = mufgcard_http11($method, $uris["scheme"], $uris["host"], $uris["path"], $query, $cookie);
169 |
170 | $tables = parse_tag($body, "table");
171 | $tds = parse_tag($tables[0]["innerHTML"], "td");
172 | // カード名称を取得する
173 | $account["acctname"] = implode(ENV_CHR_CONCATENATOR, array($settings["name"], $tds[1]["innerHTML"]));
174 |
175 | // カード番号を取得する
176 | if(preg_match("/XXXX-([0-9X]{4})/", $tds[2]["innerHTML"], $matches) > 0) {
177 | $account["acctid"] = $matches[1];
178 | }
179 |
180 | // お支払日を取得する
181 | $tds = parse_tag($tables[1]["innerHTML"], "td");
182 | $account["paydate"] = parse_date($tds[1]["innerHTML"]);
183 |
184 | // 今回ご請求合計額を取得する
185 | $account["ledge_balamt"] = 0;
186 | for( $i = 0 ; $i < 3 ; $i++ ) {
187 | $tmp = parse_amount($tds[2+$i*4]["innerHTML"]);
188 | $account["ledge_balamt"] += (-1)*$tmp;
189 | }
190 |
191 | // 実行時間(タイムアウト)を再設定する
192 | @set_time_limit(ENV_NUM_TIMEOUT);
193 |
194 | $bodies = array();
195 | // カード・照会月を選択する
196 | $as = parse_tag($body, "a");
197 | foreach($as as $a){
198 | if(preg_match("/.*detail.*/", $a["href"])) {
199 | $method = "GET";
200 | $uris = parse_uri($a["href"], $uris);
201 | $cookie = mufgcard_updatecookie($head, $cookie);
202 | list($head, $body) = mufgcard_http11($method, $uris["scheme"], $uris["host"], $uris["path"], $uris["query"], $cookie);
203 | array_push($bodies, $body);
204 | while(preg_match("/.*next\.html.*/", $body)) {
205 | $forms = parse_tag($body, "form");
206 | $c = parse_tag_search($forms, "action", "/inet/dy/meisaisyokai/next.html#meisai");
207 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
208 | $queries = array();
209 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
210 |
211 | $method = $forms[$c]["method"];
212 | $uris = parse_uri($forms[$c]["action"], $uris);
213 | $query = implode("&", $queries);
214 | $cookie = mufgcard_updatecookie($head, $cookie);
215 | list($head, $body) = mufgcard_http11($method, $uris["scheme"], $uris["host"], $uris["path"], $query, $cookie);
216 | array_push($bodies, $body);
217 | }
218 | }
219 | }
220 |
221 | // DOMツリーを生成
222 | $ofxdom = new ofxDOM("CREDITCARD", $account["acctname"]);
223 | $ofxdom->setAcctfrom(array("ACCTID" => $account["acctid"]));
224 |
225 | // 明細をパース
226 | $cds = array();
227 | foreach($bodies as $body){
228 | $cds_tmp = mufgcard_parsedom($body);
229 | if ($cds_tmp != false) {
230 | $cds = array_merge($cds, $cds_tmp);
231 | }
232 | }
233 | usort($cds, function($a, $b) {
234 | return $a['DTPOSTED'] > $b['DTPOSTED'];
235 | });
236 | foreach($cds as $cd) {
237 | $ofxdom->addTran($cd);
238 | }
239 |
240 | $cds_s = "";
241 | $cds_e = "";
242 | $items = $ofxdom->getTrans();
243 | foreach ($items as $item) {
244 | $dtposted = $item->DTPOSTED;
245 | // DTSTART, DTENDを取得
246 | if($cds_s == "") $cds_s = $dtposted;
247 | $cds_e = $dtposted;
248 | }
249 |
250 | // DTSTARTとDTENDを設定する
251 | $ofxdom->setDateRange($cds_s, $cds_e);
252 |
253 | // 残高を処理
254 | $account["ledge_balamt"] = parse_amount($account["ledge_balamt"]);
255 | $ofxdom->setBalance(array(
256 | 'BALAMT' => $account["ledge_balamt"],
257 | 'DTASOF' => ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ
258 | ));
259 |
260 | // FITIDを仕上げる
261 | $ofxdom->setFitid();
262 | // XML DOMツリーを文字列に変換
263 | $xml = $ofxdom->getXML();
264 |
265 | $resp["status"] = ENV_NUM_STATUS_SUCCESS;
266 | $resp["ofx"] = generate_ofx($resp["status"], $xml);
267 |
268 | // 実行時間(タイムアウト)を再設定する
269 | @set_time_limit(ENV_NUM_TIMEOUT);
270 |
271 | // ログアウトする
272 | $method = "GET";
273 | $uris = $uris_old;
274 | $query = "";
275 | $cookie = mufgcard_updatecookie($head, $cookie);
276 | list($head, $body) = mufgcard_http11($method, $uris["scheme"], $uris["host"], $uris["path"], $query, $cookie);
277 |
278 | // ログアウトする(NEWS+PLUS)
279 | $method = $method_mun;
280 | $uris = $uris_mun;
281 | $query = $query_mun;
282 | $cookie = $cookie_mun;
283 | list($head, $body) = mun_http11($method, $uris, $query, $cookie);
284 | }
285 | return $resp;
286 |
287 | // HTTP/1.1(NEWS+PLUS)
288 | function mun_http11($method, $uris, $query = "", $cookie = "") {
289 | $ret = "INVALID HOST";
290 | if(preg_match("/\.cr\.mufg\.jp$/", $uris["host"]) > 0) $ret = http11(strtoupper($method), $uris["scheme"], $uris["host"], 0, $uris["path"], $query, "", $cookie);
291 | return explode("\r\n\r\n", $ret, 2);
292 | }
293 |
294 | function mun_update_cookie($head, $cookie) {
295 | return update_cookie(array("PHPSESSID", "session-srv", "m_cardBrand"), parse_header($head, "set-cookie"), $cookie);
296 | }
297 |
298 | // HTTP/1.1
299 | function mufgcard_http11($method, $protocol, $host, $page = "/", $query = "", $cookie = "") {
300 | $ret = "INVALID HOST";
301 | if(preg_match("/\.mufgcard\.com$/", $host) > 0) $ret = http11(strtoupper($method), $protocol, $host, 0, $page, $query, "", $cookie);
302 | return explode("\r\n\r\n", $ret, 2);
303 | }
304 |
305 | function mufgcard_updatecookie($head, $cookie) {
306 | $ret = "";
307 | $cookies = array();
308 |
309 | $ckvs = explode(";", $cookie);
310 | foreach($ckvs as $ckv) {
311 | list($ck, $cv) = explode("=", $ckv, 2);
312 | $ck = trim($ck);
313 | $cv = trim($cv);
314 | if($ck != "" && $cv != "") $cookies[$ck] = $ck . "=" . $cv;
315 | }
316 |
317 | $cks = array("AS0[1-9]");
318 | foreach($cks as $ck) {
319 | $c = preg_match_all("/[Ss][Ee][Tt]-[Cc][Oo][Oo][Kk][Ii][Ee][\s\t]*:[\s\t]*(" . $ck . ")=([^;\r\n]*)/", $head, $matches);
320 | for($i = 0; $i < $c; $i++) $cookies[$matches[1][$i]] = $matches[1][$i] . "=" . $matches[2][$i];
321 | }
322 | $ret = implode("; ", $cookies);
323 | return $ret;
324 | }
325 |
326 | function mufgcard_parsedom($str) {
327 | // 明細表読み込み用DOMツリー作成
328 | $doc = new DOMDocument();
329 | // 引き落とし月取得
330 | $month = (preg_match("/" .preg_quote("お支払日") . ".*?" . preg_quote("年") . "([0-9]+)" . preg_quote("月") . "/s", $str, $matches) > 0 ? $matches[1] : "00");
331 | // の前のが,文字化けの原因となるため,削除
332 | $str = preg_replace('/.*<\/title>/', '', $str);
333 | //
334 | $str = str_replace(" ", "", $str);
335 | // 文字エンコード変換
336 | // $str = mb_convert_encoding($str, 'UTF-8', 'SJIS');
337 | // $str = str_replace('Shift_JIS','UTF-8',$str);
338 | // HTMLからDOMツリー作成
339 | $doc->loadHTML($str);
340 | $xpath = new DOMXPath($doc);
341 | // 明細表のテーブルを指定
342 | $tables = $xpath->query("//table[@class='mod-table font-x-small sp-font-normal transform']");
343 | // 請求がない場合
344 | if($tables->length == 0) {
345 | return false;
346 | }
347 | $rows = $tables->item(0)->getElementsByTagName('tr');
348 |
349 | $ret = "";
350 | $cds = array();
351 | $nrow = $rows->length;
352 | for($i=3; $i<$nrow; $i++) {
353 | $cd = array();
354 | $row = $rows->item($i);
355 | $cols = $row->getElementsByTagName('dd');
356 | // 利用明細でない行はスキップ
357 | if(empty($cols->item(0)->nodeValue)) continue;
358 |
359 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_CREDIT;
360 |
361 | // 日付を取得する
362 | $cd["DTPOSTED"] = parse_date(trim($cols->item(0)->nodeValue));
363 | $cd["DTPOSTED"] .= ENV_STR_OFX_TZ;
364 | // トランザクション番号(請求月とデータ種別)を生成する
365 | $cd["FITID"] = sprintf("%02d0", $month);
366 | // 摘要を取得する
367 | $cd["NAME"] = $cols->item(1)->nodeValue;
368 | // 金額を取得する
369 | $cd["TRNAMT"] = (-1)*(double)parse_amount(trim($cols->item(4)->nodeValue));
370 |
371 | array_push($cds, $cd);
372 | $cd_date = $cd["DTPOSTED"];
373 | }
374 | return $cds;
375 | }
376 | ?>
377 |
--------------------------------------------------------------------------------
/server/nanaco.inc:
--------------------------------------------------------------------------------
1 | ";
138 | $bankmsgsrsv1 .= "\r\n";
139 |
140 | // 口座情報を取得する
141 | $bankmsgsrsv1 .= "";
142 | $bankmsgsrsv1 .= "\r\n";
143 | $bankmsgsrsv1 .= "0";
144 | $bankmsgsrsv1 .= "\r\n";
145 | $bankmsgsrsv1 .= "0
INFO";
146 | $bankmsgsrsv1 .= "\r\n";
147 | $bankmsgsrsv1 .= "";
148 | $bankmsgsrsv1 .= "\r\n";
149 | $bankmsgsrsv1 .= "" . ENV_STR_OFX_CURRENCY_JPY . "";
150 | $bankmsgsrsv1 .= "\r\n";
151 | $bankmsgsrsv1 .= "";
152 | $bankmsgsrsv1 .= "" . $settings["code"] . "";
153 | $bankmsgsrsv1 .= "" . $account["branchid"] . "";
154 | $bankmsgsrsv1 .= "" . $account["acctid"] . "";
155 | $bankmsgsrsv1 .= "" . ENV_STR_ACCTTYPE_CHECKING . "";
156 | $bankmsgsrsv1 .= "";
157 | $bankmsgsrsv1 .= "\r\n";
158 | $bankmsgsrsv1 .= nanaco_parse_details($account);
159 | $bankmsgsrsv1 .= "";
160 | $bankmsgsrsv1 .= "\r\n";
161 | $bankmsgsrsv1 .= "";
162 | $bankmsgsrsv1 .= "\r\n";
163 |
164 | $bankmsgsrsv1 .= "";
165 | $bankmsgsrsv1 .= "\r\n";
166 |
167 | // OFXファイルを出力する
168 | $resp["status"] = ENV_NUM_STATUS_SUCCESS;
169 | $resp["ofx"] = generate_ofx($resp["status"], $bankmsgsrsv1);
170 | }
171 | return $resp;
172 |
173 | // HTTP/1.1
174 | function nanaco_http11($method, $uris, $query = "", $cookie = "") {
175 | $ret = "INVALID HOST";
176 | if(preg_match("/\.nanaco-net\.jp$/", $uris["host"]) > 0) $ret = http11(strtoupper($method), $uris["scheme"], $uris["host"], 0, $uris["path"], $query, "", $cookie);
177 | return explode("\r\n\r\n", $ret, 2);
178 | }
179 |
180 | function nanaco_update_cookie($head, $cookie) {
181 | return update_cookie(array("JSESSIONID", "BIGipServerPool_443_pc"), parse_header($head, "set-cookie"), $cookie);
182 | }
183 |
184 | function nanaco_get_details($body) {
185 | $rets = array();
186 | $i = 0;
187 | $trs = parse_tag($body, "tr");
188 | foreach(array_reverse($trs) as $tr) {
189 | $tds = parse_tag($tr["innerHTML"], "td");
190 | if(count($tds) == 10) {
191 | // 日時を取得する
192 | $dt = explode("
", $tds[0]["innerHTML"]);
193 |
194 | // 取引種別、および場所を取得する
195 | $name = trim(strip_tags($tds[1]["innerHTML"]));
196 | $memo = trim(strip_tags($tds[9]["innerHTML"]));
197 |
198 | // nanacoチャージ額・支払額を取得する
199 | $am = explode("
", $tds[2]["innerHTML"]);
200 | $amount = (string)((integer)parse_amount(trim(strip_tags($am[0]))) + (integer)parse_amount(trim(strip_tags(str_replace(array("(", ")"), array("", ""), $am[1])))));
201 | if($amount == "0") $amount = (string)(-1 * (integer)parse_amount(trim(strip_tags($tds[3]["innerHTML"]))));
202 |
203 | if($amount != "0") {
204 | $rets[$i]["date"] = parse_date(trim(strip_tags($dt[0])));
205 | $rets[$i]["summary"] = $name;
206 | $rets[$i]["memo"] = $memo;
207 | $rets[$i]["amount"] = $amount;
208 |
209 | $i++;
210 | }
211 | }
212 | }
213 |
214 | return $rets;
215 | }
216 |
217 | function nanaco_parse_details($account) {
218 | $ret = "";
219 | $cds = array();
220 | $cd_date = "";
221 | $cd_num = 0;
222 | $dtstart = ENV_STR_DATE_PASTDAY;
223 | foreach($account["details"] as $line) {
224 | if($dtstart > $line["date"]) $dtstart = $line["date"];
225 |
226 | $cd = array();
227 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_DIRECTDEBIT;
228 |
229 | // 日付を取得する
230 | $cd["DTPOSTED"] = $line["date"];
231 |
232 | // 通番を生成する
233 | if($cd["DTPOSTED"] == $cd_date) $cd_num++; else $cd_num = 0;
234 |
235 | // トランザクション番号を生成する
236 | $cd["FITID"] = $cd["DTPOSTED"] . "0000000" . sprintf("%05d", $cd_num);
237 |
238 | // 摘要を取得する
239 | $cd["NAME"] = $line["summary"];
240 |
241 | // 金額を取得する
242 | $cd["TRNAMT"] = parse_amount($line["amount"]);
243 | $cd["MEMO"] = ($line["memo"] != ""? $line["memo"]: ENV_STR_OFX_MEMO);
244 |
245 | array_push($cds, $cd);
246 | $cd_date = $cd["DTPOSTED"];
247 | }
248 | // BANKTRANLIST
249 | $ret .= "";
250 | $ret .= "\r\n";
251 | $ret .= "" . $dtstart . ENV_STR_OFX_TZ . "";
252 | $ret .= "" . ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ . "";
253 | $ret .= "\r\n";
254 |
255 | foreach($cds as $cd) {
256 | $ret .= "";
257 | $ret .= "" . $cd["TRNTYPE"] . "";
258 | $ret .= "" . $cd["DTPOSTED"] . ENV_STR_OFX_TZ . "";
259 | $ret .= "" . $cd["TRNAMT"] . "";
260 | $ret .= "" . $cd["FITID"] . "";
261 | $ret .= "" . $cd["NAME"] . "";
262 | $ret .= "" . $cd["MEMO"] . "";
263 | $ret .= "";
264 | $ret .= "\r\n";
265 | }
266 |
267 | $ret .= "";
268 | $ret .= "\r\n";
269 | $ret .= "";
270 | $ret .= "" . $account["balance"] . "";
271 | $ret .= "" . ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ . "";
272 | $ret .= "";
273 | $ret .= "\r\n";
274 |
275 | // 口座名称を出力する
276 | if($account["acctname"] != "") {
277 | $ret .= "" . $account["acctname"] . "";
278 | $ret .= "\r\n";
279 | }
280 |
281 | return $ret;
282 | }
283 |
284 | ?>
285 |
--------------------------------------------------------------------------------
/server/netbk.inc:
--------------------------------------------------------------------------------
1 | 0) {
31 | $method = "GET";
32 | $uris = parse_uri($locations[0], $uris);
33 | $query = "";
34 | $cookie = netbk_update_cookie($head, $cookie);
35 | list($head, $body) = netbk_http11($method, $uris, $query, $cookie);
36 | }
37 | }
38 |
39 | // ログインする
40 | $forms = parse_tag($body, "form");
41 | $c = parse_tag_search($forms, "name", "LoginForm");
42 | if($c != -1) {
43 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
44 | $queries = array();
45 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
46 | $queries["userName"] = "userName=" . $user;
47 | $queries["loginPwdSet"] = "loginPwdSet=" . $pass;
48 |
49 | $method = $forms[$c]["method"];
50 | $uris = parse_uri($forms[$c]["action"], $uris);
51 | $query = implode("&", $queries);
52 | $cookie = netbk_update_cookie($head, $cookie);
53 | list($head, $body) = netbk_http11($method, $uris, $query, $cookie);
54 | }
55 |
56 | // 重要なお知らせ画面が表示される場合、次の画面を取得する
57 | if(strpos($body, "銀行からの重要なお知らせ") !== false) {
58 | $forms = parse_tag($body, "form");
59 | $c = parse_tag_search($forms, "name", "form0103_01_100");
60 | if($c != -1) {
61 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
62 | $queries = array();
63 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
64 | if(isset($queries["imptNtcCheck"]) == true) unset($queries["imptNtcCheck"]); // 「確認しました」チェックボックスをオフにする
65 |
66 | $method = $forms[$c]["method"];
67 | $uris = parse_uri($forms[$c]["action"], $uris);
68 | $query = implode("&", $queries);
69 | $cookie = netbk_update_cookie($head, $cookie);
70 | list($head, $body) = netbk_http11($method, $uris, $query, $cookie);
71 | }
72 |
73 | // リダイレクトする
74 | $forms = parse_tag($body, "form");
75 | $c = parse_tag_search($forms, "name", "form0103_01_105");
76 | if($c != -1) {
77 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
78 | $queries = array();
79 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
80 |
81 | $method = $forms[$c]["method"];
82 | $uris = parse_uri($forms[$c]["action"], $uris);
83 | $query = implode("&", $queries);
84 | $cookie = netbk_update_cookie($head, $cookie);
85 | list($head, $body) = netbk_http11($method, $uris, $query, $cookie);
86 | }
87 | }
88 |
89 | if(strpos($body, "現在この取引はお取扱いできません") !== false) {
90 | // システムメンテナンス画面の場合
91 | $resp["status"] = ENV_NUM_STATUS_MAINTENANCE;
92 | $resp["method"] = $method;
93 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
94 | $resp["query"] = $query;
95 | $resp["cookie"] = $cookie;
96 | $resp["head"] = $head;
97 | $resp["body"] = $body;
98 | $resp["ofx"] = generate_ofx($resp["status"]);
99 | } else if(strpos($body, "前回ログイン日時") === false) {
100 | // ログイン失敗の場合
101 | $resp["status"] = ENV_NUM_STATUS_FAILURE;
102 | $resp["method"] = $method;
103 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
104 | $resp["query"] = $query;
105 | $resp["cookie"] = $cookie;
106 | $resp["head"] = $head;
107 | $resp["body"] = $body;
108 | $resp["ofx"] = generate_ofx($resp["status"]);
109 | } else {
110 | // 残高照会(口座別)画面を取得する
111 | $as = parse_tag($body, "a");
112 | foreach($as as $a) if(parse_tag_search(parse_tag($a["innerHTML"], "span"), "innerHTML", "口座情報") != -1) {
113 | $method = "GET";
114 | $uris = parse_uri($a["href"], $uris);
115 | $query = "";
116 | $cookie = netbk_update_cookie($head, $cookie);
117 | list($head, $body) = netbk_http11($method, $uris, $query, $cookie);
118 | break;
119 | }
120 |
121 | // 口座情報を取得する
122 | if(preg_match("/([0-9]{3})\-([0-9]{7})/", $body, $matches) > 0) {
123 | $branchid = $matches[1];
124 | $acctid = $matches[2];
125 | }
126 |
127 | $accounts = array();
128 |
129 | // 口座数を取得する
130 | $trs = parse_tag($body, "tr", true); // 再帰的に取得する
131 | foreach($trs as $tr) {
132 | $tds = parse_tag($tr["innerHTML"], "td");
133 | if(count($tds) == 5) {
134 | $as = parse_tag($tds[4]["innerHTML"], "a");
135 | foreach($as as $a) if(trim(strip_tags($a["innerHTML"])) == "明細" && preg_match("/.*?\/([0-9]{2})\/(01|21)\/001\/01/", $a["href"], $matches) > 0) {
136 | $accounts[$c]["acctname"] = str_replace(array("口座", " - "), array("", ENV_CHR_CONCATENATOR), trim(strip_tags($tds[0]["innerHTML"])));
137 | $accounts[$c]["id"] = ($matches[2] == "01"? $matches[1]: "00"); // SBIハイブリッド預金を00とみなす
138 | $accounts[$c]["acctid"] = $matches[1]; // 01=代表口座 02-99=目的別口座
139 | $accounts[$c]["accttype"] = $matches[2]; // 01=円普通 21=SBIハイブリッド
140 | $accounts[$c]["page"] = $a["href"];
141 | $c++;
142 | }
143 | }
144 | }
145 |
146 | // お客さま情報照会・変更画面を取得する
147 | $as = parse_tag($body, "a");
148 | $c = parse_tag_search($as, "innerHTML", "お客さま情報照会・変更");
149 | if($c != -1) {
150 | $method = "GET";
151 | $uris = parse_uri($as[$c]["href"], $uris);
152 | $query = "";
153 | $cookie = netbk_update_cookie($head, $cookie);
154 | list($head, $body) = netbk_http11($method, $uris, $query, $cookie);
155 | }
156 |
157 | // 支店名を取得する
158 | $otables = parse_tag($body, "table");
159 | foreach($otables as $otable) {
160 | $tables = parse_tag($otable["innerHTML"], "table");
161 | foreach($tables as $table) {
162 | $c = 0;
163 | $trs = parse_tag($table["innerHTML"], "tr");
164 | foreach($trs as $tr) {
165 | $divs = parse_tag($tr["innerHTML"], "div");
166 | if(count($divs) == 2 && trim(strip_tags($divs[0]["innerHTML"])) == "口座番号") {
167 | $bufs = explode(" ", preg_replace("/\s{2,}/", " ", str_replace(" ", "", trim(strip_tags($divs[1]["innerHTML"])))));
168 | for($i = 0; $i < count($accounts); $i++) $accounts[$i]["acctname"] = implode(ENV_CHR_CONCATENATOR, array($settings["name"], $bufs[1], $accounts[$i]["acctname"]));
169 | }
170 | }
171 | }
172 | }
173 |
174 | $bankmsgsrsv1 = "";
175 | $bankmsgsrsv1 .= "";
176 | $bankmsgsrsv1 .= "\r\n";
177 |
178 | // 口座数分ループする
179 | foreach($accounts as $account) {
180 | // 実行時間(タイムアウト)を再設定する
181 | @set_time_limit(ENV_NUM_TIMEOUT);
182 |
183 | // 口座情報画面を取得する
184 | $method = "GET";
185 | $uris = parse_uri($account["page"], $uris);
186 | $query = "";
187 | $cookie = netbk_update_cookie($head, $cookie);
188 | list($head, $body) = netbk_http11($method, $uris, $query, $cookie);
189 |
190 | // 入出金明細画面を取得する
191 | $forms = parse_tag($body, "form");
192 | $c = parse_tag_search($forms, "name", "form0202_01_100");
193 | if($c != -1) {
194 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
195 | $queries = array();
196 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
197 | $selects = parse_tag($forms[$c]["innerHTML"], "select");
198 | foreach($selects as $select) {
199 | $options = parse_tag($select["innerHTML"], "option");
200 | foreach($options as $option) if($select["name"] != "" && $option["selected"] == "selected") $queries[$select["name"]] = urlencode($select["name"]) . "=" . urlencode($option["value"]);
201 | }
202 | $queries["termLink"] = "termLink=05"; // 期間指定
203 | $queries["term"] = "term=05"; // 期間指定
204 | $queries["acctBusPdCodeInput"] = "acctBusPdCodeInput=" . $account["acctid"] . $account["accttype"] . "001";
205 | $queries["dsplyTrmSpcfdYearFrom"] = "dsplyTrmSpcfdYearFrom=" . substr(ENV_STR_DATE_PASTDAY, 0, 4);
206 | $queries["dsplyTrmSpcfdMonthFrom"] = "dsplyTrmSpcfdMonthFrom=" . substr(ENV_STR_DATE_PASTDAY, 4, 2);
207 | $queries["dsplyTrmSpcfdDayFrom"] = "dsplyTrmSpcfdDayFrom=" . substr(ENV_STR_DATE_PASTDAY, 6, 2);
208 | $queries["dsplyTrmSpcfdYearTo"] = "dsplyTrmSpcfdYearTo=" . substr(ENV_STR_DATE_TODAY, 0, 4);
209 | $queries["dsplyTrmSpcfdMonthTo"] = "dsplyTrmSpcfdMonthTo=" . substr(ENV_STR_DATE_TODAY, 4, 2);
210 | $queries["dsplyTrmSpcfdDayTo"] = "dsplyTrmSpcfdDayTo=" . substr(ENV_STR_DATE_TODAY, 6, 2);
211 |
212 | $method = $forms[$c]["method"];
213 | $uris = parse_uri($forms[$c]["action"], $uris);
214 | $query = implode("&", $queries);
215 | $cookie = netbk_update_cookie($head, $cookie);
216 | list($head, $body) = netbk_http11($method, $uris, $query, $cookie);
217 | }
218 |
219 | // 明細が存在しない場合、選択中の口座の残高を取得する
220 | if(strpos($body, "表示可能な明細はございません") !== false) {
221 | $divs = parse_tag($body, "div", true); // 再帰的に取得する
222 | foreach($divs as $div) if($div["class"] == "tablef01M" && $div["innerHTML"] != "選択中の口座の残高") {
223 | $account["balamt"] = parse_amount(str_replace(" ", "", trim(strip_tags($div["innerHTML"]))));
224 | break;
225 | }
226 | }
227 |
228 | $body_old = $body;
229 |
230 | // CSVファイルをダウンロードする
231 | $forms = parse_tag($body, "form");
232 | $c = parse_tag_search($forms, "name", "form0202_01_100");
233 | if($c != -1) {
234 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
235 | $queries = array();
236 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
237 | $selects = parse_tag($forms[$c]["innerHTML"], "select");
238 | foreach($selects as $select) {
239 | $options = parse_tag($select["innerHTML"], "option");
240 | foreach($options as $option) if($select["name"] != "" && $option["selected"] == "selected") $queries[$select["name"]] = urlencode($select["name"]) . "=" . urlencode($option["value"]);
241 | }
242 | $queries["termLink"] = "termLink=05"; // 期間指定
243 | $queries["term"] = "term=05"; // 期間指定
244 | $queries["acctBusPdCodeInput"] = "acctBusPdCodeInput=" . $account["acctid"] . $account["accttype"] . "001";
245 | $queries["dsplyTrmSpcfdYearFrom"] = "dsplyTrmSpcfdYearFrom=" . substr(ENV_STR_DATE_PASTDAY, 0, 4);
246 | $queries["dsplyTrmSpcfdMonthFrom"] = "dsplyTrmSpcfdMonthFrom=" . substr(ENV_STR_DATE_PASTDAY, 4, 2);
247 | $queries["dsplyTrmSpcfdDayFrom"] = "dsplyTrmSpcfdDayFrom=" . substr(ENV_STR_DATE_PASTDAY, 6, 2);
248 | $queries["dsplyTrmSpcfdYearTo"] = "dsplyTrmSpcfdYearTo=" . substr(ENV_STR_DATE_TODAY, 0, 4);
249 | $queries["dsplyTrmSpcfdMonthTo"] = "dsplyTrmSpcfdMonthTo=" . substr(ENV_STR_DATE_TODAY, 4, 2);
250 | $queries["dsplyTrmSpcfdDayTo"] = "dsplyTrmSpcfdDayTo=" . substr(ENV_STR_DATE_TODAY, 6, 2);
251 | $queries["_ActionID"] = "_ActionID=doCSVDownload"; // CSVダウンロード
252 | if(isset($queries["ACT_doShow"]) == true) unset($queries["ACT_doShow"]);
253 |
254 | $method = $forms[$c]["method"];
255 | $uris = parse_uri($forms[$c]["action"], $uris);
256 | $query = implode("&", $queries);
257 | $cookie = netbk_update_cookie($head, $cookie);
258 | list($head, $body) = netbk_http11($method, $uris, $query, $cookie);
259 |
260 | if(strpos($head, "Content-Type: text/html") === false) {
261 | $bankmsgsrsv1 .= "";
262 | $bankmsgsrsv1 .= "\r\n";
263 | $bankmsgsrsv1 .= "0";
264 | $bankmsgsrsv1 .= "\r\n";
265 | $bankmsgsrsv1 .= "0
INFO";
266 | $bankmsgsrsv1 .= "\r\n";
267 | $bankmsgsrsv1 .= "";
268 | $bankmsgsrsv1 .= "\r\n";
269 | $bankmsgsrsv1 .= "" . ENV_STR_OFX_CURRENCY_JPY . "";
270 | $bankmsgsrsv1 .= "\r\n";
271 | $bankmsgsrsv1 .= "";
272 | $bankmsgsrsv1 .= "" . $settings["code"] . "";
273 | $bankmsgsrsv1 .= "" . $branchid . "";
274 | $bankmsgsrsv1 .= "" . $acctid . "-" . $account["id"] . "";
275 | $bankmsgsrsv1 .= "" . ENV_STR_ACCTTYPE_SAVINGS . "";
276 | $bankmsgsrsv1 .= "";
277 | $bankmsgsrsv1 .= "\r\n";
278 | $bankmsgsrsv1 .= netbk_parse_csv($body, $account);
279 | $bankmsgsrsv1 .= "";
280 | $bankmsgsrsv1 .= "\r\n";
281 | $bankmsgsrsv1 .= "";
282 | $bankmsgsrsv1 .= "\r\n";
283 | }
284 | }
285 |
286 | $body = $body_old;
287 | }
288 |
289 | $bankmsgsrsv1 .= "";
290 | $bankmsgsrsv1 .= "\r\n";
291 |
292 | // 実行時間(タイムアウト)を再設定する
293 | @set_time_limit(ENV_NUM_TIMEOUT);
294 |
295 | // ログアウトする
296 | $as = parse_tag($body, "a");
297 | foreach($as as $a) if(parse_tag_search(parse_tag($a["innerHTML"], "img"), "alt", "ログアウト") != -1) {
298 | $method = "GET";
299 | $uris = parse_uri($a["href"], $uris);
300 | $query = "";
301 | $cookie = netbk_update_cookie($head, $cookie);
302 | list($head, $body) = netbk_http11($method, $uris, $query, $cookie);
303 | break;
304 | }
305 |
306 | if(ENV_BOOL_ADD_RISKBASE == true) {
307 | // 次回ログイン時に2段階認証を行わない
308 | $resp["token"] = netbk_get_token("termvalue", $cookie);
309 | }
310 |
311 | // OFXファイルを出力する
312 | $resp["status"] = ENV_NUM_STATUS_SUCCESS;
313 | if(strpos($bankmsgsrsv1, "") === false) {
314 | // 明細が存在しない場合
315 | $resp["ofx"] = generate_ofx($resp["status"]);
316 | } else {
317 | // 明細が存在する場合
318 | $resp["ofx"] = generate_ofx($resp["status"], $bankmsgsrsv1);
319 | }
320 | }
321 | return $resp;
322 |
323 | // HTTP/1.1
324 | function netbk_http11($method, $uris, $query = "", $cookie = "") {
325 | $ret = "INVALID HOST";
326 | if(preg_match("/\.netbk\.co\.jp$/", $uris["host"]) > 0) $ret = http11(strtoupper($method), $uris["scheme"], $uris["host"], 0, $uris["path"], $query, "", $cookie);
327 | return explode("\r\n\r\n", $ret, 2);
328 | }
329 |
330 | function netbk_update_cookie($head, $cookie) {
331 | return update_cookie(array("JSESSIONID", "termvalue"), parse_header($head, "set-cookie"), $cookie);
332 | }
333 |
334 | function netbk_get_token($name, $cookie) {
335 | $ret = "";
336 |
337 | $kvs = explode(";", $cookie);
338 | foreach($kvs as $kv) {
339 | list($k, $v) = explode("=", $kv, 2);
340 | $k = trim($k);
341 | if($k == $name) {
342 | $ret = $k . "=" . trim($v);
343 | break;
344 | }
345 | }
346 | return $ret;
347 | }
348 |
349 | function netbk_parse_csv($str, $account) {
350 | $ret = "";
351 | $lines = array_reverse(parse_csv(mb_convert_string($str)));
352 | $cds = array();
353 | $cds_balamt = "0";
354 | $cd_date = "";
355 | $cd_num = 0;
356 |
357 | foreach($lines as $line) {
358 | $cd = array();
359 | if(count($line) == 6 && $line[0] != "日付") {
360 | list($cd_name, $cd_dummy) = explode(ENV_CHR_SEPARATOR, str_replace(array("*", " "), array(ENV_CHR_SEPARATOR, ENV_CHR_SEPARATOR), $line[1]), 2);
361 |
362 | switch($cd_name) {
363 | case "振込":
364 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_DIRECTDEP;
365 | break;
366 | case "国税":
367 | case "地方税":
368 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_DEP;
369 | break;
370 | case "SBIハイブリッド預金":
371 | case "普通":
372 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_XFER;
373 | break;
374 | case "振替":
375 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_DEBIT;
376 | break;
377 | case "利息":
378 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_INT;
379 | break;
380 | case "ATM":
381 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_ATM;
382 | break;
383 | default:
384 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_OTHER;
385 | break;
386 | }
387 |
388 | // 日付を取得する
389 | $cd["DTPOSTED"] = parse_date($line[0]);
390 |
391 | // 通番を生成する
392 | if($cd["DTPOSTED"] == $cd_date) $cd_num++; else $cd_num = 0;
393 |
394 | // トランザクション番号を生成する
395 | $cd["FITID"] = $cd["DTPOSTED"] . sprintf("%04d", (integer)$account["accttype"]) . "000" . sprintf("%05d", $cd_num);
396 |
397 | // 摘要を取得する
398 | $cd["NAME"] = $line[1];
399 |
400 | // 金額を取得する
401 | $cd["TRNAMT"] = (string)((double)parse_amount($line[3]) - (double)parse_amount($line[2]));
402 |
403 | // 残高を取得する
404 | $cds_balamt = (string)((double)parse_amount($line[4]));
405 | $cd["MEMO"] = $line[5];
406 |
407 | array_push($cds, $cd);
408 | $cd_date = $cd["DTPOSTED"];
409 | }
410 | }
411 |
412 | if($account["balamt"] != "") $cds_balamt = $account["balamt"];
413 |
414 | // BANKTRANLIST
415 | $ret .= "";
416 | $ret .= "\r\n";
417 | $ret .= "" . ENV_STR_DATE_PASTDAY . ENV_STR_OFX_TZ . "";
418 | $ret .= "" . ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ . "";
419 | $ret .= "\r\n";
420 |
421 | foreach($cds as $cd) {
422 | $ret .= "";
423 | $ret .= "" . $cd["TRNTYPE"] . "";
424 | $ret .= "" . $cd["DTPOSTED"] . ENV_STR_OFX_TZ . "";
425 | $ret .= "" . $cd["TRNAMT"] . "";
426 | $ret .= "" . $cd["FITID"] . "";
427 | $ret .= "" . $cd["NAME"] . "";
428 | $ret .= "" . $cd["MEMO"] . "";
429 | $ret .= "";
430 | $ret .= "\r\n";
431 | }
432 |
433 | $ret .= "";
434 | $ret .= "\r\n";
435 | $ret .= "";
436 | $ret .= "" . $cds_balamt . "";
437 | $ret .= "" . ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ . "";
438 | $ret .= "";
439 | $ret .= "\r\n";
440 |
441 | // 口座名称を出力する
442 | if($account["acctname"] != "") {
443 | $ret .= "" . $account["acctname"] . "";
444 | $ret .= "\r\n";
445 | }
446 |
447 | return $ret;
448 | }
449 |
450 | ?>
451 |
--------------------------------------------------------------------------------
/server/rakutensec.inc:
--------------------------------------------------------------------------------
1 | setAcctfrom(array(
147 | "BROKERID" => $settings["code"],
148 | "ACCTID" => $acctid
149 | ));
150 |
151 | // 資産情報のHTMLを処理する
152 | $divs = parse_tag($body_balance, 'div');
153 | $c = parse_tag_search($divs, 'id', 'balance_data_actual_data');
154 | $tds = parse_tag($divs[$c]['innerHTML'], 'td');
155 | preg_match('/[0-9,]+/', $tds[21]['innerHTML'], $matches);
156 | $availcash = parse_amount($matches[0]);
157 |
158 | // 残高を設定
159 | $ofxdom->setBalance(array(
160 | 'AVAILCASH' => $availcash,
161 | 'MARGINBALANCE' => $availcash,
162 | 'SHORTBALANCE' => 0
163 | ));
164 |
165 | // 入出力履歴のCSVを処理する
166 | $body_trans = mb_convert_encoding($body_trans, "UTF-8", "sjis-win");
167 | $rows = parse_csv($body_trans);
168 | array_splice($rows, 0, 4); // ヘッダー行等最初の4行(+空行1行)をスキップする
169 | foreach ($rows as $row) {
170 | $cd = array();
171 | $date = date_parse($row[0]);
172 | $cd['DTPOSTED'] = sprintf("%d%02d%02d", $date['year'], $date['month'], $date['day']);
173 | $cd['DTPOSTED'] .= ENV_STR_OFX_TZ;
174 | if (preg_match('/[0-9,]+/', $row[1]) > 0) { // 入金
175 | $cd['TRNAMT'] = $row[1];
176 | } else { // 出金
177 | $cd['TRNAMT'] = '-' . $row[2];
178 | }
179 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_DIRECTDEP;
180 | $cd['NAME'] = $row[3] . ' ' . $row[4];
181 | // トランザクション番号(請求月とデータ種別)を生成する
182 | $cd["FITID"] = '000';
183 |
184 | // 入出力履歴をDOMに書き込む
185 | if (strtotime(ENV_STR_DATE_PASTDAY) <= strtotime($row[0]) && strtotime($row[0]) <= strtotime(ENV_STR_DATE_TODAY)) {
186 | $ofxdom->addTran($cd);
187 | } else {
188 | break;
189 | }
190 | }
191 |
192 | // DTSTARTとDTENDを設定する
193 | $ofxdom->setDateRange(ENV_STR_DATE_PASTDAY . ENV_STR_OFX_TZ, ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ);
194 |
195 | // 取引履歴(国内株式)のCSVを処理する
196 | $body_trade_jp = mb_convert_encoding($body_trade_jp, "UTF-8", "sjis-win");
197 | $rows = parse_csv($body_trade_jp);
198 | array_shift($rows); // ヘッダー行をスキップする
199 | foreach ($rows as $row) {
200 | $ct = array();
201 | $ct['CATEGORY'] = ENV_STR_OFX_STOCK;
202 | $date = date_parse($row[0]);
203 | $ct['DTTRADE'] = sprintf("%d%02d%02d000000", $date['year'], $date['month'], $date['day'])
204 | . ENV_STR_OFX_TZ;
205 | $ct['UNIQUEID'] = $row[2];
206 | $ct['SECNAME'] = $row[3];
207 | $ct['UNIQUEIDTYPE'] = ENV_STR_OFX_CODE_STOCK;
208 | $ct['UNITS'] = (int)parse_amount($row[10]);
209 | $ct['UNITPRICE'] = parse_amount($row[11]);
210 | $ct['FEES'] = (int)parse_amount($row[12]);
211 | $ct['TAXES'] = (int)parse_amount($row[13]);
212 | $ct['COMMISSION'] = (int)parse_amount($row[14]);
213 | $ct['TOTAL'] = (int)parse_amount($row[16]);
214 | $ct['SUBACCTSEC'] = ENV_STR_OFX_CASH;
215 | $ct['SUBACCTFUND'] = ENV_STR_OFX_CASH;
216 | $ct['FITID'] = '000';
217 | if (preg_match('/買付/', $row[7]) > 0) {
218 | $ct['BUYTYPE'] = ENV_STR_OFX_BUY;
219 | $ct['TOTAL'] *= -1;
220 | } else {
221 | $ct['BUYTYPE'] = ENV_STR_OFX_SELL;
222 | $ct['UNITS'] *= -1;
223 | }
224 |
225 | if (strtotime(ENV_STR_DATE_PASTDAY) <= strtotime($row[0]) && strtotime($row[0]) <= strtotime(ENV_STR_DATE_TODAY)) {
226 | $ofxdom->addTrade($ct);
227 | }
228 | }
229 |
230 | // 取引履歴(投資信託)のCSVを処理する
231 | $body_trade_mf = mb_convert_encoding($body_trade_mf, "UTF-8", "sjis-win");
232 | $rows = parse_csv($body_trade_mf);
233 | array_shift($rows); // ヘッダー行をスキップする
234 | foreach ($rows as $row) {
235 | $ct = array();
236 | $ct['CATEGORY'] = ENV_STR_OFX_FUND;
237 | $date = date_parse($row[0]);
238 | $ct['DTTRADE'] = sprintf("%d%02d%02d", $date['year'], $date['month'], $date['day'])
239 | . ENV_STR_OFX_TZ;
240 | $ct['UNIQUEID'] = md5($row[2]);
241 | $ct['SECNAME'] = $row[2];
242 | $ct['UNIQUEIDTYPE'] = ENV_STR_OFX_CODE_FUND;
243 | $ct['UNITS'] = (int)parse_amount($row[7]);
244 | $ct['UNITPRICE'] = parse_amount($row[8]);
245 | //$ct['FEES'] = (int)parse_amount($row[9]);
246 | // total = units * unitprice + (commission + fee + taxes)とするため、feeを0にする
247 | $ct['FEES'] = 0;
248 | $ct['TAXES'] = 0;
249 | $ct['COMMISSION'] = 0;
250 | $ct['TOTAL'] = (int)parse_amount($row[10]);
251 | $ct['SUBACCTSEC'] = ENV_STR_OFX_CASH;
252 | $ct['FITID'] = '000';
253 | switch ($row[5]) {
254 | case '買付':
255 | $ct['BUYTYPE'] = ENV_STR_OFX_BUY;
256 | $ct['SUBACCTFUND'] = ENV_STR_OFX_CASH;
257 | $ct['TOTAL'] *= -1;
258 | break;
259 | case '解約':
260 | $ct['BUYTYPE'] = ENV_STR_OFX_SELL;
261 | $ct['SUBACCTFUND'] = ENV_STR_OFX_CASH;
262 | $ct['UNITS'] *= -1;
263 | break;
264 | case '再投資':
265 | default:
266 | $ct['BUYTYPE'] = ENV_STR_OFX_REINVEST;
267 | $ct['INCOMETYPE'] = ENV_STR_OFX_TRNTYPE_INT;
268 | $ct['TOTAL'] *= -1;
269 | break;
270 | }
271 |
272 | if (strtotime(ENV_STR_DATE_PASTDAY) <= strtotime($row[0]) && strtotime($row[0]) <= strtotime(ENV_STR_DATE_TODAY)) {
273 | $ofxdom->addTrade($ct);
274 | }
275 | }
276 |
277 | // 保有商品一覧(国内株式)のCSVを処理する
278 | $body_pos_jp = mb_convert_encoding($body_pos_jp, "UTF-8", "sjis-win");
279 | $rows = parse_csv($body_pos_jp);
280 | array_shift($rows); // ヘッダー行をスキップする
281 | foreach ($rows as $row) {
282 | $cl = array();
283 | $cl['CATEGORY'] = ENV_STR_OFX_STOCK;
284 | $cl['HELDINACCT'] = ENV_STR_OFX_CASH;
285 | $cl['POSTYPE'] = 'LONG';
286 | $cl['DTPRICEASOF'] = ENV_STR_DATE_TODAY;
287 | $cl['UNIQUEIDTYPE'] = ENV_STR_OFX_CODE_STOCK;
288 | $cl['UNIQUEID'] = $row[1];
289 | $cl['SECNAME'] = $row[2];
290 | $cl['UNITS'] = (int)parse_amount($row[3]);
291 | $cl['UNITPRICE'] = parse_amount($row[6]);
292 | $cl['MKTVAL'] = (int)parse_amount($row[7]);
293 | $cl['MEMO'] = (int)parse_amount($row[8]);
294 |
295 | $ofxdom->addPos($cl);
296 | $ofxdom->addSec($cl);
297 | }
298 |
299 | // 保有商品一覧(投資信託)のCSVを処理する
300 | $body_pos_mf = mb_convert_encoding($body_pos_mf, "UTF-8", "sjis-win");
301 | $rows = parse_csv($body_pos_mf);
302 | array_shift($rows); // ヘッダー行をスキップする
303 | foreach ($rows as $row) {
304 | $cl = array();
305 | $cl['CATEGORY'] = ENV_STR_OFX_FUND;
306 | $cl['HELDINACCT'] = ENV_STR_OFX_CASH;
307 | $cl['POSTYPE'] = 'LONG';
308 | $cl['DTPRICEASOF'] = ENV_STR_DATE_TODAY;
309 | $cl['UNIQUEID'] = md5($row[2]);
310 | $cl['UNIQUEIDTYPE'] = ENV_STR_OFX_CODE_FUND;
311 | $cl['SECNAME'] = $row[2];
312 | $cl['UNITS'] = (int)parse_amount($row[4]);
313 | $cl['UNITPRICE'] = 1;
314 | $cl['MKTVAL'] = (int)parse_amount($row[14]);
315 | $cl['MEMO'] = $row[10];
316 |
317 | $ofxdom->addPos($cl);
318 | $ofxdom->addSec($cl);
319 | }
320 |
321 | // FITIDを仕上げる
322 | $ofxdom->setFitid();
323 | // XML DOMツリーを文字列に変換
324 | $xml = $ofxdom->getXML();
325 | $resp["status"] = ENV_NUM_STATUS_SUCCESS;
326 | $resp["ofx"] = generate_ofx($mode, $xml);
327 |
328 | return $resp;
329 |
330 | // HTTP/1.1
331 | function rakutensec_http11($method, $uris, $query = "", $cookie = "") {
332 | $ret = "INVALID HOST";
333 | if(preg_match("/\.rakuten-sec\.co\.jp$/", $uris["host"]) > 0) $ret = http11(strtoupper($method), $uris["scheme"], $uris["host"], 0, $uris["path"], $query, "", $cookie);
334 | return explode("\r\n\r\n", $ret, 2);
335 | }
336 | function rakutensec_update_cookie($head, $cookie) {
337 | return update_cookie(array(
338 | "Rg_sec",
339 | "checkTk",
340 | ), parse_header($head, "set-cookie"), $cookie);
341 | }
342 | ?>
343 |
--------------------------------------------------------------------------------
/server/saisoncard.inc:
--------------------------------------------------------------------------------
1 | 0) {
107 | // セッションを引き継ぐ
108 | $resp["status"] = ENV_NUM_STATUS_ADDITION;
109 | $resp["aid"] = "secretAnswer";
110 | $resp["additional"] = $shitsumon;
111 | $resp["sid"] = $sid;
112 | $resp["sesscookie"] = sess_encode(implode("\t", array($cookie, ENV_STR_SESSION_PADDING)));
113 | $resp["accesskey"] = sess_encode(implode("\t", array((string)$sid, $method, $uris["scheme"] . "://" . $uris["host"] . $uris["path"], $query, $pass, ENV_STR_SESSION_PADDING)));
114 |
115 | $mfachallengetrnrs = "";
116 | $mfachallengetrnrs .= "";
117 | $mfachallengetrnrs .= "";
118 | $mfachallengetrnrs .= "";
119 | $mfachallengetrnrs .= "" . $resp["aid"] . "";
120 | $mfachallengetrnrs .= "" . $resp["additional"] . "";
121 | $mfachallengetrnrs .= "";
122 | $mfachallengetrnrs .= "";
123 | $mfachallengetrnrs .= "";
124 |
125 | $resp["ofx"] = generate_ofx($resp["status"], $mfachallengetrnrs, $resp["sesscookie"], $resp["accesskey"]);
126 | } else if(strpos($body, "秘密の質問設定") !== false) {
127 | // ログイン後の画面が通常と異なる場合
128 | $resp["status"] = ENV_NUM_STATUS_CAUTION;
129 | $resp["method"] = $method;
130 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
131 | $resp["query"] = $query;
132 | $resp["cookie"] = $cookie;
133 | $resp["head"] = $head;
134 | $resp["body"] = $body;
135 | $resp["ofx"] = generate_ofx($resp["status"]);
136 | } else if(strpos($body, "メンテナンス中") !== false || strpos($body, "サービスがご利用いただけません") !== false) {
137 | // システムメンテナンス画面の場合
138 | $resp["status"] = ENV_NUM_STATUS_MAINTENANCE;
139 | $resp["method"] = $method;
140 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
141 | $resp["query"] = $query;
142 | $resp["cookie"] = $cookie;
143 | $resp["head"] = $head;
144 | $resp["body"] = $body;
145 | $resp["ofx"] = generate_ofx($resp["status"]);
146 | } else if(strpos($body, "前回ログイン") === false) {
147 | // ログイン失敗の場合
148 | $resp["status"] = ENV_NUM_STATUS_FAILURE;
149 | $resp["method"] = $method;
150 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
151 | $resp["query"] = $query;
152 | $resp["cookie"] = $cookie;
153 | $resp["head"] = $head;
154 | $resp["body"] = $body;
155 | $resp["ofx"] = generate_ofx($resp["status"]);
156 | } else {
157 | $account = array();
158 | $account["id"] = 0;
159 |
160 | // 実行時間(タイムアウト)を再設定する
161 | @set_time_limit(ENV_NUM_TIMEOUT);
162 |
163 | // Netアンサー情報照会画面を取得する
164 | $as = parse_tag($body, "a");
165 | foreach($as as $a) if(parse_tag_search(parse_tag($a["innerHTML"], "img"), "alt", "Netアンサー登録内容変更 NetアンサーID、パスワード、 メールアドレスなど ") != -1) {
166 | $method = "GET";
167 | $uris = parse_uri($a["href"], $uris);
168 | $query = "";
169 | $cookie = saisoncard_update_cookie($head, $cookie);
170 | list($head, $body) = saisoncard_http11($method, $uris, $query, $cookie);
171 | break;
172 | }
173 |
174 | $tds = parse_tag($body, "td", true); // 再帰的に取得する
175 | $bufs = array();
176 | foreach($tds as $td) if($td["class"] == "td-01") array_push($bufs, trim(strip_tags($td["innerHTML"])));
177 | if(count($bufs) >= 2) {
178 | // カード名称を取得する
179 | $account["acctname"] = implode(ENV_CHR_CONCATENATOR, array($settings["name"], $bufs[0]));
180 | $account["name"] = $settings["name"];
181 |
182 | // カード番号を取得する
183 | $account["acctid"] = $bufs[2];
184 | }
185 |
186 | // ご利用明細画面を取得する
187 | $as = parse_tag($body, "a");
188 | $c = parse_tag_search($as, "innerHTML", "ご利用明細照会");
189 | if($c != -1) {
190 | $method = "GET";
191 | $uris = parse_uri($as[$c]["href"], $uris);
192 | $query = "";
193 | $cookie = saisoncard_update_cookie($head, $cookie);
194 | list($head, $body) = saisoncard_http11($method, $uris, $query, $cookie);
195 | }
196 |
197 | // 最新の請求月を取得する(お支払日は4日であると仮定する)
198 | $c = preg_match_all("/([0-9]{1,2})" . preg_quote("月お支払分") . "/", $body, $matches);
199 | if($c > 0) {
200 | $matches[1][0] = sprintf("%02d", (integer)$matches[1][0]);
201 | $account["paydate"] = (date("m") <= $matches[1][0]? date("Y"): (string)((integer)date("Y") + 1)) . $matches[1][0] . "04";
202 | }
203 |
204 | $body_old = $body;
205 |
206 | // CSVファイルをダウンロードする
207 | $as = parse_tag($body, "a");
208 | foreach($as as $a) if(parse_tag_search(parse_tag($a["innerHTML"], "img"), "alt", "CSVダウンロード") != -1) {
209 | $method = "GET";
210 | $uris = parse_uri($a["href"], $uris);
211 | $query = "";
212 | $cookie = saisoncard_update_cookie($head, $cookie);
213 | list($head, $body) = saisoncard_http11($method, $uris, $query, $cookie);
214 | break;
215 | }
216 |
217 | if(strpos($head, "Content-Type: text/html") === false) {
218 | $creditcardmsgsrsv1 = "";
219 | $creditcardmsgsrsv1 .= "";
220 | $creditcardmsgsrsv1 .= "\r\n";
221 |
222 | $creditcardmsgsrsv1 .= "";
223 | $creditcardmsgsrsv1 .= "\r\n";
224 | $creditcardmsgsrsv1 .= "0";
225 | $creditcardmsgsrsv1 .= "\r\n";
226 | $creditcardmsgsrsv1 .= "0
INFO";
227 | $creditcardmsgsrsv1 .= "\r\n";
228 | $creditcardmsgsrsv1 .= "";
229 | $creditcardmsgsrsv1 .= "\r\n";
230 | $creditcardmsgsrsv1 .= "" . ENV_STR_OFX_CURRENCY_JPY . "";
231 | $creditcardmsgsrsv1 .= "\r\n";
232 | $creditcardmsgsrsv1 .= "";
233 | $creditcardmsgsrsv1 .= "" . $account["acctid"] . "";
234 | $creditcardmsgsrsv1 .= "";
235 | $creditcardmsgsrsv1 .= "\r\n";
236 | $creditcardmsgsrsv1 .= saisoncard_parse_csv($body, $account);
237 | $creditcardmsgsrsv1 .= "";
238 | $creditcardmsgsrsv1 .= "\r\n";
239 | $creditcardmsgsrsv1 .= "";
240 | $creditcardmsgsrsv1 .= "\r\n";
241 |
242 | $creditcardmsgsrsv1 .= "";
243 | $creditcardmsgsrsv1 .= "\r\n";
244 | }
245 |
246 | $body = $body_old;
247 |
248 | // 実行時間(タイムアウト)を再設定する
249 | @set_time_limit(ENV_NUM_TIMEOUT);
250 |
251 | // ログアウトする
252 | $as = parse_tag($body, "a");
253 | foreach($as as $a) if(parse_tag_search(parse_tag($a["innerHTML"], "img"), "alt", "ログアウト") != -1) {
254 | $method = "GET";
255 | $uris = parse_uri($a["href"], $uris);
256 | $query = "";
257 | $cookie = saisoncard_update_cookie($head, $cookie);
258 | list($head, $body) = saisoncard_http11($method, $uris, $query, $cookie);
259 | break;
260 | }
261 |
262 | // OFXファイルを出力する
263 | $resp["status"] = ENV_NUM_STATUS_SUCCESS;
264 | if(strpos($creditcardmsgsrsv1, "") === false) {
265 | // 明細が存在しない場合
266 | $resp["ofx"] = generate_ofx($resp["status"]);
267 | } else {
268 | // 明細が存在する場合
269 | $resp["ofx"] = generate_ofx($resp["status"], $creditcardmsgsrsv1);
270 | }
271 | }
272 | return $resp;
273 |
274 | // HTTP/1.1
275 | function saisoncard_http11($method, $uris, $query = "", $cookie = "") {
276 | $ret = "INVALID HOST";
277 | if(preg_match("/\.saisoncard\.co\.jp$/", $uris["host"]) > 0) $ret = http11(strtoupper($method), $uris["scheme"], $uris["host"], 0, $uris["path"], $query, "", $cookie);
278 | return explode("\r\n\r\n", $ret, 2);
279 | }
280 |
281 | function saisoncard_update_cookie($head, $cookie) {
282 | return update_cookie(array("JSESSIONID"), parse_header($head, "set-cookie"), $cookie);
283 | }
284 |
285 | function saisoncard_parse_csv($str, $account) {
286 | $ret = "";
287 | $lines = parse_csv(mb_convert_string($str));
288 | $cds = array();
289 | $cds_balamt = "0";
290 | $cds_paydate = $account["paydate"];
291 | $cds_s = "";
292 | $cds_e = "";
293 | $cd_date = "";
294 | $cd_num = 0;
295 | $ledge_balamt = 0;
296 |
297 | foreach($lines as $line) {
298 | $cd = array();
299 |
300 | if(count($line) == 2) {
301 | switch($line[0]) {
302 | case "お支払日":
303 | $cds_paydate = parse_date($line[1]);
304 | break;
305 | case "今回ご請求額":
306 | $cds_balamt = (string)(double)parse_amount($line[1]);
307 | $ledge_balamt = (double)$cds_balamt;
308 | break;
309 | case "カード名称":
310 | default:
311 | break;
312 | }
313 | } else if(count($line) == 7 && $line[0] != "利用日") {
314 | // PAYMENT固定とする
315 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_PAYMENT;
316 |
317 | // 日付を取得する
318 | $cd["DTPOSTED"] = parse_date($line[0]);
319 | if($cds_s == "") $cds_s = $cd["DTPOSTED"];
320 | $cds_e = $cd["DTPOSTED"];
321 |
322 | // 通番を生成する
323 | if($cd["DTPOSTED"] == $cd_date) $cd_num++; else $cd_num = 0;
324 |
325 | // トランザクション番号を生成する
326 | $cd["FITID"] = $cd["DTPOSTED"] . sprintf("%04d", $account["id"]) . substr($account["paydate"], 4, 2) . "0" . sprintf("%05d", $cd_num);
327 |
328 | // 摘要を取得する
329 | $cd["NAME"] = $line[1];
330 |
331 | // 金額を取得する
332 | $cd["TRNAMT"] = (string)(-1 * (double)parse_amount($line[5]));
333 | $ledge_balamt += (double)$cd["TRNAMT"];
334 |
335 | // 残高を取得する
336 | $cd["MEMO"] = ($line[6] != ""? $line[6]: ENV_STR_OFX_MEMO);
337 |
338 | array_push($cds, $cd);
339 | $cd_date = $cd["DTPOSTED"];
340 | }
341 | }
342 |
343 | if($cds_s == "") $cds_s = ENV_STR_DATE_TODAY;
344 | if($cds_e == "") $cds_e = ENV_STR_DATE_TODAY;
345 | if($cds_s > $cds_e) $cds_e = $cds_s;
346 |
347 | // クレジットカード支払請求を明細に追加する
348 | $i = count($cds);
349 | $cds[$i]["DTPOSTED"] = $cds_paydate;
350 | $cds[$i]["NAME"] = $account["name"];
351 | $cds[$i]["MEMO"] = ENV_STR_OFX_MEMO;
352 | $cds[$i]["TRNAMT"] = $cds_balamt;
353 | $cds[$i]["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_DIRECTDEBIT;
354 | $cds[$i]["FITID"] = $cds[$i]["DTPOSTED"] . sprintf("%04d", $account["id"]) . substr($account["paydate"], 4, 2) . "100000";
355 |
356 | // BANKTRANLIST
357 | $ret .= "";
358 | $ret .= "\r\n";
359 | $ret .= "" . $cds_s . ENV_STR_OFX_TZ . "";
360 | $ret .= "" . $cds_e . ENV_STR_OFX_TZ . "";
361 | $ret .= "\r\n";
362 |
363 | foreach($cds as $cd) {
364 | $ret .= "";
365 | $ret .= "" . $cd["TRNTYPE"] . "";
366 | $ret .= "" . $cd["DTPOSTED"] . ENV_STR_OFX_TZ . "";
367 | $ret .= "" . $cd["TRNAMT"] . "";
368 | $ret .= "" . $cd["FITID"] . "";
369 | $ret .= "" . $cd["NAME"] . "";
370 | $ret .= "" . $cd["MEMO"] . "";
371 | $ret .= "";
372 | $ret .= "\r\n";
373 | }
374 |
375 | $ret .= "";
376 | $ret .= "\r\n";
377 |
378 | // 支払後残高を出力する
379 | $ret .= "";
380 | $ret .= "" . (string)$ledge_balamt . "";
381 | $ret .= "" . ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ . "";
382 | $ret .= "";
383 | $ret .= "\r\n";
384 |
385 | // カード名称を出力する
386 | if($account["acctname"] != "") {
387 | $ret .= "" . $account["acctname"] . "";
388 | $ret .= "\r\n";
389 | }
390 |
391 | return $ret;
392 | }
393 |
394 | ?>
395 |
--------------------------------------------------------------------------------
/server/smbccard.inc:
--------------------------------------------------------------------------------
1 | 0) {
30 | $method = "GET";
31 | $uris = parse_uri($locations[0], $uris);
32 | $query = "";
33 | $cookie = smbccard_update_cookie($head, $cookie);
34 | list($head, $body) = smbccard_http11($method, $uris, $query, $cookie);
35 | }
36 | }
37 |
38 | // ログイン画面を取得する
39 | $as = parse_tag($body, "a");
40 |
41 | foreach($as as $a) if(strip_tags($a["innerHTML"]) == "カード会員の方 Vpassログイン") {
42 | $method = "GET";
43 | $uris = parse_uri($a["href"], $uris);
44 | $query = "";
45 | $cookie = smbccard_update_cookie($head, $cookie);
46 | list($head, $body) = smbccard_http11($method, $uris, $query, $cookie);
47 | break;
48 | }
49 |
50 | // ログインする
51 | $forms = parse_tag($body, "form");
52 | $c = parse_tag_search($forms, "name", "InForm");
53 | if($c != -1) {
54 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
55 | $queries = array();
56 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
57 | $queries["userid"] = "userid=" . $user;
58 | $queries["password"] = "password=" . $pass;
59 |
60 | $method = $forms[$c]["method"];
61 | $uris = parse_uri($forms[$c]["action"], $uris);
62 | $query = implode("&", $queries);
63 | $cookie = smbccard_update_cookie($head, $cookie);
64 | list($head, $body) = smbccard_http11($method, $uris, $query, $cookie);
65 | }
66 |
67 | // リダイレクトする
68 | $retry = 0;
69 | while($retry++ < ENV_NUM_HTTP11_RETRY) {
70 | $locations = parse_header($head, "location");
71 | if(count($locations) > 0) {
72 | $method = "GET";
73 | $uris = parse_uri($locations[0], $uris);
74 | $query = "";
75 | $cookie = smbccard_update_cookie($head, $cookie);
76 | list($head, $body) = smbccard_http11($method, $uris, $query, $cookie);
77 | }
78 | }
79 |
80 | if(strpos($body, "システムメンテナンス中") !== false) {
81 | // システムメンテナンス画面の場合
82 | $resp["status"] = ENV_NUM_STATUS_MAINTENANCE;
83 | $resp["method"] = $method;
84 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
85 | $resp["query"] = $query;
86 | $resp["cookie"] = $cookie;
87 | $resp["head"] = $head;
88 | $resp["body"] = $body;
89 | $resp["ofx"] = generate_ofx($resp["status"]);
90 | } else if(strpos($body, "IDまたはパスワードが無効となっております") !== false) {
91 | // ログイン後の画面が通常と異なる場合
92 | $resp["status"] = ENV_NUM_STATUS_CAUTION;
93 | $resp["method"] = $method;
94 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
95 | $resp["query"] = $query;
96 | $resp["cookie"] = $cookie;
97 | $resp["head"] = $head;
98 | $resp["body"] = $body;
99 | $resp["ofx"] = generate_ofx($resp["status"]);
100 | } else if(strpos($body, "ログイン中") === false) {
101 | // ログイン失敗の場合
102 | $resp["status"] = ENV_NUM_STATUS_FAILURE;
103 | $resp["method"] = $method;
104 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
105 | $resp["query"] = $query;
106 | $resp["cookie"] = $cookie;
107 | $resp["head"] = $head;
108 | $resp["body"] = $body;
109 | $resp["ofx"] = generate_ofx($resp["status"]);
110 | } else {
111 | $account = array();
112 | $account["flag"] = false;
113 | $account["paydate"] = "00000000";
114 | $account["balamt"] = "0";
115 |
116 | // 実行時間(タイムアウト)を再設定する
117 | @set_time_limit(ENV_NUM_TIMEOUT);
118 |
119 | if(strpos($body, "パスワード変更に関するお願い") !== false) {
120 | // パスワード変更に関するお願い画面の場合、ログイン中 カード会員の方TOP画面を取得する
121 | $as = parse_tag($body, "a");
122 | foreach($as as $a) if(parse_tag_search(parse_tag($a["innerHTML"], "img"), "alt", "ログイン中 カード会員の方TOP") != -1) {
123 | $method = "GET";
124 | $uris = parse_uri($a["href"], $uris);
125 | $query = "";
126 | $cookie = smbccard_update_cookie($head, $cookie);
127 | list($head, $body) = smbccard_http11($method, $uris, $query, $cookie);
128 | break;
129 | }
130 | }
131 |
132 | // カード名称を取得する
133 | $fonts = parse_tag($body, "font");
134 | $c = parse_tag_search($fonts, "color", "#006633");
135 | if($c != -1) {
136 | $account["acctname"] = implode(ENV_CHR_CONCATENATOR, array($settings["name"], trim(strip_tags($fonts[$c]["innerHTML"]))));
137 | $account["name"] = $settings["name"];
138 | }
139 |
140 | // ご利用明細画面を取得する
141 | // 最新月の確定済みの明細が0件の場合、カード番号を取得できないため、デフォルトで表示される(最新月以前で明細が1件以上ある月の)ご利用明細画面を取得する
142 | $as = parse_tag($body, "a");
143 | foreach($as as $a) if(parse_tag_search(parse_tag($a["innerHTML"], "img"), "alt", "ご利用明細を見る") != -1) {
144 | $method = "GET";
145 | $uris = parse_uri($a["href"], $uris);
146 | $query = "";
147 | $cookie = smbccard_update_cookie($head, $cookie);
148 | list($head, $body) = smbccard_http11($method, $uris, $query, $cookie);
149 | break;
150 | }
151 |
152 | // カード番号を取得する
153 | $trs = parse_tag($body, "tr", true); // 再帰的に取得する
154 | foreach($trs as $tr) {
155 | $tds = parse_tag($tr["innerHTML"], "td");
156 | if(count($tds) == 2 && $tds[0]["class"] == "sdbc2") {
157 | $account["acctid"] = trim(strip_tags($tds[0]["innerHTML"]));
158 | break;
159 | }
160 | }
161 | if($account["acctid"] == "") $account["acctid"] = $user;
162 |
163 | // お支払いについて画面を取得する
164 | $as = parse_tag($body, "a");
165 | foreach($as as $a) if(parse_tag_search(parse_tag($a["innerHTML"], "img"), "alt", "お支払いについて") != -1) {
166 | $method = "GET";
167 | $uris = parse_uri($a["href"], $uris);
168 | $query = "";
169 | $cookie = smbccard_update_cookie($head, $cookie);
170 | list($head, $body) = smbccard_http11($method, $uris, $query, $cookie);
171 | break;
172 | }
173 |
174 | // お支払い金額照会画面を取得する
175 | $as = parse_tag($body, "a");
176 | $c = parse_tag_search($as, "innerHTML", "お支払い金額照会");
177 | if($c != -1) {
178 | $method = "GET";
179 | $uris = parse_uri($as[$c]["href"], $uris);
180 | $query = "";
181 | $cookie = smbccard_update_cookie($head, $cookie);
182 | list($head, $body) = smbccard_http11($method, $uris, $query, $cookie);
183 | }
184 |
185 | // (最新月の確定済みの)ご利用明細画面を取得する
186 | $trs = parse_tag($body, "tr", true); // 再帰的に取得する
187 | $uri = "";
188 | foreach($trs as $tr) {
189 | $tds = parse_tag($tr["innerHTML"], "td");
190 | if(count($tds) == 3 && strpos($tds[0]["innerHTML"], "確定分") !== false) {
191 | // お支払日を取得する
192 | if(preg_match("/([0-9]{1,2})" . preg_quote("月") . "([0-9]{1,2})" . preg_quote("日お支払い 確定分") . "/", trim(strip_tags($tds[0]["innerHTML"])), $matches) > 0) {
193 | $matches[1] = sprintf("%02d", (integer)$matches[1]);
194 | $matches[2] = sprintf("%02d", (integer)$matches[2]);
195 | $account["paydate"] = (date("m") <= $matches[1]? date("Y"): (string)((integer)date("Y") + 1)) . $matches[1] . $matches[2];
196 | }
197 |
198 | // お支払合計額を取得する
199 | $account["balamt"] = parse_amount(strip_tags($tds[1]["innerHTML"]));
200 |
201 | $as = parse_tag($tds[2]["innerHTML"], "a");
202 | if(count($as) > 0 && parse_tag_search(parse_tag($as[0]["innerHTML"], "img"), "alt", "") != -1) $uri = $as[0]["href"];
203 | // breakしない
204 | }
205 | }
206 | if($uri != "") {
207 | $method = "GET";
208 | $uris = parse_uri($uri, $uris);
209 | $query = "";
210 | $cookie = smbccard_update_cookie($head, $cookie);
211 | list($head, $body) = smbccard_http11($method, $uris, $query, $cookie);
212 | }
213 |
214 | $body_old = $body;
215 |
216 | // CSVファイルをダウンロードする
217 | $as = parse_tag($body, "a");
218 | $c = parse_tag_search($as, "innerHTML", "CSV形式で保存");
219 | if($c != -1) {
220 | $method = "GET";
221 | $uris = parse_uri($as[$c]["href"], $uris);
222 | $query = "";
223 | $cookie = smbccard_update_cookie($head, $cookie);
224 | list($head, $body) = smbccard_http11($method, $uris, $query, $cookie);
225 | }
226 |
227 | $creditcardmsgsrsv1 = "";
228 | $creditcardmsgsrsv1 .= "";
229 | $creditcardmsgsrsv1 .= "\r\n";
230 |
231 | $creditcardmsgsrsv1 .= "";
232 | $creditcardmsgsrsv1 .= "\r\n";
233 | $creditcardmsgsrsv1 .= "0";
234 | $creditcardmsgsrsv1 .= "\r\n";
235 | $creditcardmsgsrsv1 .= "0
INFO";
236 | $creditcardmsgsrsv1 .= "\r\n";
237 | $creditcardmsgsrsv1 .= "";
238 | $creditcardmsgsrsv1 .= "\r\n";
239 | $creditcardmsgsrsv1 .= "" . ENV_STR_OFX_CURRENCY_JPY . "";
240 | $creditcardmsgsrsv1 .= "\r\n";
241 | $creditcardmsgsrsv1 .= "";
242 | $creditcardmsgsrsv1 .= "" . $account["acctid"] . "";
243 | $creditcardmsgsrsv1 .= "";
244 | $creditcardmsgsrsv1 .= "\r\n";
245 | $creditcardmsgsrsv1 .= smbccard_parse_csv($body, $account); // 0固定?(要検討)
246 | $creditcardmsgsrsv1 .= "";
247 | $creditcardmsgsrsv1 .= "\r\n";
248 | $creditcardmsgsrsv1 .= "";
249 | $creditcardmsgsrsv1 .= "\r\n";
250 |
251 | $creditcardmsgsrsv1 .= "";
252 | $creditcardmsgsrsv1 .= "\r\n";
253 |
254 | $body = $body_old;
255 |
256 | // 実行時間(タイムアウト)を再設定する
257 | @set_time_limit(ENV_NUM_TIMEOUT);
258 |
259 | // ログアウトする
260 | $as = parse_tag($body, "a");
261 | foreach($as as $a) if(parse_tag_search(parse_tag($a["innerHTML"], "img"), "alt", "ログアウト") != -1) {
262 | $method = "GET";
263 | $uris = parse_uri($a["href"], $uris);
264 | $query = "";
265 | $cookie = smbccard_update_cookie($head, $cookie);
266 | list($head, $body) = smbccard_http11($method, $uris, $query, $cookie);
267 | break;
268 | }
269 |
270 | // リダイレクトする
271 | $retry = 0;
272 | while($retry++ < ENV_NUM_HTTP11_RETRY) {
273 | $locations = parse_header($head, "location");
274 | if(count($locations) > 0) {
275 | $method = "GET";
276 | $uris = parse_uri($locations[0], $uris);
277 | $query = "";
278 | $cookie = smbccard_update_cookie($head, $cookie);
279 | list($head, $body) = smbccard_http11($method, $uris, $query, $cookie);
280 | }
281 | }
282 |
283 | // OFXファイルを出力する
284 | $resp["status"] = ENV_NUM_STATUS_SUCCESS;
285 | if(strpos($creditcardmsgsrsv1, "") === false) {
286 | // 明細が存在しない場合
287 | $resp["ofx"] = generate_ofx($resp["status"]);
288 | } else {
289 | // 明細が存在する場合
290 | $resp["ofx"] = generate_ofx($resp["status"], $creditcardmsgsrsv1);
291 | }
292 | }
293 | return $resp;
294 |
295 | // HTTP/1.1
296 | function smbccard_http11($method, $uris, $query = "", $cookie = "") {
297 | $ret = "INVALID HOST";
298 | if(preg_match("/\.smbc-card\.com$/", $uris["host"]) > 0) $ret = http11(strtoupper($method), $uris["scheme"], $uris["host"], 0, $uris["path"], $query, "", $cookie);
299 | return explode("\r\n\r\n", $ret, 2);
300 | }
301 |
302 | function smbccard_update_cookie($head, $cookie) {
303 | return update_cookie(array("vpasssession", "pass", "ch"), parse_header($head, "set-cookie"), $cookie);
304 | }
305 |
306 | function smbccard_parse_csv($str, $account) {
307 | $ret = "";
308 | $lines = array_reverse(parse_csv(mb_convert_string($str)));
309 | $cds = array();
310 | $cds_balamt = "0";
311 | $cds_s = "";
312 | $cds_e = "";
313 | $cd_date = "";
314 | $cd_num = 0;
315 |
316 | // 今回お支払金額を取得する
317 | $ledge_balamt = (double)$account["balamt"];
318 |
319 | foreach($lines as $line) {
320 | $cd = array();
321 |
322 | if(count($line) == 7 && $line[0] != "") {
323 | // WEB明細書CSVの場合
324 |
325 | // PAYMENT固定とする
326 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_PAYMENT;
327 |
328 | // 日付を取得する
329 | $cd["DTPOSTED"] = parse_date($line[0]);
330 | if($cds_s == "") $cds_s = $cd["DTPOSTED"];
331 | $cds_e = $cd["DTPOSTED"];
332 |
333 | // 通番を生成する
334 | if($cd["DTPOSTED"] == $cd_date) $cd_num++; else $cd_num = 0;
335 |
336 | // トランザクション番号を生成する
337 | $cd["FITID"] = $cd["DTPOSTED"] . "0000" . substr($account["paydate"], 4, 2) . "0" . sprintf("%05d", $cd_num);
338 |
339 | // 摘要を取得する
340 | $cd["NAME"] = $line[1];
341 |
342 | // 金額を取得する
343 | $cd["TRNAMT"] = (string)(-1 * (double)parse_amount($line[5]));
344 | $ledge_balamt += (double)$cd["TRNAMT"];
345 |
346 | // 残高を取得する
347 | $cd["MEMO"] = ($line[7] != ""? $line[7]: ENV_STR_OFX_MEMO);
348 |
349 | array_push($cds, $cd);
350 | $cd_date = $cd["DTPOSTED"];
351 | } else if(count($line) == 13) {
352 | // ご利用明細照会CSVの場合
353 |
354 | // PAYMENT固定とする
355 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_PAYMENT;
356 |
357 | // 日付を取得する
358 | $cd["DTPOSTED"] = parse_date($line[0]);
359 | if($cds_s == "") $cds_s = $cd["DTPOSTED"];
360 | $cds_e = $cd["DTPOSTED"];
361 |
362 | // 通番を生成する
363 | if($cd["DTPOSTED"] == $cd_date) $cd_num++; else $cd_num = 0;
364 |
365 | // トランザクション番号を生成する
366 | $cd["FITID"] = $cd["DTPOSTED"] . "0000" . substr($account["paydate"], 4, 2) . "0" . sprintf("%05d", $cd_num);
367 |
368 | // 摘要を取得する
369 | $cd["NAME"] = $line[1];
370 |
371 | // 金額を取得する
372 | $cd["TRNAMT"] = (string)(-1 * (double)parse_amount($line[6]));
373 | $ledge_balamt += (double)$cd["TRNAMT"];
374 |
375 | // 残高を取得する
376 | $cd["MEMO"] = ($line[3] != ""? $line[3]: ENV_STR_OFX_MEMO);
377 |
378 | array_push($cds, $cd);
379 | $cd_date = $cd["DTPOSTED"];
380 | }
381 | }
382 |
383 | if($cds_s == "") $cds_s = ENV_STR_DATE_TODAY;
384 | if($cds_e == "") $cds_e = ENV_STR_DATE_TODAY;
385 | if($cds_s > $cds_e) $cds_e = $cds_s;
386 |
387 | // クレジットカード支払請求を明細に追加する
388 | $i = count($cds);
389 | $cds[$i]["DTPOSTED"] = $account["paydate"];
390 | $cds[$i]["NAME"] = $account["name"];
391 | $cds[$i]["MEMO"] = ENV_STR_OFX_MEMO;
392 | $cds[$i]["TRNAMT"] = $account["balamt"];
393 | $cds[$i]["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_DIRECTDEBIT;
394 | $cds[$i]["FITID"] = $cds[$i]["DTPOSTED"] . "0000" . substr($account["paydate"], 4, 2) . "100000";
395 |
396 | // BANKTRANLIST
397 | $ret .= "";
398 | $ret .= "\r\n";
399 | $ret .= "" . $cds_s . ENV_STR_OFX_TZ . "";
400 | $ret .= "" . $cds_e . ENV_STR_OFX_TZ . "";
401 | $ret .= "\r\n";
402 |
403 | foreach($cds as $cd) {
404 | $ret .= "";
405 | $ret .= "" . $cd["TRNTYPE"] . "";
406 | $ret .= "" . $cd["DTPOSTED"] . ENV_STR_OFX_TZ . "";
407 | $ret .= "" . $cd["TRNAMT"] . "";
408 | $ret .= "" . $cd["FITID"] . "";
409 | $ret .= "" . $cd["NAME"] . "";
410 | $ret .= "" . $cd["MEMO"] . "";
411 | $ret .= "";
412 | $ret .= "\r\n";
413 | }
414 |
415 | $ret .= "";
416 | $ret .= "\r\n";
417 | $ret .= "";
418 | $ret .= "" . (string)$ledge_balamt . "";
419 | $ret .= "" . ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ . "";
420 | $ret .= "";
421 | $ret .= "\r\n";
422 |
423 | // カード名称を出力する
424 | if($account["acctname"] != "") {
425 | $ret .= "" . $account["acctname"] . "";
426 | $ret .= "\r\n";
427 | }
428 |
429 | return $ret;
430 | }
431 |
432 | ?>
433 |
--------------------------------------------------------------------------------
/server/smcprepaide.inc:
--------------------------------------------------------------------------------
1 | 0) {
41 | $method = "GET";
42 | $uris = parse_uri($locations[0], $uris);
43 | $query = "";
44 | $cookie = smcprepaide_update_cookie($head, $cookie);
45 | list($head, $body) = smcprepaide_http11($method, $uris, $query, $cookie);
46 | }
47 | }
48 |
49 | // ログイン画面を取得する
50 | $as = parse_tag($body, "a");
51 | foreach($as as $a) if(parse_tag_search(parse_tag($a["innerHTML"], "img"), "alt", "ログイン") != -1) {
52 | $method = "GET";
53 | $uris = parse_uri($a["href"], $uris);
54 | $query = "";
55 | $cookie = smcprepaide_update_cookie($head, $cookie);
56 | list($head, $body) = smcprepaide_http11($method, $uris, $query, $cookie);
57 | break;
58 | }
59 |
60 | // リダイレクトする
61 | $scripts = parse_tag($body, "script");
62 | foreach($scripts as $script) if(preg_match("/window\.location[\s\t]*=[\s\t]*\"(.*?)\";/i", $script["innerHTML"], $matches) > 0) {
63 | $method = "GET";
64 | $uris = parse_uri($matches[1], $uris);
65 | $query = "";
66 | $cookie = smcprepaide_update_cookie($head, $cookie);
67 | list($head, $body) = smcprepaide_http11($method, $uris, $query, $cookie);
68 | break;
69 | }
70 |
71 | // svidを取得する
72 | $svid = "";
73 | $scripts = parse_tag($body, "script");
74 | foreach($scripts as $script) if(preg_match("/svid[\s\t]*=[\s\t]*\"(.*?)\";/i", $script["innerHTML"], $matches) > 0) {
75 | $svid = $matches[1];
76 | break;
77 | }
78 |
79 | // 画像認証の画像を取得する
80 | $imgs = parse_tag($body, "img");
81 | $c = parse_tag_search($imgs, "id", "captchaImage");
82 | if($c != -1) {
83 | $imguris = parse_uri($imgs[$c]["src"], $uris);
84 | list($imghead, $imgbody) = smcprepaide_http11($method, $imguris, $query, $cookie, $uris["scheme"] . "://" . $uris["host"] . $uris["path"] . $query);
85 | $imgsrc = "data:image/jpeg;base64," . base64_encode($imgbody);
86 | $cookie = smcprepaide_update_cookie($imghead, $cookie);
87 | }
88 |
89 | // ログインする
90 | $forms = parse_tag($body, "form");
91 | $c = parse_tag_search($forms, "id", "WB0102SC01Form");
92 | if($c != -1) {
93 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
94 | $queries = array();
95 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
96 | $queries["loginId"] = "loginId=" . $user;
97 | $queries["loginPassword"] = "loginPassword=" . $pass;
98 | $queries["authCode"] = "authCode=";
99 | // if(isset($queries["forward_login"]) == true) unset($queries["forward_login"]);
100 |
101 | $method = $forms[$c]["method"];
102 | $uris = parse_uri($forms[$c]["action"], $uris);
103 | $query = implode("&", $queries);
104 | }
105 |
106 | // セッションを退避する
107 | $sid = 1;
108 | $head = "";
109 | $body = "";
110 | } else if($sid == 1) {
111 | // セッションを復元する
112 | $sid = 0;
113 | $uris = parse_uri($uri);
114 | $query = str_replace("authCode=", "authCode=" . $auth, $query);
115 | list($head, $body) = smcprepaide_http11($method, $uris, $query, $cookie);
116 | }
117 |
118 | if($sid > 0) {
119 | // セッションを引き継ぐ
120 | $resp["status"] = ENV_NUM_STATUS_ADDITION;
121 | $resp["aid"] = "authCode";
122 | $resp["additional"] = $imgsrc;
123 | $resp["sid"] = $sid;
124 | $resp["sesscookie"] = sess_encode(implode("\t", array($cookie, ENV_STR_SESSION_PADDING)));
125 | $resp["accesskey"] = sess_encode(implode("\t", array((string)$sid, $method, $uris["scheme"] . "://" . $uris["host"] . $uris["path"], $query, $svid, ENV_STR_SESSION_PADDING)));
126 |
127 | $mfachallengetrnrs = "";
128 | $mfachallengetrnrs .= "";
129 | $mfachallengetrnrs .= "";
130 | $mfachallengetrnrs .= "";
131 | $mfachallengetrnrs .= "" . $resp["aid"] . "";
132 | $mfachallengetrnrs .= "" . $resp["additional"] . "";
133 | $mfachallengetrnrs .= "";
134 | $mfachallengetrnrs .= "";
135 | $mfachallengetrnrs .= "";
136 |
137 | $resp["ofx"] = generate_ofx($resp["status"], $mfachallengetrnrs, $resp["sesscookie"], $resp["accesskey"]);
138 | } else if(strpos($body, "定例または臨時メンテナンスのため") !== false) {
139 | // システムメンテナンス画面の場合
140 | $resp["status"] = ENV_NUM_STATUS_MAINTENANCE;
141 | $resp["method"] = $method;
142 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
143 | $resp["query"] = $query;
144 | $resp["cookie"] = $cookie;
145 | $resp["head"] = $head;
146 | $resp["body"] = $body;
147 | $resp["ofx"] = generate_ofx($resp["status"]);
148 | } else if(strpos($body, "重要なお知らせがあります") !== false) {
149 | // ログイン後の画面が通常と異なる場合
150 | $resp["status"] = ENV_NUM_STATUS_CAUTION;
151 | $resp["method"] = $method;
152 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
153 | $resp["query"] = $query;
154 | $resp["cookie"] = $cookie;
155 | $resp["head"] = $head;
156 | $resp["body"] = $body;
157 | $resp["ofx"] = generate_ofx($resp["status"]);
158 | } else if(strpos($body, "前回ログイン") === false) {
159 | // ログイン失敗の場合
160 | $resp["status"] = ENV_NUM_STATUS_FAILURE;
161 | $resp["method"] = $method;
162 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
163 | $resp["query"] = $query;
164 | $resp["cookie"] = $cookie;
165 | $resp["head"] = $head;
166 | $resp["body"] = $body;
167 | $resp["ofx"] = generate_ofx($resp["status"]);
168 | } else {
169 | $accounts = array();
170 |
171 | // 口座数分ループする
172 | $forms = parse_tag($body, "form");
173 | for($c = 1; $c < count($forms); $c++) {
174 | // 登録カード詳細画面を取得する
175 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
176 | $queries = array();
177 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
178 | // if(isset($queries["forward_toWB3202SC01"]) == true) unset($queries["forward_toWB3202SC01"]); // 詳細
179 | if(isset($queries["forward_toWB2301SC01"]) == true) unset($queries["forward_toWB2301SC01"]); // チャージ
180 | if(isset($queries["forward_toWB2601SC01"]) == true) unset($queries["forward_toWB2601SC01"]); // ロック
181 | if(isset($queries["forward_toWB2602SC01"]) == true) unset($queries["forward_toWB2602SC01"]); // ロック解除
182 | if(isset($queries["forward_toWB3301SC01"]) == true) unset($queries["forward_toWB3301SC01"]); // 利用履歴照会
183 | if(isset($queries["forward_toWB2901SC01"]) == true) unset($queries["forward_toWB2901SC01"]); // 暗証番号設定
184 |
185 | $method = $forms[$c]["method"];
186 | $uris = parse_uri($forms[$c]["action"], $uris);
187 | $query = implode("&", $queries);
188 | $cookie = smcprepaide_update_cookie($head, $cookie);
189 | list($head, $body) = smcprepaide_http11($method, $uris, $query, $cookie);
190 |
191 | // 利用履歴照会画面を取得する
192 | $forms2 = parse_tag($body, "form");
193 | $inputs = parse_tag($forms2[0]["innerHTML"], "input");
194 |
195 | // 口座名(ニックネーム)を取得する
196 | $d = parse_tag_search($inputs, "name", "cardNickname");
197 | if($d != -1) $accounts[$c - 1]["acctname"] = $settings["name"] . ENV_CHR_CONCATENATOR . $inputs[$d]["value"];
198 |
199 | // 支店番号を取得する
200 | $accounts[$c - 1]["branchid"] = "0";
201 |
202 | // 口座番号を取得する
203 | $d = parse_tag_search($inputs, "name", "vcn");
204 | if($d != -1) $accounts[$c - 1]["acctid"] = $inputs[$d]["value"];
205 |
206 | // 残高を取得する
207 | $d = parse_tag_search($inputs, "name", "chargeBalance");
208 | if($d != -1) $accounts[$c - 1]["balance"] = $inputs[$d]["value"];
209 |
210 | $queries = array();
211 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
212 | unset($queries["forward_toWB2301SC01"]); // チャージ
213 | // if(isset($queries["forward_toWB3301SC01"]) == true) unset($queries["forward_toWB3301SC01"]); // 利用履歴照会
214 | if(isset($queries["forward_toWB2601SC01"]) == true) unset($queries["forward_toWB2601SC01"]); // ご利用ロック設定・解除
215 | if(isset($queries["forward_toWB2701SC01"]) == true) unset($queries["forward_toWB2701SC01"]); // カード名称の変更
216 | if(isset($queries["forward_toWB2901SC01"]) == true) unset($queries["forward_toWB2901SC01"]); // 暗証番号設定
217 | if(isset($queries["forward_toWB3201SC01"]) == true) unset($queries["forward_toWB3201SC01"]); // 戻る
218 |
219 | $method = $forms2[0]["method"];
220 | $uris = parse_uri($forms2[0]["action"], $uris);
221 | $query = implode("&", $queries);
222 | $cookie = smcprepaide_update_cookie($head, $cookie);
223 | list($head, $body) = smcprepaide_http11($method, $uris, $query, $cookie);
224 |
225 | $detail = "";
226 |
227 | do {
228 | $tbodys = parse_tag($body, "tbody");
229 | if(count($tbodys) > 1) $detail .= $tbodys[1]["innerHTML"];
230 |
231 | $as = parse_tag($body, "a");
232 | $d = parse_tag_search($as, "innerHTML", "次へ");
233 | if($d != -1) {
234 | $metod = "GET";
235 | $uris = parse_uri($as[$d]["href"], $uris);
236 | $query = "";
237 | $cookie = smcprepaide_update_cookie($head, $cookie);
238 | list($head, $body) = smcprepaide_http11($method, $uris, $query, $cookie);
239 | }
240 | } while($d != -1);
241 |
242 | if($detail != "") $accounts[$c - 1]["details"] = smcprepaide_get_details($detail);
243 |
244 | /*
245 | // カード一覧画面を取得する
246 | $as = parse_tag($body, "a");
247 | $c = parse_tag_search($as, "innerHTML", "カード一覧");
248 | if($c != -1) {
249 | $method = "GET";
250 | $uris = parse_uri($as[$c]["href"] . $svid, $uris);
251 | $query = "";
252 | $cookie = smcprepaide_update_cookie($head, $cookie);
253 | list($head, $body) = smcprepaide_http11($method, $uris, $query, $cookie);
254 | }
255 | */
256 | }
257 |
258 | // 実行時間(タイムアウト)を再設定する
259 | @set_time_limit(ENV_NUM_TIMEOUT);
260 |
261 | // ログアウトする
262 | $as = parse_tag($body, "a");
263 | foreach($as as $a) if(parse_tag_search(parse_tag($a["innerHTML"], "img"), "alt", "ログアウト") != -1) {
264 | $method = "GET";
265 | $uris = parse_uri($a["href"] . $svid, $uris);
266 | $query = "";
267 | $cookie = smcprepaide_update_cookie($head, $cookie);
268 | list($head, $body) = smcprepaide_http11($method, $uris, $query, $cookie);
269 | break;
270 | }
271 |
272 | $bankmsgsrsv1 = "";
273 | $bankmsgsrsv1 .= "";
274 | $bankmsgsrsv1 .= "\r\n";
275 |
276 | foreach($accounts as $account) {
277 | // 口座情報を取得する
278 | $bankmsgsrsv1 .= "";
279 | $bankmsgsrsv1 .= "\r\n";
280 | $bankmsgsrsv1 .= "0";
281 | $bankmsgsrsv1 .= "\r\n";
282 | $bankmsgsrsv1 .= "0
INFO";
283 | $bankmsgsrsv1 .= "\r\n";
284 | $bankmsgsrsv1 .= "";
285 | $bankmsgsrsv1 .= "\r\n";
286 | $bankmsgsrsv1 .= "" . ENV_STR_OFX_CURRENCY_JPY . "";
287 | $bankmsgsrsv1 .= "\r\n";
288 | $bankmsgsrsv1 .= "";
289 | $bankmsgsrsv1 .= "" . $settings["code"] . "";
290 | $bankmsgsrsv1 .= "" . $account["branchid"] . "";
291 | $bankmsgsrsv1 .= "" . $account["acctid"] . "";
292 | $bankmsgsrsv1 .= "" . ENV_STR_ACCTTYPE_SAVINGS . "";
293 | $bankmsgsrsv1 .= "";
294 | $bankmsgsrsv1 .= "\r\n";
295 | $bankmsgsrsv1 .= smcprepaide_parse_details($account);
296 | $bankmsgsrsv1 .= "";
297 | $bankmsgsrsv1 .= "\r\n";
298 | $bankmsgsrsv1 .= "";
299 | $bankmsgsrsv1 .= "\r\n";
300 | }
301 |
302 | $bankmsgsrsv1 .= "";
303 | $bankmsgsrsv1 .= "\r\n";
304 |
305 | // OFXファイルを出力する
306 | $resp["status"] = ENV_NUM_STATUS_SUCCESS;
307 | if(strpos($bankmsgsrsv1, "") === false) {
308 | // 明細が存在しない場合
309 | $resp["ofx"] = generate_ofx($resp["status"]);
310 | } else {
311 | // 明細が存在する場合
312 | $resp["ofx"] = generate_ofx($resp["status"], $bankmsgsrsv1);
313 | }
314 | }
315 | return $resp;
316 |
317 | // HTTP/1.1
318 | function smcprepaide_http11($method, $uris, $query = "", $cookie = "", $referer = "") {
319 | $ret = "INVALID HOST";
320 | if(preg_match("/\.smbc-card\.com$/", $uris["host"]) > 0 || preg_match("/\.vpass\.ne\.jp$/", $uris["host"]) > 0) $ret = http11(strtoupper($method), $uris["scheme"], $uris["host"], 0, $uris["path"], $query, "", $cookie, true, ENV_PRODUCT_UA, "", $referer);
321 | return explode("\r\n\r\n", $ret, 2);
322 | }
323 |
324 | function smcprepaide_update_cookie($head, $cookie) {
325 | return update_cookie(array("JSESSIONID"), parse_header($head, "set-cookie"), $cookie);
326 | }
327 |
328 | function smcprepaide_get_details($body) {
329 | $rets = array();
330 | $i = 0;
331 | $trs = array_reverse(parse_tag($body, "tr"));
332 | foreach($trs as $tr) {
333 | $tds = parse_tag($tr["innerHTML"], "td");
334 | if(count($tds) == 9) {
335 | // ご利用日時を取得する
336 | $dt = explode(" ", trim(strip_tags($tds[2]["innerHTML"])));
337 |
338 | // 期限外の明細を除外する
339 | if(ENV_STR_DATE_PASTDAY > parse_date($dt[0])) continue;
340 |
341 | $rets[$i]["date"] = parse_date($dt[0]);
342 |
343 | // 支払区分、ご利用店名、ご入金額、およびご利用金額を取得する
344 | $buf = trim(strip_tags($tds[3]["innerHTML"]));
345 | switch($buf) {
346 | case "仮発行番号入力":
347 | case "返金":
348 | case "チャージ": // debug
349 | $name = $buf;
350 | $memo = trim(strip_tags($tds[8]["innerHTML"]));
351 | $amount = parse_amount(trim(strip_tags($tds[5]["innerHTML"])));
352 | break;
353 | case "利用":
354 | default:
355 | $name = trim(strip_tags($tds[4]["innerHTML"]));
356 | $memo = trim(strip_tags($tds[1]["innerHTML"]));
357 | $memo2 = trim(strip_tags($tds[8]["innerHTML"]));
358 | if($name == "") $name = $buf;
359 | if($memo2 != "") $memo .= ENV_CHR_CONCATENATOR . $memo2;
360 | $amount = "-" . parse_amount(trim(strip_tags($tds[6]["innerHTML"])));
361 | break;
362 | }
363 | $rets[$i]["summary"] = $name;
364 | $rets[$i]["memo"] = ($memo != ""? $memo: ENV_STR_OFX_MEMO);
365 |
366 | // ご利用金額を取得する
367 | $rets[$i]["amount"] = $amount;
368 |
369 | $i++;
370 | }
371 | }
372 |
373 | return $rets;
374 | }
375 |
376 | function smcprepaide_parse_details($account) {
377 | $ret = "";
378 | $cds = array();
379 | $cd_date = "";
380 | $cd_num = 0;
381 | foreach($account["details"] as $line) {
382 | $cd = array();
383 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_DIRECTDEBIT;
384 |
385 | // 日付を取得する
386 | $cd["DTPOSTED"] = $line["date"];
387 |
388 | // 通番を生成する
389 | if($cd["DTPOSTED"] == $cd_date) $cd_num++; else $cd_num = 0;
390 |
391 | // トランザクション番号を生成する
392 | $cd["FITID"] = $cd["DTPOSTED"] . "0000000" . sprintf("%05d", $cd_num);
393 |
394 | // 摘要を取得する
395 | $cd["NAME"] = $line["summary"];
396 |
397 | // 金額を取得する
398 | $cd["TRNAMT"] = parse_amount($line["amount"]);
399 | $cd["MEMO"] = ($line["memo"] != ""? $line["memo"]: ENV_STR_OFX_MEMO);
400 |
401 | array_push($cds, $cd);
402 | $cd_date = $cd["DTPOSTED"];
403 | }
404 | // BANKTRANLIST
405 | $ret .= "";
406 | $ret .= "\r\n";
407 | $ret .= "" . ENV_STR_DATE_PASTDAY . ENV_STR_OFX_TZ . "";
408 | $ret .= "" . ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ . "";
409 | $ret .= "\r\n";
410 |
411 | foreach($cds as $cd) {
412 | $ret .= "";
413 | $ret .= "" . $cd["TRNTYPE"] . "";
414 | $ret .= "" . $cd["DTPOSTED"] . ENV_STR_OFX_TZ . "";
415 | $ret .= "" . $cd["TRNAMT"] . "";
416 | $ret .= "" . $cd["FITID"] . "";
417 | $ret .= "" . $cd["NAME"] . "";
418 | $ret .= "" . $cd["MEMO"] . "";
419 | $ret .= "";
420 | $ret .= "\r\n";
421 | }
422 |
423 | $ret .= "";
424 | $ret .= "\r\n";
425 | $ret .= "";
426 | $ret .= "" . $account["balance"] . "";
427 | $ret .= "" . ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ . "";
428 | $ret .= "";
429 | $ret .= "\r\n";
430 |
431 | // 口座名称を出力する
432 | if($account["acctname"] != "") {
433 | $ret .= "" . $account["acctname"] . "";
434 | $ret .= "\r\n";
435 | }
436 |
437 | return $ret;
438 | }
439 |
440 | ?>
441 |
--------------------------------------------------------------------------------
/server/surugavisacard.inc:
--------------------------------------------------------------------------------
1 | setAcctfrom(array("ACCTID" => $account["acctid"]));
89 |
90 | // メニューから「ご利用明細」を選択
91 | $cds = array();
92 | for ($i=0;$i<6;$i++) {
93 | $forms = parse_tag($body, "form");
94 | $c = parse_tag_search($forms, "name", "meisaiForm");
95 | $page = '/meisai.do';
96 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
97 | $queries = array();
98 | foreach ($inputs as $input) {
99 | if ($input["name"] != "") {
100 | $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
101 | }
102 | }
103 | $queries["month"] = "month=" . $i;
104 | $query = implode("&", $queries);
105 | $cookie = surugavisa_updatecookie($head, $cookie);
106 | list($head, $body) = surugavisa_http11($method, $protocol, $host, $page, $query, $cookie);
107 | // 明細をパース
108 | $cds = array_merge($cds, surugavisa_parsedom($body));
109 | }
110 | usort($cds, function($a, $b) {
111 | return $a['DTPOSTED'] > $b['DTPOSTED'];
112 | });
113 | foreach($cds as $cd) {
114 | $ofxdom->addTran($cd);
115 | }
116 | $cds_balamt = 0;
117 | $cds_s = "";
118 | $cds_e = "";
119 | $items = $ofxdom->getTrans();
120 | foreach ($items as $item) {
121 | $dtposted = $item->DTPOSTED;
122 | // DTSTART, DTENDを取得
123 | if($cds_s == "") $cds_s = $dtposted;
124 | $cds_e = $dtposted;
125 | // 残高を計算
126 | $cds_balamt += (double)$item->TRNAMT;
127 | }
128 |
129 | // DTSTARTとDTENDを設定する
130 | $ofxdom->setDateRange($cds_s, $cds_e);
131 |
132 | // 残高を処理
133 | $cds_balamt = (-1)*$cds_balamt;
134 | $ofxdom->setBalance(array(
135 | 'BALAMT' => $cds_balamt,
136 | 'DTASOF' => ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ
137 | ));
138 |
139 | // FITIDを仕上げる
140 | $ofxdom->setFitid();
141 | // XML DOMツリーを文字列に変換
142 | $xml = $ofxdom->getXML();
143 |
144 | $resp["status"] = ENV_NUM_STATUS_SUCCESS;
145 | $resp["ofx"] = generate_ofx($mode, $xml);
146 |
147 | // 実行時間(タイムアウト)を再設定する
148 | @set_time_limit(ENV_NUM_TIMEOUT);
149 |
150 | // ログアウトする
151 | $forms = parse_tag($body, "form");
152 | $c = parse_tag_search($forms, "name", "logoutForm");
153 | $page = '/logout.do';
154 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
155 | $queries = array();
156 | foreach ($inputs as $input) {
157 | if ($input["name"] != "") {
158 | $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
159 | }
160 | }
161 | $query = implode("&", $queries);
162 | $cookie = surugavisa_updatecookie($head, $cookie);
163 | list($head, $body) = surugavisa_http11($method, $protocol, $host, $page, $query, $cookie);
164 | }
165 | return $resp;
166 |
167 | // HTTP/1.1
168 | function surugavisa_http11($method, $protocol, $host, $page = "/", $query = "", $cookie = "") {
169 | $ret = "INVALID HOST";
170 | if(preg_match("/card\.surugabank\.co\.jp$/", $host) > 0) $ret = http11($method, $protocol, $host, 0, $page, $query, "", $cookie);
171 | if(preg_match("/[Ll][Oo][Cc][Aa][Tt][Ii][Oo][Nn][\s\t]*:[\s\t]*([^\r\n]+)/", $ret, $matches) > 0) {
172 | $urls = parse_url($matches[1]);
173 | if($urls["scheme"] != "") $protocol = $urls["scheme"];
174 | if($urls["host"] != "") $host = $urls["host"];
175 | if($urls["path"] != "") $page = $urls["path"];
176 | $query = ($urls["query"] != ""? $urls["query"]: "");
177 | return surugavisa_http11($method, $protocol, $host, $page, $query, $cookie);
178 | }
179 | return explode("\r\n\r\n", $ret, 2);
180 | }
181 |
182 | function surugavisa_updatecookie($head, $cookie) {
183 | return update_cookie(array("JSESSIONID"), parse_header($head, "set-cookie"), $cookie);
184 | }
185 |
186 | function surugavisa_parsedom($str) {
187 | // 明細表読み込み用DOMツリー作成
188 | $doc = new DOMDocument();
189 | // の前のが,文字化けの原因となるため,削除
190 | preg_match("/()/s", $str, $matches);
191 | $str = $matches[1];
192 | // ヘッダ付加
193 | $str = "<\/head>" . $str . "<\/html>";
194 | // 文字エンコード変換
195 | // $str = mb_convert_encoding($str, 'UTF-8', 'SJIS');
196 | //
197 | $str = str_replace(" ", "", $str);
198 | // HTMLからDOMツリー作成
199 | @$doc->loadHTML($str);
200 | $xpath = new DOMXPath($doc);
201 | // 明細表のテーブルを指定
202 | $rows = $xpath->query("//table[@class='table-type2 clear margin-b-10px']/tr");
203 |
204 | $ret = "";
205 | $cds = array();
206 | $nrow = $rows->length;
207 |
208 | for($i=0; $i<$nrow; $i++) {
209 | $cd = array();
210 | $row = $rows->item($i);
211 | $cols1 = $row->getElementsByTagName('th');
212 | $cols2 = $row->getElementsByTagName('td');
213 | // 利用明細でない行はスキップ
214 | if ($cols1->length != 2) continue;
215 |
216 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_CREDIT;
217 |
218 | // 日付を取得する
219 | preg_match("/([0-9]{4}).*?([0-9]{1,2}).*?([0-9]{1,2})/", str_replace(" ", "", $cols1->item(1)->nodeValue), $matches);
220 | $cd["DTPOSTED"] = sprintf("%d%02d%02d", $matches[1], $matches[2], $matches[3]);
221 | $cd["DTPOSTED"] .= ENV_STR_OFX_TZ;
222 |
223 | // トランザクション番号(請求月とデータ種別)を生成する
224 | $cd["FITID"] = '000';
225 | // 摘要を取得する
226 | $cd["NAME"] = $cols2->item(0)->nodeValue;
227 | // $cd["NAME"] = preg_replace('/-/', mb_convert_encoding('ー', 'UTF-8', 'sjis-win'), $cd["NAME"]);
228 | $cd["NAME"] = str_replace('-', 'ー', $cd["NAME"]);
229 | // 金額を取得する
230 | $cd["TRNAMT"] = (-1)*(double)parse_amount(trim($cols2->item(1)->nodeValue));
231 | if (strpos($cols1->item(0)->nodeValue, "取消") !== false) {
232 | $cd["NAME"] .= "(取消)";
233 | $cd["TRNAMT"] *= -1;
234 | }
235 | array_push($cds, $cd);
236 | }
237 | return $cds;
238 |
239 | }
240 | ?>
241 |
--------------------------------------------------------------------------------
/server/viewcard.inc:
--------------------------------------------------------------------------------
1 | 0) {
42 | $method = "GET";
43 | $uris = parse_uri($locations[0], $uris);
44 | $query = "";
45 | $cookie = viewcard_update_cookie($head, $cookie);
46 | list($head, $body) = viewcard_http11($method, $uris, $query, $cookie);
47 | }
48 | }
49 |
50 | // ログインする
51 | $forms = parse_tag($body, "form");
52 | $c = parse_tag_search($forms, "target", "_self");
53 | if($c != -1) {
54 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
55 | $queries = array();
56 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
57 | $queries["id"] = "id=" . $user;
58 | $queries["pass"] = "pass=" . $pass;
59 |
60 | $method = $forms[$c]["method"];
61 | $uris = parse_uri($forms[$c]["action"], $uris);
62 | $query = implode("&", $queries);
63 | $cookie = viewcard_update_cookie($head, $cookie);
64 | list($head, $body) = viewcard_http11($method, $uris, $query, $cookie);
65 | }
66 |
67 | // リダイレクトする
68 | $retry = 0;
69 | while($retry++ < ENV_NUM_HTTP11_RETRY) {
70 | $locations = parse_header($head, "location");
71 | if(count($locations) > 0) {
72 | $method = "GET";
73 | $uris = parse_uri($locations[0], $uris);
74 | $query = "";
75 | $cookie = viewcard_update_cookie($head, $cookie);
76 | list($head, $body) = viewcard_http11($method, $uris, $query, $cookie);
77 | }
78 | }
79 |
80 | if(strpos($body, "前回ログイン") === false) {
81 | // ログイン失敗の場合
82 | $resp["status"] = ENV_NUM_STATUS_FAILURE;
83 | $resp["method"] = $method;
84 | $resp["uri"] = $uris["scheme"] . "://" . $uris["host"] . $uris["path"];
85 | $resp["query"] = $query;
86 | $resp["cookie"] = $cookie;
87 | $resp["head"] = $head;
88 | $resp["body"] = $body;
89 | $resp["ofx"] = generate_ofx($resp["status"]);
90 | } else {
91 | // ご利用明細照会(お支払方法の変更)画面を取得する
92 | $as = parse_tag($body, "a");
93 | $c = parse_tag_search($as, "alt", "ご利用明細照会(お支払方法の変更)");
94 | if($c != -1) {
95 | $method = "GET";
96 | $uris = parse_uri($as[$c]["href"], $uris);
97 | $query = "";
98 | $cookie = viewcard_update_cookie($head, $cookie);
99 | list($head, $body) = viewcard_http11($method, $uris, $query, $cookie);
100 | }
101 |
102 | // リダイレクトする
103 | $retry = 0;
104 | while($retry++ < ENV_NUM_HTTP11_RETRY) {
105 | $locations = parse_header($head, "location");
106 | if(count($locations) > 0) {
107 | $method = "GET";
108 | $uris = parse_uri($locations[0], $uris);
109 | $query = "";
110 | $cookie = viewcard_update_cookie($head, $cookie);
111 | list($head, $body) = viewcard_http11($method, $uris, $query, $cookie);
112 | }
113 | }
114 |
115 | $accounts = array();
116 |
117 | // カード数を取得する
118 | $selects = parse_tag($body, "select");
119 | $c = parse_tag_search($selects, "name", "DdlCardNO");
120 | if($c != -1) {
121 | $options = parse_tag($selects[$c]["innerHTML"], "option");
122 | for($i = 0; $i < count($options); $i++) {
123 | $accounts[$i]["id"] = $options[$i]["value"];
124 | $accounts[$i]["ym"] = $ym;
125 | if(preg_match("/(.*?)[\s\t]*([0-9\*\-]+)/", trim(strip_tags($options[$i]["innerHTML"])), $matches) > 0) {
126 | // カード名称を取得する
127 | $accounts[$i]["acctname"] = implode(ENV_CHR_CONCATENATOR, array($settings["name"], $matches[1]));
128 |
129 | $accounts[$i]["name"] = $settings["name"];
130 |
131 | // カード番号を取得する
132 | $accounts[$i]["acctid"] = $matches[2];
133 | }
134 | }
135 | }
136 |
137 | $body_old = $body;
138 |
139 | $creditcardmsgsrsv1 = "";
140 | $creditcardmsgsrsv1 .= "";
141 | $creditcardmsgsrsv1 .= "\r\n";
142 |
143 | // カード数分ループする
144 | foreach($accounts as $account) {
145 | $body = $body_old;
146 |
147 | // 実行時間(タイムアウト)を再設定する
148 | @set_time_limit(ENV_NUM_TIMEOUT);
149 |
150 | // 確定済みの最新明細画面を取得する
151 | $forms = parse_tag($body, "form");
152 | $c = parse_tag_search($forms, "name", "Frm002");
153 | if($c != -1) {
154 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
155 | $queries = array();
156 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
157 | $queries["DdlCardNO"] = "DdlCardNO=" . $account["id"];
158 | $queries["__EVENTTARGET"] = "__EVENTTARGET=LnkClaimYm1"; // 確定済みの最新明細
159 |
160 | $method = $forms[$c]["method"];
161 | $uris = parse_uri($forms[$c]["action"], $uris);
162 | $query = implode("&", $queries);
163 | $cookie = viewcard_update_cookie($head, $cookie);
164 | list($head, $body) = viewcard_http11($method, $uris, $query, $cookie);
165 | }
166 |
167 | // リダイレクトする
168 | $retry = 0;
169 | while($retry++ < ENV_NUM_HTTP11_RETRY) {
170 | $locations = parse_header($head, "location");
171 | if(count($locations) > 0) {
172 | $method = "GET";
173 | $uris = parse_uri($locations[0], $uris);
174 | $query = "";
175 | $cookie = viewcard_update_cookie($head, $cookie);
176 | list($head, $body) = viewcard_http11($method, $uris, $query, $cookie);
177 | }
178 | }
179 |
180 | // お支払日は4日であると仮定する
181 | if(strpos($body, "ご請求はございません。") !== false) {
182 | $body = "";
183 | $account["paydate"] = substr(ENV_STR_DATE_TODAY, 0, 6) . "04";
184 | }
185 |
186 | $body_old = $body;
187 |
188 | // 明細CSVをダウンロードする
189 | $forms = parse_tag($body, "form");
190 | $c = parse_tag_search($forms, "name", "Form1");
191 | if($c != -1) {
192 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
193 | $queries = array();
194 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
195 | $queries["DdlCardNO"] = "DdlCardNO=" . $account["id"];
196 | $queries["BtnCsvDownloadTop.x"] = "BtnCsvDownloadTop.x=1";
197 | $queries["BtnCsvDownloadTop.y"] = "BtnCsvDownloadTop.y=1";
198 | if(isset($queries["BtnCsvDownloadTop"]) == true) unset($queries["BtnCsvDownloadTop"]);
199 | if(isset($queries["BtnCsvDownloadBottom"]) == true) unset($queries["BtnCsvDownloadBottom"]);
200 | if(isset($queries["BtnPdfDownloadTop"]) == true) unset($queries["BtnPdfDownloadTop"]);
201 | if(isset($queries["BtnPdfDownloadBottom"]) == true) unset($queries["BtnPdfDownloadBottom"]);
202 | if(isset($queries["BtnList"]) == true) unset($queries["BtnList"]);
203 |
204 | $method = $forms[$c]["method"];
205 | $uris = parse_uri($forms[$c]["action"], $uris);
206 | $query = implode("&", $queries);
207 | $cookie = viewcard_update_cookie($head, $cookie);
208 | list($head, $body) = viewcard_http11($method, $uris, $query, $cookie);
209 | }
210 |
211 | if($body == "" || strpos($head, "Content-Type: text/html") === false) {
212 | $creditcardmsgsrsv1 .= "";
213 | $creditcardmsgsrsv1 .= "\r\n";
214 | $creditcardmsgsrsv1 .= "0";
215 | $creditcardmsgsrsv1 .= "\r\n";
216 | $creditcardmsgsrsv1 .= "0
INFO";
217 | $creditcardmsgsrsv1 .= "\r\n";
218 | $creditcardmsgsrsv1 .= "";
219 | $creditcardmsgsrsv1 .= "\r\n";
220 | $creditcardmsgsrsv1 .= "" . ENV_STR_OFX_CURRENCY_JPY . "";
221 | $creditcardmsgsrsv1 .= "\r\n";
222 | $creditcardmsgsrsv1 .= "";
223 | $creditcardmsgsrsv1 .= "" . $account["acctid"] . "";
224 | $creditcardmsgsrsv1 .= "";
225 | $creditcardmsgsrsv1 .= "\r\n";
226 | $creditcardmsgsrsv1 .= viewcard_parse_csv($body, $account);
227 | $creditcardmsgsrsv1 .= "";
228 | $creditcardmsgsrsv1 .= "\r\n";
229 | $creditcardmsgsrsv1 .= "";
230 | $creditcardmsgsrsv1 .= "\r\n";
231 | }
232 |
233 | $body = $body_old;
234 | }
235 |
236 | $creditcardmsgsrsv1 .= "";
237 | $creditcardmsgsrsv1 .= "\r\n";
238 |
239 | // 実行時間(タイムアウト)を再設定する
240 | @set_time_limit(ENV_NUM_TIMEOUT);
241 |
242 | // ログアウトする
243 | $as = parse_tag($body, "a");
244 | $c = parse_tag_search($as, "innerHTML", "ログアウト"); // ログアウト
245 | if($c != -1) {
246 | $method = "GET";
247 | $uris = parse_uri($as[$c]["href"], $uris);
248 | $query = "";
249 | $cookie = viewcard_update_cookie($head, $cookie);
250 | list($head, $body) = viewcard_http11($method, $uris, $query, $cookie);
251 | }
252 |
253 | // リダイレクトする
254 | $forms = parse_tag($body, "form");
255 | $c = parse_tag_search($forms, "name", "frmMain");
256 | if($c != -1) {
257 | $inputs = parse_tag($forms[$c]["innerHTML"], "input");
258 | $queries = array();
259 | foreach($inputs as $input) if($input["name"] != "") $queries[$input["name"]] = urlencode($input["name"]) . "=" . urlencode($input["value"]);
260 | $queries["Logout.x"] = "Logout.x=0";
261 | $queries["Logout.y"] = "Logout.y=0";
262 |
263 | $method = $forms[$c]["method"];
264 | $uris = parse_uri($forms[$c]["action"], $uris);
265 | $query = implode("&", $queries);
266 | $cookie = viewcard_update_cookie($head, $cookie);
267 | list($head, $body) = viewcard_http11($method, $uris, $query, $cookie);
268 | }
269 |
270 | // リダイレクトする
271 | $retry = 0;
272 | while($retry++ < ENV_NUM_HTTP11_RETRY) {
273 | $locations = parse_header($head, "location");
274 | if(count($locations) > 0) {
275 | $method = "GET";
276 | $uris = parse_uri($locations[0], $uris);
277 | $query = "";
278 | $cookie = viewcard_update_cookie($head, $cookie);
279 | list($head, $body) = viewcard_http11($method, $uris, $query, $cookie);
280 | }
281 | }
282 |
283 | // OFXファイルを出力する
284 | $resp["status"] = ENV_NUM_STATUS_SUCCESS;
285 | if(strpos($creditcardmsgsrsv1, "") === false) {
286 | // 明細が存在しない場合
287 | $resp["ofx"] = generate_ofx($resp["status"]);
288 | } else {
289 | // 明細が存在する場合
290 | $resp["ofx"] = generate_ofx($resp["status"], $creditcardmsgsrsv1);
291 | }
292 | }
293 | return $resp;
294 |
295 | // HTTP/1.1
296 | function viewcard_http11($method, $uris, $query = "", $cookie = "") {
297 | $ret = "INVALID HOST";
298 | if(preg_match("/^viewsnet\.jp$/", $uris["host"]) > 0 || (strtoupper($method) == "GET" && preg_match("/\.jreast\.co\.jp$/", $uris["host"]) > 0)) $ret = http11(strtoupper($method), $uris["scheme"], $uris["host"], 0, $uris["path"], $query, "", $cookie);
299 | return explode("\r\n\r\n", $ret, 2);
300 | }
301 |
302 | function viewcard_update_cookie($head, $cookie) {
303 | return update_cookie(array("BIGipServerPL-VNWEB-PC_WAF-TCP80", "VIEWSNET_WEB", "ASP.NET_SessionId", "citrix_ns_id", "citrix_ns_id_.viewsnet.jp_%2F_wat"), parse_header($head, "set-cookie"), $cookie);
304 | }
305 |
306 | function viewcard_parse_csv($str, $account) {
307 | $ret = "";
308 | $lines = parse_csv(mb_convert_string($str));
309 | $cds = array();
310 | $cds_balamt = "0";
311 | $cds_paydate = $account["paydate"];
312 | $cds_s = "";
313 | $cds_e = "";
314 | $cd_date = "";
315 | $cd_num = 0;
316 | $ledge_balamt = 0;
317 |
318 | foreach($lines as $line) {
319 | $cd = array();
320 |
321 | if(count($line) == 2) {
322 | switch($line[0]) {
323 | case "お支払日":
324 | $cds_paydate = parse_date($line[1]);
325 | break;
326 | case "今回お支払金額":
327 | $cds_balamt = (string)(double)parse_amount($line[1]);
328 | $ledge_balamt = (double)$cds_balamt;
329 | break;
330 | case "会員番号":
331 | case "対象カード":
332 | default:
333 | break;
334 | }
335 | } else if(count($line) == 11 && $line[0] != "ご利用年月日") {
336 |
337 | // 日付を取得する
338 | $cd["DTPOSTED"] = parse_date($line[0]);
339 | if($line[1] == "ショッピングリボ弁済金") {
340 | $cd["DTPOSTED"] = $cds_paydate;
341 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_INT;
342 | } else {
343 | // PAYMENT固定とする
344 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_PAYMENT;
345 | }
346 | if($cds_s == "") $cds_s = $cd["DTPOSTED"];
347 | $cds_e = $cd["DTPOSTED"];
348 |
349 | // 通番を生成する
350 | if($cd["DTPOSTED"] == $cd_date) $cd_num++; else $cd_num = 0;
351 |
352 | // トランザクション番号を生成する
353 | $cd["FITID"] = $cd["DTPOSTED"] . sprintf("%04d", $account["id"]) . substr($account["paydate"], 4, 2) . "0" . sprintf("%05d", $cd_num);
354 |
355 | // 摘要を取得する
356 | $cd["NAME"] = $line[1];
357 |
358 | // 金額を取得する
359 | $cd["TRNAMT"] = (string)(-1 * (double)parse_amount($line[7]));
360 | $ledge_balamt += (double)$cd["TRNAMT"];
361 |
362 | // 残高を取得する
363 | $cd["MEMO"] = ($line[5] != ""? $line[5]: ENV_STR_OFX_MEMO);
364 |
365 | array_push($cds, $cd);
366 | $cd_date = $cd["DTPOSTED"];
367 | }
368 | }
369 |
370 | if($cds_s == "") $cds_s = ENV_STR_DATE_TODAY;
371 | if($cds_e == "") $cds_e = ENV_STR_DATE_TODAY;
372 | if($cds_s > $cds_e) $cds_e = $cds_s;
373 |
374 | // クレジットカード支払請求を明細に追加する
375 | $i = count($cds);
376 | $cds[$i]["DTPOSTED"] = $cds_paydate;
377 | $cds[$i]["NAME"] = $account["name"];
378 | $cds[$i]["MEMO"] = ENV_STR_OFX_MEMO;
379 | $cds[$i]["TRNAMT"] = $cds_balamt;
380 | $cds[$i]["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_DIRECTDEBIT;
381 | $cds[$i]["FITID"] = $cds[$i]["DTPOSTED"] . sprintf("%04d", $account["id"]) . substr($account["paydate"], 4, 2) . "100000";
382 |
383 | // BANKTRANLIST
384 | $ret .= "";
385 | $ret .= "\r\n";
386 | $ret .= "" . $cds_s . ENV_STR_OFX_TZ . "";
387 | $ret .= "" . $cds_e . ENV_STR_OFX_TZ . "";
388 | $ret .= "\r\n";
389 |
390 | foreach($cds as $cd) {
391 | $ret .= "";
392 | $ret .= "" . $cd["TRNTYPE"] . "";
393 | $ret .= "" . $cd["DTPOSTED"] . ENV_STR_OFX_TZ . "";
394 | $ret .= "" . $cd["TRNAMT"] . "";
395 | $ret .= "" . $cd["FITID"] . "";
396 | $ret .= "" . $cd["NAME"] . "";
397 | $ret .= "" . $cd["MEMO"] . "";
398 | $ret .= "";
399 | $ret .= "\r\n";
400 | }
401 |
402 | $ret .= "";
403 | $ret .= "\r\n";
404 |
405 | // 支払後残高を出力する
406 | $ret .= "";
407 | $ret .= "" . (string)$ledge_balamt . "";
408 | $ret .= "" . ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ . "";
409 | $ret .= "";
410 | $ret .= "\r\n";
411 |
412 | // カード名称を出力する
413 | if($account["acctname"] != "") {
414 | $ret .= "" . $account["acctname"] . "";
415 | $ret .= "\r\n";
416 | }
417 |
418 | return $ret;
419 | }
420 |
421 | ?>
422 |
--------------------------------------------------------------------------------
/server/waon.inc:
--------------------------------------------------------------------------------
1 | setAcctfrom(array(
101 | "BANKID" => $settings["code"],
102 | "BRANCHID" => "0",
103 | "ACCTID" => $ofxforms["cardNo"],
104 | "ACCTTYPE" => "CHECKING"
105 | ));
106 | // 日付順に昇順ソート
107 | usort($cds, function($a, $b) {
108 | return $a['DTPOSTED'] > $b['DTPOSTED'];
109 | });
110 | foreach($cds as $cd) {
111 | $ofxdom->addTran($cd);
112 | }
113 | // DTSTARTとDTENDを設定する
114 | $ofxdom->setDateRange(ENV_STR_DATE_PASTDAY . ENV_STR_OFX_TZ, ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ);
115 |
116 | // 残高を処理。ただし、取得できないため、便宜上0円とする。
117 | $ofxdom->setBalance(array(
118 | 'BALAMT' => 0,
119 | 'DTASOF' => ENV_STR_DATE_TODAY . ENV_STR_OFX_TZ
120 | ));
121 |
122 | // FITIDを仕上げる
123 | $ofxdom->setFitid();
124 | // XML DOMツリーを文字列に変換
125 | $xml = $ofxdom->getXML();
126 | $resp["status"] = ENV_NUM_STATUS_SUCCESS;
127 | $resp["ofx"] = generate_ofx($mode, $xml);
128 | }
129 | return $resp;
130 |
131 | // HTTP/1.1
132 | function waon_http11($method, $uris, $query = "", $cookie = "") {
133 | $ret = "INVALID HOST";
134 | if(preg_match("/\.waon\.com$/", $uris["host"]) > 0) $ret = http11(strtoupper($method), $uris["scheme"], $uris["host"], 0, $uris["path"], $query, "", $cookie);
135 | return explode("\r\n\r\n", $ret, 2);
136 | }
137 | function waon_update_cookie($head, $cookie) {
138 | return update_cookie(array(
139 | "JSESSIONID",
140 | "citrix_ns_id_.waon.com_%2F_wat",
141 | "Money-VS32-Cookie",
142 | "citrix_ns_id",
143 | "Waon-SSLVS04-Cookie",
144 | ), parse_header($head, "set-cookie"), $cookie);
145 | }
146 |
147 | function waon_parsedom($str) {
148 | $str = str_replace("Shift_JIS", "UTF-8", $str);
149 | $doc = new DOMDocument();
150 | @$doc->loadHTML($str);
151 | $xpath = new DOMXPath($doc);
152 | $rows = $xpath->query("//table[@class='y']/tr");
153 |
154 | $cds = array();
155 | $nrow = $rows->length;
156 |
157 | for ($i=1; $i<$nrow; $i++) {
158 | $cd = array();
159 | $cd["TRNTYPE"] = ENV_STR_OFX_TRNTYPE_DIRECTDEBIT;
160 |
161 | $row = $rows->item($i);
162 | $cols = $row->getElementsByTagName('td');
163 | // 日付を取得する
164 | if (!preg_match("/([0-9]{4})\/([0-9]{1,2})\/([0-9]{1,2})/", trim($cols->item(0)->nodeValue), $matches)) {
165 | // 当月に明細が存在しなければスキップ
166 | break;
167 | }
168 | $cd["DTPOSTED"] = sprintf("%d%02d%02d", $matches[1], $matches[2], $matches[3]);
169 | $cd["DTPOSTED"] .= ENV_STR_OFX_TZ;
170 |
171 | // トランザクション番号(請求月とデータ種別)を生成する
172 | $cd["FITID"] = '000';
173 |
174 | $cd['NAME'] = trim($cols->item(1)->nodeValue);
175 | $cd['TRNAMT'] = (int)parse_amount(trim($cols->item(2)->nodeValue));
176 | if (preg_match("/支払/", $cols->item(3)->nodeValue) && !preg_match("/支払取消/", $cols->item(3)->nodeValue)) {
177 | $cd['TRNAMT'] *= -1;
178 | }
179 | array_push($cds, $cd);
180 | }
181 | return $cds;
182 | }
183 | ?>
184 |
--------------------------------------------------------------------------------
/start_php.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | cd /d %~dp0
3 | php.exe -S 127.0.0.1:8000
4 |
--------------------------------------------------------------------------------