-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.php
95 lines (85 loc) · 5.88 KB
/
index.php
1
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
<?php if (isset($_POST['convert'])) {
$error = false;
if (strrchr($_FILES['transactions']['name'],".") != ".xls") {
$error = "<div class=\"error\">The file you uploaded is not a valid export from the Discover website.</div>";
} elseif ($_FILES['transactions']['size'] > 51200) {
$error = "<div class=\"error\">The file you uploaded is too large. The maximum allowed file size is 50KB.</div>";
} else {
$html = file_get_contents($_FILES['transactions']['tmp_name']);
$html = str_replace([" ","&"],["","&"],$html);
$doc = new DOMDocument();
$doc->loadHTML($html);
$parsed = simplexml_import_dom($doc);
$transactions = $parsed->body->table[1]->tr;
if (empty($transactions)) {
$error = "<div class=\"error\">No transactions were found in the file you imported.</div>";
}
if ($error === false) {
header("Content-Type: application/x-ofx");
header("Content-Disposition: attachment; filename=\"transactions.ofx\"");
echo file_get_contents("header.xml");
$counter = 0;
foreach ($transactions as $transaction) {
if ($counter > 0) {
$tds = $transaction->td;
$date = strtotime($tds[0]);
$amount = floatval(str_replace(",","",$tds[3])); ?>
<STMTTRN>
<TRNTYPE>DEBIT
<DTPOSTED><?php echo date("YmdHis",$date); ?>[0:GMT]
<TRNAMT><?php echo ($amount > 0 ? "-" : "").abs($amount)."\n"; ?>
<NAME><?php echo $tds[2]."\n"; ?>
</STMTTRN>
<?php }
$counter++;
} //End of $transactions as $transaction FOREACH
echo file_get_contents("footer.xml");
} //End of $error === false IF
} //End of strrchr($_FILES['transactions']['name'],".") != ".xls" || $_FILES['transactions']['size'] > 51200 IFs
} //End of isset($_POST['convert']) IF
if ($error !== false) {
include ("header.html"); ?>
<h1>Discover Transactions Excel to OFX Converter for YNAB</h1>
<?php echo $error; ?>
<p>If you're here, you too have enjoyed the lovely months-long inability to import transactions from your Discover card into YNAB. I wrote this tool to help ease the pain. Follow the steps below:</p>
<ol>
<li>Login to your account at https://card.discover.com/, and browse to the Activity & Statements page using the Activity menu at the top. On the right side, click the Download link:<br>
<img src="images/activity_statements.png" alt="Activity & Statements Page Screenshot"></li>
<li>In the Download Options popup that appears, select Excel, then click Download:<br>
<img src="images/download_options.png" alt="Download Options Popup Screeenshot"></li>
<li>Upload the <em>Discover-RecentActivity-YYYYMMDD.xls</em> or <em>Discover-Statement-YYYYMMDD.xls</em> file here, then click the <em>Convert</em> button:
<form method="post" enctype="multipart/form-data">
<div id="upload_feedback"></div>
<p>File <small>(Max 50KB)</small>: <input type="file" name="transactions" accept=".xls"> <input type="submit" name="convert" value="Convert"></p>
</form>
<script type="text/javascript">
const fileField = document.querySelector("input[type='file']");
const fileFeedback = document.querySelector("#upload_feedback");
fileField.addEventListener("change", (evt) => {
if (evt.target.files[0].size > 51200) {
let errorDiv = document.createElement("div");
errorDiv.setAttribute("class","error");
errorDiv.append("The file you selected is too large. The maximum allowed file size is 50KB.");
fileFeedback.appendChild(errorDiv);
}
});
</script>
</li>
<li>Import the <em>transactions.ofx</em> file generated by this tool into your Discover account in YNAB:<br>
<img src="images/ynab.png" alt="YNAB Import Screenshot"></li>
</ol>
<h2>Why Should I Trust Sharing My Data with You?</h2>
<p>Greetings, fellow paranoid security-conscious person; this is an excellent question. If you open the <em>Discover-RecentActivity-YYYYMMDD.xls</em> or <em>Discover-Statement-YYYYMMDD.xls</em> file you downloaded from Discover's website in something OTHER than Excel, you'll see that it's not even an Excel-formatted file at all. It's actually an HTML file that uses an XLS extension; Discover is taking advantage of Excel being kind enough to re-render the data when you open it despite the format being incorrect.</p>
<p>Here are some things to help ease your stress:</p>
<ul>
<li>If you open the export file in any program, you'll notice that <strong>your full account number does not appear anywhere in this file</strong>.</li>
<li>The server hosting this tool has been configured to only accept connections over HTTPS. This ensures that the contents of your file are encrypted while in transit.</li>
<li><strong>Your data is not saved to the server's filesystem or any database, nor sent to any other servers.</strong></li>
<li>In the interest of full transparency, you can view all of the source code for this tool at <a href="https://github.com/IridescentShadow/ynab-discover-converter" target="_blank">https://github.com/IridescentShadow/ynab-discover-converter</a>. This will let you verify for yourself that the claims above are valid.</li>
<li>And finally, this tool uses the <a href="https://unlicense.org/" target="_blank">Unlicense</a>, so feel free to download the code from Github and put it on your own server.</li>
</ul>
<h2>This is Great, How Can I Thank You?</h2>
<p>This tool and the code that powers it are a gift to the YNAB userbase. If you're YNABing correctly, your money has more important jobs than giving it to me.</p>
<p>Instead, call Discover customer support at <a href="tel:+18003472683">1-800-347-2683</a> or chat with them at <a href="https://www.discover.com/credit-cards/contact-us/" target="_blank">https://www.discover.com/credit-cards/contact-us/</a> and tell them if they don't restore native OFX exports in the next 3 months, you're cancelling your card. <strong>Seriously.</strong> If enough of us do it, they'll either listen or lose customers.</p>
<?php include("footer.html");
} //End of $error !== false IF ?>