Using Apple Pay

Apple Pay is a payment service from Apple that allows users to store sets of card details in the Wallet app and use them for purchases with the device. These include face-to-face purchases with a mobile device (such as an iPhone) and online purchases with the Safari web browser.

ProcessOut lets you offer Apple Pay as a payment option to your customers. Go to Dashboard › Connections › New connections › Apple Pay to enable Apple Pay, add the payment certificates (which Apple uses to encrypt payment data), and configure the domains where you want to accept payments.

To accept payments with Apple Pay, you must get an Apple Developer account and also integrate our Apple Pay features into your website, as described in the sections below.

Using your Apple Developer account

Before you can start using Apple Pay, you must first create an Apple Developer account, if you have
not already done so. When you have an account, follow the instructions to configure Apple Pay, which includes generating the certificates that you will need to accept payments with Smart Router.

The developer account also lets you use a sandbox testing environment that is similar to the one we provide. It lets you simulate payments during development without using any real-world customer data. To enable the sandbox:

  1. Log into App Store Connect.
  2. In Users and Access, go to the Testers page (under the Sandbox heading), and click on the plus sign ("+") to create a new test user.
  3. Fill out the form, making sure that you note the email and password you provide, and then click Invite.
  4. On your test device, log out of your personal iCloud account and log in using the newly created test credentials.
  5. Go into Wallet & Apple Pay in your Settings.
  6. Click on Add Credit or Debit Card, and then Enter Card Details Manually.
  7. You can now use any of the Apple Pay test cards. For example, you can use 4761 1200 1000 0492, exp 11/2022 and CVC 533 as a Visa test card.

Adding the Apple Pay button to your website

The HTML sample below shows how to use CSS styling to add the Apple Pay button to your page. Note that the CSS attributes for Apple Pay are specific to Apple's Safari browser and are not supported in other browsers. The styling uses the white variant of the logo and keeps the button hidden by default.

<style>
  #apple-pay-button {
    display: none;
    background-color: black;
    background-image: -webkit-named-image(apple-pay-logo-white);
    background-size: 100% 100%;
    background-origin: content-box;
    background-repeat: no-repeat;
    width: 100%;
    height: 44px;
    padding: 10px 0;
    border-radius: 10px;
  }
  #apple-pay-button.visible {
    display: block;
  }
</style>
<button id="apple-pay-button"></button>

You should always use JavaScript code to check that Apple Pay is available before showing the button to your customer.

Firstly, follow our setting up your environment documentation for the web to enable the processout.js library in your web page. Then, check if the customer's browser supports Apple Pay and show the button using code like the following:

var client = new ProcessOut.ProcessOut("proj_XypcVbbihw7uzAVj18egy1nZeppStAhu");

client.applePay.checkAvailability(function(err) {
  // Show the button only if there is no error
  if (err) {
    console.log(err);
  } else {
    document.getElementById("apple-pay-button").className += "visible";
  }
});

This call will use default Apple Pay configuration for checking availability. To use another configuration you can specify merchantApplePayCertificateId in the second argument:

client.applePay.checkAvailability(function(err) {
  // Show the button only if there is no error
  if (err) {
    console.log(err);
  } else {
    document.getElementById("apple-pay-button").className += "visible";
  }
},{merchantApplePayCertificateId: "{applepay_mid}"});

Tokenizing the user's card

The Apple Pay payment sheet lets the customer confirm their payment. You must only show the sheet in response to an action from the customer, such as a mouse click. The following code adds an event listener for a click on the Apple Pay button that was created in the HTML.

document.getElementById("apple-pay-button").
  addEventListener("click", tokenizeApplePay);

function tokenizeApplePay() {
  // Respond to the click.
}

You must create an ApplePayPaymentRequest object to tokenize an Apple Pay card (this object is referred to as session in the example code just below). The fields that you must supply at minimum to create the object are:

  • total: an object with fields for the label of the transaction and the amount to pay
  • currencyCode: currency code in ISO 4217 format with 3 letters
  • countryCode: country code in ISO 3166 format with 2 letters

📘

Note that the value in the amount field of total is displayed to the customer in the sheet but Apple Pay does not require you to charge the same amount when you capture the payment. However, we strongly recommend that you charge the same amount that you show on the sheet.

You can also supply many other fields for the session object, but processout.js will supply sensible defaults if you omit them. The example shows how you can use the request fields to select a particular ApplePay MID (merchantApplePayCertificateId) and merchant certificate (merchantCertificateId) for the tokenization:

function tokenizeApplePay() {
  var session = client.applePay.newSession({
    total: {
      label: "Amazing invoice",
      amount: "19.99"
    },
    currencyCode: "USD",
    countryCode: "US",
    merchantApplePayCertificateId: "ApplePay MID",
    merchantCertificateId: "merchant certificate id for the current domain"
  });
}

Use the session object to activate and respond to the payment sheet:

function tokenizeApplePay() {
  var session = client.applePay.newSession({
    total: {
      label: "Amazing invoice",
      amount: "19.99"
    },
    currencyCode: "USD",
    countryCode: "US",
    merchantCertificateId: "merchant certificate id"
  });

  client.tokenize(session, {
    // Some custom data, such as your internal customer_id
  }, function(card) {
    // Calling session.completePayment with STATUS_SUCCESS closes the
    // Apple Pay payment sheet with a success message
    session.completePayment(ApplePaySession.STATUS_SUCCESS);
    console.log(card.id);

  }, function(err) {
    // STATUS_FAILURE shows an error on the Apple Pay payment sheet
    session.completePayment(ApplePaySession.STATUS_FAILURE);
    console.log(err);

  });
}

Your code should send the card.id token back to the server, where you can use it to capture a payment.

Customizing your integration

You can also add functions to the session object that will be called in response to specific user actions:

  • oncancel: called when the user cancels the payment
  • onpaymentmethodselected: called when the user selects a new payment method
  • onshippingcontactselected: called when the user selects a new shipping contact
  • onshippingmethodselected: called when the user selects a new shipping method
  • onpaymentauthorizedPostprocess: called after the payment is authorized (ProcessOut's default handler is executed first)

All of these functions receive a single event parameter:

session.oncancel = function(event) {
  // Custom action
};

session.onpaymentmethodselected = function(event) {
  // Custom action
};

session.onshippingcontactselected = function(event) {
  // Custom action
};

session.onshippingmethodselected = function(event) {
  // Custom action
};

session.onpaymentauthorizedPostprocess = function(event) {
  // Custom action
};

For example, you could use the oncancel() function to ask the user if they really want to abort the purchase and call event.preventDefault() to prevent the cancellation if they choose to continue.

Using Apple Pay on iOS

First, you should obtain and set up the ProcessOut iOS SDK in your project by following the instructions for iOS.

1. Enabling Apple Pay in Xcode

To enable Apple Pay for your app, follow these steps in Xcode:

  1. Open your project settings in Xcode.

  2. Navigate to the Signing & Capabilities tab.

  3. Click the + Capability button and add the Apple Pay capability.

At this stage, you may be asked to log in to your Apple Developer account. Once logged in, select the Merchant ID you previously created. This completes the setup, and your app will be ready to accept payments via Apple Pay.

2. Checking Apple Pay Support

Before displaying the Apple Pay button, you need to ensure that the customer's device supports Apple Pay. You can use PKPaymentAuthorizationController or PKPaymentAuthorizationViewController to check this.

For example, in UIKit, you can check for support and display the Apple Pay button as follows:

guard PKPaymentAuthorizationController.canMakePayments() else {
  return
}
let button = PKPaymentButton(paymentButtonType: .plain, paymentButtonStyle: .black)
button.addTarget(self, action: #selector(didTouchPaymentButton), for: .touchUpInside)
// todo: add the button to the view hierarchy

Alternatively, if you're using SwiftUI, you can use the built-in PayWithApplePayButton.

3. Create the Payment Request

When the user taps the Apple Pay button, you will need to create a PKPaymentRequest. This request contains all the necessary information about the transaction. You can customize it to suit your needs, but for more detailed guidance, please refer to Apple’s documentation.

Below is an example of the most minimal payment request:

let request = PKPaymentRequest()
request.merchantIdentifier = "YOUR_MERCHANT_IDENTIFIER"
request.merchantCapabilities = [.threeDSecure]
request.paymentSummaryItems = [
  .init(label: "Example", amount: 100)
]
request.currencyCode = "USD"
request.countryCode = "US"
request.supportedNetworks = [.visa, .masterCard, .amex]

4. Tokenize the Payment Request

To authorize the previously created payment request, you need to create a POApplePayTokenizationRequest and submit it to the cards service. The SDK will handle the presentation and dismissal of the Apple Pay payment sheet automatically.

You can also customize the tokenization request further:

  • Use the contact property to override the billing address collected during payment authorization.
  • Optionally, pass a metadata argument that will be assigned to the card object after tokenization.

Here’s an example of how to create and submit a tokenization request:

let tokenizationRequest = POApplePayTokenizationRequest(
  paymentRequest: paymentRequest
)
let card = try await ProcessOut.shared.cards.tokenize(request: tokenizationRequest)

This will tokenize the payment request and return a card object that you can use for further processing.

5. Invoice Authorization

After tokenizing the card, the next step is to authorize the invoice with it.

The recommended approach is to handle this during the Apple Pay session. To do so, create an object that conforms to the POApplePayTokenizationDelegate protocol and pass it when performing tokenization. The SDK will retain the delegate for the duration of the tokenization process.

Once the payment is successfully authorized, the SDK will call the func applePayTokenization(didAuthorizePayment:card:) method, where you can use the provided card object to authorize the invoice.

Here’s an example:

final class ApplePayTokenizationCoordinator: POApplePayTokenizationDelegate {

  func applePayTokenization(
    didAuthorizePayment payment: PKPayment, card: POCard
  ) async -> PKPaymentAuthorizationResult {
    do {
      let request = POInvoiceAuthorizationRequest(invoiceId: "iv_xyz", source: card.id)
      try await invoicesService.authorizeInvoice(request: request, threeDSService: threeDSService)
      return .init(status: .success, errors: nil)
    } catch {
      let error = PKPaymentError(.unknownError)
      return .init(status: .failure, errors: [error])
    }
  }

  private let invoicesService: POInvoicesService
  private let threeDSService: PO3DSService
}

let coordinator = ApplePayTokenizationCoordinator(...)
let card = try await ProcessOut.shared.cards.tokenize(
  request: tokenizationRequest, delegate: coordinator
)

The delegate also allows for additional customization and monitoring of the payment lifecycle, such as:

  • Responding to changes in payment details like coupons, shipping methods, and contact info.

  • Updating the merchant session.

  • Getting notified when the payment is authorized and tokenized.

Manual Tokenization

Alternatively, you can manually authorize a PKPaymentRequest using PKPaymentAuthorizationController or any other Apple-provided method. After authorization, you can tokenize the PKPayment using the cards service.

Here’s an example of how to manually tokenize the payment:

let tokenizationRequest = POApplePayPaymentTokenizationRequest(
  payment: payment
)
let card = try await ProcessOut.shared.cards.tokenize(
  request: tokenizationRequest
)

In this approach, you handle the payment authorization process yourself and then use the tokenization request to create a card object for further processing.