7.0 KiB
PayMV QR Screen
Generates a receive-payment PayMV / Favara QR code. Generation only — the send/scan side of PayMV lives in TransferFragment via newInstanceWithAutoScan() and the QR scanner.
Fahipay QRs are a work in progress. Thijooree's Fahipay card matches Fahipay's design, but the Fahipay app currently rejects the QRs it generates as "Invalid QR". BML QRs scan fine. See PayMV QR Format → Fahipay.
Fragment — PayMvQrFragment
A single screen (no tabs). Re-renders the QR live (300 ms debounce) as the user edits the form. It can also be opened for a saved contact with PayMvQrFragment.forContact(accountNumber, name, bank). The QR then pays into the contact's account, and the account picker and phone toggle are hidden.
Fields
| Field | Source / behaviour |
|---|---|
| Source account dropdown | viewModel.accounts, filtered to non-card MVR accounts (MIB, M-Faisa and BML USD currently excluded — flagged as TODO in source). Defaults to CredentialStore.getDefaultAccountNumber() when set |
Amount (etAmount) |
Optional. Blank / zero / unparseable → open-amount QR. Commas are stripped |
Reference (etReference) |
Free-text purpose, written to tag 62→08. Blank → tag omitted (BML), or PAYMENT (Fahipay) |
Include phone (switchIncludePhone) |
When on, writes the saved BML / Fahipay mobile to sub-tag 26→05, normalised to +960XXXXXXX |
What goes on the card
| Item | Value |
|---|---|
| Name | BML / MIB: accountBriefName. Fahipay: the holder's full name (profileName, falling back to the saved Fahipay profile's fullName) — not the generic "Fahipay Wallet" brief name. Contacts: the contact's name. Always uppercased |
| QR | The payload below, white modules on the card blue, error correction M, no quiet zone |
| Vertical text | The QR's reference (tag 62→05) — see below |
| Amount | Not printed on the card (neither bank does); it only appears inside the QR, and in BML's vertical text |
Vertical text (reference)
Both banks print a short code vertically beside the QR, reading bottom-to-top. It is the same string as the payload's reference, tag 62→05, so Thijooree calculates the reference first and uses it for both.
| Bank | Reference / vertical text | Example |
|---|---|---|
| BML | Account number converted to base-32 (digits 0-9A-V, uppercase), followed by the amount exactly as typed (commas removed, no forced decimals), capped at 25 chars |
7730000188362 → 70V3UKKUA; with amount 100 → 70V3UKKUA100 |
| Fahipay | P + 9 random uppercase alphanumeric chars. No amount |
P2KVTPYL4E |
| Other (MIB contacts) | 9 random uppercase alphanumeric chars | WHQS0SX5O |
BML's base-32 is AccountNumbertoBase32 from the BML app: BigInt(account), repeatedly % 32 into the alphabet 0123456789ABCDEFGHIJKLMNOPQRSTUV. If the account number isn't numeric, Thijooree falls back to a random 9-char reference.
Card Rendering
Two renderers, chosen by the target's bank. Both return a Bitmap shown in ivQrCard (fitCenter) and used for Share / Save.
BML (and MIB) — renderQrCard()
A 1:1 copy of BML app v2.1.47's ReceiveCard React Native component (decompiled from the Hermes bundle). All values are BML's StyleSheet values in dp, laid out for a 560 dp reference screen width (SCREEN_WIDTH_DP) and drawn at 2 px/dp (PX_PER_DP), so the card comes out about 1024 px wide.
| Element | Spec |
|---|---|
| Colour | mmaBlue #0E5CA4 everywhere |
| Card | Width sw − 48. Blue background, radius 20. The white top section is inset 2 dp (top corners 18), which shows as a thin blue border |
| Header row | 32 dp from top, 40 dp side margins. Left: bml_logo_paymv ("BANK OF MALDIVES" wordmark, from BML's assets) contained in 0.38·sw × 0.38·sw·0.1117. Right: "PayMV QR", Sofia Pro Bold, #0E5CA4, sized to BML's 0.2·sw × 0.2·sw·0.1733 image box, shifted down 1 dp. MIB uses mib_faisanet_logo in the same box |
| QR panel | 24 dp below the header, 40 dp side margins, radius 16, 24 dp bottom margin |
| Name | Roboto (system default) regular, 14 sp, white; 8 + 12 dp above, 16 dp below |
| QR | 0.5·sw square; 37 dp padding below |
| Vertical text | Roboto 10 sp, black at 80 % opacity, rotated −90°. Centred railW/1.37 − railW/2 right of the QR's right edge and (qr + railW/1.5)/2 down from the QR top, where railW = sw/1.85. Ellipsized to railW |
| Footer | "MALDIVES NATIONAL QR", Sofia Pro Bold (res/font/sofia_pro_bold.ttf), 0.046·sw, letter spacing 1.2 dp, 12 dp vertical padding |
Fahipay — renderFahipayQrCard()
Fahipay's app doesn't draw its card; it shows an image generated by Fahipay's server (api/app/qr/). Thijooree copies that image's layout, measured in pixels on its 1240 × 1322 canvas. Text is sized so capital letters match the measured cap heights.
| Element | Spec |
|---|---|
| Colour | #005DA3 |
| Card | Blue, radius 50. White area inset 6 px (top corners 44) down to y 1174. The blue below it is the footer |
| Header row | Square app icon fahipay_logo at (94, 94)–(163, 163), then the "FahiPay" wordmark fahipay_logo_long at x 178, y 104, 48 px tall — both, side by side |
| "PayMV QR" | Sofia Pro Bold, blue, right-aligned at x 1147, cap height 30 (cap top y 101) |
| QR panel | (166, 218)–(1074, 1126), radius 55 |
| Name | Roboto regular, white, centred at x 619, cap height 30 (cap top y 314). Shrinks to fit the panel minus 80 px |
| QR | 562 px at (338, 417) |
| Vertical text | Montserrat Regular (res/font/montserrat_regular.ttf), blue, cap height 27, rotated −90°. It sits in the white margin right of the panel: text starts at y 1087, baseline at x 1171 |
| Footer | "MALDIVES NATIONAL QR", Sofia Pro Bold, white, cap height 55.5 (cap top y 1220), BML's letter spacing (1.2/25.76 em) |
Fonts follow the BML card (Sofia Pro Bold, Roboto), except the vertical text, which keeps Fahipay's Montserrat.
Generation
buildQrPayload() assembles a decimal TLV payload per the PayMV QR Format:
- Tag 01:
11(static). Fahipay QRs with an amount use12(dynamic) - Tag 26: GUI (
mv.favara.mpqr), acquirer BIC ×2 —MALBMVMV(BML) /MADVMVMV(MIB) /FAHIMVMV(Fahipay), account number, optional mobile,IPAY - Tag 54: amount as
%.2f. If there's no amount: omitted (BML),***(Fahipay) - Tag 59: name, uppercased, max 25 chars
- Tag 60: Fahipay only —
LD+ 4 random digits - Tag 62: the reference (above) + purpose
- Tag 80: GUI + timestamp
yyyy-MM-dd'T'HH:mm:ss.00000 - Appends
"6304"and computes CRC-16/CCITT-FALSE over the full string
Actions
- Share (
btnShare) — writes<name>_paymv_qr.pngto the cache and shares it viaFileProvider+ACTION_SEND - Save (
btnSave) — writes<name>_PayMV_QR.pngtoMediaStore.Images/Pictures/
← OTP Screen Next → BML QR Pay