Host Card Emulation / Card Session for payment URL

We have a financial application where we want to use NFC to broadcast a Payment URL to another iPhone or Android device when initiating a payment transaction. This will then open the banking application installed on the recipient’s device, allowing the transaction to be completed.

We have already made the necessary requests to Apple and configured the entitlements file as follows:

	<key>aps-environment</key>
	<string>development</string>
	<key>com.apple.developer.nfc.hce</key>
	<true/>
	<key>com.apple.developer.nfc.hce.iso7816.select-identifier-prefixes</key>
	<array>
		<string>D2760000850101</string>
	</array>
	<key>com.apple.developer.nfc.readersession.formats</key>
	<array>
		<string>TAG</string>
        <string>NDEF</string>
	</array>
</dict>

I've tried to use CardSession with the sample code provided by Apple on their site: Card Session

The connection between the devices (two iPhones, OS is above iOS 17.4) is established, the event stream's case .received(let cardAPDU): works, however, when I send the response, nothing really happens

Initial APDU response:

CLA  | 0x00
INS  | 0xA4
P1   | 0x04
P2   | 0x00
DATA | 0x7D2760000850101 (guess this is the AID)
Le   | 00

Sending the apdu response in the event stream via:

do {
   guard let request = APDUUtil.createAPDURequest(from: paymentUrl) else { return }
   try await cardAPDU.respond(response: request)
   await cardSession.stopEmulation(status: .success)      
 }
static func createAPDURequest(from paymentUrl: URL?) -> Data? {
        guard let paymentUrl else { return nil }
        
        let ndefMessage = APDUUtil.createNDEFMessage(from: paymentUrl)
        APDUUtil.updateNdefRecordFile(ndefMessage: ndefMessage)

        let data = Data(mNdefRecordFile)
        
        let apdu = NFCISO7816APDU(instructionClass: 0x00,
                                  instructionCode: 0xA4,
                                  p1Parameter: 0x04,
                                  p2Parameter: 0x00,
                                  data: data,
                                  expectedResponseLength: -1) // Tried with different values
        
        return apdu.data
    }
static func createNDEFMessage(from url: URL?) -> NFCNDEFMessage? {
        guard let url,
              let payload = NFCNDEFPayload.wellKnownTypeURIPayload(url: url) else {
            return nil
        }
        
        return NFCNDEFMessage(records: [payload])
    }
static func updateNdefRecordFile(ndefMessage: NFCNDEFMessage?) {
        guard let ndefMessage else {
               return
           }
           
           // Convert the NFCNDEFMessage to Data
           let ndefMessageData = ndefMessage.records.reduce(Data()) { result, record -> Data in
               var result = result
               result.append(record.payload)
               return result
           }
           
           let nlen = ndefMessageData.count
           mNdefRecordFile = [UInt8](repeating: 0, count: nlen + 2)
           
           // Store the length in the first two bytes (big-endian format)
           mNdefRecordFile[0] = UInt8((nlen & 0xFF00) >> 8)
           mNdefRecordFile[1] = UInt8(nlen & 0xFF)
           
           // Copy the NDEF message data into the data starting at index 2
           mNdefRecordFile.replaceSubrange(2..<mNdefRecordFile.count, with: ndefMessageData)
    }

Could someone please help? I also tried to send the payment url as Data made from url.

We have a working Android application, which uses HCE too (they use NDEF message and byte arrays in communication).

As I've seen, the NFCNDEFReaderSessionDelegate and NFCTagReaderSessionDelegate is not suitable for communication between two iOS devices...

We will need some specific info about your development team and configuration to investigate this further. To discuss your specific use case in detail, and for us to share some additional information, please open a support request at https://developer.apple.com/contact/request/code-level-support/ and reference this forum thread in the "Did someone from Apple ask you to submit ..." section

Host Card Emulation / Card Session for payment URL
 
 
Q