Wallet and Apple Pay: Creating Great Customer Experiences

Description: Get the latest news and updates from the Wallet and Apple Pay team. Learn how iPhone and Apple Watch can power innovative commerce experiences. Hear about the latest design best practices for Apple Pay. And discover how to create your own contactless passes for rewards cards, gift cards, tickets and more.

Why use passes?

  • Easy to use contactlessly or with a barcode
  • Synced across all devices and backed with iCloud
  • Intelligently shown on lock screen and in search for quick access Continue the seamless Apple Pay experience into the physical world

Adding passes to Wallet

func addPasses(_
  passes: [PKPass], 
  withCompletionHandler completion: ((PKPassLibraryAddPassesStatus) -> Void)? = nil

// With Swift 5.5 concurrency:
func addPasses(_ passes: [PKPass]) async -> PKPassLibraryAddPassesStatus
  • Presents a simple alert to the user requesting to add or review the passes
  • Less friction than presenting PKAddPassesViewController
  • Lets you handle the completion outcome in the callback

Best practices

  • Suggest adding passes that were created outside of your app
  • Add related passes to Wallet as a group
  • Make it easy for people to quickly add passes they do not have
  • Let people jump to their passes in Wallet from your app
  • New

Designing passes

  • Use pass fields to display relevant text
  • Use vibrant colors to make your pass stand out
  • Design a pass that looks great on all devices
  • Avoid reproducing existing physical passes
  • Don’t encode user information in the strip image (not shown on Apple Watch)

Passes on Apple Watch

  • Does not support the strip image
  • Thumbnail image is not displayed
  • Users cannot access the pass details

Additional row support

  • New this year
  • can only be used in auxiliary fields in an eventTicket pass type
  • Can add only one extra row
  • Auxiliary fields are then displayed on one row up to the limit of fourth fields per row
"auxiliaryFields": [
    "label": "Date",
    "key": "Date",
    "value": "June 9, 2018",
    "row": 0
  }, {
    "label": "Section",
    "key": "Section",
    "value": "10",
    "row": 1
  • Only values of 0 and 1 are supported
  • On older versions, "row" is ignored

Rich pass content


  • Add this functionality with the locations, relevantText, and relevantDate pass JSON fields
  • Pass appears on lock screen at the right moment
  • Handles multiple relevant passes
  • Always add relevancy information and trust the system to present as required

Semantic Tags (new)


You can add additional related data that is not important for display, but associated with a field.

  "key": "event",
  "label": "Apple Park",
  "value": "Revenge Of The Passes",
  "semantics": {
    "eventName": "Revenge Of The Passes: A Wallet Story",
    "venueName": "Apple Park 1",
    "venuePhoneNumber": "+1(408)888-8888"

Semantics can be associated with the pass and not with any field, in the following example we tell PassKit that the phone should be muted during the movie (movie ticket example):

  "semantics": {
    "eventType": "PKEventTypeMovie",
    "silenceRequested": true,
    "duration": 7245

Siri will then be able to offer the user the ability to quickly enable do not disturb at the right time

Contactless passes

  • Requires an NFC Certificate to get started
  • Apply for access
  • Your readers must support the Apple Value added Services protocol

Missing anything? Corrections? Contributions are welcome 😃


Written by

Federico Zanetello

Federico Zanetello

Software engineer with a strong passion for well-written code, thought-out composable architectures, automation, tests, and more.