← all adapters

psd2-style

simulates Open Banking / PSD2 (Berlin Group NextGenPSD2) 1.3.6

restadapter v0.1.019 routes

verification

VMVM tier — no SDK suite yet· surface 19 · not implemented 6 · differs 7

use it

# add to stunt.yaml
services:
  psd2:
    adapter: embedded:psd2-style

# then
$ stunt up

The embedded: source extracts this adapter from the binary — no git clone, fully offline.

how to mock the Open Banking / PSD2 (Berlin Group NextGenPSD2) API locally

Install stunt, paste the service block above into stunt.yaml, run stunt up — then point your client at localhost instead of Open Banking / PSD2 (Berlin Group NextGenPSD2). It works offline, keeps state across requests and restarts, and every response is synthetic: the route shapes, status codes, pagination, and webhook delivery follow the real Open Banking / PSD2 (Berlin Group NextGenPSD2) 1.3.6 surface — the data is fake, the behavior is real.

backing stores

consentsauthorisationsaccountstransactionsaccess_tokens

api surface (19)

generated from the adapter manifest — exactly what boots, nothing more

19 routes
POST/v1/oauth/token
POST/v1/consents
GET/v1/consents/{consentId}
DELETE/v1/consents/{consentId}
POST/v1/consents/{consentId}/authorisations
GET/v1/consents/{consentId}/authorisations/{authorisationId}
PUT/v1/consents/{consentId}/authorisations/{authorisationId}
POST/v1/consents/{consentId}/authorisations/{authorisationId}
GET/v1/accounts
GET/v1/accounts/{resourceId}/balances
GET/v1/accounts/{resourceId}/transactions
POST/v1/payments/{product}
GET/v1/payments/{product}/{paymentId}/status
POST/v1/payments/{product}/{paymentId}/authorisations
GET/v1/payments/{product}/{paymentId}/authorisations/{authorisationId}
PUT/v1/payments/{product}/{paymentId}/authorisations/{authorisationId}
POST/v1/payments/{product}/{paymentId}/authorisations/{authorisationId}
GET/v1/payments/{product}/{paymentId}
DELETE/v1/payments/{product}/{paymentId}

VM-verified behaviors (24)

  • the tpp token endpoint mints a bearer; other grants and missing or unknown bearers are rejected
  • a created consent answers 201 received with self and startAuthorisation links, and reads back
  • the sca redirect flow advances one hop per PUT: started → psuAuthenticated → scaReceived
  • an update carrying neither method nor OTP is a 400 PARAMETER_INVALID that leaves the chain put
  • after the 1s challenge window a read derives finalised and the consent reads valid
  • delete terminates the consent and consent-bound reads then reject it
  • account reads require a valid consent: 401 CONSENT_INVALID without one
  • a valid consent unlocks the seeded account list with per-account links
  • withBalance=true embeds an interimBooked balance in each account entry
  • the balances read returns interimBooked and forwardAvailable pairs and 404s unknown accounts
  • the transaction report requires bookingStatus and dateFrom
  • bookingStatus splits booked from pending and dateFrom/dateTo bound the report
  • a restricted consent scopes the account list and 404s uncovered reads
  • a consent past its validUntil finalises but gates reads with 401 CONSENT_EXPIRED
  • with no Consent-ID header, only-expired consents still answer CONSENT_EXPIRED
  • an unknown Consent-ID is 400 CONSENT_INVALID; a not-yet-finalised one is 401 CONSENT_INVALID
  • page/size walks every account exactly once with a next link only between pages
  • the next href round-trips the caller's other query params (withBalance)
  • a malformed page cursor is 400 FORMAT_ERROR; a cursor past the end is an empty last page
  • the tpp bearer dies at its 3600s expires_in with 401 TOKEN_EXPIRED
  • a payment validates its product and amount before answering 201 RCVD with startAuthorisation
  • the payment SCA chain mirrors the consent chain and finalises on read
  • the transaction status walks RCVD → ACTC → ACSC on the clock and terminal payments refuse cancellation
  • a non-terminal payment cancels to 204/CANC and simulate_fail drives RJCT

Not implemented (6)

  • No Confirmation of Funds (POST /v1/funds-confirmations)
  • No card accounts (GET /v1/card-accounts and card transactions)
  • No periodic or bulk payments (standing orders)
  • No transaction detail (GET /v1/accounts/{id}/transactions/{resourceId})
  • No GET /v1/consents/{id}/status sub-resource
  • No payment cancellation-authorisations SCA sub-resource

Differs from the real API (7)

  • SCA finalisation is derive-on-read after a fixed 1s challenge window
  • Payment status derives on read: ACTC at 1s, ACSC at 3s — fixed, not bank async
  • simulate_fail: true in POST /payments forces RJCT (simulator-only trigger)
  • Signed transition webhooks are a simulator extension; NextGenPSD2 defines none
  • scaRedirect _links URL is synthetic — no real bank SCA login page behind it
  • DELETE consent returns 200 + body; real NextGenPSD2 returns 204 No Content
  • PARAMETER_MISSING-<FIELD> error codes are simulator conventions, not the official code list
want more of the Open Banking / PSD2 (Berlin Group NextGenPSD2) surface? adapters are YAML + Starlark — the authoring guide covers adding routes, fixtures, and state machines. Open an issue for anything big first, or just file a PR — merged routes ship in the next release.