WWDC Quick Look 💓 By SwiftGGTeam
What's new in Wallet and Apple Pay

What's new in Wallet and Apple Pay

观看原视频

Highlight

iOS 15 的 Apple Pay 支付 sheet 用 SwiftUI 完全重写,新增优惠券码、发货日期范围、只读收货地址等 API;Wallet 支持多 pass 批量下载和过期 pass 自动隐藏。

核心内容

你在做一个电商 App。用户选好商品,点击购买,弹出 Apple Pay 支付 sheet。这个流程在 iOS 14 已经能跑通,但有几个痛点:

  • 用户忘记输入优惠码,只能取消支付、返回购物车、输入优惠码、重新发起支付
  • 发货时间只能写文字描述,无法显示精确的日期范围
  • 自提地址和收货地址混在一起,用户可能误改

iOS 15 的 Apple Pay 重新设计了支付 sheet,从底层用 SwiftUI 重写,同时新增了一批 API 解决这些痛点。

Wallet 也有更新:现在可以一次下载多个 pass,过期的票券会自动隐藏,不再 clutter 用户的 Wallet。

详细内容

多 pass 批量下载

01:39

以前从网页添加 pass,一次只能加一张。iOS 15 支持批量下载:

  1. 把多个 .pkpass 文件打包成 zip
  2. 文件扩展名改为 .pkpasses
  3. MIME type 设为 application/vnd.apple.pkpasses

用户点击下载链接后,Wallet 会一次性处理所有 pass。

关键点:

  • 适合电影票、演唱会门票等多张场景
  • 只需要改文件格式和 MIME type,服务端逻辑不变

过期 pass 自动隐藏

02:28

Wallet 现在会自动隐藏过期 pass,保持界面整洁。判断逻辑基于三个字段:

  • expirationDate 早于当前日期
  • relevantDate 早于当前日期超过一天
  • voided 被设为 true

关键点:

  • 确保 pass 的这三个字段设置正确
  • 用户仍然可以在”已过期”分类中找到隐藏的 pass
  • 不要依赖用户手动删除旧 pass

支付 sheet 全新设计

05:04

iOS 15 的 Apple Pay sheet 用 SwiftUI 完全重写,视觉更清晰、交互更流畅。具体改进:

  • 新用户添加卡片和地址的流程简化
  • 老用户可以在支付 sheet 内直接添加新卡,不用跳转
  • 错误提示重新设计,更明确
  • 新增 summary view,显示商品明细、折扣、小计
  • 应用图标现在显示在 summary view 上(网页支付显示 Web Clip 图标)

关键点:

  • 新设计自动生效,无需修改代码
  • 网页支付建议设置 Web Clip 图标(2x 和 3x,放在网站根目录)
  • iOS 15 通知图标变大,PKPass 图标最小需要 38x38 @1x

发货日期范围

07:40

新增 dateComponentsRange 属性,可以在支付 sheet 中显示精确的发货或自提时间:

let shippingMethod = PKShippingMethod(
    label: "标准快递",
    amount: 10.00
)

let calendar = Calendar.current
let today = Date()
let shippingStart = calendar.date(byAdding: .day, value: 3, to: today)!
let shippingEnd = calendar.date(byAdding: .day, value: 7, to: today)!

shippingMethod.dateComponentsRange = PKDateComponentsRange(
    start: calendar.dateComponents([.year, .month, .day], from: shippingStart),
    end: calendar.dateComponents([.year, .month, .day], from: shippingEnd)
)

关键点:

  • 使用 DateComponents 而非简单 Date,内置时区和日历支持
  • 可以显示”预计 3-7 天送达”或”明天 14:00 自提”
  • 网页版 Apple Pay 有对应的 JavaScript API

只读收货地址

09:36

自提场景下,地址是固定的(比如某个门店),不应该让用户修改。iOS 15 支持设置只读地址:

let address = CNMutablePostalAddress()
address.street = "1 Infinite Loop"
address.city = "Cupertino"
address.state = "CA"
address.postalCode = "95014"

let contact = PKContact()
contact.postalAddress = address

paymentRequest.shippingContact = contact
paymentRequest.shippingType = .storePickup
paymentRequest.shippingContactEditingMode = .enabled
paymentRequest.requiredShippingContactFields = [.postalAddress]

关键点:

  • shippingContactEditingMode 设为 .enabled 时,用户看到的地址是只读的
  • 适合自提、固定取货点等场景
  • 网页版通过 shippingContactEditingMode 字段实现同样效果

优惠券码

10:46

用户可以在支付 sheet 内直接输入优惠码,不用取消支付流程。实现方式:

// 启用优惠券支持
paymentRequest.supportsCouponCode = true
paymentRequest.couponCode = "WELCOME10" // 可选:预填充

// 处理优惠码变更
default func paymentAuthorizationController(
    _ controller: PKPaymentAuthorizationController,
    didChangeCouponCode couponCode: String,
    handler: @escaping (PKPaymentRequestCouponCodeUpdate) -> Void
) {
    if couponCode == "FESTIVAL" {
        // 有效优惠码,更新总价
        let updatedItems = applyDiscount(couponCode)
        handler(PKPaymentRequestCouponCodeUpdate(
            paymentSummaryItems: updatedItems
        ))
    } else if couponCode.isEmpty {
        // 空码,恢复原价
        handler(PKPaymentRequestCouponCodeUpdate(
            paymentSummaryItems: originalItems
        ))
    } else {
        // 无效优惠码,显示错误
        let error = PKPaymentRequest.paymentCouponCodeInvalidError(
            withLocalizedDescription: "优惠码无效"
        )
        handler(PKPaymentRequestCouponCodeUpdate(
            errors: [error],
            paymentSummaryItems: originalItems,
            shippingMethods: shippingMethods
        ))
    }
}

关键点:

  • supportsCouponCode = true 开启功能
  • didChangeCouponCode 委托方法实时验证
  • 提供 paymentCouponCodeInvalidErrorpaymentCouponCodeExpiredError 两种错误类型
  • 建议预填充已知有效优惠码,减少用户输入

新的 JavaScript 支付按钮

04:23

Apple Pay on the Web 新增了纯 JavaScript 实现的支付按钮,支持所有当前按钮类型和样式:

const button = document.createElement('apple-pay-button');
button.setAttribute('buttonstyle', 'black');
button.setAttribute('type', 'plain');
button.setAttribute('locale', 'zh-CN');

关键点:

  • 按钮大小和样式可自定义
  • 样式前缀为 apple-pay-
  • 支持所有现有按钮类型(Buy、Donate、Set Up 等)

核心启发

  1. 给电商 App 加上支付 sheet 内的优惠券输入。用户忘记输优惠码是购物车放弃的主要原因之一。iOS 15 的 supportsCouponCode 让用户不用离开支付流程就能补输入。入口 API:PKPaymentRequest.supportsCouponCode + PKPaymentAuthorizationControllerDelegate.didChangeCouponCode

  2. 显示精确的发货时间范围。“预计 3-5 天送达”比”尽快发货”更能建立用户信任。用 PKDateComponentsRange 设置起止日期,支付 sheet 会自动格式化显示。入口 API:PKShippingMethod.dateComponentsRange

  3. 为自提场景设置只读地址。如果用户选择的是门店自提,不要让他在支付 sheet 里修改地址。用 shippingContact + shippingContactEditingMode 锁定地址。入口 API:PKPaymentRequest.shippingContact + .shippingContactEditingMode

  4. 批量发放活动门票。音乐节、电影院、展会等场景一次发多张票。把 .pkpass 文件打包成 .pkpasses,用户一次下载全部票券。入口 API:zip + .pkpasses 扩展名 + application/vnd.apple.pkpasses MIME type。

  5. 设置 Web Clip 图标提升网页支付信任感。网页版 Apple Pay 现在会在支付 sheet 显示网站图标。在网站根目录放置 120x120 和 180x180 的图标,Apple Pay 会自动获取。入口 API:<link rel="apple-touch-icon"> 或根目录 apple-touch-icon.png

关联 Session

评论

GitHub Issues · utterances