Aplicația miaPOS
Cum se folosește aplicația miaPOS pe terminal POS hardware sau pe smart device — autentificare, deschiderea zilei, acceptarea plăților, rapoarte, închiderea zilei.
Versiune document: 1.0 Versiune produs
(UI): 1.0.14 Data: 01.05.2026 Codename
intern: POS-flow Surse: ecrane referință din
POS-flow/ (autentificare, deschidere-zi, tranzacții,
rambursari, anulare, rapoarte, inchidere-zi, setari-qr, setari-limba,
suport) Platforme: Android (Jetpack Compose) și iOS
(SwiftUI) — același flux UX, diferențe minore de stil
1. Privire de ansamblu
miaPOS este aplicația de acceptare instant payments destinată comercianților din Moldova — ruta principală de procesare prin schema MIA (Money Instant Acceptance, BNM). Aplicația rulează pe terminale POS Android dedicate (sau dispozitive smart) și pe iOS pentru SoftPOS, cu logo co-brand MAIB pentru terminalele emise de această bancă.
1.1 Funcționalități acoperite
- Autentificare în 3 pași (terminal → OTP → cont vânzător) cu opțiunea de onboarding prin email
- Lifecycle al zilei comerciale: Deschidere zi → tranzacții → Închidere zi cu raport Z
- Generare QR de plată (dinamic / static / hibrid) cu sumă fixă, controlată sau nespecificată
- Anulare QR generat înainte de plată
- Listă tranzacții cu detaliu (mesaj
pacs.008+ cod SWIFT plătitor) - Rambursare integrală sau parțială cu motiv standardizat
- Setări per-vânzător: tip QR, limbă, contact suport
- Versiune aplicație vizibilă în pagina Suport
1.2 Brand & co-branding
- Logo principal mia (plăți instant) pe ecranele de autentificare/QR
- Logo co-brand al băncii (ex. MAIB) afișat sub logo-ul mia pe ecranul QR
- Footer aplicație: Powered by FINERGY
- Versiunea curentă:
1.0.14(vizibilă în Profil → Suport)
1.3 Limbi suportate
- Română (default)
- English
- Русский
Selectabil din Profil → Schimbați limba.
1.4 Stack tehnic (referință internă)
- Android: Kotlin + Jetpack Compose, MVI
(cf.
pos-android/) - iOS: Swift + SwiftUI (cf.
pos-ios/) - Backend:
pos-terminal-svc,cap-svc,mia-db— protocoale gRPC/REST + ISO20022 (pacs.008.001.10)
2. Autentificare
Flux în 3 pași (terminal → OTP → user) plus opțiunea de a primi datele de onboarding pe email.
2.1 Pasul 1 — Date despre terminal
Câmpuri:
| Câmp | Tip | Validare |
|---|---|---|
| IDNO | numeric | 13 cifre — ID-ul fiscal al comerciantului |
| ID terminal | alfanumeric | format T0001 (eliberat de bancă/operator) |
Acțiuni: - Următorul (activ după completarea ambelor câmpuri) - Link „Trimiteți onboarding pe email” — pentru cazul în care comerciantul nu are credențialele
2.2 Modal — Trimite onboarding pe email
- Textul informativ: „Dacă sunteți de acord, vom trimite datele dvs. de onboarding la adresa de email specificată”
- Câmpuri: IDNO, Email
- Acțiuni: Înapoi / OK
2.3 Pasul 2 — Confirmare OTP
- 6 casete OTP, autofocus secvențial
- Numărul mascat afișat (ex.
+373 *****212) - Cooldown re-send: 25 secunde („Retrimiteți după 25 sec”)
- Săgeată ← back către ecranul de date terminal
2.4 POS activat cu succes
Confirmare vizuală (✓ verde) că terminalul a fost asociat cu succes. Buton Continua → trece la login utilizator.
2.5 Pasul 3 — Conectare la cont (Login + Parolă)
Header informativ (read-only): - Terminal #T0001 -
IDNO: 999*******999 - Numele comerciantului (ex.
Finergy Tech) - Adresa magazinului (ex. Chișinău, 31 august
60)
Câmpuri:
| Câmp | Tip | Validare |
|---|---|---|
| Login | alfanumeric | login-ul vânzătorului (sau telefon — vezi flag Utiliză numărul de telefon din Merchant Portal) |
| Parola | password | + 👁 toggle vizibilitate |
Acțiune: Intră.
Notă: vânzătorii sunt creați din Merchant Portal (secțiunea Vânzători), unde administratorul poate genera/regenera parola și o poate trimite pe email vânzătorului.
3. Lifecycle ziua comercială
Lifecycle obligatoriu: pentru a procesa tranzacții, ziua trebuie deschisă; la final, ziua se închide cu generare raport Z.
3.1 Ziua închisă (gating pentru Tranzacții)
- Iconiță 🌙 + mesaj „Ziua este închisă. Pentru a începe, deschideți ziua.”
- Buton primary Deschide ziua (full-width, albastru)
3.2 Banner persistent în Profil când ziua e închisă
- Banner sus în pagina Profil: „Ziua este închisă”
- Lângă numele operatorului apare butonul Deschide ziua (înlocuiește butonul Închide ziua din starea normală)
3.3 Confirmare deschidere zi
Modal cu 2 acțiuni: Înapoi / Confirmă.
3.4 Terminal — ziua deschisă (intrare sumă)
Header: Terminal (id: T0001) + linia descriptivă cu
numele comerciantului și adresa.
Conținut central: - Eticheta tipului de QR curent (ex. „QR
dinamic” — set din Setări QR) - Prompt: „Introduceți suma”
- Display sumă: 0.00 - Keypad numeric (1–9, 0, separator
zecimal ., ⌫ backspace, OK)
3.5 Suma completată — buton OK activ
- Suma introdusă (ex.
10.00) - ✕ icon → resetează suma la
0.00 - OK (verde) → generează QR
3.6 QR generat (ziua deschisă)
Layout cu fundal dark navy: - Logo MIA + MAIB
(co-brand) sus-centru - ← (back) sus-stânga • 🔗 share sus-dreapta -
Card SUMA DE PLATĂ + valoarea (ex.
10.00 MDL, verde) - Codul QR central (alb
pe fundal alb-cream) - Footer: timestamp
HH:MM:SS, DD.MM.YYYY + locația comerciantului - Buton
Anulare (text roșu) jos
3.7 Plată finalizată
- ✓ verde (icon)
- Text: „Plata a fost finalizată!“
- Sumă (ex.
10.00 MDL) - Câmpuri: Data și ID tranzacție
- Buton OK(8) — countdown de auto-închidere 8 sec
- Buton secundar 📋 (bon/clipboard) — afișează detaliul/duplicat bon
3.8 Tranzacția în lista zilei
Listă cu titlu Tranzacții + acțiuni sus-dreapta: - 🔄 refresh listă - 📄 raport curent (Z-report în timp real)
Element listă: - #2790 + sumă
(10.00 MDL) + bifă verde ✓ (plătit) - Timestamp
(HH:MM, DD.MM.YYYY)
3.9 Închidere zi — confirmare + raport Z
Triggered prin butonul Închide ziua din pagina Profil.
Modal cu 2 acțiuni: Înapoi / Confirmă.
3.10 Confirmare/închidere raport Z
După confirmare, raportul Z (totaluri zi: număr tranzacții, suma totală, comisioane, rambursări) este afișat și permite închiderea finală cu OK.
Atenție: după închidere, ziua revine la starea închisă — orice tranzacție nouă va necesita o nouă deschidere.
4. Tranzacții
4.1 Listă
Element listă: - #ID tranzacție (ex.
#2790) - Sumă + valuta
(10.00 MDL) - Timestamp -
Indicator stare (dreapta-jos): - ✓ verde =
PLATIT (efectuată cu succes) - ↻ gri/albastru =
rambursată parțial sau integral
Header — acțiuni: - 🔄 refresh - 📄 raport curent
4.2 Detaliu tranzacție
Câmpuri afișate:
| Câmp | Exemplu |
|---|---|
| ID tranzacție | 2790 |
| Suma | 10.00 MDL |
| Stare | PLATIT ✓ |
| Tipul mesajului SWIFT | PACS.008.001.10 |
| ID-ul mesajului SWIFT | 1585701D-9922-43E0-9FCE-29E3FA2D1863 (UUID) |
| Codul SWIFT al plătitorului | CMTBMD2X (banca emitentă) |
| Data | 19:29, 24.04.2026 |
Acțiuni jos: - 🔄 Rambursare (full-width, dark navy) - 📋 bon (icon button — duplicat bon de tipărire)
4.3 Stări tranzacție
| Stare | Indicator | Tranziții |
|---|---|---|
| PLATIT | ✓ verde | → RAMBURSAT PARȚIAL / RAMBURSAT INTEGRAL |
| RAMBURSAT PARȚIAL | ↻ albastru | poate fi rambursată diferența |
| RAMBURSAT INTEGRAL | ↻ gri | terminal — fără acțiuni suplimentare |
5. Rambursări
5.1 Formular rambursare
Trigger: butonul Rambursare din detaliul tranzacției.
Câmpuri:
| Câmp | Tip | Validare |
|---|---|---|
| Motivul | dropdown | listă fixă (vezi 5.2) — obligatoriu |
| Descrierea motivului | text liber | recomandat, obligatoriu pentru Problema tehnica |
| Rambursare parțială | toggle | dacă activ → apare câmp Suma de rambursare parțială ≤
suma originală |
Sub câmpuri: read-only Data +
ID tranzacție.
Buton primary Rambursarea sumei (activ doar când motivul e selectat).
5.2 Lista motivelor de rambursare (dropdown)
Motive standardizate (ISO 20022 — RJCT reasons +
custom):
- Tranzacție respinsă din cauza timeout la PSP acceptant
- Cont incorect
- Contul plătitorului este invalid sau lipsește
- Contul beneficiarului este invalid sau lipsește
- Contul plătitorului a fost închis
- Cont specificat este blocat sau procesarea tranzacțiilor cu implicarea acestuia este interzisă
- Contul beneficiarului a fost închis
- Moneda contului este nevalidă sau lipsește
- Codul tranzacției nu este acceptat/autorizat
- Valoarea plății este mai mare decât maximul permis
- Valoarea fondurilor disponibile pentru a acoperi suma specificată în mesaj este insuficientă
- Dublicat
- Suma primită nu este suma convenită sau așteptată
- Suma este nevalidă sau lipsește
- Detaliile aferente beneficiarului sunt insuficiente/incorecte
- Decizia clientului (cel mai utilizat — refund la cererea cumpărătorului)
- ID mesajului/ID instrucțiunii nu este unic
- Mesajul/plata nu poate fi procesată din cauza unor probleme tehnice la nivelul participantului
- Contul plătitorului nu există
- Detaliile plății sunt inadecvate
- Problema tehnică
5.3 Rambursare parțială — sumă specificată
- Toggle Rambursare parțială = ON
- Câmp Suma de rambursare parțială (ex.
5) - Suma originală afișată sub toggle (
10.00 MDL) - Buton Rambursarea sumei (activ după validare)
5.4 Stare „În procesare” (decizia bancară pendentă)
- Mesaj: „Așteptarea deciziei privind rambursarea fondurilor”
- Progress bar (animat)
- Buton Rambursarea sumei disabled până la response
5.5 Listă cu tranzacția rambursată parțial
- Tranzacția originală
#2791—10.00 MDL✓ - Tranzacția-rambursare
#2792—5.00 MDL↻ (icon refund)
Notă tehnică: rambursarea în MIA generează o tranzacție inversă nouă (mesaj
pacs.008în direcție opusă), nu modifică tranzacția originală.
5.6 Detaliu rambursare
Câmpuri: - ID tranzacție (ex. 2792) - Suma rambursată
(5.00 MDL) - Stare: RAMBURSAT
PARȚIAL ↻ - Tipul mesajului SWIFT (în pre-prod poate apărea
MOCK; în producție pacs.008.001.10) - ID-ul
mesajului SWIFT (UUID) - Codul SWIFT al plătitorului
(în pre-prod INTEGRATION SVC; în prod codul real al băncii)
- Data
6. Anulare QR
6.1 Buton Anulare pe ecranul QR
Buton Anulare (text roșu, jos) — disponibil cât timp QR-ul este activ și plata nu a fost încă efectuată.
6.2 Confirmare anulare
Modal cu 2 acțiuni: Înapoi / Confirmă.
După anulare: - QR-ul devine invalid (orice scan ulterior eșuează) - Operațiunea apare în Merchant Portal → Operațiuni online cu stare REFUZATE
7. Setări pentru codul QR
Setarea controlează cum se generează QR-urile pe acest terminal (per-vânzător).
7.1 QR dinamic (default)
- QR dinamic (default): acceptă doar o sumă fixă. O tranzacție / QR.
- Câmp Timp de acțiune (sec) — TTL al QR-ului
(default
300sec = 5 min) - Buton Aplică
7.2 QR static (cu sub-opțiuni)
QR static: acceptă sume fixe, controlate și nespecificate. Tranzacții / QR nelimitate.
Sub-tipuri: - Suma fixă — sumă pre-imprimată; clientul nu poate modifica - Suma controlată — limite min/max; clientul confirmă în limite - Sumă nespecificată — clientul introduce orice sumă
Caz uz: QR-uri statice imprimate pe sticker la tejghea / pe factură.
7.3 QR hibrid (cu sub-opțiuni)
QR hibrid: acceptă doar sume fixe și controlate. Nu mai mult de o tranzacție odată.
Sub-tipuri: - Suma fixă - Suma controlată
Caz uz: QR fizic la POS pentru sume specifice (ex. abonament lunar) — un singur client la un moment dat.
7.4 Timp de acțiune (TTL)
Câmp comun tuturor tipurilor — durata de validitate a QR-ului în
secunde (default 300).
| Tip QR | Tranzacții/QR | Sub-opțiuni | TTL recomandat |
|---|---|---|---|
| Dinamic | 1 | – | 300 sec |
| Static | ∞ | Fixă / Controlată / Nespecificată | mare (zile) |
| Hibrid | 1 odată | Fixă / Controlată | 300–600 sec |
8. Setări — limbă
8.1 Acces Profil
Acces din Profil → Schimbați limba.
8.2 Selecție limbă
Liste cu 3 opțiuni: - Română (default, bifă albastră ✓) - English - Русский
Buton Aplică — devine activ doar la modificarea limbii.
Persistență: preferința este stocată local pe dispozitiv (per-vânzător dacă există multipli pe același device).
9. Suport
Acces din Profil → Suport.
Câmpuri: - Telefon: 60665335 (clickable
— tel: link) - Email:
[email protected] (clickable —
mailto: link) - App version:
1.0.14 (read-only)
Notă: versiunea aplicației este folosită de echipa de suport pentru a corela bug-uri cu build-uri specifice.
10. Profil
Punct central al meniului utilizator. Conținut:
Header - Titlu „Profil” - ⏏ logout (sus-dreapta — text roșu)
Card cont vânzător - Avatar - Nume operator (ex. Operator 5) - ID vânzător: 370 - Închide ziua (sus-dreapta în card) — buton primary roșu
Card terminal & locație (read-only) -
Terminal #T0001 - Numele magazinului
(Finergy store) - Adresa
(Chișinău, 31 august 60)
Acțiuni meniu - ⊞ Setări pentru codul QR → §7 - 🌐 Schimbați limba → §8 - 🎧 Suport → §9
Footer: Powered by FINERGY
Bottom navigation (3 tab-uri): - ⊞ Terminal — keypad de plată (§3.4) - ⇄ Tranzacții — listă (§4) - 👤 Profil (activ)
11. Element-set comun (componente vizuale & UX patterns)
11.1 Coduri culoare pentru stări
| Culoare | Semnificație | Exemple |
|---|---|---|
| 🟢 Verde | Succes / final pozitiv | PLATIT ✓, „POS activat cu succes”, „Plata a fost finalizată!“, buton OK pe keypad |
| 🟡 Albastru | Acțiune principală | Deschide ziua, Aplică, link-uri active, indicator parțial-rambursat |
| 🔴 Roșu | Acțiuni distructive / atenție | Anulare, Închide ziua, logout, banner „Ziua este închisă” |
| ⚫ Gri | Inactiv / final neutru | Buton disabled (ex. OK când suma e
0.00), RAMBURSAT INTEGRAL |
| ⚫ Dark navy | Header / context elevat | Card sumă pe ecranul QR, butonul Rambursare |
11.2 Pattern-uri recurente
- Confirmări distructive sau cu impact: modal cu 2 butoane Înapoi / Confirmă — folosit pentru anulare QR, deschidere/închidere zi.
- Top-bar cu icon de raport (📄): prezent pe pagina Tranzacții — afișează raportul intermediar pentru ziua curentă.
- Auto-close cu countdown: ecranul de succes plată
afișează
OK(8)cu countdown 8 sec → revine la keypad. - Bottom navigation 3-tab: Terminal / Tranzacții / Profil — același pattern pe Android și iOS.
- Header de context: pe ecranele de plată și pe modul
login, afișează
Terminal (id: X)+ locația — păstrează vânzătorul orientat.
11.3 Multi-currency
În producție Moldova, valuta este MDL (etichetată
explicit în UI). Aplicația suportă structural valută variabilă (la nivel
de mesaj pacs.008), dar UI-ul actual este optimizat
MDL.
11.4 Modul offline
QR-ul este generat local (string-ul EMVCo deterministic), dar
confirmarea plății necesită conexiune la pos-terminal-svc.
Tranzacțiile efectuate pe app de plătitor în timpul disconectării
terminalului apar în listă la sincronizarea ulterioară.
12. Glosar tehnic
| Termen | Definiție |
|---|---|
| MIA | Money Instant Acceptance — schema IPS Moldova (BNM) |
| pacs.008.001.10 | Mesaj ISO20022 de payment instruction (versiunea folosită pe MIA) |
| PSP acceptant | Payment Service Provider la merchant — în cazul nostru miaPOS via banca acquiring |
| IDNO | Identificator de stat al persoanei juridice (Moldova) |
| ID terminal | Cod unic per-terminal (ex. T0001) |
| OTP | One-Time Password — cod de 6 cifre primit prin SMS |
| QR dinamic / static / hibrid | Variante de cod QR cu durate și logici diferite (vezi §7) |
| Z-report | Raport cumulativ generat la închiderea zilei comerciale |
| Codul SWIFT al plătitorului | BIC al băncii emitente a contului plătitorului (ex.
CMTBMD2X = MAIB) |
13. Lifecycle complet (diagrama text)
┌──────────┐
│ Lansare │
│ app │
└────┬─────┘
│
▼
┌─────────────────┐ NU ┌──────────────────┐
│ Date terminal │ ─────►│ Trimiteți onboard│
│ (IDNO + ID) │ │ pe email │
└────┬────────────┘ └──────────────────┘
│
▼
┌──────────┐
│ OTP SMS │
│ (6 cifre)│
└────┬─────┘
│
▼
┌──────────────────┐
│ POS activat ✓ │
└────┬─────────────┘
│
▼
┌──────────────────┐
│ Login (User+Pwd) │
└────┬─────────────┘
│
▼
┌──────────────────────────┐
│ Profil — ZI ÎNCHISĂ │
│ [Deschide ziua] │
└────┬─────────────────────┘
│ confirm
▼
┌──────────────────────────┐ ┌────────────────────┐
│ Terminal — keypad sumă │ ─► │ Anulare QR │
└────┬─────────────────────┘ └────────────────────┘
│ OK
▼
┌──────────────────────────┐
│ QR generat (TTL 300s) │
└────┬─────────────────────┘
│ scan + confirm de client
▼
┌──────────────────────────┐
│ Plata finalizată ✓ │ ──► Tranzacție în listă
└──────────────────────────┘
│
│ (după N tranzacții)
▼
┌──────────────────────────┐
│ Profil — [Închide ziua] │
└────┬─────────────────────┘
│ confirm
▼
┌──────────────────────────┐
│ Raport Z afișat → OK │
└──────────────────────────┘
14. DoD (Definition of Done) pentru documentație
15. Anexe — referințe ecrane
POS-flow/
├── autentificare/ (1, 2-onboarding-email, 3-otp, 4-pos-activat, 5-login)
├── deschidere-zi/ (1.0-zi-inchisa-tranzactii, 1.1-profil-zi-inchisa,
│ 2-confirma-deschidere, 3-keypad-empty, 4-keypad-suma,
│ 5-qr-activ, 6-plata-finalizata, 8-tranz-in-lista)
├── tranzactii/ (1-listă, 2-detaliu)
├── rambursari/ (1-formular, 2-dropdown-motive, 3-parțială,
│ 4-așteptare, 5-listă-rambursată, 6-detaliu)
├── anulare/ (1-buton, 2-confirmare)
├── inchidere-zi/ (1-confirmare, 2-închidere-raport)
├── rapoarte/ (1-profil, 2-detaliu-tranz)
├── setari-qr/ (1-dinamic, 2-static-cu-sub, 3-hibrid-cu-sub, 4-ttl)
├── setari-limba/ (1-profil, 2-listă)
└── suport/ (1-info-contact, 2-profil)
Document generat pe baza ecranelor de referință din
POS-flow/ — versiune 1.0.14 a aplicației
miaPOS pentru Android și iOS.