API Documentation Apple Pay

Apple Pay  is a revolutionary purchasing experience for iOS. It is currently available for US and UK customers charging USD and GBP on supported iOS devices such as the iPhone 6. This guide explains how to process Apple Pay transactions with CityPay.

How it works

Apple Pay allows customers to make purchases in iOS mobile apps using Touch ID on the latest Apple devices. Users are able to add their credit or debit card information using a tokenisation service which encrypts the card number. The service uses a device specific identifier known as the DPAN in place of the card number to handle transactions securely.


Apple Pay requires the customer's card issuing bank to be part of the Apple Pay program with Visa, MasterCard and American Express supporting the processing network. 

To integrate with CityPay and Apple Pay, you will need a merchant account via CityPay and a developer account with Apple.


Before you can use Apple Pay, you will need to configure a certificate and a merchant identifier. To do this

  1. Sign in to your Apple Developer account and browse to  Member Center
  2. Go to Certificates, Identifiers & Profiles and click on Identifiers > Merchant IDs
  3. Create and register a new Merchant ID with Apple
  4. You will need to download a CSR (certificate signing request) from CityPay (Currently this is handled via support@citypay.com). 
  5. Generate a new Apple Pay Certificate in the Apple Developer portal by
    1. Selecting Production Certificates
    2. Apple Pay Certificate
    3. select the Merchant ID you created
    4. Upload the CSR to Apple
  6. Download the created Apple Pay Certificate and return this to CityPay (via support@citypay.com). At this stage, we will configure your account with the generated certificate to allow us to decrypt payments.

The Apple Pay Merchant ID must correspond with your entitlements and the certificate registered with CityPay

Development Environment

To configure an App in Xcode, enable Apple Pay under the Targets Capabilities

Select your merchant Id configured previously

Apple have specific identity and user experience guidelines which may be enforced during the App Store review process. You should consult these guidelines as well as Apple's developer information guide when designing your app.

CityPay iOS SDK

CityPay provide a development kit for iOS which integrates directly with Apple Pay. The SDK supports integration with a PKPaymentAuthorizationViewController and allows you to adapt processing to a CityPayRequest instance.

This integration method was chosen to provide full control and configuration of the Apple Pay workflow whilst simplifying the transactional process to our implementation.

Integration Guide

Setting up the payment button

The payment button should only be displayed if the user can make payments. There are 2 levels to check 

  1. canMakePayments determines that the device is capable of conducting ApplePay payments; and

  2. canMakePaymentsUsingNetworks determines that the device can use the given network. The actual decision on this is complex and determined by Apple and the Card Issuer. 


import PassKit
import UIKit
import CityPayKit

class MyApplePayController: UIViewController {
	let SupportedPaymentNetworks = [PKPaymentNetworkAmex, PKPaymentNetworkVisa, PKPaymentNetworkMasterCard]

	@IBOutlet weak var applePayButton: PKPaymentButton!
	override func viewDidLoad() {
        if (PKPaymentAuthorizationViewController.canMakePayments() &&
            PKPaymentAuthorizationViewController.canMakePaymentsUsingNetworks(SupportedPaymentNetworks)) {
            applePayButton.hidden = false
        } else {
            applePayButton.hidden = true
    // example purchase function which creates a payment on touch of the payment button
    @IBAction func purchase(sender: PKPaymentButton) {

Initialise a PKPaymentRequest

Apple Pay is centralised around the PKPaymentRequest which should be used to initialise the Apple Pay payment.

// initialise a PK Payment Request
let request = PKPaymentRequest()
request.merchantIdentifier = "YOUR_APPLE_PAY_MERCHANT_ID"
request.supportedNetworks = SupportedPaymentNetworks
// All CityPay payments are performed with 3DS
request.merchantCapabilities = PKMerchantCapability.Capability3DS
request.countryCode = "GB"
request.currencyCode = "GBP"
// determine required fields e.g. based on the selected item type
switch (demo.ItemType) {
	case ItemType.Delivered:
		request.requiredShippingAddressFields = PKAddressField.PostalAddress
	case ItemType.Electronic:
		request.requiredShippingAddressFields = PKAddressField.Email
// calculate shipping if needed
let shippingPrice: NSDecimalNumber = NSDecimalNumber(string: "5.0")
request.paymentSummaryItems = [
	PKPaymentSummaryItem(label: swag.title, amount: swag.price),
	PKPaymentSummaryItem(label: "Shipping", amount: shippingPrice),
	PKPaymentSummaryItem(label: "CityPay", amount: swag.price.decimalNumberByAdding(shippingPrice))

The following recommendations are made

  • Use the country code where your business is located
  • The currency code must match what you can process with your CityPay merchant id.
  • Only the  PKMerchantCapability.Capability3DS is supported, EMV is for in store payments
  • SupportedPaymentNetworks should match what your able to process. Note that Apple do not allow filtering by debit or credit cards. The CityPay gateway will be able to determine this and return an authorised or rejected transaction response accordingly

Create a PKPaymentAuthorizationViewController

When the user selects the Apply Pay button you will need to add a controller to initiate the Apple Pay process

// initialise the payment view controller with the payment request
let applePayController = PKPaymentAuthorizationViewController(paymentRequest: request)
// set as controller's delegate to manage payment
applePayController.delegate = self
self.presentViewController(applePayController, animated: true, completion: nil)

Implement PKPaymentAuthorizationViewControllerDelegate

Once the user has authenticated payment a delegate of the controller runs the payment authorisation process. This is where we implement the CityPayKit into the Apple Pay process. 

// create an implementation of the PKPaymentAuthorizationViewControllerDelegate
extension BuySwagViewController: PKPaymentAuthorizationViewControllerDelegate {

    // implement paymentAuthorizationViewController and offest the payment processing to CityPay
    func paymentAuthorizationViewController(controller: PKPaymentAuthorizationViewController, 
			didAuthorizePayment payment: PKPayment, 
			completion: (PKPaymentAuthorizationStatus) -> Void) {
				let cp = CityPayRequest(
					merchantId: 105, 
					licenceKey: "LK", 
					identifier: "ApplePayTest1", 
					test: true
					payment: payment,
					completion: completion,
					paymentResponse: { (response:CityPayResponse) -> Void in
						// todo business logic on your side...

	func paymentAuthorizationViewControllerDidFinish(controller: PKPaymentAuthorizationViewController) {
        controller.dismissViewControllerAnimated(true, completion: nil)

An implementation will adapt the paymentAuthorizationViewController function to a CityPayRequest instance. At this point you are able to 

  1. provide the CityPay merchant id. This should match the processing currency of your transaction.
  2. provide the CityPay licence key which is used for processing Apple Pay payments. 
  3. provide an identifier which is your reference for the transaction
  4. provide a Bool value whether the transaction is for testing or false for production.

Once the request object has been initialised, call the applePay function on the instance. You will be required to provide 

  1. The controller instance
  2. the PKPayment object which contains the encrypted card data and payment information
  3. a reference to the completion handler which informs PassKit whether a transaction was successful
  4. a paymentResponse closure which provides an instance of the CityPayResponse object outlining the result of the transaction. This is included to determine the result of processing and therefore update your systems accordingly. 
+44 (0)1534 884000