miaPOS app
How to use the miaPOS app on a hardware POS terminal or a smart device — sign in, open the day, accept payments, run reports, close the day.
Document version: 1.0 Product version
(UI): 1.0.14 Date: 01.05.2026 Internal
codename: POS-flow Sources: reference screens
from POS-flow/ (authentication, day-open, transactions,
refunds, cancellation, reports, day-close, QR settings, language
settings, support) Platforms: Android (Jetpack Compose)
and iOS (SwiftUI) — same UX flow, minor styling differences
Note on screenshots. The screenshots below show the default Romanian UI. The app supports English, Romanian and Russian — switch the language from
Profile → Change language.
1. Overview
miaPOS is the instant-payment acceptance app for merchants in Moldova — the main processing route is through the MIA scheme (Money Instant Acceptance, National Bank of Moldova). The app runs on dedicated Android POS terminals (or smart devices) and on iOS for SoftPOS, with the co-brand MAIB logo for terminals issued by that bank.
1.1 Covered functionality
- 3-step authentication (terminal → OTP → seller account) with email-onboarding option
- Commercial-day lifecycle: Open day → transactions → Close day with Z-report
- Payment QR generation (dynamic / static / hybrid) with fixed, controlled or unspecified amount
- Cancel a generated QR before it is paid
- Transaction list with details (
pacs.008message + payer SWIFT code) - Full or partial refund with a standardized reason
- Per-seller settings: QR type, language, support contact
- App version visible in the Support page
1.2 Brand & co-branding
- Primary mia logo (instant payments) on auth/QR screens
- Bank co-brand logo (e.g. MAIB) shown under the mia logo on the QR screen
- App footer: Powered by FINERGY
- Current version:
1.0.14(visible in Profile → Support)
1.3 Supported languages
- Română (default)
- English
- Русский
Selectable from Profile → Change language.
1.4 Tech stack (internal reference)
- Android: Kotlin + Jetpack Compose, MVI (see
pos-android/) - iOS: Swift + SwiftUI (see
pos-ios/) - Backend:
pos-terminal-svc,cap-svc,mia-db— gRPC/REST + ISO 20022 (pacs.008.001.10)
2. Authentication
A 3-step flow (terminal → OTP → user) plus the option to receive onboarding details by email.
2.1 Step 1 — Terminal data
Fields:
| Field | Type | Validation |
|---|---|---|
| IDNO | numeric | 13 digits — the merchant’s fiscal ID |
| Terminal ID | alphanumeric | format T0001 (issued by the bank/operator) |
Actions:
- Next (active once both fields are filled)
- Send onboarding by email link — for the case where the merchant doesn’t have credentials yet
2.2 Modal — Send onboarding by email
- Informational text: “If you agree, we will send your onboarding data to the specified email address.”
- Fields: IDNO, Email
- Actions: Back / OK
2.3 Step 2 — OTP confirmation
- 6 OTP boxes, sequential autofocus
- Masked phone number shown (e.g.
+373 *****212) - Resend cooldown: 25 seconds (“Resend after 25 sec”)
- ← back arrow to the terminal-data screen
2.4 POS activated successfully
Visual confirmation (green ✓) that the terminal was successfully linked. Continue button → proceeds to user login.
2.5 Step 3 — Sign in to your account (Login + Password)
Informational header (read-only):
Terminal #T0001IDNO: 999*******999- Merchant name (e.g. Finergy Tech)
- Store address (e.g. Chișinău, 31 august 60)
Fields:
| Field | Type | Validation |
|---|---|---|
| Login | alphanumeric | the seller’s login (or phone number — see the Use phone number flag in Merchant Portal) |
| Password | password | + 👁 visibility toggle |
Action: Sign in.
Note: sellers are created in the Merchant Portal (the Sellers section), where the administrator can generate/regenerate the password and email it to the seller.
3. Commercial-day lifecycle
A mandatory lifecycle: to process transactions, the day must be open; at the end, the day is closed with a Z-report.
3.1 Day closed (gate for Transactions)
- 🌙 icon + message “Day is closed. To start, open the day.”
- Primary Open day button (full-width, blue)
3.2 Persistent banner in Profile when the day is closed
- Banner at the top of the Profile page: “Day is closed”
- Next to the operator name, the Open day button appears (replacing the Close day button visible in the normal state)
3.3 Open-day confirmation
Modal with 2 actions: Back / Confirm.
3.4 Terminal — day open (amount entry)
Header: Terminal (id: T0001) + descriptive line with the
merchant name and address.
Central content:
- Current QR type label (e.g. “Dynamic QR” — set from QR settings)
- Prompt: “Enter amount”
- Amount display:
0.00 - Numeric keypad (1–9, 0, decimal separator
., ⌫ backspace, OK)
3.5 Amount entered — OK active
- Amount entered (e.g.
10.00) - ✕ icon → resets the amount to
0.00 - OK (green) → generates the QR
3.6 QR generated (day open)
Layout with dark-navy background:
- MIA + MAIB logo (co-brand) at top-center
- ← (back) top-left • 🔗 share top-right
- AMOUNT TO PAY card + value
(e.g.
10.00 MDL, green) - QR code centered (white on cream-white background)
- Footer:
HH:MM:SS, DD.MM.YYYYtimestamp + merchant location - Cancel button (red text) at the bottom
3.7 Payment completed
- ✓ green (icon)
- Text: “Payment completed!”
- Amount (e.g.
10.00 MDL) - Fields: Date and Transaction ID
- OK(8) button — 8-second auto-close countdown
- 📋 secondary button (receipt / clipboard) — shows the receipt detail / duplicate
3.8 Transaction in the day list
List with Transactions title + top-right actions:
- 🔄 refresh list
- 📄 current report (real-time Z-report)
List item:
- #2790 + amount (
10.00 MDL) + green ✓ (paid) - Timestamp (
HH:MM, DD.MM.YYYY)
3.9 Close day — confirmation + Z-report
Triggered by the Close day button on the Profile page.
Modal with 2 actions: Back / Confirm.
3.10 Confirm/close Z-report
After confirmation, the Z-report (day totals: number of transactions, total amount, fees, refunds) is displayed and allows the final close with OK.
Attention: after closing, the day goes back to the closed state — any new transaction will require a new open.
4. Transactions
4.1 List
List item:
- #transaction ID (e.g.
#2790) - Amount + currency (
10.00 MDL) - Timestamp
- Status indicator (bottom-right):
- ✓ green = PAID (successfully executed)
- ↻ gray/blue = partially or fully refunded
Header — actions:
- 🔄 refresh
- 📄 current report
4.2 Transaction detail
Fields displayed:
| Field | Example |
|---|---|
| Transaction ID | 2790 |
| Amount | 10.00 MDL |
| Status | PAID ✓ |
| SWIFT message type | PACS.008.001.10 |
| SWIFT message ID | 1585701D-9922-43E0-9FCE-29E3FA2D1863 (UUID) |
| Payer SWIFT code | CMTBMD2X (issuing bank) |
| Date | 19:29, 24.04.2026 |
Bottom actions:
- 🔄 Refund (full-width, dark navy)
- 📋 Receipt (icon button — duplicate print receipt)
4.3 Transaction states
| State | Indicator | Transitions |
|---|---|---|
| PAID | ✓ green | → PARTIALLY REFUNDED / FULLY REFUNDED |
| PARTIALLY REFUNDED | ↻ blue | the remainder can still be refunded |
| FULLY REFUNDED | ↻ gray | terminal — no further actions |
5. Refunds
5.1 Refund form
Trigger: the Refund button in the transaction detail.
Fields:
| Field | Type | Validation |
|---|---|---|
| Reason | dropdown | fixed list (see 5.2) — required |
| Reason description | free text | recommended; required for Technical problem |
| Partial refund | toggle | if active → a Partial refund amount field appears, ≤
original amount |
Below the fields: read-only Date +
Transaction ID.
Primary Refund amount button (active only when a reason is selected).
5.2 Refund-reason list (dropdown)
Standardized reasons (ISO 20022 — RJCT reasons +
custom):
- Transaction rejected due to acceptor-PSP timeout
- Incorrect account
- Payer account is invalid or missing
- Payee account is invalid or missing
- Payer account is closed
- Specified account is blocked or processing of transactions involving it is prohibited
- Payee account is closed
- Account currency is invalid or missing
- Transaction code is not accepted/authorized
- Payment value is greater than the maximum allowed
- Available funds to cover the amount specified in the message are insufficient
- Duplicate
- Received amount is not the agreed or expected amount
- Amount is invalid or missing
- Payee-related details are insufficient/incorrect
- Customer decision (most-used — refund at buyer request)
- Message ID / instruction ID is not unique
- Message/payment cannot be processed due to technical issues at the participant
- Payer account does not exist
- Payment details are inadequate
- Technical problem
5.3 Partial refund — specified amount
- Partial refund toggle = ON
- Partial refund amount field
(e.g.
5) - Original amount shown under the toggle (
10.00 MDL) - Refund amount button (active after validation)
5.4 “Processing” state (bank decision pending)
- Message: “Waiting for the funds-refund decision”
- Animated progress bar
- Refund amount button disabled until response
5.5 List with the partially refunded transaction
- Original transaction
#2791—10.00 MDL✓ - Refund transaction
#2792—5.00 MDL↻ (refund icon)
Technical note: a refund in MIA generates a new reverse transaction (a
pacs.008message in the opposite direction); it does not modify the original transaction.
5.6 Refund detail
Fields:
- Transaction ID (e.g.
2792) - Refunded amount (
5.00 MDL) - Status: PARTIALLY REFUNDED ↻
- SWIFT message type (in pre-prod may appear as
MOCK; in productionpacs.008.001.10) - SWIFT message ID (UUID)
- Payer SWIFT code (in pre-prod
INTEGRATION SVC; in prod the real bank code) - Date
6. Cancel QR
6.1 Cancel button on the QR screen
Cancel button (red text, bottom) — available while the QR is active and payment has not yet been made.
6.2 Cancel confirmation
Modal with 2 actions: Back / Confirm.
After cancellation:
- The QR becomes invalid (any subsequent scan fails)
- The operation appears in Merchant Portal → Online operations with REJECTED status
7. QR code settings
The setting controls how QRs are generated on this terminal (per-seller).
7.1 Dynamic QR (default)
- Dynamic QR (default): accepts only a fixed amount. One transaction per QR.
- Time-to-live field (sec) — QR TTL (default
300sec = 5 min) - Apply button
7.2 Static QR (with sub-options)
Static QR: accepts fixed, controlled and unspecified amounts. Unlimited transactions per QR.
Sub-types:
- Fixed amount — pre-printed amount; customer cannot change it
- Controlled amount — min/max limits; customer confirms within limits
- Unspecified amount — customer enters any amount
Use case: static QRs printed on stickers at the counter / on invoices.
7.3 Hybrid QR (with sub-options)
Hybrid QR: accepts only fixed and controlled amounts. No more than one transaction at a time.
Sub-types:
- Fixed amount
- Controlled amount
Use case: a physical QR at the POS for specific amounts (e.g. monthly subscription) — one customer at a time.
7.4 Time-to-live (TTL)
Field common to all types — the validity duration of the QR in
seconds (default 300).
| QR type | Transactions/QR | Sub-options | Recommended TTL |
|---|---|---|---|
| Dynamic | 1 | – | 300 sec |
| Static | ∞ | Fixed / Controlled / Unspecified | large (days) |
| Hybrid | 1 at a time | Fixed / Controlled | 300–600 sec |
8. Settings — language
8.1 Profile access
Access from Profile → Change language.
8.2 Language selection
List with 3 options:
- Română (default, blue ✓)
- English
- Русский
Apply button — only active when the language changes.
Persistence: the preference is stored locally on the device (per-seller if multiple share the same device).
9. Support
Access from Profile → Support.
Fields:
- Phone:
60665335(clickable —tel:link) - Email:
[email protected](clickable —mailto:link) - App version:
1.0.14(read-only)
Note: the app version is used by the support team to correlate bugs with specific builds.
10. Profile
Central point of the user menu. Content:
Header
- “Profile” title
- ⏏ logout (top-right — red text)
Seller-account card
- Avatar
- Operator name (e.g. Operator 5)
- Seller ID: 370
- Close day (top-right of the card) — primary red button
Terminal & location card (read-only)
Terminal #T0001- Store name (
Finergy store) - Address (
Chișinău, 31 august 60)
Menu actions
- ⊞ QR code settings → §7
- 🌐 Change language → §8
- 🎧 Support → §9
Footer: Powered by FINERGY
Bottom navigation (3 tabs):
- ⊞ Terminal — payment keypad (§3.4)
- ⇄ Transactions — list (§4)
- 👤 Profile (active)
11. Common element-set (visual components & UX patterns)
11.1 Color codes for states
| Color | Meaning | Examples |
|---|---|---|
| 🟢 Green | Success / positive end | PAID ✓, “POS activated successfully”, “Payment completed!”, keypad OK |
| 🟡 Blue | Primary action | Open day, Apply, active links, partial-refund indicator |
| 🔴 Red | Destructive actions / attention | Cancel, Close day, logout, “Day is closed” banner |
| ⚫ Gray | Inactive / neutral end | Disabled button (e.g. OK when amount is
0.00), FULLY REFUNDED |
| ⚫ Dark navy | Elevated header / context | Amount card on the QR screen, Refund button |
11.2 Recurring patterns
- Destructive or impactful confirmations: modal with 2 buttons Back / Confirm — used for QR cancellation, day open/close.
- Top bar with report icon (📄): present on the Transactions page — shows the interim report for the current day.
- Auto-close with countdown: the payment-success
screen shows
OK(8)with an 8-sec countdown → returns to the keypad. - 3-tab bottom navigation: Terminal / Transactions / Profile — same pattern on Android and iOS.
- Context header: on payment screens and on the login
modal, displays
Terminal (id: X)+ location — keeps the seller oriented.
11.3 Multi-currency
In Moldova production, the currency is MDL
(explicitly labelled in the UI). The app supports structurally variable
currency (at the pacs.008 message level), but the current
UI is optimised for MDL.
11.4 Offline mode
The QR is generated locally (the EMVCo deterministic string), but
payment confirmation requires a connection to
pos-terminal-svc. Transactions executed by the payer’s app
while the terminal is disconnected appear in the list after the next
sync.
12. Technical glossary
| Term | Definition |
|---|---|
| MIA | Money Instant Acceptance — the IPS scheme of Moldova (NBM) |
| pacs.008.001.10 | ISO 20022 payment-instruction message (the version used on MIA) |
| Acceptor PSP | The Payment Service Provider on the merchant side — in our case miaPOS via the acquiring bank |
| IDNO | State identifier of a legal entity (Moldova) |
| Terminal ID | Unique code per terminal (e.g. T0001) |
| OTP | One-Time Password — 6-digit code received via SMS |
| Dynamic / static / hybrid QR | QR-code variants with different lifetimes and semantics (see §7) |
| Z-report | Cumulative report generated when the commercial day is closed |
| Payer SWIFT code | BIC of the issuing bank of the payer’s account
(e.g. CMTBMD2X = MAIB) |
13. Full lifecycle (text diagram)
┌──────────┐
│ Launch │
│ app │
└────┬─────┘
│
▼
┌─────────────────┐ NO ┌──────────────────┐
│ Terminal data │ ─────► │ Send onboarding │
│ (IDNO + ID) │ │ by email │
└────┬────────────┘ └──────────────────┘
│
▼
┌──────────┐
│ SMS OTP │
│ (6 digit)│
└────┬─────┘
│
▼
┌──────────────────┐
│ POS activated ✓ │
└────┬─────────────┘
│
▼
┌──────────────────┐
│ Login (User+Pwd) │
└────┬─────────────┘
│
▼
┌──────────────────────────┐
│ Profile — DAY CLOSED │
│ [Open day] │
└────┬─────────────────────┘
│ confirm
▼
┌──────────────────────────┐ ┌────────────────────┐
│ Terminal — amount keypad │ ─► │ Cancel QR │
└────┬─────────────────────┘ └────────────────────┘
│ OK
▼
┌──────────────────────────┐
│ QR generated (TTL 300s) │
└────┬─────────────────────┘
│ scan + confirm by customer
▼
┌──────────────────────────┐
│ Payment completed ✓ │ ──► Transaction in list
└──────────────────────────┘
│
│ (after N transactions)
▼
┌──────────────────────────┐
│ Profile — [Close day] │
└────┬─────────────────────┘
│ confirm
▼
┌──────────────────────────┐
│ Z-report displayed → OK │
└──────────────────────────┘
14. DoD (Definition of Done) for documentation
15. Annex — screen references
POS-flow/
├── autentificare/ (1, 2-onboarding-email, 3-otp, 4-pos-activated, 5-login)
├── deschidere-zi/ (1.0-day-closed-transactions, 1.1-profile-day-closed,
│ 2-confirm-open, 3-keypad-empty, 4-keypad-amount,
│ 5-qr-active, 6-payment-completed, 8-tx-in-list)
├── tranzactii/ (1-list, 2-detail)
├── rambursari/ (1-form, 2-dropdown-reasons, 3-partial,
│ 4-waiting, 5-list-refunded, 6-detail)
├── anulare/ (1-button, 2-confirmation)
├── inchidere-zi/ (1-confirmation, 2-close-report)
├── rapoarte/ (1-profile, 2-tx-detail)
├── setari-qr/ (1-dynamic, 2-static-with-sub, 3-hybrid-with-sub, 4-ttl)
├── setari-limba/ (1-profile, 2-list)
└── suport/ (1-contact-info, 2-profile)
Document generated from the reference screens in
POS-flow/ — version 1.0.14 of the miaPOS
application for Android and iOS.