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 支持批量下载:
- 把多个
.pkpass文件打包成 zip - 文件扩展名改为
.pkpasses - 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委托方法实时验证 - 提供
paymentCouponCodeInvalidError和paymentCouponCodeExpiredError两种错误类型 - 建议预填充已知有效优惠码,减少用户输入
新的 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 等)
核心启发
-
给电商 App 加上支付 sheet 内的优惠券输入。用户忘记输优惠码是购物车放弃的主要原因之一。iOS 15 的
supportsCouponCode让用户不用离开支付流程就能补输入。入口 API:PKPaymentRequest.supportsCouponCode+PKPaymentAuthorizationControllerDelegate.didChangeCouponCode。 -
显示精确的发货时间范围。“预计 3-5 天送达”比”尽快发货”更能建立用户信任。用
PKDateComponentsRange设置起止日期,支付 sheet 会自动格式化显示。入口 API:PKShippingMethod.dateComponentsRange。 -
为自提场景设置只读地址。如果用户选择的是门店自提,不要让他在支付 sheet 里修改地址。用
shippingContact+shippingContactEditingMode锁定地址。入口 API:PKPaymentRequest.shippingContact+.shippingContactEditingMode。 -
批量发放活动门票。音乐节、电影院、展会等场景一次发多张票。把
.pkpass文件打包成.pkpasses,用户一次下载全部票券。入口 API:zip +.pkpasses扩展名 +application/vnd.apple.pkpassesMIME type。 -
设置 Web Clip 图标提升网页支付信任感。网页版 Apple Pay 现在会在支付 sheet 显示网站图标。在网站根目录放置 120x120 和 180x180 的图标,Apple Pay 会自动获取。入口 API:
<link rel="apple-touch-icon">或根目录apple-touch-icon.png。
关联 Session
- Meet StoreKit 2 — StoreKit 2 全新 Swift API,支持应用内购买和订阅管理
- Support customers and handle refunds — StoreKit 2 客户支持和退款处理
- Build custom experiences with Wallet — 深入构建 Wallet 自定义体验
- What’s new in Safari and WebKit — Safari 和 WebKit 新特性,包括 Apple Pay on the Web 改进
评论
GitHub Issues · utterances