omnibank / powens
Omnibank Powens: bank aggregation through Powens (ex Budget Insight) - its Webview for the consent, accounts, balances, transactions, CONNECTION_SYNCED webhooks.
Requires
- php: >=8.2
- omniscient/omnibank: ^1.0@dev
- symfony/http-client: ^6.4|^7.0|^8.0
Requires (Dev)
- phpunit/phpunit: ^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-17 14:09:15 UTC
README
Powens (ex Budget Insight) for omniscient/omnibank: the user connects their banks in Powens' Webview; their accounts, balances and transactions are read with the user's permanent token; CONNECTION_SYNCED webhooks say when the data is fresh or the consent must be renewed.
Unverified. Written from Powens' published documentation and recorded answers (
Tests/Fixtures); it has not yet been run against a real Powens sandbox. Try it with real keys (docker compose run --rm omnibank connect powensinomniscient/omnibank'sdocker/) before relying on it, and drop this notice once it holds - the webhook signature above all.
$gateway = (new PowensGatewayFactory($http))->create(['domain' => '...', 'client_id' => '...', 'client_secret' => '...']); // $http: the application's HTTP client; none given, the factory makes its own
No framework needed: the package requires omniscient/omnibank and symfony/http-client. In a
Symfony application, the same through the bundle's configuration:
omnibank: gateways: banks: factory: powens options: domain: 'nakaya-sandbox.biapi.pro' # the client's domain in the Powens console client_id: '%env(POWENS_CLIENT_ID)%' client_secret: '%env(POWENS_CLIENT_SECRET)%' redirect_uri: 'https://app.example/bank/back' # when connect() is given no return URL webhook_secret: '%env(POWENS_WEBHOOK_SECRET)%' # for notify() webhook_url: 'https://app.example/bank/webhook' # the URL registered: its path is signed language: fr # the Webview's
connect()- the first time,POST /2.0/auth/initcreates the Powens user; its permanent token goes in the connection's state (auth_token,user_id): keep the connection. Each time,GET /2.0/auth/token/codegives a temporary code and the result's URL is the Webview:https://webview.powens.com/connect?domain=…&client_id=…&redirect_uri=…&code=…. When the consent is NEEDS_RENEWAL and the state hasconnection_id, it is the/reconnectpage of that connection. The Webview sends the user back withconnection_idin the query: put it in the state and mark the consent active ($connection->withState([...] + $connection->state)->withConsent(Consent::active())).accounts()-GET /2.0/users/me/accounts(deleted ones left out);balances()-GET /2.0/users/me/accounts/{id}:balance(booked), and withcoming(expected).transactions()-GET /2.0/users/me/accounts/{id}/transactions?min_date=&max_date=&limit=, every page (_links.next.href, else the next offset while pages come full); coming and deleted transactions left out;original_wordingis the label,counterpartyits name and IBAN.notify()- a body with aconnectionis CONNECTION_SYNCED: itsconnectionId, and its state as the consent -SCARequired,webauthRequired,decoupled,additionalInformationNeeded,actionNeeded,wrongpass,passwordExpiredare NEEDS_RENEWAL; none (or a bank outage:websiteUnavailable,rateLimiting,bug) is ACTIVE;expireis its expiry. Another body comes backUNKNOWN, consent NONE (it says nothing of it).- No
transfer()in this version.
Webhook signature - an assumption. Powens signs webhooks with the console's webhook secret in
BI-Signature, with BI-Signature-Date. This package takes base64(HMAC-SHA256(secret,
POST.<webhook path>.<BI-Signature-Date>.<body>)) - which needs webhook_url - and also the
HMAC-SHA256 of the body alone (base64 or hex). Check it against a real sandbox webhook and keep
only what Powens sends.
A 5xx, a 429 or a network failure is an UnavailableException, never an empty list.
Credentials: in the Powens console (console.powens.com), a domain (<x>-sandbox.biapi.pro
for the sandbox), a client application's client_id and client_secret with the return URL
whitelisted, and a webhook on CONNECTION_SYNCED with its secret.
Responsibility
This package is an independent, unofficial client: it is not affiliated with, endorsed by or sponsored by Powens SAS. It reaches their service on behalf of whoever runs it, and it does not redistribute their data beyond the short excerpts recorded as test fixtures. Its MIT licence covers this package's code only and grants no right to the service or to its data.
Whoever installs and runs this package is responsible for complying with Powens's terms (powens.com/sas-conditions-use), for obtaining whatever they require (an account, a key, a licence or subscription, an attribution or a citation, a rate limit to respect), and for any use made of what it returns. The authors publish it free of charge, make no commercial use of it, and accept no liability for how it is used (see LICENSE).
License: MIT since 2026-10-09; earlier versions remain published under LGPL-3.0-or-later.