So that would lead me to believe it's a problem on USAA's end...? In my testing, I also cracked open the source code for LibOFX and looked at how it sends its date, as I am able to successfully connect to USAA through LibOFX's sample program, ofxconnect.
I tried their syntax, but no dice there either. I'm 100% confused.
Here is the full PHP code I am using, if it helps at all:
<?php
$milliseconds = milliseconds();
$tz_offset = date('Z')/3600;
$date = date("YmdHis." . $milliseconds . "[$tz_offset:T]");
$url = "https://service2.usaa.com/ofx/OFXServlet";
$post_string = "OFXHEADER:100\r\n
DATA:OFXSGML\r\n
VERSION:102\r\n
SECURITY:NONE\r\n
ENCODING:USASCII\r\n
CHARSET:1252\r\n
COMPRESSION:NONE\r\n
OLDFILEUID:NONE\r\n
NEWFILEUID:NONE\r\n\r\n
<OFX>
<SIGNONMSGSRQV1>
<SONRQ>
<DTCLIENT>$date</DTCLIENT>
<USERID>xxxxxxxx</USERID>
<USERPASS>xxxxxxxx</USERPASS>
<LANGUAGE>ENG</LANGUAGE>
<FI>
<ORG>USAA</ORG>
<FID>24591</FID>
</FI>
<APPID>MJWPHP</APPID>
<APPVER>0100</APPVER>
</SONRQ>
</SIGNONMSGSRQV1>
<BANKMSGSRQV1>
<STMTTRNRQ>
<TRNUID>1001</TRNUID>
<STMTRQ>
<BANKACCTFROM>
<BANKID>xxxxxxxxx</BANKID>
<ACCTID>xxxxxxxxx</ACCTID>
<ACCTTYPE>CHECKING</ACCTTYPE>
</BANKACCTFROM>
<INCTRAN>
<INCLUDE>Y</INCLUDE>
</INCTRAN>
</STMTRQ>
</STMTTRNRQ>
</BANKMSGSRQV1>
</OFX>";
$headers = array("User-Agent: MJWPHP","Content-Type: application/x-ofx");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
$info = curl_getinfo($ch);
$data = curl_exec($ch);
if(curl_errno($ch))
print curl_error($ch);
else
curl_close($ch);
echo $data;
function milliseconds()
{
$m = explode(' ', microtime());
$milli = substr($m[0], 2, 3);
return $milli;
}
?>