Files
Emoney-Info---IOS/Emoney Info/Classes/api/TapCashApi.swift
Wira Basalamah 8f0b001501 Initial commit
2026-04-24 04:55:24 +07:00

179 lines
6.3 KiB
Swift
Executable File

//
// TapCashApi.swift
// Emoney Info
//
// Created by Wira Irawan on 26/07/24.
//
import Foundation
import CoreNFC
public class TapCashApi : UnifiedNfcApi {
var emoney : Emoney = Emoney()
var tapCashData : TapCashData = TapCashData()
var riwayatList: [RiwayatCard] = []
var start = 0
var totalLog = 0
public override init() {}
public func checkBalance(){
apduRunner.exchangeApdu(apduCommand: EmoneyApduCommands.TAPCASH_APDU01, completionHandler: {response in
if (response.sw1 == 0x90 && response.sw2 == 0x00){
self.emoney.setCardLabel("BNI TapCash")
self.tapCashData.setPurseData(response.getData().bytes)
let balance = self.tapCashData.getPurseBalance()?.hexString().hex2decimal()
self.emoney.setBalance(balance!)
self.emoney.setCardNumber(self.tapCashData.getCAN()!.hexString())
self.totalLog = (self.tapCashData.getTotalRecords()?.hexString().hex2decimal())!
if (self.totalLog > 10){
self.totalLog = 10
}
debugLog("total log " + String(self.totalLog))
self.getHistory(index: 0)
} else {
self.emoney.setTampilRiwayat(false)
self.updateScreen()
self.apduRunner.sessionEx?.alertMessage = "readFinish".localizeString(string: self.langCode!)
self.apduRunner.invalidateSession()
}
})
}
private func getHistory(index : Int){
let st = String(index).leftPad(with: "0", length: 2)
//90 32 03 00 01 00 10
let TAPCASH_LOG = NFCISO7816APDU(instructionClass : 0x90, instructionCode : 0x32, p1Parameter : 0x03, p2Parameter : 0x00, data : Data(_ : st.stringToBytes()!), expectedResponseLength : 16)
debugLog(TAPCASH_LOG.toHexString())
apduRunner.exchangeApdu(apduCommand: TAPCASH_LOG, completionHandler: {response in
if (response.sw1 == 0x90 && response.sw2 == 0x00){
self.addRiwayatTransaksi(data: response.getData().bytes)
}
self.start+=1
if (self.start < (self.totalLog)){
self.getHistory(index: self.start)
} else {
self.updateScreen()
self.riwayatList = self.riwayatList.sorted(by: { $0.getTransationTime()?.compare($1.getTransationTime()!) == .orderedDescending })
if (self.riwayatList.count > 0){
self.emoney.setRiwayatList(self.riwayatList)
self.emoney.setTampilRiwayat(true)
}
self.apduRunner.sessionEx?.alertMessage = "readFinish".localizeString(string: self.langCode!)
self.apduRunner.invalidateSession()
}
})
}
private func updateScreen(){
if (self.apduRunner.callback != nil){
self.apduRunner.callback?.complete(emoney: self.emoney)
}
}
private func addRiwayatTransaksi(data: [UInt8]) {
let trxType = Array(data[0..<1])
let trxAmount = Array(data[1..<4])
let trxDateTimes = Array(data[4..<8])
//let trxUserData = Array(data[8..<16])
let title = trxType.hexString()
var amount: Int
if title.lowercased() == "01" || title.lowercased() == "05" || title.lowercased() == "07" || title.lowercased() == "10" || title.lowercased() == "20" {
amount = trxAmount.hexString().secondComplementsAmount()
} else {
amount = trxType.hexString().hex2decimal()
}
let riwayatCard = RiwayatCard()
riwayatCard.setTitle(getStatementTitle(header: trxType.hexString()))
riwayatCard.setProsesTipe(getTranscationType(header: trxType.hexString()))
riwayatCard.setAmount(amount)
let transactionTime = self.getTransactionTime(julian: trxDateTimes.hexString())
riwayatCard.setTransactionTime(transactionTime)
riwayatList.append(riwayatCard)
}
private func getStatementTitle(header: String) -> String {
var title = ""
switch header.uppercased() {
case "01":
title = "payment".localizeString(string: self.langCode!)
case "02":
title = "Black List Card"
case "03":
title = "topup".localizeString(string: self.langCode!)
case "04":
title = "topup".localizeString(string: self.langCode!)
case "05":
title = "statementFee".localizeString(string: self.langCode!)
case "06":
title = "updateBalance".localizeString(string: self.langCode!)
case "07":
title = "gracePeriod".localizeString(string: self.langCode!)
case "10":
title = "refund".localizeString(string: self.langCode!)
case "20":
title = "refund".localizeString(string: self.langCode!)
case "22":
title = "close".localizeString(string: self.langCode!)
case "F0":
title = "atu".localizeString(string: self.langCode!)
default:
break
}
return title
}
private func getTranscationType(header: String) -> Int {
switch header.uppercased() {
case "01":
return 1
case "02":
return 2
case "03":
return 0
case "04":
return 0
case "05":
return 1
case "06":
return 6
case "07":
return 7
case "10":
return 10
case "20":
return 20
case "22":
return 22
default:
break
}
return 0
}
func getTransactionTime(julian: String) -> Date {
let dec = julian.hex2decimal()
let cal = Calendar.current
// set to 1st January 1995
var dateComponents = DateComponents()
dateComponents.year = 1995
dateComponents.month = 1
dateComponents.day = 1
dateComponents.hour = 0
dateComponents.minute = 0
dateComponents.second = 0
if let date = cal.date(from: dateComponents) {
let newDate = date.addingTimeInterval(Double(dec))
return newDate
}
return Date()
}
}