InApp Provisioning — Enrolling cards [EN]

David Martinez
6 min readJan 4, 2021

--

In this article we will explain some concepts and tips about how to enroll a card into ApplePay (InApp provisioning). This process allows your users enroll their cards inside your own app without using Apple Wallet.

InApp provisioning flow

Before start, let’s check how ApplePay infrastructure works for this process and which role play the users and servers involved.

Enroll flow
  1. The user start the enroll process clicking “Add To Apple Wallet” button in your app.

2. Apple wallet request the public certificates that will be used by third party server (Issuer Host) for encrypt the payload (that allow us to enroll the card).

3. Apple servers send to Wallet a group of information that contains the public certificates and a nonce/nonceSignature pair used to securize the information that will be passed between servers.

4. Wallet send to your app (through delegate methods) this package of information: public certificates, nonce and nonceSignature.

5. Our app will work as a bridge connection between Apple and our third party server. All the information received by Apple must be sent to our custom servers.

Note: Before perform this sent (step 5), it’s possible that the app must execute a change over one of the three items explained before, for example, translate into base64 the nonce items. Your Issuer host must provide you this information.

6. The issuer host …:
6.a. Prepare the user payload
6.b. Generate a pair of ephemeral key (required by Apple)
6.c. Encrypt the payload with the public key sent by Apple and generate a private ephemeral key.
6.d. Send to the app… the payload (encrypted) and the public ephemeral key. Additionally, must generate an OTP (one true pair) needed by the Payment Network Operator (PNO) and pass to the app too.

7. The app encapsulates all this information:
* payload[encryptedPassData]
* ephemeral public Key
* OTP [activationData]
into a PKAddPaymentPassRequest located at PassKit API.

8. Apple Wallet move these details to the Apple servers where all this information will be checked and validated.

9. Finally this information travels to the PNO where the enrollment process will be finished.

Where do we start?

Well, at this point we know the theory so we shall begin to recover all the information we need to execute the implementation.

At first we need to activate the entitlement called ApplePay In-App Provisioning Distribution into the developer portal in the same way of other entitlement such as push notifications, app groups … So, open developer portal panel and search Certificates, Identifiers & Profiles -> Profiles -> Our distribution profile -> Edit -> and… Where is this configuration?

Well, you need to know that this entitlement its not available by default into our panel. It’s neccessary request its activation to Apple through its support email (apple-pay-provisioning@apple.com) or using another official communication channel.

Note: Remember that enterprise account hasn’t got access to this feature.

Once Apple has validated us as team/entity open your panel again. You will find the following menu available:

developer portal — configure InApp entitlement

As you can see, this feature it’s available for production environment only so your QA must work with real device/cards. Apple offers support to validate the encrypted information generated by the issuer host. For more information check the “XI. Sample Payment Data” included into the “ApplePay user manual” at the bottom of this article.

And now … let’s start programming! 🎉.

Update 10 Septembre 2022

Working in a project that uses this feature I found some additional changes that you must perform to enable this feature and that allows PassKit library to create the necessary view controllers. These changes are:

  • Enable one more thing into developer portal. For this, go to your developer portal -> Certificates and profiles -> Identifiers and look for your appId. Once your in, go to Additional Capabilities tab and mark the option with the In-App Provisioning like in the following screenshot
developer portal — enable In-App into app ID configuration
  • Second, open your project and search for the entitlements file (if you haven’t this file actually, create it following the link above). Once you are, and according to the Apple specification you must include the entitlement com.apple.developer.payment-pass-provisioning with value YES (1), and that’s all.
Entitlements file— include pass entitlement

Let’s coding!

In the following implementation will cover from scratch a simple integration in which we will add to our UIViewController the Apple enrollment button and implements the bridge communication explained before. Feel free to adapt all the code presented below to your own arquitecture :).

Adding the PassKitButton.

Let’s start adding the import of the PassKit library and the enroll button.

If you launch your application you must see something like this:

Launch enrollment proccess

Once our button is configured, we must connect with the PassKit interface that open the InApp flow.

// 1:
We must check if our device has the ability to manage ApplePay. If not, you must present a warning to your users or avoid them to access this feature.

// 2:
Enroll start …

// 3:
Preload the card information that feeds the PassKit view controller that will be displayed.

// 4:
Create the view model required by PassKit framework (PKAddPaymentPassRequestConfiguration) and pass it all the information that you recover in step 3. Apple allow you a minimal customization over the screens presented into InApp enrollment flow. Check this information in the following images:

ApplePay — Enroll — Card information
Apple Pay — Enroll — Device selection

This looks familiar … right? These screens are the same ones used by Wallet native app.

Once the configuration is ready, create the PKAddPaymentPassViewController with the configuration given. This controller will present the flow explained above.

// 5:
Finally, present the view controller (as usual, with a present(viewController:animated:completion) method) and listen to the PKAddPaymentPassViewControllerDelegate events.

Bridge Apple <-> App <-> IssuerHost implementation

Once the views are ready, we must implement the connection between all servers involved through addPaymentPassViewController method that provide us the information needed (certificated, nonce and nonceSignature). Let’s check an example:

// 1:
At first, cook all third party server data needed. This action will group all the Apple information plus all additional information required by your server to validate the transaction (the FPAN of your card, expiration date …)

// 2:
Perform the call to your business data layer and wait for the response..

// 3:
Our third party server must send to us all information required by Apple to finish the transaction, so activationData, ephemeralPublicKey and encriptedPassData must be found at this point in your server response. With this information, build the PKAddPaymentPassRequest and send back the control to Apple through handler callback.

// 4:
For sure, checks if anyone fails.

And that’s all! This is the basic implementation for Apple InApp provisioning! Good work!

To improve the user experience check the following article that gives you more details, for example, how to know if the user is or not enrolled actually.

Thanks for reading!

Bibliography

--

--