Payments
Payments with Wealth Reader
Wealth Reader lets you prepare an immutable payment order from your backend and complete bank authorization in a dedicated secure widget (PSD2 / PIS – Payment Initiation Services). The API credential, sensitive beneficiary accounts and internal connection details are never delivered to the browser.
The deterministic sandbox lets you integrate without moving real money, but it is not activated by a parameter: it is a separate deployment with its own base URL and credential, provided by Wealth Reader on request (see Security and testing). In sandbox, profile-institutions returns a single simulated institution. The expected_mode field does not switch environments: it only checks that you are targeting the intended environment, returning 409 payment_mode_mismatch on a mismatch.
A bank's availability for aggregation does not imply identical availability for payment initiation. In production, the Wealth Reader institution catalogue offers coverage in Spain and across Europe.
Two-step architecture
Payment integration follows a strict separation of responsibilities in two steps:
sequenceDiagram autonumber actor Usuario as User participant Front as Frontend (Merchant) participant Back as Backend (Merchant) participant API as Wealth Reader API participant Widget as Payments Widget participant Banco as Bank (SCA) Note over Back,API: Prerequisite (managed profiles only) Back->>API: POST /payments/?action=profile-institutions API-->>Back: Profile catalogue (institution_code) Note over Back,API: Step 1: Create the immutable intent (Server-to-Server) Back->>API: POST /payments/?action=create (with X-API-Key and Idempotency-Key) API-->>Back: 201 with payment.id + ephemeral payment.widget.token Note over Front,Widget: Step 2: Load and authorize in the widget (Browser) Back->>Front: Deliver payment.id and payment.widget.token Front->>Widget: WealthReaderPayments.mount(...) or load-payments.js Widget->>Usuario: Display immutable institution, amount and payment reference Usuario->>Widget: Authorize the payment Widget->>Banco: Redirect / App to App (SCA) Banco->>API: SCA return to the Wealth Reader callback API-->>Widget: Technical authorization confirmation Note over Back,API: Financial reconciliation and confirmation loop Until a terminal status Back->>API: POST /payments/?action=status API-->>Back: payment_status: not_initiated | pending | settled | ... end
- Step 1 (Secure backend): Your server creates a payment intent (
POST /payments/?action=create) with itsX-API-Key, anIdempotency-KeyandContent-Type: application/json. This call immutably fixes the amount (amount_minor, in cents), currency (currency, currently onlyEUR), beneficiary (beneficiary.nameandbeneficiary.iban), bank statement reference (reference), your internal reference (customer_reference) and permitted web origin (allowed_origin). All six fields are required, and the body uses a strict allowlist: any unrecognized field returns422 invalid_request. - Response:
201with{"success": true, "payment": {…}}— or200for an idempotent replay. The intent identifier is inpayment.id, and the ephemeral widget token is inpayment.widget.token. - Step 2 (Merchant frontend): The browser mounts the widget using the official
load-payments.jsscript or theWealthReaderPayments.mount()function, supplying onlypayment.idandpayment.widget.token. The user selects their bank (if not preselected in the intent) and completes strong customer authentication (SCA) in the bank's interface. - Financial confirmation: Your backend queries the status using
POST /payments/?action=status, with a body of exactly{"payment_intent_id": "<id>"}. There is no webhook: poll until a terminal status is reached.
Two collection models
Wealth Reader supports two models to suit business needs:
- Standard merchant integration (own beneficiary):
- The merchant freely specifies the beneficiary name and IBAN, amount, currency (
EUR), payment reference and its own order reference. - You can filter the banks available to the user with
allowed_institution_codes, or allow the entire catalogue.
- The merchant freely specifies the beneficiary name and IBAN, amount, currency (
- Managed profiles (such as
cruz_roja_demo):- Designed for donations and public demonstrations.
- The server fixes the official destination accounts to ensure that funds can only reach the charity (for example, the Spanish Red Cross, with amounts bounded between
0,01 EURand1,00 EUR).
Unified bank directory
Wealth Reader provides a unified catalogue of European institutions ready for PSD2 payment initiation through:
GET https://api.wealthreader.com/payments/entities/?country=ES
It returns banks with normalized names, logos, supported transfer methods and technical requirements (such as requesting the payer's debtor IBAN). Supported filters are country, search (alias q), code, payment_method, limit and offset.
This endpoint is public: it does not require X-API-Key. Sending it adds nothing and consumes one call from your credential's quota.
Always use the codes exactly as returned in code. Intent creation validates the format of allowed_institution_codes, but does not check whether they exist in the catalogue: a mistyped code does not fail at creation and later results in an empty bank selector.
interaction_status: completed only means that the technical on-screen interaction has ended. A payment is only considered final when payment_status is settled. Possible payment_status values are not_initiated, pending, settled, rejected, cancelled, expired, failed and unknown; see Statuses, polling and reconciliation.
Separation of responsibilities
- The payment credential (
X-API-Key) is used only server-to-server. Never include it in frontend code or public repositories. - The browser receives only the intent identifier and a short-lived ephemeral token bound to the HTTPS origin.
- The widget cannot change the amount, currency, beneficiary, payment reference or authorized institutions.
- Closing the modal or widget does not replace querying the financial status from the backend.
- Payments do not share credentials, tokens or callbacks with Wealth Reader's bank aggregation product.
Credentials and quota
Your payment credential must have the PAYMENTS product enabled; otherwise the API returns 403 payments_not_allowed. A missing or malformed credential returns 401 invalid_api_key.
Each authenticated call consumes one unit of your API key's cumulative counter. This is a lifetime counter, with no time window or automatic replenishment: once exhausted, all payment calls permanently return 429 api_limit_reached until the limit is increased. Waiting or retrying does not resolve this. If you expect high volume — or a public demo, where each page load consumes a call — agree the limit with Wealth Reader before publishing.
Next step
Continue with Integration and widget.