PHPackages                             fernandocarletti/ofx - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Parsing &amp; Serialization](/categories/parsing)
4. /
5. fernandocarletti/ofx

ActiveLibrary[Parsing &amp; Serialization](/categories/parsing)

fernandocarletti/ofx
====================

Object-oriented PHP parser for Open Financial Exchange (OFX) files supporting OFX v1 (SGML) and v2 (XML)

1.0.3(2mo ago)117MITPHPPHP ^8.4CI passing

Since Jan 27Pushed 2mo agoCompare

[ Source](https://github.com/fernandocarletti/ofx)[ Packagist](https://packagist.org/packages/fernandocarletti/ofx)[ RSS](/packages/fernandocarletti-ofx/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (6)Versions (5)Used By (0)

PHP OFX
=======

[](#php-ofx)

> **Disclaimer:** This library was built entirely using [OpenCode](https://opencode.ai) and Claude Opus 4.5.

[![License: MIT](https://camo.githubusercontent.com/08cef40a9105b6526ca22088bc514fbfdbc9aac1ddbf8d4e6c750e3a88a44dca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c75652e737667)](LICENSE)[![PHP Version](https://camo.githubusercontent.com/e7fb02d4dba7ebc18300495e44eda0d0f1e5e176b17b0ad8542e31cf06735e73/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e342532422d3737374242342e737667)](https://php.net)![Tests](https://camo.githubusercontent.com/c552e51e912bd8f08dffbd96f472004490324df905a76daf652a100d2a197ade/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f54657374732d32383325323070617373696e672d627269676874677265656e2e737667)

A modern, object-oriented PHP parser for Open Financial Exchange (OFX) files. Supports both OFX v1 (SGML) and OFX v2 (XML) formats with human-friendly property names and full type safety.

Features
--------

[](#features)

- **Dual Format Support** - Parses both OFX v1 (SGML) and v2 (XML) formats
- **Complete OFX Coverage** - Supports all major OFX domains: banking, credit cards, investments, bill pay, transfers, tax forms, and more
- **Human-Friendly API** - Property names like `transactionId` and `accountNumber` instead of cryptic OFX tags like `TRNUID` and `ACCTID`
- **Modern PHP** - Built for PHP 8.4+ using property hooks and strict typing
- **Fully Typed** - Complete type declarations for IDE autocompletion and static analysis
- **Zero Dependencies** - Only requires standard PHP extensions

Installation
------------

[](#installation)

```
composer require fernandocarletti/ofx
```

Quick Start
-----------

[](#quick-start)

```
use Ofx\Parser;

$parser = new Parser();
$ofx = $parser->parseFile('/path/to/statement.ofx');

// Access bank statement transactions
$bankMessages = $ofx->bankMessagesResponseV1;
$statement = $bankMessages->statementTransactionResponses[0]->statementResponse;

foreach ($statement->transactionList->transactions as $transaction) {
    echo sprintf(
        "%s: %s %s\n",
        $transaction->datePosted->format('Y-m-d'),
        $transaction->name,
        $transaction->amount
    );
}

// Check balances
echo "Ledger Balance: " . $statement->ledgerBalance->amount . "\n";
echo "Available Balance: " . $statement->availableBalance->amount . "\n";
```

Usage Examples
--------------

[](#usage-examples)

### Parsing Bank Statements

[](#parsing-bank-statements)

```
use Ofx\Parser;

$parser = new Parser();
$ofx = $parser->parseFile('bank_statement.ofx');

$statement = $ofx->bankMessagesResponseV1
    ->statementTransactionResponses[0]
    ->statementResponse;

// Account information
$account = $statement->bankAccount;
echo "Routing: " . $account->routingNumber . "\n";
echo "Account: " . $account->accountId . "\n";
echo "Type: " . $account->accountType->value . "\n"; // CHECKING, SAVINGS, etc.

// Transaction details
foreach ($statement->transactionList->transactions as $txn) {
    echo sprintf(
        "[%s] %s - %s (%s)\n",
        $txn->type->value,           // CREDIT, DEBIT, CHECK, etc.
        $txn->transactionId,
        $txn->name,
        $txn->amount
    );

    if ($txn->isDebit()) {
        echo "  This was a debit transaction\n";
    }

    if ($txn->checkNumber !== null) {
        echo "  Check #" . $txn->checkNumber . "\n";
    }
}
```

### Parsing Credit Card Statements

[](#parsing-credit-card-statements)

```
$ofx = $parser->parseFile('credit_card.ofx');

$statement = $ofx->creditCardMessagesResponseV1
    ->statementTransactionResponses[0]
    ->creditCardStatementResponse;

// Credit card account
echo "Card: " . $statement->creditCardAccount->accountId . "\n";

// Transactions
foreach ($statement->transactionList->transactions as $txn) {
    echo $txn->datePosted->format('M d') . ": ";
    echo $txn->name . " " . $txn->amount . "\n";
}

// Balances
echo "Current Balance: " . $statement->ledgerBalance->amount . "\n";
echo "Available Credit: " . $statement->availableBalance->amount . "\n";
```

### Parsing Investment Statements

[](#parsing-investment-statements)

```
$ofx = $parser->parseFile('investment.ofx');

$statement = $ofx->investmentMessagesResponseV1
    ->statementTransactionResponses[0]
    ->investmentStatementResponse;

// Investment account
$account = $statement->investmentAccount;
echo "Broker ID: " . $account->brokerId . "\n";
echo "Account: " . $account->accountId . "\n";

// Positions
foreach ($statement->positionList->positions as $position) {
    echo sprintf(
        "%s: %s units @ %s\n",
        $position->securityId->uniqueId,
        $position->units,
        $position->unitPrice
    );
}

// Investment transactions (buys, sells, dividends, etc.)
$txnList = $statement->investmentTransactionList;
foreach ($txnList->buyStock ?? [] as $buy) {
    echo "BUY: " . $buy->securityId->uniqueId . "\n";
}
```

### Accessing Header Information

[](#accessing-header-information)

```
$ofx = $parser->parseFile('statement.ofx');

// Header is available after parsing
$header = $parser->parsedHeader;

echo "OFX Version: " . $header->version . "\n";       // 102, 160, 200, 220, etc.
echo "Is v1 (SGML): " . ($header->isVersion1 ? 'Yes' : 'No') . "\n";
echo "Is v2 (XML): " . ($header->isVersion2 ? 'Yes' : 'No') . "\n";
echo "Encoding: " . $header->encoding . "\n";         // UTF-8, Windows-1252, etc.
```

### Parsing from Different Sources

[](#parsing-from-different-sources)

```
// From file path
$ofx = $parser->parseFile('/path/to/file.ofx');

// From string content
$content = file_get_contents('statement.ofx');
$ofx = $parser->parseString($content);

// From stream resource
$stream = fopen('statement.ofx', 'r');
$ofx = $parser->parseStream($stream);
fclose($stream);
```

### Checking Signon Status

[](#checking-signon-status)

```
$ofx = $parser->parseFile('statement.ofx');

$signon = $ofx->signonMessagesResponseV1->signonResponse;

if ($signon->status->isSuccess()) {
    echo "Signed on successfully\n";
    echo "Server date: " . $signon->serverDate->format('Y-m-d H:i:s') . "\n";
    echo "Language: " . $signon->language->value . "\n";

    if ($signon->financialInstitution !== null) {
        echo "FI: " . $signon->financialInstitution->organization . "\n";
    }
} else {
    echo "Signon failed: " . $signon->status->code . "\n";
    echo "Message: " . $signon->status->message . "\n";
}
```

Supported OFX Domains
---------------------

[](#supported-ofx-domains)

DomainRequestResponseDescription**Signon**`signonMessagesRequestV1``signonMessagesResponseV1`Authentication and session management**Signup**`signupMessagesRequestV1``signupMessagesResponseV1`Account enrollment and information**Bank**`bankMessagesRequestV1``bankMessagesResponseV1`Bank account statements and transactions**Credit Card**`creditCardMessagesRequestV1``creditCardMessagesResponseV1`Credit card statements and transactions**Investment**`investmentMessagesRequestV1``investmentMessagesResponseV1`Brokerage statements, positions, trades**Security List**`securityListMessagesRequestV1``securityListMessagesResponseV1`Security (stock/fund/bond) information**Profile**`profileMessagesRequestV1``profileMessagesResponseV1`Financial institution capabilities**Email**`emailMessagesRequestV1``emailMessagesResponseV1`Secure messaging with FI**Bill Pay**`billPayMessagesRequestV1``billPayMessagesResponseV1`Bill payment and payee management**Interbank Transfer**`interbankTransferMessagesRequestV1``interbankTransferMessagesResponseV1`Transfers between institutions**Wire Transfer**`wireTransferMessagesRequestV1``wireTransferMessagesResponseV1`Wire transfer processing**Tax 1099**`tax1099MessagesRequestV1``tax1099MessagesResponseV1`Tax form 1099 variants (INT, DIV, B, R, etc.)Requirements
------------

[](#requirements)

- PHP 8.4 or higher
- Extensions: `simplexml`, `libxml`, `bcmath`, `mbstring`

Development
-----------

[](#development)

```
# Install dependencies
composer install

# Run tests
composer test

# Run static analysis
composer analyse

# Check code style
composer cs-check

# Fix code style
composer cs-fix
```

License
-------

[](#license)

This library is open-sourced software licensed under the [MIT license](LICENSE).

###  Health Score

42

—

FairBetter than 90% of packages

Maintenance87

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~13 days

Total

4

Last Release

62d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/b121ec34d63c31e660256a848448088b4749ff138204b475397281466db362a0?d=identicon)[fernandocarletti](/maintainers/fernandocarletti)

---

Top Contributors

[![fernandocarletti](https://avatars.githubusercontent.com/u/416930?v=4)](https://github.com/fernandocarletti "fernandocarletti (3 commits)")

---

Tags

parserfinanceBankingofxfinancialinvestmentqfx

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/fernandocarletti-ofx/health.svg)

```
[![Health](https://phpackages.com/badges/fernandocarletti-ofx/health.svg)](https://phpackages.com/packages/fernandocarletti-ofx)
```

###  Alternatives

[nikic/php-parser

A PHP parser written in PHP

17.4k902.6M1.8k](/packages/nikic-php-parser)[doctrine/lexer

PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.

11.2k910.8M118](/packages/doctrine-lexer)[abcaeffchen/sephpa

Generates SEPA files for credit transfers (pain.001.001.03, pain.001.002.03, pain.001.003.03, pain.001.001.09) and direct debit (pain.008.001.02, pain.008.002.02, pain.008.003.02, pain.008.001.08)

711.7M](/packages/abcaeffchen-sephpa)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
