3

I'm Developing Apple Pay Card Provisioning Apple Pay In-App Provisioning Card I got this continuing this functionality getting the nonce & nonceSignatures from Apple server after getting this trying to send PKAddPassPaymentRequest in the below formate not getting anything is the format is correct what I'm sending

PKAddPaymentPassRequest *request = [[PKAddPaymentPassRequest alloc] init];
request.encryptedPassData =[@"XXXXXXXXXXX" dataUsingEncoding:NSUTF8StringEncoding];
request.activationData =[@"XXXXXXXXXXX" dataUsingEncoding:NSUTF8StringEncoding];
request.ephemeralPublicKey =[@"XXXXXXXXXXX" dataUsingEncoding:NSUTF8StringEncoding];

Thanks in advance.

S P Balu Kommuri
  • 890
  • 10
  • 28

1 Answers1

9

Prerequisite: Get all entitlements and updated profiles. You can test push provisioning to producation only by testflight or appstore. You can request for sandbox env into your device from Apple. They can enable QA env in your device by installing a profile. Then you can test push provisioning in QA env as well.

Once you meet all requirements,

1. Create configuration and fill required details

PKAddPaymentPassRequestConfiguration *config= 
     [[PKAddPaymentPassRequestConfiguration alloc] 
       initWithEncryptionScheme:PKEncryptionSchemeECC_V2];

2. Create PKAddPaymentPassViewController and present it

self.addPaymentPassModal = 
     [[PKAddPaymentPassViewController alloc]
       initWithRequestConfiguration:config delegate:self];

3. Implement delegate methods.

- (void)addPaymentPassViewController:(PKAddPaymentPassViewController *)controller 
generateRequestWithCertificateChain:(NSArray<NSData *> *)certificates
                           nonce:(NSData *)nonce
                  nonceSignature:(NSData *)nonceSignature
               completionHandler:(void(^)(PKAddPaymentPassRequest *request))handler {

  PKAddPaymentPassRequest *paymentPassRequest = [[PKAddPaymentPassRequest alloc] init];

  paymentPassRequest.encryptedPassData = [[NSData alloc]
                initWithBase64EncodedString:encryptedPassData options:0];

  paymentPassRequest.activationData = [activationData 
                 dataUsingEncoding:NSUTF8StringEncoding];

  paymentPassRequest.ephemeralPublicKey = [[NSData alloc] 
                 initWithBase64EncodedString:ephemeralPublicKey options:0];

  handler(paymentPassRequest);

}

- (void)addPaymentPassViewController:(PKAddPaymentPassViewController *)controller
      didFinishAddingPaymentPass:(nullable PKPaymentPass *)pass
                           error:(nullable NSError *)error {

 //Will get called once push provisioning complete

}
Scott Condron
  • 1,902
  • 16
  • 20
  • Thank you almost same i implemented it will be helpfull for me. – S P Balu Kommuri May 23 '18 at 04:30
  • Hi, I am implementing the same functionality. I have passed card details to PKAddPaymentPassViewController and presented it. But on clicking next button, I am getting an error saying "Could not add card. Try again later or contact your issuer for more information". Do you what am I doing wrong? I have written the delegate methods also as you have mentioned above. Where do I get the certificate, nonce and nonce signature? – bhoomi Jun 18 '18 at 11:13
  • 1
    On Click of Next, the control will come back to the below delegate method with nonce, nonce signature and certificate chain. (void)addPaymentPassViewController:(PKAddPaymentPassViewController *)controller generateRequestWithCertificateChain:(NSArray *)certificates nonce:(NSData *)nonce nonceSignature:(NSData *)nonceSignature completionHandler:(void(^)(PKAddPaymentPassRequest *request))handler Then you have to create PKAddPaymentPassRequest with these data as mentioned above. – Rajesh Rajendran Pillai Jun 19 '18 at 14:55
  • Thanks Rajesh. To create PKAddPaymentPassRequest with encryptedPassData, activationData, and ephemeralPublicKey I need these data from my server. How can I set these data at this point as I have not yet received these data from my server? – bhoomi Jun 20 '18 at 05:45
  • Hi, I'm getting the nonce, nonceSignature, Certificate chain and creating the `PKAddPaymentPassRequest` with the respective data. Passing the same in completion handler but Apple guys are not receiving my request. Can you please help me on this. They are telling I'm not calling the completionHandler with the AddPaymentPassRequest. @RajeshRajendranPillai – S P Balu Kommuri Jul 09 '18 at 07:09
  • Hi Rajesh, As per apple I shared the below source code with them. `PKAddPaymentPassRequest *paymentPassRequest = [[PKAddPaymentPassRequest alloc] init]; paymentPassRequest.encryptedPassData = [[NSData alloc] initWithBase64EncodedString:encryptedPassDataStr options:0]; paymentPassRequest.activationData = [[NSData alloc] initWithBase64EncodedString:activationDataStr options:0]; paymentPassRequest.ephemeralPublicKey = [[NSData alloc] initWithBase64EncodedString:ephemKeyStr options:0]; handler(paymentPassRequest);` they are telling "I'm are referring to the wrong handler". – S P Balu Kommuri Jul 10 '18 at 04:34
  • @Balu Did you have success adding payment card to the wallet right from your app? If so, could you please share the steps? I am also running into the same generic error message "Could not add card to wallet", every time I invoke the handler with PKAddPaymentPassRequest. – stack2012 Dec 05 '18 at 05:00
  • 1
    @booleanBoy ya I implemented. A lot of stuff has to do from Card provider and can able to test only in the production environment using test flight. Encryption should be proper from server side as well. Have to follow the documentation provided by Apple for Both App and Server. Better to use ECC mode. – S P Balu Kommuri Dec 05 '18 at 05:28
  • We are actually using ECC encryption mechanism. Do you have any idea what could be the reason behind that generic alert message I've described in my above comment? Where should I be looking into? As far as the environment is concerned, we are using dev. The dev profile we are using has got Apple wallet entitlements. Also, the wallet app in iOS has been made to point sandbox environment by installing a push provisioning profile on the device. @Balu – stack2012 Dec 05 '18 at 15:33
  • Is your request reaches apple sandbox server? If apple guys confirmed that? If they are able to get a request from your application, If yes ? Are they able to decrypt? – S P Balu Kommuri Dec 06 '18 at 11:58
  • How are people getting com.apple.developer.payment-pass-provisioning added to their development profiles? We have explicitly been told by Apple that the entitlement is only for distribution profiles? – venturidoo Dec 18 '18 at 00:12
  • 1
    @RajeshRajendranPillai - How do you guys pass the certificates from Apple back to your own servers? Are you just converting the Data directly to base64 and sending it off? Or do you need to do any conversions in app first? – venturidoo Jan 10 '19 at 04:16
  • Hi, I'm implementing Apple Pay for the bank I work for. I have the service who give me the encrypted data and I can associate correctly a card to Apple Pay. I see that in the wallet. When I try to recover all the passes using PKPassLibrary().passes() I get an empty array. Is this a thing that I can test only with TestFlight? – Edoardo Vicoli May 06 '19 at 11:36
  • @Balu I'm implementing apple in-app provisioning but i stuck in that generic error modal. How did you implemented all the path? We are using ECC encryption, we are able to retrieve all data (encryptedPassData, ephemeralPublicKey and activationData) but we could not reach apple server (in testflight, apple cannot see our request). Have you found something important from your problem to the moment you could finally add the pass to wallet? – Luca Taccagni Nov 10 '19 at 15:40
  • @LucaTaccagni in which format you are sending all this data (encryptedPassData, ephemeralPublicKey and activationData) to the apple server. if any of the data formate is improper they cannot get our requests... – S P Balu Kommuri Nov 10 '19 at 16:06
  • @Balu are base64 all except for activationData which is utf8 (we do ut exactly as is written above in the “3. Implement delegate methods” part – Luca Taccagni Nov 10 '19 at 17:35
  • @LucaTaccagni then that’s the correct process. Are you testing with distribution certificate in testflight only ryt? – S P Balu Kommuri Nov 10 '19 at 17:43
  • Yes of course. We had whitelisted devices and cards from apple too. But there’s no way to solve the problem. – Luca Taccagni Nov 10 '19 at 17:46
  • @LucaTaccagni in this case i suspect that there is an issue while generating Activation key. Then only our requests are not able to reach apple servers. – S P Balu Kommuri Nov 14 '19 at 05:48
  • @Balu I’ve solved my issue. The problem was that I was trying to send data created couple of days ago and obviously they weren’t valid anymore. So if someone have this problem i recommend to do all steps as documentation says and to test with TESTFLIGHT only. – Luca Taccagni Nov 14 '19 at 10:36
  • @LucaTaccagni that’s great. – S P Balu Kommuri Nov 14 '19 at 11:17
  • hey, how are you converting certificates, nonce, noncesignature to the strings ? Can you please help – Mahendra Thotakura Jun 03 '21 at 08:32
  • @MahendraThotakura you can convert it like this (this is swift you can find similar for objective-c): let certificateLeaf = certificates[0].base64EncodedString(); let certificateSubCA = certificates[1].base64EncodedString(); let nonceString = nonce.base64EncodedString(); let nonceSignature = nonceSignature.base64EncodedString(); – Lukáš Šálek Jun 03 '21 at 09:40
  • @Lukᚊálek thanks for your response, I have implemented the same, I'm getting success from our server, when I send the empherialKey,ActivationData,EncryptedPassData back to PKAddPaymentPassRequest, I'm getting the error saying "Could not add card". – Mahendra Thotakura Jun 03 '21 at 11:46
  • @MahendraThotakura We dont have implemented endpoints for this logic yet...You are one step ahead of me (I will be there next week) ... but I would expect it is because dev mod ... you should use one of these cards and some apple id/account (I really did not get it ) https://developer.apple.com/apple-pay/sandbox-testing/. Let me know if you find a solution – Lukáš Šálek Jun 03 '21 at 12:19
  • @Lukᚊálek these sandbox cards can only be used by adding them to Apple Wallet manually, but we ned to add them through PKAddPaymentPassRequestConfiguration. – Mahendra Thotakura Jun 03 '21 at 13:35
  • hey, I have enabled the sandbox mode on Apple wallet and I'm trying to add the card to wallet, I'm getting an error Your issuer does not yet offer support for this card! can someone help me on this? – Mahendra Thotakura Jun 04 '21 at 05:17
  • @MahendraThotakura any solution? I just get all data what i need (`activationData`,`encryptedPassData`,`ephemeralPublicKey`) but when i put them into `handler(paymentPassRequest)` it will show me alert dialog with Could Not Add Card try it later or contact card issuer ... did you have the same issue? – Lukáš Šálek Jun 23 '21 at 07:17
  • @MahendraThotakura btw how did you init `PKAddPaymentPassRequest.init()`?? my endpoint return json i had to do this `let ephemeralPublicKeyString = dictionaryJson["ephemeralPublicKey"] as! String;` and then ` let ephemeralPublicKey = Data(ephemeralPublicKeyString.utf8) ` and put it into PKAddPaymentPassRequest ` paymentPassRequest.encryptedPassData = encryptedPassData; ` – Lukáš Šálek Jun 23 '21 at 07:24
  • @Lukᚊálek, yes I also got the similar issue "Could not add card", We can only test this feature from TestFlight. And coming to the conversion of empherialKey, ActivationData and EncryptedPassData we have to convert it based on the Encryption your server team is doing.. In our case it is Hex conversion. – Mahendra Thotakura Jun 23 '21 at 09:03
  • @MahendraThotakura Hi i still stack on that "Could not add card" error... can you please share with me all that you have in "addPaymentPassViewController" ?? it will be very help full for me ... i created StackOverflow question here https://stackoverflow.com/questions/68210197/apple-in-app-provisioning-could-not-add-card i am really desperate – Lukáš Šálek Jul 15 '21 at 07:33