Implementation Guide
Before starting implementation you should have completed Installation of the MPP SDK.
MPP SDK helps the Issuer with Apple Pay In-App Provisioning implementation. Apple Pay In-App Provisioning provides a credit or debit card issuer the ability to initiate the card provisioning process for Apple Pay directly from the Issuer's iOS app.
Cardholders will find the In-App Provisioning feature an extremely convenient method to provision their payment details into their iOS devices by avoiding the need to input card details manually. Apple Pay Wallet needs to be setup before payment card is provisioned to it. This is done via the PassKit framework. PassKit in Apple Developer Documentation.
Adding payment passes requires a special entitlement issued by Apple, see MPP SDK Installation Step 6.
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.
- swift
- objective-c
let cardId = "<value>"
let cardSecret = "<value>"
let cardParams = MppCardDataParameters.init(cardId: cardId, cardSecret: cardSecret)
NSString *cardId = @"<value>";
NSString *cardSecret = @"<value>";
MppCardDataParameters *cardParams = [MppCardDataParameters cardDataParametersWithCardId:cardId cardSecret:cardSecret];
or
- swift
- objective-c
let encryptedCardData = "<value>"
let publicKeyFingerprint = "<value>"
let encryptedKey = "<value>"
let initialVector = "<value>"
let cardParams = MppCardDataParameters.init(encryptedCardData: encryptedCardData,
publicKeyFingerprint: publicKeyFingerprint,
encryptedKey: encryptedKey,
initialVector: initialVector)
NSString *encryptedCardData = @"<value>";
NSString *publicKeyFingerprint = @"<value>";
NSString *encryptedKey = @"<value>";
NSString *initialVector = @"<value>";
MppCardDataParameters *cardParams =
[MppCardDataParameters cardDataParametersWithEncryptedCardData: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.
- swift
- objective-c
import MeaPushProvisioning
...
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
MeaPushProvisioning.loadConfig("custom_config_name")
...
return true
}
#import <MeaPushProvisioning/MeaPushProvisioning.h>
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[MeaPushProvisioning loadConfig:@"custom_config_name"];
...
return YES;
}
MPP SDK raises an exception if configuration file is missing, broken or otherwise fails to load.
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.
primaryAccountIdentifier
1. 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.
2. 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.
3. 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.
- swift
- objective-c
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.
// ...
}
}
}
}
BOOL isPassLibraryAvailable = [PKPassLibrary isPassLibraryAvailable];
BOOL canAddPaymentPass = [PKAddPaymentPassViewController canAddPaymentPass];
if (isPassLibraryAvailable && canAddPaymentPass) {
[MeaPushProvisioning initializeOemTokenization:cardParams completionHandler:^(MppInitializeOemTokenizationResponseData *data, NSError *error) {
if ([data isValid]) {
BOOL canAddPaymentPassWithPAI = YES;
NSString *primaryAccountIdentifier = data.primaryAccountIdentifier;
// Field primaryAccountIdentifier is always empty for the first tokenization.
if (primaryAccountIdentifier.length > 0) {
if (@available(iOS 13.4, *)) {
canAddPaymentPassWithPAI = [MeaPushProvisioning canAddSecureElementPassWithPrimaryAccountIdentifier:primaryAccountIdentifier];
} else {
canAddPaymentPassWithPAI = [MeaPushProvisioning canAddPaymentPassWithPrimaryAccountIdentifier:primaryAccountIdentifier];
}
}
if (canAddPaymentPassWithPAI) {
self.tokenizationResponseData = data;
// 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.
- swift
- objective-c
let addPassButton = PKAddPassButton(addPassButtonStyle: PKAddPassButtonStyle.black)
addPassButton.frame = CGRect(x:45.0, y: 340.0, width: 320, height: 20)
view.addSubview(addPassButton)
PKAddPassButton *addPassButton = [PKAddPassButton addPassButtonWithStyle:PKAddPassButtonStyleBlack];
[self.view addSubview:addPassButton];
[addPassButton addTarget:self action:@selector(addPassButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
Show or Hide Add to Apple Wallet Button
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 if App ID
(TeamID.BundleID
) is specified in associatedApplicationIdentifiers
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
Read further only when app needs to detect if PKPaymentPass
or PKSecureElementPass
can be added specifically to Apple Wallet on iPhone or Apple Watch. Use for Apple Watch only when it is paired to iPhone.
1. 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.
2. Detect if Apple Watch is paired with iPhone.
- swift
- objective-c
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.
}
}
#import <WatchConnectivity/WatchConnectivity.h>
...
if ([WCSession isSupported]) { // Check if the iPhone supports Watch Connectivity session handling.
WCSession *session = [WCSession defaultSession];
[session setDelegate:self];
[session activateSession]; // Activate the session, asynchronous call to delegate method below.
}
...
- (void)session:(WCSession *)session activationDidCompleteWithState:(WCSessionActivationState)activationState error:(NSError *)error
{
if (activationState == WCSessionActivationStateActivated && [session isPaired]) {
// Apple Watch is paired with iPhone.
}
}
3. Check if PKPaymentPass
or PKSecureElementPass
is already added to Apple Wallet on iPhone or Apple Watch:
- Apple Wallet on iPhone:
- swift
- objective-c
// 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")
// Before iOS 13.4
BOOL cardExists = [MeaPushProvisioning paymentPassExistsWithPrimaryAccountIdentifier:@"<primaryAccountIdentifier>"];
BOOL cardExists = [MeaPushProvisioning paymentPassExistsWithPrimaryAccountNumberSuffix:@"4321"];
// iOS 13.4+
BOOL cardExists = [MeaPushProvisioning secureElementPassExistsWithPrimaryAccountIdentifier:@"<primaryAccountIdentifier>"];
BOOL cardExists = [MeaPushProvisioning secureElementPassExistsWithPrimaryAccountNumberSuffix:@"4321"]; // 13.4+
- Apple Watch:
- swift
- objective-c
// 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")
// Before iOS 13.4
BOOL cardExists = [MeaPushProvisioning remotePaymentPassExistsWithPrimaryAccountIdentifier:@"<primaryAccountIdentifier>"];
BOOL cardExists = [MeaPushProvisioning remotePaymentPassExistsWithPrimaryAccountNumberSuffix:@"4321"];
// iOS 13.4+
BOOL cardExists = [MeaPushProvisioning remoteSecureElementPassExistsWithPrimaryAccountIdentifier:@"<primaryAccountIdentifier>"];
BOOL cardExists = [MeaPushProvisioning remoteSecureElementPassExistsWithPrimaryAccountNumberSuffix:@"4321"]; // 13.4+
Pay with Apple Pay Button
When card is added to Apple Wallet, instead of hiding Add to Apple Wallet button the app can show Pay with Apple Pay button, tapping the button can present a specific card for payment. Use PKPassLibrary.present(pass: PKSecureElementPass) to select the card for payment.
Use PKPaymentButton class to create a Pay with Apple Pay button. iOS SDK provides a control with the correct appearance.
- swift
- objective-c
let payButton = PKPaymentButton(paymentButtonType: PKPaymentButtonType.inStore, paymentButtonStyle: PKPaymentButtonStyle.black)
payButton.frame = CGRect(x:45.0, y: 340.0, width: 320, height: 20)
view.addSubview(payButton)
PKPaymentButton *payButton = [PKPaymentButton buttonWithType:PKPaymentButtonTypeInStore style:PKPaymentButtonStyleBlack];
[self.view addSubview:payButton];
[payButton addTarget:self action:@selector(payButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
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.
- swift
- objective-c
let addPaymentPassRequestConfiguration = self.tokenizationResponseData?.addPaymentPassRequestConfiguration
addPaymentPassRequestConfiguration?.cardholderName = "Cardholder Name"
let paymentPassController =
PKAddPaymentPassViewController.init(requestConfiguration: addPaymentPassRequestConfiguration!, delegate: self)
self.present(paymentPassController!, animated: true, completion: nil)
PKAddPaymentPassRequestConfiguration *addPaymentPassRequestConfiguration = [self.tokenizationResponseData addPaymentPassRequestConfiguration];
[addPaymentPassRequestConfiguration setCardholderName:@"Cardholder Name"];
PKAddPaymentPassViewController *paymentPassController =
[[PKAddPaymentPassViewController alloc] initWithRequestConfiguration:addPaymentPassRequestConfiguration delegate:self];
[self presentViewController:paymentPassController animated:YES 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.
- swift
- objective-c
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)
}
- (void)addPaymentPassViewController:(PKAddPaymentPassViewController *)controller
generateRequestWithCertificateChain:(NSArray<NSData *> *)certificates
nonce:(NSData *)nonce
nonceSignature:(NSData *)nonceSignature
completionHandler:(void(^)(PKAddPaymentPassRequest *request))handler
{
MppCompleteOemTokenizationData *tokenizationData =
[MppCompleteOemTokenizationData tokenizationDataWithTokenizationReceipt:self.tokenizationResponseData.tokenizationReceipt certificates:certificates nonce:nonce nonceSignature:nonceSignature];
[MeaPushProvisioning completeOemTokenization:tokenizationData completionHandler:^(MppCompleteOemTokenizationResponseData *data, NSError *error) {
BOOL valid = [data isValid];
if (valid && !error) {
PKAddPaymentPassRequest *addPaymentPassRequest = [data addPaymentPassRequest];
handler(addPaymentPassRequest);
}
}];
}
- (void)addPaymentPassViewController:(PKAddPaymentPassViewController *)controller didFinishAddingPaymentPass:(PKPaymentPass *)pass error:(NSError *)error
{
[self.presentedViewController dismissViewControllerAnimated:YES 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 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.
Issuers can implement In-App Verification using one of the two methods:
- Obtaining activation data with cryptographic OTP and passing to Apple Wallet
- Server-side activation
Activation Data with Cryptographic OTP
This method uses a cryptographic value that is generated by the issuer and is validated by TSP.
Sequence Diagram
Implementation
Issuer's app must do the following to provide app-to-app verification functionality:
1. Initiate activation process
Apple Wallet application redirects the end user to the issuer application and the issuer application has to check that it is launched from the Apple Wallet. Apple Wallet uses appLaunchURL
with appended query parameters that identify the pass to be activated.
"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.
For example:
scheme://path?passTypeIdentifier=paymentpass.com.apple&action=verify&serialNumber=pr.prod.pod1_1...
Use passTypeIdentifier
and serialNumber
to identify selected pass for activation.
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
.
2. Authenticate the cardholder
Use the standard issuer's app authentication to verify the user.
3. Find pass with specific serial number
Use method MeaPushProvisioning.secureElementPassWithSerialNumber(serialNumber)
to find the selected pass for activation, and determine if activation state of a Secure Element Pass is set to requiresActivation
.
4. Get activation data
Find the related card for specific pass, fetch cardId
, cardSecret
, and use MeaPushProvisioning.getActivationData(...)
method to get the activation data:
- swift
- objective-c
MeaPushProvisioning.getActivationData(cardParams) { (data, error) in
if let activationData = data {
// Activation data received, proceed to the Pass activation
} else {
// Handle error.
}
}
[MeaPushProvisioning getActivationData:cardParams
completionHandler:^(NSString * _Nullable activationData, NSError * _Nullable error) {
if (activationData) {
// Activation data received, proceed to card activation
} else {
// Handle error
}
}];
5. Complete activation
Activate secureElementPass
using the activation data received in previous step:
- swift
- objective-c
MeaPushProvisioning.activate(secureElementPass, withActivationData: activationData) { (activated, error) in
if (activated) {
// Pass activated successfully.
} else {
// Handle error.
}
}
[MeaPushProvisioning activateSecureElementPass:secureElementPass
withActivationData:activationData
completionHandler:^(BOOL activated, NSError * _Nullable error) {
if (activated) {
// Pass activated successfully.
} else {
// Handle Error
}
}];
Server-side Activation
This method allows to activate the pass using TSP APIs.
Sequence Diagram
Implementation
1. Initiate activation process
This step is identical to other activation method, see Initiate activation process.
2. Authenticate the cardholder
Use the standard issuer's app authentication to verify the user.
3. Find pass with specific serial number
Use method MeaPushProvisioning.secureElementPassWithSerialNumber(serialNumber)
to find the selected pass for activation, and determine if activation state of a Secure Element Pass is set to requiresActivation
.
4. Complete activation
Use method MeaPushProvisioning.activateSecureElementPass(secureElementPass, paymentNetwork)
to activate the pass.
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.
- swift
- objective-c
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.
}
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self selector:@selector(handleChangeNotification:) name:PKPassLibraryDidChangeNotification object:nil];
[notificationCenter addObserver:self selector:@selector(handleChangeNotification:) name:PKPassLibraryRemotePaymentPassesDidChangeNotification object:nil];
...
- (void)handleChangeNotification:(NSNotification *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.
- swift
- objective-c
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.PKPassLibraryDidChange, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.PKPassLibraryRemotePaymentPassesDidChangeNotification, object: nil)
[[NSNotificationCenter defaultCenter] removeObserver:self name:PKPassLibraryDidChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:PKPassLibraryRemotePaymentPassesDidChangeNotification object:nil];
Debugging
Apple Wallet Logging
- Install
WalletFull.mobileconfig
profile by following Wallet Logging Instructions. - Record Sysdiagnose Apple Pay logs by following the official documentation "Getting Started with Apple Pay: In-App Provisioning, Verification, Security, and Wallet Extensions - 9. Troubleshooting".
SDK Logging
Use setDebugLoggingEnabled
method to enable/disable logging to console. Use versionName
and versionCode
methods to check the version of the SDK, when necessary.
- swift
- objective-c
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
}
#import <MeaPushProvisioning/MeaPushProvisioning.h>
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[MeaPushProvisioning setDebugLoggingEnabled:YES];
NSLog(@"SDK version: %@, code: %@", [MeaPushProvisioning versionName], [MeaPushProvisioning versionCode]);
...
return YES;
}
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