Apple Pay Integration
Prerequisite
- Create Apple Pay merchant ID.
- Create a Payment Processing certificate.
- Enable Apple Pay in Xcode.
For instructions on these Apple Pay setups, see:
Apple servers use the certificate to encrypt payment data and Netaxept to decrypt and process payment.
For further information about getting Netaxept CSR certificate, please refer to files below:
Netaxept - Apple Pay Payment Flow
Netaxept - Apple Pay Integration doc
Step-by-step process
- In your Apple Developer Account site, get your Merchant ID (not your Netaxept Merchant ID).
- In your Netaxept ADMIN site, get Apple Pay certificate following the instructions given.
- In your project, enable Apple Pay capability with the correct Apple Pay Merchant ID you just created.
- Navigate to your Apple Pay certificate obtained in step 1 and add the certificate to KeyChain (e.g. by double-clicking the file).
- Use Pia SDK for Apple Pay according to the development guide shown below and in the PiaSample project.
Apple Pay - Checkout Overview
Apple Pay with PiA SDK
Step 1: Check Apple Pay Support
First, check if Apple Pay is supported by the device or that user is not restricted to use Apple Pay due to e.g. Parental control settings. The app should also check supported networks which user can make payments through.
/// Apple's UI design guidelines encourage checking this condition
/// before displaying 'Buy with Pay' button.
guard PKPaymentAuthorizationViewController.canMakePayments() else {
return // Not supported on device / User is restricted
}
guard PKPaymentAuthorizationViewController.canMakePayments(
usingNetworks: supportedApplePayNetworks) else {
presentAppleWalletSetupEnquiry()
return
}
If the user does not have a supported card for the payment, the application may lead user to a different payment method or open Wallet app so that the user can add a card in Wallet as follows:
// MARK: Apple Wallet Setup
func presentAppleWalletSetupEnquiry() {
let alert = UIAlertController(
title: .titleAppleWalletNotSetup,
message: .messageOpenAppleWalletApp,
preferredStyle: .alert)
let cancel = UIAlertAction(title: .actionCancel, style: .cancel, handler: nil)
let openWalletsApp = UIAlertAction(title: .actionSetup, style: .default) { _ in
if let walletAppURL = URL(string: "shoebox://url-scheme"),
UIApplication.shared.canOpenURL(walletAppURL) {
UIApplication.shared.openURL(walletAppURL)
} else {
self.navigationController.showAlert(
title: .titleCannotOpenAppleWallet,
message: .messageManuallyOpenAppleWallet)
}
}
[cancel, openWalletsApp].forEach(alert.addAction(_:))
self.navigationController.present(alert, animated: true, completion: nil)
}
Step 2: Present Apple Pay Payment Authorization Sheet
Start by creating a payment request (an instance of PKPaymentRequest
from Apple’s PassKit framework) using PiaSDK’s helper.
The helper covers all the mandatory parameters for a valid payment request. Based on the requirements of an application,
the request can be modified to include more information. e.g. The sample app further modifies the request by including
shipping address in the payment request.
let request = PiaSDK.makeApplePayPaymentRequest(
for: supportedApplePayNetworks,
countryCode: "NO", // Norway
applePayMerchantID: "ApplePay merchant ID",
merchantCapabilities: .capability3DS,
currencyCode: "EUR",
summeryItems: [
PKPaymentSummaryItem(label: "Item name", amount: itemCost)
]
)
guard let controller = PKPaymentAuthorizationViewController(paymentRequest: request) else {
return
}
controller.delegate = self
present(controller, animated: true, completion: nil)
Step 3: Implement The Payment Authorization Delegate
The next step is to implement the two required delegate methods in PKPaymentAuthorizationViewControllerDelegate
.
Following user’s approval to proceed with the payment, didAuthorizePayment
delegate method is called with the payment
object (an instance of PKPayment
). Pia SDK provides a helper to obtain a token (UTF-8 string) parsing this object into the accepted
format by Netaxept SOAP API. Pass this payment data to your merchant backend and essentially to Netaxept.
The sample app implements the delegate method as follows:
func paymentAuthorizationViewController(
_ controller: PKPaymentAuthorizationViewController,
didAuthorizePayment payment: PKPayment,
completion: @escaping (PKPaymentAuthorizationStatus) -> Void) {
let token = PiaSDK.netaxeptSOAPPaymentData(from: payment.token)
api.registerApplePay(for: orderDetails, token: token) { [weak self] result in
guard case .success(let transaction) = result else {
self?.transaction = nil
completion(PKPaymentAuthorizationStatus.failure)
return
}
self?.api.commitTransaction(transaction.transactionId , commitType: .payment) { result in
switch result {
case .success(_):
self?.transaction = transaction
completion(.success)
case .failure(_):
self?.transaction = nil
completion(.failure)
}
}
}
}
Following invoking of the completion block in didAuthorizePayment
delegate method, PassKit
notifies completion
via paymentAuthorizationViewControllerDidFinish
delegate call. The authorization payment sheet should be
dismissed in this delegate call.
func paymentAuthorizationViewControllerDidFinish(_ controller: PKPaymentAuthorizationViewController) {
defer { self.transaction = nil }
controller.presentingViewController?.dismiss(animated: true, completion: nil)
}
Note: This delegate is called directly (without didAuthorizePayment
preceding delegate call) if user cancels payment
in the payment authorization sheet.
(If the payment process contains shipping contact address, its necessary to implement the associated delegate methods in the protocol in order to adjust shipping cost accordingly)
Netaxept backend integration request body - Apple Pay payment registration:
{
"paymentData" : "string",
"paymentMethodActionList" : {
"PaymentMethod" : "ApplePay"
}
}
The paymentData should contain th encrypted Payment Data from Apple pay of the following format:
{
"paymentData" : {
"version" : "string",
"data" : "string",
"signature" : "string",
"header" : {
"ephemeralPublicKey" : "string",
"publicKeyHash" : "string",
"transactionId" : "string"
}
},
"paymentMethod" : {
"displayName" : "string",
"network" : "string",
"type" : "string"
},
"transactionIdentifier" : "string"
}
Note: Netaxept backend integration tips can be found in 5.4 Backend Tips, Request body - Apple Pay payment registration section