Push provisioning

To start Apple Wallet push provisioning, use PKAddPaymentPassViewController with PKAddPaymentPassRequestConfiguration . 

 The configuration should use the .ECC_V2 encryption scheme. 

 import PassKit

let configuration = PKAddPaymentPassRequestConfiguration(encryptionScheme: .ECC_V2)!

configuration.cardholderName = "John Doe"

configuration.primaryAccountSuffix = "1234" // Last 4 digits of the card number

// Required when provisioning to Apple Watch.

// Use deviceAccountIdentifier from the phone PassItem.

configuration.primaryAccountIdentifier = phonePassItem.deviceAccountIdentifier

let viewController = PKAddPaymentPassViewController(

 requestConfiguration: configuration,

 delegate: delegate

)

 

 If the card is being added to Apple Watch, primaryAccountIdentifier should be set using deviceAccountIdentifier from the phone PassItem . 

 Delegate Implementation 

 The application must implement PKAddPaymentPassViewControllerDelegate . 

 In generateRequestWithCertificateChain , call the TMP API endpoint: 

 POST /issuer/push-provisioning/signed-cards

 

 For Apple Pay, the request requires certificate , nonce , and nonceSignature . The TMP response returns activationData , ephemeralPublicKey , and encryptedData , which are required to create PKAddPaymentPassRequest . 

 Swift Example 

 import PassKit

final class AddPaymentPassDelegate: NSObject, PKAddPaymentPassViewControllerDelegate {

 func addPaymentPassViewController(

 _ controller: PKAddPaymentPassViewController,

 generateRequestWithCertificateChain certificates: [Data],

 nonce: Data,

 nonceSignature: Data,

 completionHandler handler: @escaping (PKAddPaymentPassRequest) -> Void

 ) {

 Task {

 do {

 let signedCard = try await signCard(

 certificates: certificates,

 nonce: nonce,

 nonceSignature: nonceSignature

 )

 let request = PKAddPaymentPassRequest()

 request.activationData = Data(base64Encoded: signedCard.activationData)

 request.ephemeralPublicKey = Data(base64Encoded: signedCard.ephemeralPublicKey)

 request.encryptedPassData = Data(base64Encoded: signedCard.encryptedData)

 handler(request)

 } catch {

 controller.dismiss(animated: true)

 }

 }

 }

 func addPaymentPassViewController(

 _ controller: PKAddPaymentPassViewController,

 didFinishAdding pass: PKPaymentPass?,

 error: Error?

 ) {

 controller.dismiss(animated: true)

 if let error {

 // Handle provisioning error

 print("Apple Wallet provisioning failed: \\(error)")

 return

 }

 // Provisioning finished successfully

 }

}

 

 Notes 

 

 The code above is simplified and should be adapted to the existing TMP integration layer. 

 Sensitive card data should not be handled directly in the mobile application unless explicitly required by the approved architecture.