Topic: VB.NET HttpWebRequest Example

Greetings, I created this today and I know its kind of incomplete but i've gotten it to basically work for me. I wanted one that could do Chase for my company and the financial software im developing for them. I will post the source code free on here for others to examine and learn with. As far as I know this is the only example i've found for accessing OFX Direct connect in the .NET. For the "Account Activity" porition I copied the OFX spec directly from the OFX website in their banking example. I still cannot get the Account List request to work I get a 400 bad request any help on that would be appreciated. Without further ado here it is.

    Public Class OFXDownload
        Dim objReq As HttpWebRequest
        Dim DataBuffer As New StringBuilder
        Dim ReqStream As IO.Stream
        Dim _ResponseString As String
        Dim objResponse As HttpWebResponse
        Dim ResponseStream As IO.Stream
        Dim CurrGuid As String
        Dim _UserName As String
        Dim _Password As String

        Public Enum RequestType
            AccountList = 0
            AccountActivity = 1
        End Enum
        Public Sub New(ByVal ofx_RequestType As RequestType, ByVal userName As String, ByVal password As String, ByVal AccountID As String, ByVal BankID As String, ByVal org As String, ByVal FID As String)

            _UserName = userName
            _Password = password
            CurrGuid = Guid.NewGuid.ToString
            Dim clientDate As String
            clientDate = Format(DateTime.Now, "yyyyMMddHHmmss")



            DataBuffer.AppendLine("OFXHEADER:100")
            DataBuffer.AppendLine("DATA:OFXSGML")
            DataBuffer.AppendLine("VERSION:102")
            DataBuffer.AppendLine("SECURITY:NONE")
            DataBuffer.AppendLine("ENCODING:USASCII")
            DataBuffer.AppendLine("CHARSET:1252")
            DataBuffer.AppendLine("COMPRESSION:NONE")
            DataBuffer.AppendLine("OLDFILEUID:NONE")
            DataBuffer.AppendLine("NEWFILEUID:NONE")
            DataBuffer.AppendLine()
            DataBuffer.AppendLine("<OFX>")
            DataBuffer.AppendLine("<SIGNONMSGSRQV1>")
            DataBuffer.AppendLine("<SONRQ>")
            DataBuffer.AppendLine("<DTCLIENT>" & clientDate)
            DataBuffer.AppendLine("<USERID>" & userName)
            DataBuffer.AppendLine("<USERPASS>" & password)
            DataBuffer.AppendLine("<LANGUAGE>ENG")
            DataBuffer.AppendLine("<FI>")
            DataBuffer.AppendLine("<ORG>" & org)
            DataBuffer.AppendLine("<FID>" & FID)
            DataBuffer.AppendLine("</FI>")
            DataBuffer.AppendLine("<APPID>QWIN")
            DataBuffer.AppendLine("<APPVER>0900")
            DataBuffer.AppendLine("</SONRQ>")
            DataBuffer.AppendLine("</SIGNONMSGSRQV1>")

            Select Case ofx_RequestType
                Case RequestType.AccountList
                    DataBuffer.AppendLine("<SIGNUPMSGSRQV1>")
                    DataBuffer.AppendLine("<ACCTINFOTRNRQ>")
                    DataBuffer.AppendLine("<ACCTINFORQ>")
                    DataBuffer.AppendLine("<DTACCTUP>19700101000000")
                    DataBuffer.AppendLine("</ACCTINFORQ>")
                    DataBuffer.AppendLine("</ACCTINFOTRNRQ>")
                    DataBuffer.AppendLine("</SIGNUPMSGSRQV1>")
                    DataBuffer.AppendLine("</OFX>")
                Case RequestType.AccountActivity
                    DataBuffer.Append("<BANKMSGSRQV1>")
                    DataBuffer.Append("<STMTTRNRQ>")
                    DataBuffer.Append("<TRNUID>" & CurrGuid)
                    DataBuffer.Append("<STMTRQ>")
                    DataBuffer.Append("<BANKACCTFROM>")
                    DataBuffer.Append("<BANKID>" & BankID)
                    DataBuffer.Append("<ACCTID>" & AccountID)
                    DataBuffer.Append("<ACCTTYPE>CHECKING")
                    DataBuffer.Append("</BANKACCTFROM>")
                    DataBuffer.Append("<INCTRAN>")
                    DataBuffer.Append("<INCLUDE>Y")
                    DataBuffer.Append("</INCTRAN>")
                    DataBuffer.Append("</STMTRQ>")
                    DataBuffer.Append("</STMTTRNRQ>")
                    DataBuffer.Append("</BANKMSGSRQV1>")
                    DataBuffer.Append("</OFX>")

                    'later
            End Select
        End Sub
        Public Function Download() As String
            MsgBox(DataBuffer.ToString)
            Dim byteBuffer() As Byte = Encoding.ASCII.GetBytes(DataBuffer.ToString)
            Dim responseReader As StreamReader

            objReq = WebRequest.Create("https://ofx.chase.com")
            objReq.Method = "POST"
            objReq.ContentType = "application/x-ofx"
            objReq.Accept = "*/*, application/x-ofx"
            objReq.ContentLength = byteBuffer.Length
            System.Net.ServicePointManager.Expect100Continue = False
            ReqStream = objReq.GetRequestStream
            ReqStream.Write(byteBuffer, 0, byteBuffer.Length)
            ReqStream.Close()
            objResponse = objReq.GetResponse

            ResponseStream = objReq.GetResponse.GetResponseStream
            responseReader = New StreamReader(ResponseStream)
            _ResponseString = responseReader.ReadToEnd
            Return _ResponseString


        End Function
        Public ReadOnly Property ResponseString()
            Get
                ResponseString = _ResponseString
            End Get
        End Property
    End Class

and an example of how to use:

Dim MyOFXData as new OFXDownload(OFXDownload.RequestType.AccountActivity,"username","password","ACCOUNTID","BANKID","ORG","FID")
MessageBox.show(MyOFXData.Download)

This will return in string format the OFX Data. Parsing it is of course up to you.

Re: VB.NET HttpWebRequest Example

Hi,

The account request should follow this form:

<SIGNUPMSGSRQV1>
<ACCTINFOTRNRQ>
<TRNUID>C0A84BC5-6332-4674-ACEF-6149F15423B5
<CLTCOOKIE>4
<ACCTINFORQ>
<DTACCTUP>19700101000000
</ACCTINFORQ>
</ACCTINFOTRNRQ>
</SIGNUPMSGSRQV1

This should appear after the ofx header and the signon request (SIGNONMSGSRQV1).

Re: VB.NET HttpWebRequest Example

Thankyou sir!

4 (edited by jadacyrus 2010-01-15 17:20:00)

Re: VB.NET HttpWebRequest Example

Here is a more complete version which fixes the account request and also parses the information for you and stores the data in easy to use collection objects.

   Public Structure _BankItem
        Dim ItemType As String
        Dim DatePosted As String
        Dim ItemAmount As String
        Dim FITID As String
        Dim CheckNumber As String
        Dim Memo As String
        Dim ItemName As String

    End Structure
    Public Structure _AccountListInfo
        Dim AccountName As String
        Dim BankID As String
        Dim AccountID As String
        Dim AccountType As String
        Dim Status As String
    End Structure
    Public Class OFXDownload
        Dim objReq As HttpWebRequest
        Dim DataBuffer As New StringBuilder
        Dim ReqStream As IO.Stream
        Dim _ResponseString As String
        Dim objResponse As HttpWebResponse
        Dim ResponseStream As IO.Stream
        Dim CurrGuid As String
        Dim _UserName As String
        Dim _Password As String
        Dim _BankItemCollection As New Collection(Of _BankItem)
        Dim _LedgerBalance As String
        Dim _AvailableBalance As String
        Dim _RequestType As RequestType
        Dim _AccountListCollection As New Collection(Of _AccountListInfo)



        Public Enum RequestType
            AccountList = 0
            AccountActivity = 1
        End Enum
        Public ReadOnly Property AccountListCollection() As Collection(Of _AccountListInfo)
            Get
                AccountListCollection = _AccountListCollection
            End Get
        End Property
        Public ReadOnly Property BankItemCollection() As Collection(Of _BankItem)
            Get
                BankItemCollection = _BankItemCollection
            End Get
        End Property
        Public ReadOnly Property LedgerBalance() As String
            Get
                LedgerBalance = _LedgerBalance
            End Get
        End Property
        Public ReadOnly Property AvailableBalance() As String
            Get
                AvailableBalance = _AvailableBalance
            End Get
        End Property
        Public Sub New(ByVal ofx_RequestType As RequestType, ByVal userName As String, ByVal password As String, ByVal AccountID As String, ByVal BankID As String, ByVal org As String, ByVal FID As String)

            _UserName = userName
            _Password = password
            CurrGuid = Guid.NewGuid.ToString
            Dim clientDate As String
            clientDate = Format(DateTime.Now, "yyyyMMddHHmmss")



            DataBuffer.AppendLine("OFXHEADER:100")
            DataBuffer.AppendLine("DATA:OFXSGML")
            DataBuffer.AppendLine("VERSION:102")
            DataBuffer.AppendLine("SECURITY:NONE")
            DataBuffer.AppendLine("ENCODING:USASCII")
            DataBuffer.AppendLine("CHARSET:1252")
            DataBuffer.AppendLine("COMPRESSION:NONE")
            DataBuffer.AppendLine("OLDFILEUID:NONE")
            DataBuffer.AppendLine("NEWFILEUID:NONE")
            DataBuffer.AppendLine()
            DataBuffer.AppendLine("<OFX>")
            DataBuffer.AppendLine("<SIGNONMSGSRQV1>")
            DataBuffer.AppendLine("<SONRQ>")
            DataBuffer.AppendLine("<DTCLIENT>" & clientDate)
            DataBuffer.AppendLine("<USERID>" & userName)
            DataBuffer.AppendLine("<USERPASS>" & password)
            DataBuffer.AppendLine("<LANGUAGE>ENG")
            DataBuffer.AppendLine("<FI>")
            DataBuffer.AppendLine("<ORG>" & org)
            DataBuffer.AppendLine("<FID>" & FID)
            DataBuffer.AppendLine("</FI>")
            DataBuffer.AppendLine("<APPID>QWIN")
            DataBuffer.AppendLine("<APPVER>0900")
            DataBuffer.AppendLine("</SONRQ>")
            DataBuffer.AppendLine("</SIGNONMSGSRQV1>")
            _RequestType = ofx_RequestType
            Select Case ofx_RequestType
                Case RequestType.AccountList
                    DataBuffer.AppendLine("<SIGNUPMSGSRQV1>")
                    DataBuffer.AppendLine("<ACCTINFOTRNRQ>")
                    DataBuffer.AppendLine("<TRNUID>" & CurrGuid)
                    DataBuffer.AppendLine("<CLTCOOKIE>4")
                    DataBuffer.AppendLine("<ACCTINFORQ>")
                    DataBuffer.AppendLine("<DTACCTUP>19700101000000")
                    DataBuffer.AppendLine("</ACCTINFORQ>")
                    DataBuffer.AppendLine("</ACCTINFOTRNRQ>")
                    DataBuffer.AppendLine("</SIGNUPMSGSRQV1>")
                    DataBuffer.AppendLine("</OFX>")
                Case RequestType.AccountActivity
                    DataBuffer.Append("<BANKMSGSRQV1>")
                    DataBuffer.Append("<STMTTRNRQ>")
                    DataBuffer.Append("<TRNUID>" & CurrGuid)
                    DataBuffer.Append("<STMTRQ>")
                    DataBuffer.Append("<BANKACCTFROM>")
                    DataBuffer.Append("<BANKID>" & BankID)
                    DataBuffer.Append("<ACCTID>" & AccountID)
                    DataBuffer.Append("<ACCTTYPE>CHECKING")
                    DataBuffer.Append("</BANKACCTFROM>")
                    DataBuffer.Append("<INCTRAN>")
                    DataBuffer.Append("<INCLUDE>Y")
                    DataBuffer.Append("</INCTRAN>")
                    DataBuffer.Append("</STMTRQ>")
                    DataBuffer.Append("</STMTTRNRQ>")
                    DataBuffer.Append("</BANKMSGSRQV1>")
                    DataBuffer.Append("</OFX>")

                    'later
            End Select
        End Sub
        Public Function Download() As String
            Dim byteBuffer() As Byte = Encoding.ASCII.GetBytes(DataBuffer.ToString)
            Dim responseReader As StreamReader


            objReq = WebRequest.Create("https://ofx.chase.com")
            objReq.Method = "POST"
            objReq.ContentType = "application/x-ofx"
            objReq.Accept = "*/*, application/x-ofx"
            objReq.ContentLength = byteBuffer.Length
            System.Net.ServicePointManager.Expect100Continue = False
            ReqStream = objReq.GetRequestStream
            ReqStream.Write(byteBuffer, 0, byteBuffer.Length)
            ReqStream.Close()
            objResponse = objReq.GetResponse

            ResponseStream = objReq.GetResponse.GetResponseStream
            responseReader = New StreamReader(ResponseStream)
            _ResponseString = responseReader.ReadToEnd
            Select Case _RequestType
                Case RequestType.AccountActivity
                    ParseBankItems()
                Case RequestType.AccountList
                    ParseAccountList()
            End Select

            Return _ResponseString


        End Function
        Private Sub ParseAccountList()
            _AccountListCollection.Clear()
            Dim AccountName As String
            Dim BankID As String
            Dim AccountID As String
            Dim AccountType As String
            Dim Status As String

            Dim MyAccountInfo As _AccountListInfo

            Dim AccntInfoList() As String = Split(_ResponseString, "<ACCTINFO>")
            For Each Account As String In AccntInfoList
                If InStr(Account, "<DESC>") Then
                    'This is an account item
                    MyAccountInfo.AccountID = ""
                    MyAccountInfo.AccountName = ""
                    MyAccountInfo.AccountType = ""
                    MyAccountInfo.BankID = ""
                    MyAccountInfo.Status = ""

                    AccountName = Split(Account, "<DESC>")(1)
                    AccountName = AccountName.Substring(0, AccountName.IndexOf("<"))
                    MyAccountInfo.AccountName = AccountName

                    BankID = Split(Account, "<BANKID>")(1)
                    BankID = BankID.Substring(0, BankID.IndexOf("<"))
                    MyAccountInfo.BankID = BankID

                    AccountID = Split(Account, "<ACCTID>")(1)
                    AccountID = AccountID.Substring(0, AccountID.IndexOf("<"))
                    MyAccountInfo.AccountID = AccountID

                    AccountType = Split(Account, "<ACCTTYPE>")(1)
                    AccountType = AccountType.Substring(0, AccountType.IndexOf("<"))
                    MyAccountInfo.AccountType = AccountType

                    Status = Split(Account, "<SVCSTATUS>")(1)
                    Status = Status.Substring(0, Status.IndexOf("<"))
                    MyAccountInfo.Status = Status
                    _AccountListCollection.Add(MyAccountInfo)

                End If
            Next
        End Sub
        Private Sub ParseBankItems()
            _BankItemCollection.Clear()
            Dim TransactionType As String
            Dim DatePosted As String
            Dim Amount As String
            Dim FITID As String
            Dim Memo As String
            Dim CheckNumber As String
            Dim ItemName As String
            Dim MyTransaction As _BankItem
            Dim BankTransList() As String
            BankTransList = Split(_ResponseString, "<BANKTRANLIST>")
            Dim TransactionList() As String
            TransactionList = Split(BankTransList(1), "<STMTTRN>")
            Dim LedgerBal() As String = Split(_ResponseString, "<LEDGERBAL>")
            _LedgerBalance = Split(LedgerBal(1), "<BALAMT>")(1)
            _LedgerBalance = _LedgerBalance.Substring(0, _LedgerBalance.IndexOf("<"))
            Dim AvailBal() As String = Split(_ResponseString, "<AVAILBAL>")
            _AvailableBalance = Split(AvailBal(1), "<BALAMT>")(1)
            _AvailableBalance = _AvailableBalance.Substring(0, _AvailableBalance.IndexOf("<"))

            For Each Transaction As String In TransactionList
                If InStr(Transaction, "TRNTYPE") Then
                    MyTransaction.CheckNumber = ""
                    MyTransaction.DatePosted = ""
                    MyTransaction.FITID = ""
                    MyTransaction.ItemAmount = ""
                    MyTransaction.ItemName = ""
                    MyTransaction.ItemType = ""
                    MyTransaction.Memo = ""

                    'This is a transaction

                    TransactionType = Split(Transaction, "<TRNTYPE>")(1)
                    TransactionType = TransactionType.Substring(0, TransactionType.IndexOf("<"))

                    MyTransaction.ItemType = TransactionType

                    DatePosted = Split(Transaction, "<DTPOSTED>")(1)
                    DatePosted = DatePosted.Substring(0, DatePosted.IndexOf("<"))
                    DatePosted = DatePosted.Substring(0, 8)
                    DatePosted = DatePosted.Substring(4, 2) & "/" & DatePosted.Substring(6, 2) & "/" & DatePosted.Substring(0, 4)
                    MyTransaction.DatePosted = DatePosted

                    Amount = Split(Transaction, "<TRNAMT>")(1)
                    Amount = Amount.Substring(0, Amount.IndexOf("<"))

                    MyTransaction.ItemAmount = Amount

                    FITID = Split(Transaction, "<FITID>")(1)
                    FITID = FITID.Substring(0, FITID.IndexOf("<"))
                    MyTransaction.FITID = FITID
                    If InStr(Transaction, "<CHECKNUM>") Then 'its a check
                        CheckNumber = Split(Transaction, "<CHECKNUM>")(1)
                        CheckNumber = CheckNumber.Substring(0, CheckNumber.IndexOf("<"))
                        MyTransaction.CheckNumber = CheckNumber
                    End If
                    If InStr(Transaction, "<MEMO>") Then 'It has a memo
                        Memo = Split(Transaction, "<MEMO>")(1)
                        Memo = Memo.Substring(0, Memo.IndexOf("<"))
                        MyTransaction.Memo = Memo
                    End If
                    ItemName = Split(Transaction, "<NAME>")(1)
                    ItemName = ItemName.Substring(0, ItemName.IndexOf("<"))
                    MyTransaction.ItemName = ItemName


                    _BankItemCollection.Add(MyTransaction)

                End If
            Next
        End Sub
        
        Public ReadOnly Property ResponseString() As String
            Get
                ResponseString = _ResponseString
            End Get
        End Property
    End Class

Feel free to improve & use and thanks for running a very informative website for information that is not so easily attainable. This is my gift back. Oh yea, also i've only tested this with chase so I have no idea how it will work on other ofx servers.

5 (edited by sandMan 2010-01-18 19:30:01)

Re: VB.NET HttpWebRequest Example

jadacyrus- Thank you.  Your code snipet was the first to work for me on a bunch I've downloaded.  Mostly my problem was getting the message request format correct.  SharpCash seems to have the right sequence to make the webservice request, but the message format I was trying was constantly coming back with a 400 bad request error.  I've gotten the code below to work on two other banks for Check, Savings and Credit.

Note:  I added two parameters to your constructor.  'url' and 'accountType'.  The 'url' field allows me to switch banks.  The 'accountType' field gives me checking/savings and credit.  The way I changed the message in my opinion is some poor coding, but it works for me.  I'm intending on improving this code and when I get a chance, I'll post my updates.

Thank you, thank you.  Hope my changes helps others!

P.S.  Take note of this line:

                    DataBuffer.Append("<ACCTTYPE>" & accountType)

When I pass in CHECKING or SAVINGS for accountType, that line will put the accountType into the OFX Request Message.  If it's CREDIT, then that line is not written to the Request and my code changes the Request Message structure.

P.S#2. I also changed the appid/appver codes to Microsoft Money and version 1500 which worked better for me.

   Public Sub New(ByVal ofx_RequestType As RequestType, ByVal url As String, ByVal userName As String, ByVal password As String, ByVal AccountID As String, ByVal accountType As String, ByVal BankID As String, ByVal org As String, ByVal FID As String)

        _UserName = userName
        _Password = password
        _url = url
        CurrGuid = Guid.NewGuid.ToString
        Dim clientDate As String
        clientDate = Format(DateTime.Now, "yyyyMMddHHmmss")



        DataBuffer.AppendLine("OFXHEADER:100")
        DataBuffer.AppendLine("DATA:OFXSGML")
        DataBuffer.AppendLine("VERSION:102")
        DataBuffer.AppendLine("SECURITY:NONE")
        DataBuffer.AppendLine("ENCODING:USASCII")
        DataBuffer.AppendLine("CHARSET:1252")
        DataBuffer.AppendLine("COMPRESSION:NONE")
        DataBuffer.AppendLine("OLDFILEUID:NONE")
        DataBuffer.AppendLine("NEWFILEUID:NONE")
        DataBuffer.AppendLine()
        DataBuffer.AppendLine("<OFX>")
        DataBuffer.AppendLine("<SIGNONMSGSRQV1>")
        DataBuffer.AppendLine("<SONRQ>")
        DataBuffer.AppendLine("<DTCLIENT>" & clientDate)
        DataBuffer.AppendLine("<USERID>" & userName)
        DataBuffer.AppendLine("<USERPASS>" & password)
        DataBuffer.AppendLine("<LANGUAGE>ENG")
        DataBuffer.AppendLine("<FI>")
        DataBuffer.AppendLine("<ORG>" & org)
        DataBuffer.AppendLine("<FID>" & FID)
        DataBuffer.AppendLine("</FI>")
        DataBuffer.AppendLine("<APPID>Money") ' QWIN")
        DataBuffer.AppendLine("<APPVER>1500") '0900")
        DataBuffer.AppendLine("</SONRQ>")
        DataBuffer.AppendLine("</SIGNONMSGSRQV1>")

        Select Case ofx_RequestType
            Case RequestType.AccountList
                DataBuffer.AppendLine("<SIGNUPMSGSRQV1>")
                DataBuffer.AppendLine("<ACCTINFOTRNRQ>")
                DataBuffer.AppendLine("<ACCTINFORQ>")
                DataBuffer.AppendLine("<DTACCTUP>19700101000000")
                DataBuffer.AppendLine("</ACCTINFORQ>")
                DataBuffer.AppendLine("</ACCTINFOTRNRQ>")
                DataBuffer.AppendLine("</SIGNUPMSGSRQV1>")
                DataBuffer.AppendLine("</OFX>")
            Case RequestType.AccountActivity
                If accountType = "CREDIT" Then
                    DataBuffer.Append("<CREDITCARDMSGSRQV1>")
                    DataBuffer.Append("<CCSTMTTRNRQ>")
                Else
                    DataBuffer.Append("<BANKMSGSRQV1>")
                    DataBuffer.Append("<STMTTRNRQ>")
                End If
                DataBuffer.Append("<TRNUID>" & CurrGuid)
                If accountType = "CREDIT" Then
                    DataBuffer.Append("<CCSTMTRQ>")
                    DataBuffer.Append("<CCACCTFROM>")
                Else
                    DataBuffer.Append("<STMTRQ>")
                    DataBuffer.Append("<BANKACCTFROM>")
                    DataBuffer.Append("<BANKID>" & BankID)
                End If
                DataBuffer.Append("<ACCTID>" & AccountID)
                If accountType = "CREDIT" Then
                    DataBuffer.Append("</CCACCTFROM>")
                Else
                    DataBuffer.Append("<ACCTTYPE>" & accountType)
                    DataBuffer.Append("</BANKACCTFROM>")
                End If
                DataBuffer.Append("<INCTRAN>")
                DataBuffer.Append("<INCLUDE>Y")
                DataBuffer.Append("</INCTRAN>")

                If accountType = "CREDIT" Then
                    DataBuffer.Append("</CCSTMTRQ>")
                    DataBuffer.Append("</CCSTMTTRNRQ>")
                    DataBuffer.Append("</CREDITCARDMSGSRQV1>")
                Else
                    DataBuffer.Append("</STMTRQ>")
                    DataBuffer.Append("</STMTTRNRQ>")
                    DataBuffer.Append("</BANKMSGSRQV1>")
                End If
                DataBuffer.Append("</OFX>")

                'later
        End Select
    End Sub

Re: VB.NET HttpWebRequest Example

Here's your same program translated to JAVA with a few tweaks I performed...

package vbj;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

import vbj.OFXDownload;


public class OFXDownload
{
    public StringBuilder DataBuffer = new StringBuilder ();
    private String CurrGuid = null;
    private String _url = null;

    public OFXDownload(int ofx_RequestType, String  url, String  userName, String  password, String  AccountID, String  AccountType, String  BankID, String  org, String  FID) {
        _url = url;
        UUID idOne = UUID.randomUUID();
        CurrGuid=idOne.toString(); 
        String clientDate = null;
       
        SimpleDateFormat formatter = new SimpleDateFormat ("yyyyMMddHHmmss");
        Date currentTime_1 = new Date();
        clientDate = formatter.format(currentTime_1);
       
        DataBuffer.append("OFXHEADER:100\r\n");
        DataBuffer.append("DATA:OFXSGML\r\n");
        DataBuffer.append("VERSION:102\r\n");
        DataBuffer.append("SECURITY:NONE\r\n");
        DataBuffer.append("ENCODING:USASCII\r\n");
        DataBuffer.append("CHARSET:1252\r\n");
        DataBuffer.append("COMPRESSION:NONE\r\n");
        DataBuffer.append("OLDFILEUID:NONE\r\n");
        DataBuffer.append("NEWFILEUID:NONE\r\n");
        DataBuffer.append("\r\n");
        DataBuffer.append("<OFX>\r\n");
        DataBuffer.append("<SIGNONMSGSRQV1>\r\n");
        DataBuffer.append("<SONRQ>\r\n");
        DataBuffer.append("<DTCLIENT>" + clientDate);
        DataBuffer.append("<USERID>" + userName);
        DataBuffer.append("<USERPASS>" + password);
        DataBuffer.append("<LANGUAGE>ENG\r\n");
        DataBuffer.append("<FI>\r\n");
        DataBuffer.append("<ORG>" + org);
        DataBuffer.append("<FID>" + FID);
        DataBuffer.append("</FI>\r\n");
        DataBuffer.append("<APPID>Money\r\n");
        //  QWIN")
        DataBuffer.append("<APPVER>1500\r\n");
        // 0900")
        DataBuffer.append("</SONRQ>\r\n");
        DataBuffer.append("</SIGNONMSGSRQV1>\r\n");
        switch (ofx_RequestType) {
            case 1:
                DataBuffer.append("<SIGNUPMSGSRQV1>\r\n");
                DataBuffer.append("<ACCTINFOTRNRQ>\r\n");
                DataBuffer.append("<ACCTINFORQ>\r\n");
                DataBuffer.append("<DTACCTUP>19700101000000\r\n");
                DataBuffer.append("</ACCTINFORQ>\r\n");
                DataBuffer.append("</ACCTINFOTRNRQ>\r\n");
                DataBuffer.append("</SIGNUPMSGSRQV1>\r\n");
                DataBuffer.append("</OFX>\r\n");
                break;
            case 2:
                if (AccountType.equals("CREDIT")) {
                    DataBuffer.append("<CREDITCARDMSGSRQV1>\r\n");
                    DataBuffer.append("<CCSTMTTRNRQ>\r\n");
                }
                else  {
                    DataBuffer.append("<BANKMSGSRQV1>\r\n");
                    DataBuffer.append("<STMTTRNRQ>\r\n");
                }
                DataBuffer.append("<TRNUID>" + CurrGuid);
                if (AccountType.equals("CREDIT")) {
                    DataBuffer.append("<CCSTMTRQ>\r\n");
                    DataBuffer.append("<CCACCTFROM>\r\n");
                }
                else  {
                    DataBuffer.append("<STMTRQ>\r\n");
                    DataBuffer.append("<BANKACCTFROM>\r\n");
                    DataBuffer.append("<BANKID>" + BankID);
                }
                DataBuffer.append("<ACCTID>" + AccountID);
                if (AccountType.equals("CREDIT")) {
                    DataBuffer.append("</CCACCTFROM>\r\n");
                }
                else  {
                    DataBuffer.append("<ACCTTYPE>" + AccountType);
                    DataBuffer.append("</BANKACCTFROM>\r\n");
                }
                DataBuffer.append("<INCTRAN>\r\n");
                DataBuffer.append("<INCLUDE>Y\r\n");
                DataBuffer.append("</INCTRAN>\r\n");
                if (AccountType.equals("CREDIT")) {
                    DataBuffer.append("</CCSTMTRQ>\r\n");
                    DataBuffer.append("</CCSTMTTRNRQ>\r\n");
                    DataBuffer.append("</CREDITCARDMSGSRQV1>\r\n");
                }
                else  {
                    DataBuffer.append("</STMTRQ>\r\n");
                    DataBuffer.append("</STMTTRNRQ>\r\n");
                    DataBuffer.append("</BANKMSGSRQV1>\r\n");
                }
                DataBuffer.append("</OFX>\r\n");
                // later
                break;
        }
    }

    public String Download() {
       
        try {
            String data = DataBuffer.toString();

            URL url = new URL(_url);
            URLConnection conn = url.openConnection();
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            conn.setRequestProperty("Content-Type","application/x-ofx");

            // Send header
            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
            DataOutputStream printout = new DataOutputStream(conn.getOutputStream());
            printout.writeBytes(data);
            printout.flush();
            printout.close();
            
            // Get the response
            BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = rd.readLine()) != null) {
                System.out.println(line);
            }
            wr.close();
            rd.close();
        } catch (Exception e) {
            System.out.println(e.toString());
        }

       
        return "";
    }
   
    public static void main(String [] args)
    {
        OFXDownload MyOFXData;
        MyOFXData = new OFXDownload(2, "URL", "user", "password", "account#", "CREDIT", "bankid", "org", "fid");
        System.out.println(MyOFXData.DataBuffer.toString());
        System.out.println(MyOFXData.Download());
    }
   
}

7 (edited by jadacyrus 2010-01-22 03:51:11)

Re: VB.NET HttpWebRequest Example

Very cool , I appreciate the feedback & updates!

edit: I'm interested in expanding this code to include more features of the OFX protocol but unfortunately I cant really find any good source of the specification of this protocol w/ examples. My next would be to retrieve check images from the bank. If you have any information or valuable resources for OFX spec definitely let me know. I will be checking back here routinely to keep up to date with this stuff. Thanks again

Re: VB.NET HttpWebRequest Example

Wow totally missed the download spec link at ofx.net

http://ofx.net/DownloadPage/Downloads.aspx

will be studying this now

Re: VB.NET HttpWebRequest Example

I have been trying to implement check/statement image, but no luck testing it so far...

The main problem is that I do not know any FI that supports OFX 2.1 (transaction image download service is supported only by this version), so I can test my app.

Does anybody know any FI that supports OFX 2.1 and image download service?

Please help! Thank you in advance.

Re: VB.NET HttpWebRequest Example

Yeah, does not seem to work for me either.

Re: VB.NET HttpWebRequest Example

I tried everything yesterday attempting to get a simple transaction download working.  I feel I am essentially doing the exact same things as this example with the exception that it is C#.  All I get with this code is a Bad Request (400).

using System;
using System.IO;
using System.Net;
using System.Text;

namespace OfxBankStatement
{
    public class BankStatement
    {
        public BankStatement()
        {
            Language = "ENG";
        }

        public string UserId { get; set; }
        public string Password { get; set; }
        public string Language { get; set; }
        public string FiUrl { get; set; }
        public string FiOrg { get; set; }
        public string Fid { get; set; }
        public string BankId { get; set; }
        public string AccountId { get; set; }
        public AccountType AccountType { get; set; }

        public void GetStatement()
        {
            StringBuilder messageBuilder = new StringBuilder();

            messageBuilder.AppendLine("OFXHEADER:100");
            messageBuilder.AppendLine("DATA:OFXSGML");
            messageBuilder.AppendLine("VERSION:102");
            messageBuilder.AppendLine("SECURITY:NONE");
            messageBuilder.AppendLine("ENCODING:USASCII");
            messageBuilder.AppendLine("CHARSET:1252");
            messageBuilder.AppendLine("COMPRESSION:NONE");
            messageBuilder.AppendLine("OLDFILEUID:NONE");
            messageBuilder.AppendLine("NEWFILEUID:NONE");
            messageBuilder.AppendLine();
            messageBuilder.AppendLine("<OFX>");
            messageBuilder.AppendLine("<SIGNONMSGSRQV1>");
            messageBuilder.AppendLine("<SONRQ>");
            messageBuilder.AppendLine(string.Format("<DTCLIENT>{0}[-5:EST]", DateTime.Now.ToString("yyyyMMddHHmmss.000")));
            messageBuilder.AppendLine(string.Format("<USERID>{0}", UserId));
            messageBuilder.AppendLine(string.Format("<USERPASS>{0}", Password));
            messageBuilder.AppendLine(string.Format("<LANGUAGE>{0}", Language));
            messageBuilder.AppendLine("<FI>");
            messageBuilder.AppendLine(string.Format("<ORG>{0}", FiOrg));
            messageBuilder.AppendLine(string.Format("<FID>{0}", Fid));
            messageBuilder.AppendLine("</FI>");
            messageBuilder.AppendLine(string.Format("<APPID>{0}", "MyApp"));
            messageBuilder.AppendLine(string.Format("<APPVER>{0}", "0100"));
            messageBuilder.AppendLine("</SONRQ>");
            messageBuilder.AppendLine("</SIGNONMSGSRQV1>");
            messageBuilder.AppendLine("<BANKMSGSRQV1>");
            messageBuilder.AppendLine("<STMTTRNRQ>");
            messageBuilder.AppendLine(string.Format("<TRNUID>{0}", Guid.NewGuid().ToString("N").ToUpper()));
            messageBuilder.AppendLine("<STMTRQ>");
            messageBuilder.AppendLine("<BANKACCTFROM>");
            messageBuilder.AppendLine(string.Format("<BANKID>{0}", BankId));
            messageBuilder.AppendLine(string.Format("<ACCTID>{0}", AccountId));
            messageBuilder.AppendLine(string.Format("<ACCTTYPE>{0}", AccountType));
            messageBuilder.AppendLine("</BANKACCTFROM>");
            messageBuilder.AppendLine("<INCTRAN>");
            messageBuilder.AppendLine(string.Format("<INCLUDE>{0}", "N"));
            messageBuilder.AppendLine("</INCTRAN>");
            messageBuilder.AppendLine("</STMTRQ>");
            messageBuilder.AppendLine("</STMTTRNRQ>");
            messageBuilder.AppendLine("</BANKMSGSRQV1>");
            messageBuilder.AppendLine("</OFX>");

            string message = messageBuilder.ToString();
            byte[] messageBytes = Encoding.ASCII.GetBytes(message);

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(FiUrl);
            request.Method = "POST";
            request.ContentType = "application/x-ofx";
            request.Accept = "*/*, application/x-ofx";
            request.ContentLength = messageBytes.Length;
            ServicePointManager.Expect100Continue = false;

            Stream requestStream = request.GetRequestStream();
            requestStream.Write(messageBytes, 0, messageBytes.Length);
            requestStream.Close();

            try
            {
                WebResponse response = request.GetResponse();
            }
            catch (WebException ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadLine();
            }
        }
    }
}

Re: VB.NET HttpWebRequest Example

Go figure...  I guess I didn't try everything... Downloaded the OFXViewer (found the link on this forum but here is the official site: http://fi.intuit.com/ofximplementation/ … dcdevelop) and it pointed out the errors.  Turns out some CRLFs were the culprit.  I changed the above code to the following.  Instead of a StringBuilder and using AppendLine I put all the strings in a List<string> and the used String.Join with the Environment.NewLine.  This evidently put the correct CRLF that the server was looking for and all is well.

            List<string> messageBuilder = new List<string>();

            messageBuilder.Add("OFXHEADER:100");
            messageBuilder.Add("DATA:OFXSGML");
            messageBuilder.Add("VERSION:102");
            messageBuilder.Add("SECURITY:NONE");
            messageBuilder.Add("ENCODING:USASCII");
            messageBuilder.Add("CHARSET:1252");
            messageBuilder.Add("COMPRESSION:NONE");
            messageBuilder.Add("OLDFILEUID:NONE");
            messageBuilder.Add("NEWFILEUID:NONE");
            messageBuilder.Add("");
            messageBuilder.Add("<OFX>");
            messageBuilder.Add("<SIGNONMSGSRQV1>");
            messageBuilder.Add("<SONRQ>");
            messageBuilder.Add(string.Format("<DTCLIENT>{0}[-5:EST]", DateTime.Now.ToString("yyyyMMddHHmmss.000")));
            messageBuilder.Add(string.Format("<USERID>{0}", UserId));
            messageBuilder.Add(string.Format("<USERPASS>{0}", Password));
            messageBuilder.Add(string.Format("<LANGUAGE>{0}", Language));
            messageBuilder.Add("<FI>");
            messageBuilder.Add(string.Format("<ORG>{0}", FiOrg));
            messageBuilder.Add(string.Format("<FID>{0}", Fid));
            messageBuilder.Add("</FI>");
            messageBuilder.Add(string.Format("<APPID>{0}", "MyApp"));
            messageBuilder.Add(string.Format("<APPVER>{0}", "0100"));
            messageBuilder.Add("</SONRQ>");
            messageBuilder.Add("</SIGNONMSGSRQV1>");
            messageBuilder.Add("<BANKMSGSRQV1>");
            messageBuilder.Add("<STMTTRNRQ>");
            messageBuilder.Add(string.Format("<TRNUID>{0}", Guid.NewGuid().ToString("N").ToUpper()));
            messageBuilder.Add("<STMTRQ>");
            messageBuilder.Add("<BANKACCTFROM>");
            messageBuilder.Add(string.Format("<BANKID>{0}", BankId));
            messageBuilder.Add(string.Format("<ACCTID>{0}", AccountId));
            messageBuilder.Add(string.Format("<ACCTTYPE>{0}", AccountType));
            messageBuilder.Add("</BANKACCTFROM>");
            messageBuilder.Add("<INCTRAN>");
            messageBuilder.Add(string.Format("<INCLUDE>{0}", "N"));
            messageBuilder.Add("</INCTRAN>");
            messageBuilder.Add("</STMTRQ>");
            messageBuilder.Add("</STMTTRNRQ>");
            messageBuilder.Add("</BANKMSGSRQV1>");
            messageBuilder.Add("</OFX>");

            string message = String.Join(Environment.NewLine, messageBuilder);

Re: VB.NET HttpWebRequest Example

One quick note.  Your method will work on windows where the newline is a \r\n.  It may not work under unix environments which only use a \n.  You may have better luck explicitly joining the strings with a \r\n.

Re: VB.NET HttpWebRequest Example

Good call.  Switched them over to \r\n and all still works.

Re: VB.NET HttpWebRequest Example

Thanks so much for the great examples.  I've been using to to download my own bank and credit card statements.  I've been attempting to also connect to a investment brokerage firm (American Funds), but keep getting sign on errors.  Does anyone have a working example of an investment brokerage statement download?  Here is what I've got so far for the request.

OFXHEADER:100
DATA:OFXSGML
VERSION:102
SECURITY:TYPE1
ENCODING:USASCII
CHARSET:1252
COMPRESSION:NONE
OLDFILEUID:NONE
NEWFILEUID:92A69E94-3361-45DC-BC03-27E64C8C4D9A

<OFX>
<SIGNONMSGSRQV1>
<SONRQ>
<DTCLIENT>20120511051316
<USERID>USERNAME
<USERPASS>PASSWORD
<LANGUAGE>ENG
<FI>
<ORG>DST
<FID>7779
</FI>
<APPID>QWIN
<APPVER>1800
</SONRQ>
</SIGNONMSGSRQV1>
<INVSTMTMSGSRQV1>
<INVSTMTTRNRQ>
<TRNUID>948264DB-F36E-4B2E-A016-73CD5A52942A
<CLTCOOKIE>4
<INVSTMTRQ>
<INVACCTFROM>
<BROKERID>www.americanfunds.com
<ACCTID>MY-ACCOUNT-NUMBER
</INVACCTFROM>
<INCTRAN>
<DTSTART>20120501
<DTEND>20120511155514
<INCLUDE>Y
</INCTRAN>
<INCOO>Y
<INCPOS>
<DTASOF>20120511051316
<INCLUDE>Y
</INCPOS>
<INCBAL>Y
</INVSTMTRQ>
</INVSTMTTRNRQ>
</INVSTMTMSGSRQV1>
</OFX>

Re: VB.NET HttpWebRequest Example

I think the problem is on the dates' format. Most FI servers like dates to be exactly in the same format.
While you have:
<DTSTART>20120501
<DTEND>20120511155514

Try to set DTSTART same as DTEND format (yyyyMMddhhmmss) and see what happens.

Re: VB.NET HttpWebRequest Example

Hello,

Thanks for the response. I doesn't look like the date was the issue.  Based on the error message it seems like its a problem with the login part of the request. Does the rest of the request look ok?

Re: VB.NET HttpWebRequest Example

The other thing I can think of is security type in ofx headers. Try setting it to 'none' instead of 'type1':

SECURITY:NONE

The rest looks ok. Let me know if that works for you.

Re: VB.NET HttpWebRequest Example

I can't get past the ERROR 15500 when attempting to access the Chase Banking.  Here is the XML:

OFXHEADER:100
DATA:OFXSGML
VERSION:102
SECURITY:NONE
ENCODING:USASCII
CHARSET:1252
COMPRESSION:NONE
OLDFILEUID:NONE
NEWFILEUID:NONE

<OFX>
<SIGNONMSGSRQV1>
<SONRQ>
<DTCLIENT>20130618103544.000[-5:EST]
<USERID>xxxxxx
<USERPASS>yyyyyy
<LANGUAGE>ENG
<FI>
<ORG>Chase Bank
<FID>1601
</FI>
<INTU.BID>10898
<APPID>QWIN
<APPVER>1900
</SONRQ>
</SIGNONMSGSRQV1>
<BANKMSGSRQV1>
<STMTTRNRQ>
<TRNUID>90BAEDE714D44EE799036297A67D442E
<STMTRQ>
<BANKACCTFROM>
<BANKID>bbbbbbb
<ACCTID>aaaaaaa
<ACCTTYPE>CHECKING
</BANKACCTFROM>
<INCTRAN>
<INCLUDE>N
</INCTRAN>
</STMTRQ>
</STMTTRNRQ>
</BANKMSGSRQV1>
</OFX>

I'm using the following url:

https://www.oasis.cfree.com/1601.ofxgp

Has anyone had any recent success in accessing Chase Checking through the OFX direct connect protocol?  If so, what combination of URL, FID and ORG is used?  Also, I'm using the username and password for online banking as the username and password for OFX direct connect.  Is that correct?

Finally, I activated the PFM direct connect service yesterday.

Any help or advice is appreciated.