I am trying to create payment app which support the tap & pay functionality. I am already done with the Connecting App to NFC terminal with use of SELECT APDU Command.
Now, I want to send the stored card details from app to NFC Terminal, so it can make transaction.
Can you suggest me any kind of documents, which can help me to achieve it, such as how to send the details securely and in what kind of format it should be send?
any help would be appreciated.
here is the code
Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.nfcemulator">
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc.hce"
android:required="true" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.NFCEmulator">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".service.HCEService"
android:exported="true"
android:permission="android.permission.BIND_NFC_SERVICE">
<intent-filter>
<action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE" />
</intent-filter>
<meta-data
android:name="android.nfc.cardemulation.host_apdu_service"
android:resource="@xml/apduservice" />
</service>
</application>
</manifest>
HCE Service
class HCEService: HostApduService() {
companion object {
val TAG = "Host Card Emulator"
val STATUS_SUCCESS = "9000"
val STATUS_FAILED = "6F00"
val CLA_NOT_SUPPORTED = "6E00"
val INS_NOT_SUPPORTED = "6D00"
val AID = "A0000002471001"
val SELECT_INS = "A4"
val DEFAULT_CLA = "00"
val MIN_APDU_LENGTH = 12
}
override fun onDeactivated(reason: Int) {
Log.d(TAG, "Deactivated: " + reason)
}
override fun processCommandApdu(commandApdu: ByteArray?, extras: Bundle?): ByteArray {
if (commandApdu == null) {
return Utils.hexStringToByteArray(STATUS_FAILED)
}
val hexCommandApdu = Utils.toHex(commandApdu)
if (hexCommandApdu.length < MIN_APDU_LENGTH) {
return Utils.hexStringToByteArray(STATUS_FAILED)
}
if (hexCommandApdu.substring(0, 2) != DEFAULT_CLA) {
return Utils.hexStringToByteArray(CLA_NOT_SUPPORTED)
}
if (hexCommandApdu.substring(2, 4) != SELECT_INS) {
return Utils.hexStringToByteArray(INS_NOT_SUPPORTED)
}
if (hexCommandApdu.substring(10, 24) == AID) {
return Utils.hexStringToByteArray(STATUS_SUCCESS)
} else {
return Utils.hexStringToByteArray(STATUS_FAILED)
}
}
}
apduservices.xml
<?xml version="1.0" encoding="utf-8"?>
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/hce_service"
android:requireDeviceUnlock="false">
<aid-group android:description="@string/aid_groups"
android:category="other">
<aid-filter android:name="325041592E5359532E4444463031"/>
</aid-group>
</host-apdu-service>