Bank statement PDF to QBO without uploading
Published 25 September 2026 · by Tekiba
LedgerDrop Pro reads the statement PDF inside your browser and writes the rows as a file in Web Connect (QBO) format, or as OFX or QIF. Nothing is uploaded; there is nowhere to upload it to. What nobody outside Intuit can promise is that QuickBooks will accept a QBO that did not come from a bank: Intuit does not publish the format, and QuickBooks checks the bank the file names. If it refuses, nothing else gets round that: Web Connect reads only .qbo.
What a QBO file is
QuickBooks Desktop's Web Connect reads one kind of file. Intuit's own help page for its import errors says to make sure the file “is a .qbo file, the only type Web Connect can read” (Intuit, Fix Web Connect import errors).
Underneath, a QBO is an OFX (Open Financial Exchange) file with one extra element of Intuit's, INTU.BID. The OFX specifications are published, and still readable through the Internet Archive now that ofx.net has gone; the extra element is not. So everything in a LedgerDrop QBO comes from the OFX 2.1.1 specification and its XML schema except that element, its value 3000 and the FI block beside it, which are marked as coming from other converters' help pages.
What is in the file
Two fictional rows, written by the converter's own code:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?OFX OFXHEADER="200" VERSION="211" SECURITY="NONE" OLDFILEUID="NONE" NEWFILEUID="NONE"?>
<OFX>
<SIGNONMSGSRSV1>
<SONRS>
<STATUS>
<CODE>0</CODE>
<SEVERITY>INFO</SEVERITY>
</STATUS>
<DTSERVER>20240601093000</DTSERVER>
<LANGUAGE>ENG</LANGUAGE>
<FI>
<ORG>LedgerDrop</ORG>
<FID>3000</FID>
</FI>
<INTU.BID>3000</INTU.BID>
</SONRS>
</SIGNONMSGSRSV1>
<BANKMSGSRSV1>
<STMTTRNRS>
<TRNUID>0</TRNUID>
<STATUS>
<CODE>0</CODE>
<SEVERITY>INFO</SEVERITY>
</STATUS>
<STMTRS>
<CURDEF>USD</CURDEF>
<BANKACCTFROM>
<BANKID>000000000</BANKID>
<ACCTID>1234</ACCTID>
<ACCTTYPE>CHECKING</ACCTTYPE>
</BANKACCTFROM>
<BANKTRANLIST>
<DTSTART>20240501</DTSTART>
<DTEND>20240601</DTEND>
<STMTTRN>
<TRNTYPE>CREDIT</TRNTYPE>
<DTPOSTED>20240508</DTPOSTED>
<TRNAMT>1450.00</TRNAMT>
<FITID>20240508-5ef8065225add426-1</FITID>
<NAME>Deposit - invoice 2110 Brightwel</NAME>
<MEMO>Deposit - invoice 2110 Brightwell Ltd</MEMO>
</STMTTRN>
<STMTTRN>
<TRNTYPE>DEBIT</TRNTYPE>
<DTPOSTED>20240514</DTPOSTED>
<TRNAMT>-86.40</TRNAMT>
<FITID>20240514-eeb09d5da8e7eabb-1</FITID>
<NAME>Card purchase - Halden Tools</NAME>
</STMTTRN>
</BANKTRANLIST>
<LEDGERBAL>
<BALAMT>6175.95</BALAMT>
<DTASOF>20240531</DTASOF>
</LEDGERBAL>
</STMTRS>
</STMTTRNRS>
</BANKMSGSRSV1>
</OFX>
Three parts of it decide whether the file is right.
The sign of each amount
The specification is plain: “Transaction amounts are signed from the perspective of the customer. For example, a credit card payment is positive while a credit card purchase is negative.” LedgerDrop's CSV is signed the same way, row for row. A card that prints what you owe as a positive number has it turned round in the file, owing 150.00 becoming −150.00, but only when the statement's own figures show which way it prints; otherwise there is no OFX.
A transaction ID that does not change
Every row carries a FITID, and “FITIDs must be unique within the scope of an account”. An importer uses them to spot a transaction it already has, so LedgerDrop builds each from the row itself: the date, a short hash of date, amount, description and check number, and a count for otherwise identical rows, such as two coffees on one day. Convert the same statement again, with the same settings, and every row gets the same ID.
A balance the statement printed
An OFX statement has to state a closing balance. LedgerDrop uses the one printed, or else the running balance beside the last row, if no other row shares its date. Failing both, it refuses to write the OFX or QBO rather than invent a number your software might set the account to. QIF has no balance, so it can still go out as QIF.
Where QuickBooks may say no
Intuit lists the message: “QuickBooks is unable to verify the Financial Institution information for this download.” Which banks it accepts is not published. Other converters say INTU.BID 3000 is accepted; LedgerDrop uses 3000 unless you change it. Intuit also notes that “Import of web connect files (.qbo) requires you to sign in to your Intuit Account within QuickBooks Desktop”.
OFX and QIF, for other software
The OFX is the same file without those borrowed parts, as XML (2.1.1) or the older SGML (1.0.3). YNAB, for one, says “QFX and OFX files are options”, and offers “Swap Inflow and Outflow” at import if a file arrives the other way round.
QIF is older still. Intuit's own description, Quicken Interchange Format (QIF) files, calls it “a specially formatted text (ASCII) file”: a line such as !Type:Bank, then a date, amount, check number and payee per transaction, each ended with ^. Its examples put the month first, so that is the default; YYYY-MM-DD is offered too, marked as not in Intuit's text.
How to do it
- Open the converter and drop the statement PDF. It never leaves the tab.
- Check the balance check and the table.
- Under “File format”, choose QBO, OFX or QIF; for QBO or OFX, type the account's last four digits.
- Download. Several statements come out as a ZIP, one file each.
Convert a statement → The table and the balance check are free on any statement. QBO, OFX and QIF files are LedgerDrop Pro, $39 once.
What this will not do
It will not read a scanned statement: there is no OCR, free or Pro. It does not connect to your bank or to QuickBooks. And it will not tell you a file “will import”.
Questions
Will the QBO file import into QuickBooks Desktop?
It may, and nobody outside Intuit can promise it. The file follows the OFX specification with Intuit's INTU.BID added, but QuickBooks checks the bank a Web Connect file names and can refuse one it does not recognise. Web Connect reads only .qbo, so the OFX and CSV are for other programs, not a way round that. LedgerDrop has not been tested by importing a file into QuickBooks.
Why does LedgerDrop refuse to write an OFX for some statements?
Because an OFX statement has to state a closing balance, and some statements print neither a closing balance nor a running balance that is surely the last. LedgerDrop will not make one up. QIF carries no balance, so that statement can still be written as QIF, or as a CSV.
If I convert the same statement twice, will I get duplicate transactions?
Not from the IDs. Each row's FITID is built from its date, amount and description, so the same statement with the same settings gives the same IDs, which is what an importer uses to recognise transactions it already has. Whether your program skips them is up to the program, so look at the first import before relying on it.
Next: should debits be negative in a bank CSV?, how to check a converted bank statement CSV for errors, and QBO vs OFX vs QIF compared.