Implementation
Sequence Diagram
Card Data Parameters
Push provisioning flow is started by initializing MppCardDataParameters
object with CardId
, CardSecret
or EncryptedPan
. Initialize MppCardDataParams
.
Guide for encryptedCardData
generation can be found in Card Data Encryption manual.
let cardId = "<value>"
let cardSecret = "<value>"
let cardParams = MppCardDataParameters.init(cardId: cardId, cardSecret: cardSecret)
or
let encryptedCardData = "<value>"
let publicKeyFingerprint = "<value>"
let encryptedKey = "<value>"
let initialVector = "<value>"
let cardParams = MppCardDataParameters.init(encryptedCardData: encryptedCardData,
publicKeyFingerprint: publicKeyFingerprint,
encryptedKey: encryptedKey,
initialVector: initialVector)
Loading Configuration
By default MPP SDK is loading mea_config
configuration file, however a custom name can be used. When defining a custom name for the configuration file use MeaPushProvisioning.loadConfig(configFileName: String)
to load the configuration. Configuration file can be placed anywhere in application bundle.
import MeaPushProvisioning
...
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
MeaPushProvisioning.loadConfig("custom_config_name")
...
return true
}
INFO
MPP SDK raises an exception if configuration file is missing, broken or otherwise fails to load.
❗ Double check that you added mea_config
(or file with custom name) to specific target:
Initialize Apple Pay In-App Provisioning
MPP SDK provides MeaPushProvisioning
class with initializeOemTokenization
method to initiate Apple Pay In-App provisioning.
Initiate in-app push provisioning by using MeaPushProvisioning.initializeOemTokenization
method and MppCardDataParameters
parameter. Check if the payment card can be added to Apple Pay by using primaryAccountIdentifier
in response. Go to Show or hide "Add to Apple Wallet" button.
Tokenization receipt in response data MppInitializeOemTokenizationResponseData
has a validity determined by tokenizationResponseData.validFor
value in milliseconds. During the validity time frame (by default 15 minutes) tokenization receipt can be used in MeaPushProvisioning.completeOemTokenization(tokenizationData)
, when tokenization receipt expires a new initiation is required.
INFO
primaryAccountIdentifier
- Value is always empty for the very first push provisioning of the specific card. Empty value indicates that card can be added to Apple Pay.
- Users may have different passes installed on different paired devices (for example, on an iPhone and an Apple Watch). This property allows to filter out the devices that already contain a matching pass.
- Once the value is fetched for a specific card app should cache primaryAccountIdentifier to avoid unnecessary
MeaPushProvisioning.initializeOemTokenization
calls every time when Add to Apple Wallet button should be shown or hidden.
let isPassLibraryAvailable = PKPassLibrary.isPassLibraryAvailable()
let canAddPaymentPass = PKAddPaymentPassViewController.canAddPaymentPass()
if (isPassLibraryAvailable && canAddPaymentPass) {
MeaPushProvisioning.initializeOemTokenization(mppCardParameters) { (responseData, error) in
if (responseData?.isValid())! {
// Field primaryAccountIdentifier is always empty for the very first tokenization of the card.
var canAddPaymentPassWithPAI = true
if let primaryAccountIdentifier = responseData?.primaryAccountIdentifier, !primaryAccountIdentifier.isEmpty {
if #available(iOS 13.4, *) {
canAddPaymentPassWithPAI = MeaPushProvisioning.canAddSecureElementPass(primaryAccountIdentifier: primaryAccountIdentifier)
} else {
canAddPaymentPassWithPAI = MeaPushProvisioning.canAddPaymentPass(withPrimaryAccountIdentifier: primaryAccountIdentifier)
}
}
if (canAddPaymentPassWithPAI) {
self.tokenizationResponseData = responseData;
// Show "Add to Apple Wallet" button.
// ...
}
}
}
}
Add to Apple Wallet Button
Use PKAddPassButton class to create an Add to Apple Wallet button. iOS SDK provides a control with the correct appearance.
let addPassButton = PKAddPassButton(addPassButtonStyle: PKAddPassButtonStyle.black)
addPassButton.frame = CGRect(x:45.0, y: 340.0, width: 320, height: 20)
view.addSubview(addPassButton)
Show or Hide Add to Apple Wallet Button
INFO
associatedApplicationIdentifiers
Correct configuration of
associatedApplicationIdentifiers
allows the respective app to see, access and activate your payment passes.[[PKPassLibrary new] passes]
,[[PKPassLibrary new] remotePaymentPasses]
/[[PKPassLibrary new] remoteSecureElementPasses]
and[passLibrary canAddPaymentPassWithPrimaryAccountIdentifier:]
/[passLibrary canAddSecureElementPassWithPrimaryAccountIdentifier:]
will ONLY return passes ifApp ID
(TeamID.BundleID
) is specified inassociatedApplicationIdentifiers
on token service provider side.
App ID
is constructed by combining the Team ID with the App bundle ID, for example,A1B2C3D4E5.com.thebank.mobileapp
.
TeamID
is the Apple Developer team which is used to distribute your app via App Store.BundleID
is the ID of your app.
App is responsible to check and decide if "Add to Apple Wallet" should be shown or hidden for the user using primaryAccountIdentifier
or primaryAccountNumberSuffix
. Using primaryAccountNumberSuffix
is useful when Customer Service API backend connection is not available. Button should be shown only when card is not added to Apple Pay already. Only one of the following approaches should be used.
Use the following methods to check whether the card with specific primaryAccountNumberSuffix
can be added to Apple Wallet:
MeaPushProvisioning.canAddPaymentPass(withPrimaryAccountNumberSuffix:)
(before iOS 13.4)MeaPushProvisioning.canAddSecureElementPass(withPrimaryAccountNumberSuffix:)
(iOS 13.4+)
Use the following methods to check whether the card with specific primaryAccountIdentifier
can be added to Apple Wallet:
MeaPushProvisioning.canAddPaymentPass(withPrimaryAccountIdentifier:)
(before iOS 13.4)MeaPushProvisioning.canAddSecureElementPass(withPrimaryAccountIdentifier:)
(iOS 13.4+)
Return value indicates whether the app can add a card to Apple Pay for the provided primary account identifier. This function does not provide specific information about Apple Wallet on iPhone or Apple Watch.
Caching PrimaryAccountIdentifier
App should cache primaryAccountIdentifier
value for the specific card to avoid unnecessary MeaPushProvisioning.initializeOemTokenization
calls every time when Add to Apple Wallet button should be shown or hidden. The value can be cached permanently.
Check if Card Can Be Added to Apple Wallet on iPhone or Apple Watch
INFO
Read further only when app needs to detect if
PKPaymentPass
orPKSecureElementPass
can be added specifically to Apple Wallet on iPhone or Apple Watch. Use for Apple Watch only when it is paired to iPhone.
- Use one of the methods listed above to check whether the card can be added to Apple Wallet on iPhone or Apple Watch. Return value of the function indicates if card can be added, however it does not provide specific information about Apple Wallet on iPhone or Apple Watch.
- Detect if Apple Watch is paired with iPhone.
import WatchConnectivity
...
if WCSession.isSupported() { // Check if the iPhone supports Watch Connectivity session handling.
let session = WCSession.default()
session.delegate = self
session.activate() // Activate the session, asynchronous call to delegate method below.
}
...
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
if activationState == .activated && session.isPaired {
// Apple Watch is paired with iPhone.
}
}
- Check if
PKPaymentPass
orPKSecureElementPass
is already added to Apple Wallet on iPhone or Apple Watch:
- Apple Wallet on iPhone:
// Before iOS 13.4
let cardExists = MeaPushProvisioning.paymentPassExists(withPrimaryAccountIdentifier: "<primaryAccountIdentifier>")
let cardExists = MeaPushProvisioning.paymentPassExists(withPrimaryAccountNumberSuffix: "4321")
// iOS 13.4+
let cardExists = MeaPushProvisioning.secureElementPassExists(withPrimaryAccountIdentifier: "<primaryAccountIdentifier>")
let cardExists = MeaPushProvisioning.secureElementPassExists(withPrimaryAccountNumberSuffix: "4321")
- Apple Watch:
// Before iOS 13.4
let cardExists = MeaPushProvisioning.remotePaymentPassExists(withPrimaryAccountIdentifier: "<primaryAccountIdentifier>")
let cardExists = MeaPushProvisioning.remotePaymentPassExists(withPrimaryAccountNumberSuffix: "4321")
// iOS 13.4+
let cardExists = MeaPushProvisioning.remoteSecureElementPassExists(withPrimaryAccountIdentifier: "<primaryAccountIdentifier>")
let cardExists = MeaPushProvisioning.remoteSecureElementPassExists(withPrimaryAccountNumberSuffix: "4321")
Add Payment Pass View Controller
Mobile application have to create an instance of PKAddPaymentPassViewController
class, which lets your app prompt the user to add pass to the pass library.
PKAddPaymentPassViewController
have to be initialized using data retrieved in initializeOemTokenization:completionHandler:
handler and a delegate that implements PKAddPaymentPassViewControllerDelegate
protocol.
let addPaymentPassRequestConfiguration = self.tokenizationResponseData?.addPaymentPassRequestConfiguration
addPaymentPassRequestConfiguration?.cardholderName = "Cardholder Name"
let paymentPassController =
PKAddPaymentPassViewController.init(requestConfiguration: addPaymentPassRequestConfiguration!, delegate: self)
self.present(paymentPassController!, animated: true, completion: nil)
Complete Apple Pay In-App Provisioning
For completion of provisioning MeaPushProvisioning
class provides completeOemTokenization
method. This method exchanges Apple certificates and signature with Issuer Host.
Delegate should implement PKAddPaymentPassViewControllerDelegate
protocol to call completeOemTokenization:completionHandler:
method, once the data is exchanged PKAddPaymentPassRequest
is passed to the handler to add the payment card to Apple Wallet. In the end and delegate method is invoked to inform you if request has succeeded or failed.
func addPaymentPassViewController(_ controller: PKAddPaymentPassViewController,
generateRequestWithCertificateChain certificates: [Data],
nonce: Data, nonceSignature: Data,
completionHandler handler: @escaping (PKAddPaymentPassRequest) -> Void) {
let tokenizationData =
MppCompleteOemTokenizationData(tokenizationReceipt: self.tokenizationResponseData.tokenizationReceipt,
certificates: certificates,
nonce: nonce,
nonceSignature: nonceSignature)
MeaPushProvisioning.completeOemTokenization(tokenizationData){ (responseData, error) in
if (responseData?.isValid())! {
handler((responseData?.addPaymentPassRequest)!)
}
}
}
func addPaymentPassViewController(_ controller: PKAddPaymentPassViewController,
didFinishAdding pass: PKPaymentPass?,
error: Error?) {
self.presentedViewController?.dismiss(animated: true, completion: nil)
}
In-App Verification
Apple Pay In-App Verification provides a credit or debit card issuer the means to utilize its iOS mobile app for the verification of users and activation of a payment pass previously provisioned via Apple Wallet.
Users will find the In-App Verification feature a convenient method to activate their recently provisioned payment passes in addition to existing SMS/E-mail OTP and call center ID&V methods.
In-App Verification Sequence Diagram
Adding In-App Verification
Issuer's app must do the following to provide app-to-app verification functionality:
1. Initiate activation process
Prompt the user immediately after initial login to activate a pass that is awaiting activation. Alternatively, the app can trigger a different experience if the user is deep linked from Apple Wallet for activation via the ‘appLaunchURL’
.
INFO
"appLaunchURL":["scheme://path"]
This key is passed to the issuer’s app when the user clicks on the issuer’s app icon from the back of the pass in Apple Wallet or when the issuer’s app is opened during In-App Verification.
Defining a custom URL scheme for your app.
2. Authenticate the cardholder
Use the standard issuer's app authentication to verify the user.
3. Get activation code
Application should determine if activation state of a Secure Element Pass is set to requiresActivation.
Use MeaPushProvisioning.getActivationData(...)
method to get activation code:
MeaPushProvisioning.getActivationData(cardParams) { (data, error) in
if let activationData = data {
// Activation data received, proceed to the Pass activation
} else {
// Handle error.
}
}
4. Complete activation
Activate secureElementPass using the activation data received in previous step:
MeaPushProvisioning.activate(secureElementPass, withActivationData: activationData) { (activated, error) in
if (activated) {
// Pass activated successfully.
} else {
// Handle error.
}
}
Handle Apple Wallet Change Notifications
PassKit posts a PKPassLibraryDidChangeNotification
notification when a pass is added or removed on iPhone device, and a PKPassLibraryRemotePaymentPassesDidChangeNotification
notification is posted when a pass is added or removed on a paired Watch.
Listen to these notifications to refresh the state of Add to Apple Wallet button. These notification are received and can be handled when app is in foreground.
Start listening to change notifications.
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(self.handleChangeNotification(notification:)), name: NSNotification.Name.PKPassLibraryDidChange, object: nil)
notificationCenter.addObserver(self, selector: #selector(self.handleChangeNotification(notification:)), name: NSNotification.Name.PKPassLibraryRemotePaymentPassesDidChange, object: nil)
...
@objc func handleChangeNotification(notification: Notification) {
// The notification’s user info dictionary describes the changes.
// Refresh the state of the Add to Apple Wallet button here.
}
Stop listening to change notifications.
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.PKPassLibraryDidChange, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.PKPassLibraryRemotePaymentPassesDidChangeNotification, object: nil)
Wallet Extensions
INFO
Support for Wallet Extensions (In-App Provisioning Extensions) is mandatory.
References
- Refer to section "Wallet Extensions" in "Getting Started with Apple Pay In-App Provisioning, Verification, and Security v4" guide shared by Apple to Issuer when signing the Apple Pay contract.
- See Apple WWDC 2020 - Adding Cards to Apple Pay to learn about Apple introducing In-App Provisioning Extensions.
- See Creating an App Extension to learn about App Extensions.
Overview
Wallet Extensions (In-App Provisioning or Issuer Extensions) make it easier for users to know that they can add a payment pass to Apple Pay by improving discoverability from right within Apple Wallet.
This functionality provides users the ability to have the in-app experience of adding a payment pass, but it is initiated directly inside of Apple Wallet. The process starts and finishes within Apple Wallet and is a convenient method for users to provision their payment passes. Apple introduced Wallet Extensions in iOS 14. Issuer application needs to provide special App Extensions to Apple Wallet to be able to request and provision available cards.
INFO
- Issuer app needs to be installed and the user needs to have opened the app at least once so that Apple Wallet knows that there are payment passes available. Apple Wallet can also prompt for user authentication when adding a payment pass.
- Use of the Wallet Extension requires the same entitlement file used for In-App Provisioning:
com.apple.developer.payment-pass-provisioning
.- In order for Wallet to hide passes that user already has added to the device, passes should include the extension's bundle identifier in
associatedApplicationIdentifiers
on token service provider side.
Issuer Provisioning Extensions Sequence Diagram
Adding Wallet Extensions
Wallet Extensions feature is app extension based and lets the issuer app extend custom functionality and content, and make it available in Apple Wallet. All of the methods are triggered by Apple Wallet and the app extensions ability to enable behavior is solely based on the completion handlers and return values. This feature relies on two extensions:
- Issuer app should provide a non-UI extension (subclass of
PKIssuerProvisioningExtensionHandler
) to report on the status of the extension and the payment passes available for provisioning like when adding payment passes to Apple Pay from within the issuer app. - Issuer app should provide a UI extension (UIViewController that conforms to
PKIssuerProvisioningExtensionAuthorizationProviding
) to perform authentication of the user if the non-UI extension reports in its status that authentication is required. The UI extension is a separate screen that uses the same issuer app login credentials. UI extension is not a redirect to the issuer app.
❗❗❗ Wallet Extensions do not use a specific extension type template.
So this means you need to create some extension (for example
Intents Extension
) and remove all unnecessary auto-generated files. Leave onlyInfo.plist
andHandler
class file.
1. Creating App Extensions
Select Intents Extension as the base. Create two app extensions IssuerNonUIExtension
and IssuerUIExtension
following the steps below.
- Add an app extension to Xcode app project, choose
File > New > Target
, selectiOS > Application Extension > Intents Extension
.
- Set options for the new target. Create a unique bundle ID for the extension and add App IDs to
associatedApplicationIdentifiers
in PNO metadata.
For example,
A1B2C3D4E5.com.bank.app
A1B2C3D4E5.com.bank.app.IssuerNonUIExtension
A1B2C3D4E5.com.bank.app.IssuerUIExtension
- Activate the created scheme, if asked.
- Add
PassKit.framework
toFrameworks and Libraries
of theIssuerNonUIExtension
andIssuerUIExtension
targets, and removeIntents.framework
which is not needed. - Remove
Intents.framework
of theIssuerUIExtension
target.
2. App Extensions Configuration
- Register both app
extension bundle identifiers
in Apple Developer portal Identifiers section. Createprovisioning profiles
accordingly. - Create a new App Group and add the main app and both app extension bundle identifiers to the app group, so data can be shared between them.
- Add
mea_config
toIssuerNonUIExtension
which is consuming MPP SDK. App extension is run separately from the main app process, so SDK is initialized separately.
3. Implementing Issuer Authorization Provider Extension
IssuerAuthorizationExtensionHandler
UI extension should conform toPKIssuerProvisioningExtensionAuthorizationProviding
protocol. Apple Wallet interrogates the issuer app to determine the user's authorization status, and the authorization UI extension performs user authentication.- App UI extension has a memory limit of
60 MB
, developers are responsible to optimize the code and libraries to fit this requirement.
IssuerAuthorizationExtensionHandler.swift
import PassKit
import UIKit
@available(iOS 14.0, *)
class IssuerAuthorizationExtensionHandler: UIViewController, PKIssuerProvisioningExtensionAuthorizationProviding {
var completionHandler: ((PKIssuerProvisioningExtensionAuthorizationResult) -> Void)?
override func viewDidLoad() {
super.viewDidLoad()
// Set up view and authenticate user.
}
func authenticateUser() {
let userAuthenticated = true // User authentication outcome.
let authorizationResult: PKIssuerProvisioningExtensionAuthorizationResult = userAuthenticated ? .authorized : .canceled
self.completionHandler?(authorizationResult)
}
}
4. Implementing Issuer Extension Handler
IssuerExtensionHandler
non-UI class must be a subclass ofPKIssuerProvisioningExtensionHandler
. Issuer app must be installed and the user must open the issuer app at least once for the system to call the issuer extension handler.- App Non-UI extension has a memory limit of
55 MB
, developers are responsible to optimize the code and libraries to fit this requirement.
❗❗❗ System will create new instance of
PKIssuerProvisioningExtensionHandler
for every method callSo this means you can not share data between method calls via private class properties!!!
But you may use another approaches, like global variables outside of the class.
IssuerExtensionHandler.swift
import PassKit
import MeaPushProvisioning
@available(iOS 14.0, *)
class IssuerExtensionHandler: PKIssuerProvisioningExtensionHandler {
func status(completion: @escaping (PKIssuerProvisioningExtensionStatus) -> Void) {
// Determines if there is a pass available and if adding the pass requires authentication.
// The completion handler takes a parameter status of type PKIssuerProvisioningExtensionStatus that indicates
// whether there are any payment cards available to add as Wallet passes.
// PKIssuerProvisioningExtensionStatus has the following properties:
// requiresAuthentication: Bool - authorization required before passes can be added.
// passEntriesAvailable: Bool - passes will be available to add (at least one).
// remotePassEntriesAvailable: Bool - passes will be available to add on the remote device (at least one).
// The handler should be invoked within 100ms. The extension is not displayed to the user in Wallet if this criteria is not met.
}
func passEntries(completion: @escaping ([PKIssuerProvisioningExtensionPassEntry]) -> Void) {
// Finds the list of passes available to add to an iPhone.
// The completion handler takes a parameter entries of type Array<PKIssuerProvisioningExtensionPassEntry> representing
// the passes that are available to add to Wallet.
// Call MeaPushProvisioning.initializeOemTokenization(cardParams, completionHandler: { (data: MppInitializeOemTokenizationResponseData, error: Error?) in ... }) and initialize PKIssuerProvisioningExtensionPaymentPassEntry for each card that can be added to Wallet and add to the array.
// Use addPaymentPassRequestConfiguration of MppInitializeOemTokenizationResponseData object to set addRequestConfiguration.
// PKIssuerProvisioningExtensionPaymentPassEntry has the following properties:
// art: CGImage - image representing the card displayed to the user. The image must have square corners and should not include personally identifiable information like user name or account number.
// title: String - a name for the pass that the system displays to the user when they add or select the card.
// identifier: String - an internal value the issuer uses to identify the card. This identifier must be stable.
// addRequestConfiguration: PKAddPaymentPassRequestConfiguration - the configuration data used for setting up and displaying a view controller that lets the user add a payment pass.
// Do not return payment passes that are already present in the user’s pass library.
// The handler should be invoked within 20 seconds or will be treated as a failure and the attempt halted.
}
func remotePassEntries(completion: @escaping ([PKIssuerProvisioningExtensionPassEntry]) -> Void) {
// Finds the list of passes available to add to an Apple Watch.
// The completion handler takes a parameter entries of type Array<PKIssuerProvisioningExtensionPassEntry> representing
// the passes that are available to add to Apple Watch.
// Call MeaPushProvisioning.initializeOemTokenization(cardParams, completionHandler: { (data: MppInitializeOemTokenizationResponseData, error: Error?) in ... }) and initialize PKIssuerProvisioningExtensionPaymentPassEntry for each card that can be added to Wallet and add to the array.
// Use addPaymentPassRequestConfiguration of MppInitializeOemTokenizationResponseData object to set addRequestConfiguration.
// PKIssuerProvisioningExtensionPaymentPassEntry has the following properties:
// art: CGImage - image representing the card displayed to the user. The image must have square corners and should not include personally identifiable information like user name or account number.
// title: String - a name for the pass that the system displays to the user when they add or select the card.
// identifier: String - an internal value the issuer uses to identify the card. This identifier must be stable.
// addRequestConfiguration: PKAddPaymentPassRequestConfiguration - the configuration data used for setting up and displaying a view controller that lets the user add a payment pass.
// Do not return payment passes that are already present in the user’s pass library.
// The handler should be invoked within 20 seconds or will be treated as a failure and the attempt halted.
}
func generateAddPaymentPassRequestForPassEntryWithIdentifier(
_ identifier: String,
configuration: PKAddPaymentPassRequestConfiguration,
certificateChain certificates: [Data],
nonce: Data,
nonceSignature: Data,
completionHandler completion: @escaping (PKAddPaymentPassRequest?) -> Void) {
// Creates an object with the data the system needs to add a card to Apple Pay.
// identifier: String - an internal value the issuer uses to identify the card.
// configuration: PKAddPaymentPassRequestConfiguration - the configuration the system uses to add a secure pass. This configuration is prepared in methods passEntriesWithCompletion: and remotePassEntriesWithCompletion:.
// certificates, nonce, nonceSignature - parameters are generated by Apple Pay identically to PKAddPaymentPassViewControllerDelegate methods.
// The completion handler is called by the system for the data needed to add a card to Apple Pay.
// This handler takes a parameter request of type PKAddPaymentPassRequestConfiguration that contains the card data the system needs to add a card to Apple Pay.
// Call MeaPushProvisioning.completeOemTokenization(tokenizationData, completionHandler: { (data: MppCompleteOemTokenizationResponseData, error: Error?) in ... }), and
// use addPaymentPassRequest of MppCompleteOemTokenizationResponseData to set request in completion handler.
// The continuation handler must be called within 20 seconds or an error is displayed.
// Subsequent to timeout, the continuation handler is invalid and invocations is ignored.
}
}
5. Updating Extension's Info.plist
- Modify
NSExtension
dictionary in extension'sInfo.plist
, deleteNSExtensionAttributes
entry.
NSExtensionPointIdentifier and NSExtensionPrincipalClass should be specified in the extension Info.plist
properties dictionary:
Non-UI App Extension
Values:
Key | Type | Value |
---|---|---|
NSExtensionPointIdentifier | String | com.apple.PassKit.issuer-provisioning |
NSExtensionPrincipalClass | String | $(PRODUCT_MODULE_NAME).IssuerExtensionHandler |
UI App Extension
Values:
Key | Type | Value |
---|---|---|
NSExtensionPointIdentifier | String | com.apple.PassKit.issuer-provisioning.authorization |
NSExtensionPrincipalClass | String | $(PRODUCT_MODULE_NAME).IssuerAuthorizationExtensionHandler |
6. Setting Code Signing Entitlements
- Issuer Extensions use the same entitlement file used for issuer app In-App Provisioning.
Debugging
Use 'setDebugLoggingEnabled' method to enable/disable logging to console. Use 'versionName' and 'versionCode' methods to check the version of the SDK, when necessary.
import MeaPushProvisioning
...
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
MeaPushProvisioning.setDebugLoggingEnabled(true)
print(String(format: "SDK version: %@, code: %@", MeaPushProvisioning.versionName(), MeaPushProvisioning.versionCode()))
...
return true
}
Testing in Sandbox Mode
Apple Pay In-App Provisioning entitlement com.apple.developer.payment-pass-provisioning
only works with distribution provisioning profiles, which means that even after you obtain it, the only way to test the end-to-end push provisioning flow is by first distributing the app via TestFlight or the App Store.
Apple Pay Sandbox Testing: Sandbox Testing
References
Updated about 1 year ago