Skip to main content

Showing activity and statements

Every feature so far writes - it creates cards, moves money, saves payees. This page builds the other half of the app: the read surfaces your customers look at most. There are two of them, and picking the right one for each screen matters.

Where this fits

This page assumes you've built cards and payments - the activity these screens display. Like every read here, your backend calls the API and serves the data to your UI; your client never calls these endpoints directly.

Two views, two jobs

Weavr splits the read side into two distinct surfaces, because a live feed and an authoritative record pull in opposite directions:

Screen in your appUseWhy
A live account or card activity feedTransaction activityShows in-flight activity the moment it happens - pending, processing, returned, settled
A downloadable bank statementStatementsAn immutable, per-period record with opening and closing balances, for compliance and archiving

A card payment, for example, streams through the activity feed across its whole lifecycle - authorization, settlement, any refund - and once it settles it also appears as a single line on the statement. Same transaction, two views, each doing its job.

Step 1: Build the activity feed

The activity feed is the screen customers open to see "what's happening on my account (or card) right now". It's a live, unified feed of every transaction type - transfers, sends, wire transfersWire Transfer A transaction that moves funds between accounts. An incoming wire transfer moves funds from a third-party bank account to a Weavr managed account, while an outgoing wire transfer moves funds from a Weavr managed account to a third-party bank account. Wire transfers require the managed account to have an assigned IBAN (for EUR) or sort code and account number (for GBP)., card payments, fees, and system transactions - in one normalized shape.

Your backend queries the feed per instrumentInstrument A financial product owned by an Identity. There are two types: Managed Accounts (stored-value accounts that hold balances and can receive wire transfers) and Managed Cards (prepaid cards - virtual or physical - used for purchases).:

GET/managed_accounts/{id}/transactionsTry it
GET/managed_cards/{id}/transactionsTry it

You can also query across all instruments with GET /transactions, or fetch a single entry by id.

Collapsed and expanded records

The reference app shows the pattern to build every activity list on - a scannable list of collapsed rows, each of which opens into an expanded detail view:

  • Collapsed record - the list row, built from the top-level fields every entry shares: type, status, direction, amount, and the timestamps. Because these are normalized, one row layout renders every transaction type consistently.
  • Expanded record - when a customer taps a row, surface the type-specific detail from the entry's transaction object.

Our open-source transaction activity reference app demonstrates both views for an account feed and a card feed. Here's the pattern, with each pinPIN Personal Identification Number - the numeric code a cardholder enters to authorize chip-and-PIN purchases and ATM withdrawals. PIN is only present on physical managed cards. Weavr returns it tokenized on `GET /managed_cards/{id}` (with a stepped-up token), and the SDK detokenizes it inside a secure PIN display component. mapped to the endpoint that feeds it:

SDK component (renders the area)API endpoint (the data source)

Hover or focus a numbered pin to see which Weavr secure component renders the area, or which API endpoint supplies its data - then click to open the docs.

Card payment timelines

A card payment isn't a single event - it's an authorization, one or more settlements, and any reversal or refund. In the expanded record, show the card payment event timeline so a customer can follow how one payment progressed, not just its current state.

Retrieve a card payment and its events from your backend:

GET/card_payments/{id}Try it

See card payments for the full lifecycle and how to retrieve them.

Step 2: Build downloadable statements

A statement is the authoritative, immutable record of what settled on an instrumentInstrument A financial product owned by an Identity. There are two types: Managed Accounts (stored-value accounts that hold balances and can receive wire transfers) and Managed Cards (prepaid cards - virtual or physical - used for purchases). over a period - the document a customer archives and an auditor relies on. Unlike the activity feed, it carries opening and closing balances and a regulatory footer, and it only ever shows settled transactions.

Retrieve a statement per instrumentInstrument A financial product owned by an Identity. There are two types: Managed Accounts (stored-value accounts that hold balances and can receive wire transfers) and Managed Cards (prepaid cards - virtual or physical - used for purchases).:

GET/managed_accounts/{id}/statementTry it
{
"entry": [
{
"transactionId": {
"type": "AUTHORISATION",
"id": "string"
},
"entryState": "PENDING",
"originalAmount": {
"currency": "str",
"amount": 0
},
"forexRate": {
"value": 0,
"scale": -128
},
"transactionAmount": {
"currency": "str",
"amount": 0
},
"availableBalanceAdjustment": {
"currency": "str",
"amount": 0
},
"actualBalanceAdjustment": {
"currency": "str",
"amount": 0
},
"balanceAfter": {
"currency": "str",
"amount": 0
},
"availableBalanceAfter": {
"currency": "str",
"amount": 0
},
"actualBalanceAfter": {
"currency": "str",
"amount": 0
},
"transactionFee": {
"currency": "str",
"amount": 0
},
"cardholderFee": {
"currency": "str",
"amount": 0
},
"processedTimestamp": 0,
"sourceAmount": {
"currency": "str",
"amount": 0
},
"userCurrencyTransactionDetails": {
"userTransactionAmount": {
"currency": "str",
"amount": 0
},
"userExchangeRate": "string"
},
"additionalFields": {
"property1": "string",
"property2": "string"
}
}
],
"count": 0,
"responseCount": 0,
"startBalance": {
"currency": "str",
"amount": 0
},
"endBalance": {
"currency": "str",
"amount": 0
},
"footer": "string"
}
GET/managed_cards/{id}/statementTry it
{
"entry": [
{
"transactionId": {
"type": "AUTHORISATION",
"id": "string"
},
"entryState": "PENDING",
"originalAmount": {
"currency": "str",
"amount": 0
},
"forexRate": {
"value": 0,
"scale": -128
},
"transactionAmount": {
"currency": "str",
"amount": 0
},
"availableBalanceAdjustment": {
"currency": "str",
"amount": 0
},
"actualBalanceAdjustment": {
"currency": "str",
"amount": 0
},
"balanceAfter": {
"currency": "str",
"amount": 0
},
"availableBalanceAfter": {
"currency": "str",
"amount": 0
},
"actualBalanceAfter": {
"currency": "str",
"amount": 0
},
"transactionFee": {
"currency": "str",
"amount": 0
},
"cardholderFee": {
"currency": "str",
"amount": 0
},
"processedTimestamp": 0,
"sourceAmount": {
"currency": "str",
"amount": 0
},
"userCurrencyTransactionDetails": {
"userTransactionAmount": {
"currency": "str",
"amount": 0
},
"userExchangeRate": "string"
},
"additionalFields": {
"property1": "string",
"property2": "string"
}
}
],
"count": 0,
"responseCount": 0,
"startBalance": {
"currency": "str",
"amount": 0
},
"endBalance": {
"currency": "str",
"amount": 0
},
"footer": "string"
}

Choose a format for the screen

The same statement comes in three formats, so pick per surface:

FormatRequest withUse it for
JSONAccept: application/jsonRendering your own on-screen statement view
PDFAccept: application/pdfA download button - our curated rendering, regulatory footer included
CSVAccept: text/csvLetting customers export to a spreadsheet or accounting tool
Ship our PDF unchanged

The PDF is our out-of-the-box rendering of the exact same data, with the regulatory footer already in place. We recommend serving it as-is for your download button rather than rendering your own - it's suitable as the record an account holder keeps.

The open-source statements reference app shows how to present a statement and its records on screen, and how the PDF maps back to the API fields:

SDK component (renders the area)API endpoint (the data source)

Hover or focus a numbered pin to see which Weavr secure component renders the area, or which API endpoint supplies its data - then click to open the docs.

Balances are computed for you

Opening and closing balances come straight from the statement's openingBalance and closingBalance fields. Don't reconstruct them client-side - the same period always returns the same result, so you can safely cache it. See statements overview.

Step 3: Keep views fresh with webhooks

Both views are reads, but your app shouldn't poll them. Anything in the activity feed is also delivered by webhook, so subscribe to card, account, and transaction events and refresh the relevant screen when one arrives. That keeps the live feed live without hammering the API.

Read from your backend, never the client

Your backend calls the activity and statement endpoints and serves the data to your UI. Your client should never call these endpoints directly - the same rule that applies everywhere else in the app.

What you've built

Your app now shows the read side of finance: a live, normalized activity feed for accounts and cards, card payment timelines, and authoritative statements customers can view or download as PDF and CSV.

That completes the embedded app blueprint - authentication, cards, payments, trusted payeesTrusted Payee A trusted recipient for payments, including the business or individual's details and their bank account or instrument details. Sending to a Trusted Payee may let customers skip Strong Customer Authentication (SCA) on Outgoing Wire Transfer or Send transactions, reducing the number of approval steps required. Previously referred to as a Beneficiary., and the views that surface it all. From here, deepen any area through its full reference: