PHPackages                             open-banking-io/client - 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. [API Development](/categories/api)
4. /
5. open-banking-io/client

ActiveLibrary[API Development](/categories/api)

open-banking-io/client
======================

Server-to-server client for open-banking.io: API-key auth and local zero-knowledge envelope decryption.

v0.2.0(1mo ago)00MITPHPPHP &gt;=8.1

Since Jun 10Pushed 1w agoCompare

[ Source](https://github.com/open-banking-io/client-php)[ Packagist](https://packagist.org/packages/open-banking-io/client)[ Docs](https://open-banking.io)[ RSS](/packages/open-banking-io-client/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (4)Versions (3)Used By (0)

 [ ![open-banking.io](https://raw.githubusercontent.com/open-banking-io/clients/main/.github/logo.png) ](https://open-banking.io)

open-banking-io (PHP)
=====================

[](#open-banking-io-php)

Server-to-server client for [open-banking.io](https://open-banking.io). It authenticates with your **API key** and decrypts the **zero-knowledge** data envelopes locally with your exported **private key** — the service only ever returns ciphertext it cannot read.

```
composer require open-banking-io/client
```

Requires PHP **8.1+** with `ext-openssl`, `ext-curl` and `ext-json` (no runtime Composer dependencies).

Every request carries a `User-Agent: open-banking-io/php/` header (`Client::VERSION`) and uses a 30s total / 10s connect timeout.

```
use OpenBankingIO\Client;

// Load the credentials .json you exported from the app (API key + private key).
$client = Client::fromCredentials('credentials.json');

foreach ($client->getAccounts() as $account) {
    $booked = null;
    foreach ($account->balances as $b) {
        if ($b->type === 'ITBD') {
            $booked = $b;
        }
    }
    $label = $account->displayName ?? $account->ownerName;
    printf("%s %s: %s %s\n", $label, $account->iban, $booked?->amount, $account->currency);

    $page = $client->getTransactions($account->id, ['limit' => 50]);
    foreach ($page->items as $t) {
        printf("  %s  %s  %s %s\n", $t->bookingDate, $t->creditorName ?? $t->debtorName, $t->amount, $t->currency);
    }

    // Trigger an online sync (decrypts the account uid locally and posts it):
    $client->sync($account->id);
}
```

Or construct it explicitly:

```
$client = new Client($apiBaseUrl, $apiKey, $privateKeyPkcs8);
```

Custom transport &amp; timeouts
-------------------------------

[](#custom-transport--timeouts)

Both the constructor and `Client::fromCredentials()` take an optional `array $options` for proxy, custom CA / mTLS, and timeout control. `curl_options` (a map of `CURLOPT_* => value`) is applied **last**, so it wins over the SDK defaults; `timeout` / `connect_timeout` (seconds) override the 30s / 10s defaults:

```
$client = new Client($apiBaseUrl, $apiKey, $privateKeyPkcs8, [
    'timeout' => 60,          // total request timeout (seconds)
    'connect_timeout' => 5,   // connection-establishment timeout (seconds)
    'curl_options' => [
        CURLOPT_PROXY  => 'http://proxy.internal:8080',
        CURLOPT_CAINFO => '/etc/ssl/corp-ca.pem',
    ],
]);

// Same options are accepted by the bundle loader:
$client = Client::fromCredentials('credentials.json', ['timeout' => 60]);
```

API
---

[](#api)

- `getAccounts(): Account[]` — decrypts each account's envelope, display name and balances.
- `getTransactions(string $accountId, array $opts = []): TransactionPage` — `$opts` keys: `from`, `to`, `limit`, `offset`.
- `getConnections(): Connection[]`
- `sync(string $accountId): SyncResult` — decrypts the account uid locally and posts it; throws if the account has no active session.
- `syncAll(): SyncAllResult` — syncs every account that has an active session.

Money/amount fields are exposed as **decimal `string`s** (exact; never a float). Models are `final` classes with `readonly` public properties under `OpenBankingIO\Model`.

Encryption
----------

[](#encryption)

Envelopes use **ECDH P-256 → HKDF-SHA256 → AES-256-GCM** and are decrypted entirely in-process with `ext-openssl`. Full wire format and the other language clients: [repo README](https://github.com/open-banking-io/clients) · [`THREAT_MODEL.md`](https://github.com/open-banking-io/clients/blob/main/THREAT_MODEL.md).

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

[](#development)

```
composer install
vendor/bin/phpunit
```

The tests read the shared fixtures at the repo-root `fixtures/` directory. The integration test spins up a local mock API using PHP's built-in server (`php -S`) as a subprocess.

### Static analysis &amp; formatting

[](#static-analysis--formatting)

```
vendor/bin/phpstan analyse                       # PHPStan level max (src/ + tests/)
vendor/bin/php-cs-fixer fix --dry-run --diff     # PSR-12 check (drop --dry-run to apply)
```

### Coverage

[](#coverage)

Coverage needs a driver. CI runs with **pcov**; locally you can also use Xdebug via `XDEBUG_MODE=coverage`. The `` config emits Cobertura plus a text summary:

```
# CI / pcov:
php -d pcov.enabled=1 vendor/bin/phpunit --coverage-cobertura=coverage/cobertura.xml
# or with Xdebug:
XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-cobertura=coverage/cobertura.xml
```

The report is written to `coverage/cobertura.xml` (gitignored). Because `phpunit.xml` enables a `` report and `failOnWarning`, run the suite **with a coverage driver present**(pcov or `XDEBUG_MODE=coverage`); otherwise PHPUnit emits a "no coverage driver" warning.

Publishing (monorepo caveat)
----------------------------

[](#publishing-monorepo-caveat)

PHP packages are distributed through [Packagist](https://packagist.org), which auto-syncs from GitHub when a new tag is pushed. **Packagist expects `composer.json` at a repository root**, but this package lives in the `php/` subdirectory of a monorepo. Two ways to publish it:

1. **Subtree mirror (recommended):** publish `php/` to a dedicated mirror repo, e.g. `git subtree split --prefix=php -b php-release && git push  php-release:main`, and register that mirror on Packagist.
2. **VCS config pointing at the path:** some Packagist setups can be configured to read a package from a subdirectory — this is not the default and may require a custom/Private Packagist config.

This is intentionally **not solved here** — the `publish-php.yml` workflow validates the manifest and runs the tests, then optionally pings Packagist's update API when the `PACKAGIST_USERNAME`/`PACKAGIST_API_TOKEN` secrets are present.

MIT licensed.

###  Health Score

35

—

LowBetter than 77% of packages

Maintenance95

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity33

Early-stage or recently created project

 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 ~0 days

Total

2

Last Release

45d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/7979529?v=4)[Nicolaj Helmer Hartmann](/maintainers/nicolaj-hartmann)[@nicolaj-hartmann](https://github.com/nicolaj-hartmann)

---

Top Contributors

[![nicolaj-hartmann](https://avatars.githubusercontent.com/u/7979529?v=4)](https://github.com/nicolaj-hartmann "nicolaj-hartmann (9 commits)")

---

Tags

ecdhBankingpsd2Open Bankingzero-knowledge

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/open-banking-io-client/health.svg)

```
[![Health](https://phpackages.com/badges/open-banking-io-client/health.svg)](https://phpackages.com/packages/open-banking-io-client)
```

###  Alternatives

[nordigen/nordigen-php

Nordigen official API client for PHP

42387.2k5](/packages/nordigen-nordigen-php)[bunq/sdk_php

bunq PHP SDK

89244.3k2](/packages/bunq-sdk-php)[oaklabs/psd2

API client for banks supporting psd2 APIs.

318.1k](/packages/oaklabs-psd2)[mhujer/fio-api-php

Fio API PHP implemention

37226.0k1](/packages/mhujer-fio-api-php)[starkbank/sdk

SDK to facilitate PHP integrations with Stark Bank

15184.9k](/packages/starkbank-sdk)

PHPackages © 2026

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