Integrating Apple Pay into your iOS App

Apple Pay is arguably the best form of payment in an iOS app. It’s easy and efficient for both the user and the developer. Long gone are the days of typing in your credit card info — users can now quickly make transactions through ApplePay and your app should support this service.

Note: To implement Apple Pay, you must have an Apple Developer’s Account. Learn more about the developer’s program.

Let’s Get Started

First, download the starter project here. Take a look at this project, in the ViewController.swift file, we have the Shoe struct:

struct Shoe {
var name: String
var price: Double
}

We’ll use this along with the array of Shoes to populate our picker view and retrieve the price later on (feel free to change the shoes if you’d like to).

To get started with Apple Pay, we need to create a merchant ID in the developer portal. This ID will allow Apple to identify your app as a “merchant” for purchases. Before we create one, you’ll need a unique bundle identifier for your app. In the app settings, go to the identity and put your own bundle identifier as you would if you were making your own app (e.g. com.yourname.app-name).

Next, head over to the developer member center and select “Certificates, Identifiers, and Profiles” in the menu. Select “Merchant IDs” from the left menu. Tap the plus “+” on the top right-hand corner.

In the description, enter the name of your app, such as “Shoe Store”. In the identifier, type “merchant.” + your bundle identifier. For me, that would be “merchant.com.pranavwadhwa.Shoe-Store”. Tap “Continue” and then “Register”.

For the next part, we’re going to need a certificate signing request (CSR). Open up Keychain Access, and from the top menu select “Certificate Assistance” and “Request a Certificate from a Certificate Authority” as shown in the picture.

Put your email address in the “User Email Address” field and select the “saved to disk” option for your request (you can leave the CA email address empty).

We’re almost back to coding! We just need to create a payment processing certificate, which will be used to secure transaction data. Go back to the member center and select “All Certificates” from the side menu. Tap the plus “+” button on the top right corner to create a new certificate.

Under “Production”, select “Apple Pay Payment Processing Certificate”.

Then, select the merchant ID you created earlier. Next, under “Apple Pay Payment Processing Certificate”, tap on “Create Certificate”. Apple will ask, “Will payments associated with this Merchant ID be processed exclusively in China?” Select yes. Continue through the process, and it will ask you to upload your CSR that you saved from Keychain Access.

Great job! You created your certificate. Download it and save it with your project. Then, double click on it, and it will be processed in Keychain Access.

Let’s head back over to Xcode and enable Apple Pay there. Under “Capabilities”, turn on Apple Pay, and ensure that you have selected the correct merchant ID (If you don’t see yours, try tapping the + and enter the name of your merchant ID).

Time to Start Coding

Open the ViewController.swift file, and inside the class, add the following function:

func displayDefaultAlert(title: String?, message: String?) {
    let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
let okAction = UIAlertAction(title: “Ok”, style: .default, handler: nil)
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
}

If you’ve used alerts in the past, you’ll know that this will simply display an alert with a simple dismiss action. We’ll use this to display info to the user as they go through the Apple Pay process. Now, go to the buyShoeTapped method:

@IBAction func buyShoeTapped(_ sender: UIButton) {
    // Open Apple Pay purchase
}

First, let’s find the current shoe that the user has picked and create a PKPaymentSummaryItem using that info. Add the following lines:

@IBAction func buyShoeTapped(_ sender: UIButton) {
    let selectedIndex = shoePickerView.selectedRow(inComponent: 0)
let shoe = shoeData[selectedIndex]
let paymentItem = PKPaymentSummaryItem.init(label: shoe.name, amount: NSDecimalNumber(value: shoe.price))
}

This will find the selected row in the picker (as we only have one component), get the corresponding shoe, and create a payment item using that information. We will use this item when filling out the payment request. Next, we have to declare a list of methods the user can pay with. In order to do that, we have to add

import PassKit

at the top of the file. Now, back in our buyShoeTapped function, let’s identify our payment methods:

@IBAction func buyShoeTapped(_ sender: UIButton) {
...
    let paymentNetworks = [PKPaymentNetwork.amex, .discover, .masterCard, .visa]
}

With this, we have to check if the user can make payments with one of these networks and let them know if they can’t:

if PKPaymentAuthorizationViewController.canMakePayments(usingNetworks: paymentNetworks) {
} else {
    displayDefaultAlert(title: "Error", message: "Unable to make Apple Pay transaction.")
}

Now, we’re going to create a PKPaymentRequest that will contain information about the transaction. Add the following:

if PKPaymentAuthorizationViewController.canMakePayments(usingNetworks: paymentNetworks) {
let request = PKPaymentRequest()
request.currencyCode = “USD” // 1
request.countryCode = “US” // 2
request.merchantIdentifier = “merchant.com.pranavwadhwa.Shoe-Store” // 3
request.merchantCapabilities = PKMerchantCapability.capability3DS // 4
request.supportedNetworks = paymentNetworks // 5
request.paymentSummaryItems = [paymentItem] // 6
}

Let’s take a close look at this.

Lines 1 and 2 establish the currency and country code — you can change these to fit your app.

Line 3 verifies your merchant ID. Make sure to change line 3 and input the name of the merchant ID you created.

Line 4 checks the type of transaction. PKMerchantCapability.capability3DS uses the 3-D Secure protocol, a secure way of processing debit and credit cards.

Lastly, lines 5 and 6 use the payment networks and the payment item we created earlier. This is only the basic information; you can add more information in the request, such as the billing information, shipping methods, and supported countries. Check the full list of properties of the PKPaymentRequest. if needed.

Finally, let’s present the View Controller to the user.

if PKPaymentAuthorizationViewController.canMakePayments(usingNetworks: paymentNetworks) {
...
    guard let paymentVC = PKPaymentAuthorizationViewController(paymentRequest: request) else {
    displayDefaultAlert(title: "Error", message: "Unable to present Apple Pay authorization.")
return
}
    paymentVC.delegate = self
self.present(paymentVC, animated: true, completion: nil)
}

You’ll see an error — don’t panic, we’ll fix it soon. Here, we’re using a guard statement to safely unwrap the PKPaymentAuthorizationViewController, and displaying it accordingly. The error we’re facing is that we assigned the paymentVC’ s delegate to the ViewController , but the ViewController does not currently conform to that protocol. Let’s fix that. Below the class, let’s create an extension:

class ViewController: UIViewController {
...
}
extension ViewController: PKPaymentAuthorizationViewControllerDelegate {
    func paymentAuthorizationViewControllerDidFinish(_ controller: PKPaymentAuthorizationViewController) {
    }
    func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewController, didAuthorizePayment payment: PKPayment, handler completion: @escaping (PKPaymentAuthorizationResult) -> Void) {
    }
}

We’re almost done! We just need to add these two functions. In the first one, paymentAuthorizationViewControllerDidFinish, add the following:

dismiss(animated: true, completion: nil)

This will dismiss the payment view controller after it’s done. In the second function, didAuthorizePayment, add the following to dismiss the view controller (if it hasn’t already been dismissed by the didFinish function) and display a success message to the user:

dismiss(animated: true, completion: nil)
displayDefaultAlert(title: "Success!", message: "The Apple Pay transaction was complete.")

We’re finished! Run the app, and you’ll see the payment view controller.

Unfortunately, it won’t actually make the transaction yet as we haven’t added a backend to receive the payment. If you want to add that backend, look into backing Apple Pay with Stripe.


Follow us on social media platforms:
Facebook: facebook.com/AppCodamobile/
Twitter: twitter.com/AppCodaMobile
Instagram: instagram.com/AppCodadotcom

If you enjoyed this article, please click the 👏 button and share to help others find it! Feel free to leave a comment below.