# 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](25-qr-scanner.md). > **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](18-paymv-qr-format.md#fahipay-work-in-progress). --- ## 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](18-paymv-qr-format.md#generating-a-receive-payment-qr): 1. Tag 01: `11` (static). Fahipay QRs with an amount use `12` (dynamic) 2. Tag 26: GUI (`mv.favara.mpqr`), acquirer BIC ×2 — `MALBMVMV` (BML) / `MADVMVMV` (MIB) / `FAHIMVMV` (Fahipay), account number, optional mobile, `IPAY` 3. Tag 54: amount as `%.2f`. If there's no amount: omitted (BML), `***` (Fahipay) 4. Tag 59: name, uppercased, max 25 chars 5. Tag 60: Fahipay only — `LD` + 4 random digits 6. Tag 62: the reference (above) + purpose 7. Tag 80: GUI + timestamp `yyyy-MM-dd'T'HH:mm:ss.00000` 8. Appends `"6304"` and computes CRC-16/CCITT-FALSE over the full string ### Actions - **Share** (`btnShare`) — writes `_paymv_qr.png` to the cache and shares it via `FileProvider` + `ACTION_SEND` - **Save** (`btnSave`) — writes `_PayMV_QR.png` to `MediaStore.Images` / `Pictures/` ---   --- [← OTP Screen](10-otp-screen.md)     **Next →** [BML QR Pay](12-bml-qr-pay.md)