Files
Thijooree-iOS/Thijooree iOS/Utils/PaymvQrParser.swift
T
modeazimandClaude Sonnet 4.6 2bbb280380 Add Tap to Pay feature and misc fixes
Adds BML contactless token fetching, APDU emulation utility, TapToPayViewModel, and TapToPayView with NFC animation. Also updates QR scanner, transfer flow, dashboard, and home views.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 01:27:27 +05:00

64 lines
2.0 KiB
Swift

import Foundation
struct PaymvQrResult: Equatable {
let account: String
let amount: String?
let merchantName: String?
let purpose: String?
}
enum PaymvQrParser {
static func extractBmlGatewayUrl(_ raw: String) -> String? {
if raw.hasPrefix("https://pay.bml.com.mv/app/") { return raw }
let root = parseTLV(raw)
guard let bmlMerchantInfo = root["35"].flatMap({ parseTLV($0) }),
let inner = bmlMerchantInfo["20"].flatMap({ parseTLV($0) }),
let url = inner["01"],
url.hasPrefix("https://pay.bml.com.mv/app/") else { return nil }
return url
}
static func parse(_ qr: String) -> PaymvQrResult? {
let tlvs = parseTLV(qr)
// Tag 26: merchant account info — sub-tag 03 = account number
var account: String?
if let tag26 = tlvs["26"] {
let sub = parseTLV(tag26)
account = sub["03"]
}
guard let acc = account, !acc.isEmpty else { return nil }
let amount = tlvs["54"]
let name = tlvs["59"]
// Tag 62: additional data — sub-tag 08 = purpose/reference
var purpose: String?
if let tag62 = tlvs["62"] {
let sub = parseTLV(tag62)
purpose = sub["08"]
}
return PaymvQrResult(account: acc, amount: amount, merchantName: name, purpose: purpose)
}
private static func parseTLV(_ s: String) -> [String: String] {
var result: [String: String] = [:]
var idx = s.startIndex
while s.distance(from: idx, to: s.endIndex) >= 4 {
let idEnd = s.index(idx, offsetBy: 2)
let lenEnd = s.index(idEnd, offsetBy: 2)
let id = String(s[idx..<idEnd])
guard let len = Int(s[idEnd..<lenEnd]) else { break }
idx = lenEnd
guard s.distance(from: idx, to: s.endIndex) >= len else { break }
let valEnd = s.index(idx, offsetBy: len)
result[id] = String(s[idx..<valEnd])
idx = valEnd
}
return result
}
}