ApplePayKit:一个简单易用的 Apple Pay Swift Package
是一个面向 iOS 16+ 的轻量 Apple Pay Swift Package。它负责构建支付请求、检查设备能力、展示系统支付面板,并把支付令牌交给你的服务端授权逻辑。
核心业务与视图组件分为三个独立模块:
ApplePayKit:配置、请求构建、能力检查和授权流程。ApplePayKitSwiftUI:基于官方PayWithApplePayButton的可选 SwiftUI 按钮。ApplePayKitUIKit:基于官方PKPaymentButton的可选 UIKit 按钮。
只想使用自己的支付按钮时,仅引入 ApplePayKit 即可。
接入前准备
- 在 Apple Developer 后台创建 Merchant ID 和支付处理证书。
- 在 App Target 的 Signing & Capabilities 中添加 Apple Pay,勾选同一个 Merchant ID。
- 在支付服务商或自有服务端完成 Apple Pay 证书与令牌处理配置。
- 将本仓库作为 Swift Package 添加到项目,并按界面技术选择核心及视图产品。
Apple Pay 返回的支付令牌必须发送到可信服务端或支付服务商处理。不要仅凭客户端回调发货,也不要把证书私钥放进 App。
最简用法
建议把 ApplePayClient 保存为页面或支付服务的强引用属性,直到支付流程结束。
import Foundation
import ApplePayKit
import PassKit
@MainActor
final class CheckoutService {
private let applePay = ApplePayClient(
configuration: ApplePayConfiguration(
merchantIdentifier: "merchant.com.yourcompany.app",
countryCode: "CN",
currencyCode: "CNY",
supportedNetworks: [.chinaUnionPay, .visa, .masterCard],
merchantCapabilities: [.threeDSecure, .emv]
)
)
func pay() {
applePay.present(
items: [
ApplePayItem(label: "高级会员", amount: 98),
ApplePayItem(label: "优惠", amount: -10)
],
total: ApplePayItem(label: "示例", amount: 88),
applicationData: Data("order-1001".utf8),
authorizationHandler: { payment in
// 把 payment.token.paymentData 上传到你的服务端。
try await PaymentAPI.confirmApplePay(
tokenData: payment.token.paymentData
)
return PKPaymentAuthorizationResult(status: .success, errors: [])
},
onSuccess: { payment in
print("支付完成:\(payment.token.transactionIdentifier)")
},
onFailure: { error in
// 取消、配置错误、设备不可用和授权失败都会进入这里。
print(error.localizedDescription)
}
)
}
}原有 completion: (Result<PKPayment, ApplePayError>) -> Void 接口仍然保留,方便需要统一结果流的项目继续使用。
支付按钮
ApplePayKit 不限制支付入口。无论使用哪种按钮,都只需在点击事件中调用上面的 CheckoutService.pay()。
SwiftUI
SwiftUI 项目添加 ApplePayKitSwiftUI 产品,然后使用封装后的官方按钮:
import ApplePayKitSwiftUI
import PassKit
import SwiftUI
ApplePayButton(.buy, style: .black) {
checkoutService.pay()
}
.frame(height: 48)UIKit
UIKit 项目添加 ApplePayKitUIKit 产品,然后使用封装后的官方按钮:
import ApplePayKitUIKit
import UIKit
final class CheckoutViewController: UIViewController {
private let checkoutService = CheckoutService()
private lazy var applePayButton = ApplePayButtonView(
type: .buy,
style: .black,
cornerRadius: 8
) { [weak self] in
self?.checkoutService.pay()
}
}自定义支付入口
已有按钮、订单列表或统一收银台也可以直接触发业务层:
import ApplePayKit
Button("确认支付") {
checkoutService.pay()
}如果按钮明确用于 Apple Pay,应遵循 Apple Pay 按钮的品牌与界面规范;自定义入口不会改变 ApplePayKit 的支付处理方式。
可用性检查
switch applePay.availability() {
case .available:
// 展示 Apple Pay 按钮
case .supportedCardUnavailable:
// 可提示用户先在 Wallet 中添加受支持的银行卡
case .applePayUnavailable:
// 隐藏 Apple Pay 入口或提供其他支付方式
}高级请求
周期付款、延迟付款或需要进一步修改 PKPaymentRequest 时,可先调用 makeRequest,设置 PassKit 的高级字段后,再通过 present(request:authorizationHandler:completion:) 展示。
测试说明
支付面板与真实扣款必须在支持 Apple Pay 的设备、正确签名的 App、沙盒测试卡及可用的支付服务端环境中验证。单元测试和模拟器构建只能验证请求构建及编译正确性,不能证明真实支付链路成功。
Apple 官方资料
::[设置 Apple Pay]{link=“https://developer.apple.com/documentation/passkit/setting-up-apple-pay” type=“info”} ::[在 App 中提供 Apple Pay]{link=“https://developer.apple.com/documentation/passkit/offering-apple-pay-in-your-app” type=“info”} ::[支付令牌格式]{link=“https://developer.apple.com/documentation/passkit/payment-token-format-reference” type=“info”}
