Files
android/docs/thijooree/11-paymv-qr-screen.md
T

7.0 KiB
Raw Blame History

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:

  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 <name>_paymv_qr.png to the cache and shares it via FileProvider + ACTION_SEND
  • Save (btnSave) — writes <name>_PayMV_QR.png to MediaStore.Images / Pictures/

 


← OTP Screen     Next → BML QR Pay