Serbia’s amended Payment Services Act made AIS access enforceable from 6 May 2025, with banks granted a transition window until 1 January 2026 to finish wiring up the interfaces, per BDK Advokati’s summary of the amendments. Raiffeisen banka a.d. Beograd — the issuer behind Moja mBanka Raiffeisen — sits inside that perimeter, which is why this brief is written around the AIS path first and the protocol-analysis fallback second. The app itself bundles two products into one binary: a retail mBanka for iRačun holders and a business mBanka for entrepreneurs and small companies, per its Raiffeisenbank.rs m-banking page.
For an integrator that wants programmatic reach into a customer’s balances, turnover, statements, IPS dinar payments, FX-account activity, IPS QR generation, exchange-office orders, investment-fund unit holdings or SEF-linked invoices, the studio takes the brief, arranges the authorized access route with the account holder during onboarding, and delivers runnable source plus the OpenAPI/auth-flow documentation. The client gives the app name and what they need from it; access and compliance paperwork are handled on our side of the engagement.
Serbia’s open-banking switch, and what it changes for this bank
The PSA amendments enter Serbian law in August 2024 and become applicable on 6 May 2025, with the bank-side build deadline pushed to 1 January 2026. That schedule, attributed to the Karanović & Partners write-up of the harmonisation, is the load-bearing fact for this page: it means a properly registered AIS provider can call into Raiffeisen Serbia accounts under a customer’s explicit consent, with the bank obliged to expose the access surface. Article 46a of the amended PSA names the AIS-side rules; Article 46b names the PIS-side rules.
Consent in this regime is per account, time-bound, and revocable in-app by the account holder. The studio runs onboarding so that the consent record, the access logs and the data-minimization scope are written into the contract with the client before any data is read — authorized, documented, logged, and NDAed where needed. The same compliance posture covers the protocol-analysis fallback we use while the bank-side AIS interfaces are still inside the transition window.
What records the app actually holds
Drawn from the app’s own retail and business feature descriptions and the bank’s m-banking page. Granularity is read end-to-end; the integrator column shows the typical use we deliver code for.
| Domain | Where it comes from in the app | Granularity | What an integrator does with it |
|---|---|---|---|
| Account balance & turnover | Retail and Business overview screens; per dinar and FX account | Per-transaction, real-time after each posting | Books a normalized ledger; powers reconciliation and accounting feeds |
| Dinar payments (IPS) | Quick payment by IPS QR scan; predefined payments | Per order, IPS reference, ~seconds settlement | Drives the «pay now» flow in third-party checkouts and payouts |
| IPS QR generation | Business app, «send QR to buyer» | Per invoice / per buyer | Pulls QR codes into POS, invoicing or marketplace UI |
| Statements | Turnover & statements per account; SWIFT statements for FX | Daily, monthly, on-demand | Pipes PDFs and structured statements into accounting systems |
| FX accounts & payments | FX iRačun, FX payments with accompanying documents, Loro incoming | Per order; per incoming | Confirms inbound FX, automates outbound with document attachment |
| Exchange office | Buy/sell of 10+ currencies, banknote sale and purchase | Per order, with timestamped rate | Reads quoted rates; rebooks orders programmatically |
| Card management | Digital cards, temporary blocking, card data | Per card | Driver for help-desk tooling, fraud workflows |
| Investment & pension funds | Holdings overview inside the retail app | Per fund position | Brings holdings into portfolio dashboards |
| SEF (Electronic Invoice System) link | Business app, «Linking to SEF» | Per invoice, per status change | Reconciles invoice lifecycle to received and outgoing payments |
| Inbox / notifications | Inbox messages from the bank; push notifications | Per message, per event | Feeds bank events into the client’s ops dashboard |
Three routes to those records
Route A — Serbia-registered AIS under the amended PSA
Once a customer has signed AIS consent, an NBS-registered AIS provider can pull consolidated balance and turnover data from the bank’s open-banking interface. Reach is broad for read-only account information; durability is high because the contract is with the NBS-facing interface, not the app binary. Effort sits in the registration, the indemnity insurance, and the consent-management plumbing; the studio runs that setup with the client during onboarding and writes the consent ledger into the deliverable.
Route B — Authorized protocol analysis of the Moja mBanka traffic
For surfaces that go beyond classical AIS (IPS QR generation, FX-payment document attachment, exchange-office orders, SEF link state, investment-fund holdings), the studio works from the app traffic with the account holder’s written authorization. We map the device-binding, biometric step-up, push-notification confirmation and token-refresh chain, and we hand back the request/response shapes. Durability is medium — tied to app versions — which is why the source bundle includes a re-walk script the team can run after a release.
Route C — Consented credential access
Where the customer prefers, the integration runs against the account using the customer’s own credentials and a short-lived session token, with the read scope and retention window pinned to what the client actually needs. This is the lightest-effort path and is the right call when the integration only needs read-only views for one or a handful of accounts.
The recommendation we put on the page: lead with Route A for the accounts where AIS consent is in place, fall back to Route B for the non-AIS surfaces (IPS QR generation, FX documents, SEF link, fund positions), and reserve Route C for tightly-scoped reads. The two are not exclusive — we routinely ship a hybrid build.
What you receive at the end of the cycle
- OpenAPI 3.1 spec covering retail and business surfaces: accounts list, balances, turnover, statements, IPS payment, IPS QR encode/decode, FX order with document attachment, exchange-office quote and order, investment-fund holdings, SEF link state, inbox.
- Auth-flow report — device binding, biometric step-up, push-notification confirmation and token-refresh chain — matched to the way Moja mBanka actually challenges the session, with the OAuth/cookie sequence drawn end to end.
- Runnable source in Python or Node.js for the read paths above and the IPS payment path; one library, idiomatic SDK shape, with retry/backoff hooks for the IPS RSD 300,000 ceiling.
- Automated tests against a consenting account or a sponsor sandbox arranged with the client during onboarding, with fixtures captured from the auth-flow walk.
- Interface documentation: per-endpoint contract, error codes mapped to Moja mBanka’s own inbox/notification error surface, sample payloads, and the re-walk script for app-version refreshes.
- Compliance and retention note pinned to the NBS PSA (consent scope, expiry, revocation, data-minimization defaults) and to GDPR-equivalent Serbian data-protection rules.
How the source code lands
Illustrative shape, drawn from the kind of auth-flow walk and turnover read we routinely deliver. Field names are confirmed during the build, not asserted here.
# moja_mbanka_raiffeisen/client.py (illustrative; confirmed during the build)
from .auth import DeviceBoundSession
def fetch_turnover(account_id: str, since: str, *, currency: str = "RSD"):
s = DeviceBoundSession.resume() # device pin + biometric step-up
s.refresh_if_needed() # rotates the bearer + cookie pair
r = s.get(
f"/retail/accounts/{account_id}/turnover",
params={"from": since, "currency": currency},
)
if r.status_code == 401: # session aged out
s.reauthenticate(push_confirmation=True) # push-notification re-confirm
r = s.get(r.request.url)
return [
{
"posted_at": row["valueDate"],
"amount": row["amount"], # RSD in minor units (paras)
"currency": row["ccy"], # RSD, EUR, USD, CHF...
"counterparty": row.get("partnerName"),
"reference": row.get("referenceNumber"),
"ips_id": row.get("ipsRef"), # present for IPS instant transfers
"category": row.get("autoCategory"), # My Finances categorization
}
for row in r.json()["items"]
]
The same shape generalizes to the business endpoints (turnover per Business iRačun, SWIFT statement download, Loro incoming approval). The IPS QR path is its own small module because it generates and parses against the NBS IPS specification rather than a Moja mBanka-specific format.
Particulars the build accounts for
- The customer commonly holds three kinds of accounts in parallel — an RSD iRačun, one or more FX accounts for incoming foreign-currency, and an exchange-office account. The data model we hand over keeps balances per currency and per account-type rather than collapsing them, because the FX-payment routing rules the app actually applies disappear when you flatten the ledger.
- IPS dinar payments cap at RSD 300,000 per individual order, with average processing around 1.2 seconds, per the NBS IPS page. We wire the IPS module with that ceiling enforced client-side and with idempotency keys on the order, so a retry over a slow connection does not double-post inside the instant window.
- The SEF (Sistem Elektronskih Faktura) link is a separate event stream from account turnover. We treat invoice IDs and SEF status changes as their own sync channel and reconcile to the payments stream by reference number — collapsing them into one feed loses the «invoice paid» lifecycle the business app relies on.
- The push-notification confirmation is part of the auth chain, not an alert. A session that ages out is reauthenticated through a push-confirmation step on the user’s registered device. We arrange that handshake during onboarding (consenting account or sponsor sandbox), so the build does not silently fall back to credential-only auth.
Interface, in screenshots
Captured from the Play Store listing for rs.Raiffeisen.mobile. Click to enlarge.
Questions integrators ask about Moja mBanka
Does the May 2025 open-banking switch in Serbia mean a third party can already query Moja mBanka accounts today?
The amended Payment Services Act made AIS access enforceable on 6 May 2025, but banks were granted a transition window until 1 January 2026 to finish wiring up the interfaces. In practice we run two tracks in parallel: a Serbia-registered AIS path where it is available for that customer’s accounts, and authorized protocol analysis of the app traffic with the account-holder’s consent as the working fallback. Either way the deliverable is the same source code and OpenAPI spec.
Where do IPS instant payments and SEF-linked invoices show up in the data you would hand over?
IPS dinar payments arrive in the account turnover stream with the IPS reference and the 1.2-second-class processing timestamp; we expose them as separate fields rather than folding them into a generic «transfers» bucket. SEF (Sistem Elektronskih Faktura) invoice IDs and status changes come through the business app’s SEF link and are modelled as their own sync channel, reconciled to payments by reference number.
How do you handle a customer who holds both a dinar iRačun and an FX account in the same mBanka profile?
We keep them as distinct ledger objects in the schema, each with its own currency tag and account-type tag. Collapsing RSD and EUR/USD/CHF into one balance loses the FX-payment routing rules the app actually applies, so we keep them split end to end and only roll up to a customer-level aggregate where the caller asks for one.
What happens to the build when Raiffeisen ships a new version of Moja mBanka?
For the protocol-analysis track we hand over a re-validation script in the source bundle that exercises the auth flow and the main read endpoints; the studio also offers a small maintenance retainer to re-walk the surfaces when the app version changes. The AIS track is more stable because the contract is the NBS-facing interface, not the app binary.
The price tag we put on the page: $300 buys runnable source for Moja mBanka Raiffeisen plus the OpenAPI spec, auth-flow report, automated tests and interface documentation, paid only after delivery once you have signed off — or call the same surfaces as a pay-per-call hosted API with no upfront fee. Either model runs a 1–2 week cycle from brief to source-in-hand. Tell us the app and the surfaces you need at openbankingstudio.com/contact and we will scope it.
Sources behind this page
Checked in May 2026 against the bank’s own m-banking page, the Play Store listing for rs.Raiffeisen.mobile, the National Bank of Serbia’s IPS reference, and the legal write-ups of the amended Payment Services Act. Primary deep links used while writing:
- Raiffeisen banka — Mobilno bankarstvo / Moja mBanka (English)
- Play Store listing — Moja mBanka Raiffeisen
- BDK Advokati — Serbia amends payment services regulations to allow open banking
- NBS — Instant Payments Serbia (IPS) system
OpenBanking Studio · integration desk mapping, 20 May 2026.
App profile (collapsed)
Name: Moja mBanka Raiffeisen · Package: rs.Raiffeisen.mobile (per the Play Store listing) · iOS bundle: id1053503191 (per the App Store listing). Issued by Raiffeisen banka a.d. Beograd. Two product modes in one binary — retail (iRačun, digital cards, IPS QR, exchange office, My Finances categorization, investment- and pension-fund overview, mobile-cash QR withdrawal, foreign-currency payments) and business (Business iRačun, FX accounts including incoming, IPS QR send/receive, SWIFT statements, Loro approval, SEF link, electronic-signature statements). Support per the Play Store listing: rol.support@raiffeisenbank.rs, +381 11 3202100.