Loading...
Loading...
Compare original and translation side by side
merchant.com.example.appmerchant.com.example.appimport PassKit
func canMakePayments() -> Bool {
// Check device supports Apple Pay at all
guard PKPaymentAuthorizationController.canMakePayments() else {
return false
}
// Check user has cards for the networks you support
return PKPaymentAuthorizationController.canMakePayments(
usingNetworks: [.visa, .masterCard, .amex, .discover],
capabilities: .threeDSecure
)
}import PassKit
func canMakePayments() -> Bool {
// 检查设备是否支持Apple Pay
guard PKPaymentAuthorizationController.canMakePayments() else {
return false
}
// 检查用户是否有支持对应支付网络的卡片
return PKPaymentAuthorizationController.canMakePayments(
usingNetworks: [.visa, .masterCard, .amex, .discover],
capabilities: .threeDSecure
)
}PayWithApplePayButtonimport SwiftUI
import PassKit
struct CheckoutView: View {
var body: some View {
PayWithApplePayButton(.buy) {
startPayment()
}
.payWithApplePayButtonStyle(.black)
.frame(height: 48)
.padding()
}
}PayWithApplePayButtonimport SwiftUI
import PassKit
struct CheckoutView: View {
var body: some View {
PayWithApplePayButton(.buy) {
startPayment()
}
.payWithApplePayButtonStyle(.black)
.frame(height: 48)
.padding()
}
}PKPaymentButtonlet button = PKPaymentButton(
paymentButtonType: .buy,
paymentButtonStyle: .black
)
button.cornerRadius = 12
button.addTarget(self, action: #selector(startPayment), for: .touchUpInside).buy.setUp.inStore.donate.checkout.book.subscribe.reload.addMoney.topUp.order.rent.support.contribute.tipPKPaymentButtonlet button = PKPaymentButton(
paymentButtonType: .buy,
paymentButtonStyle: .black
)
button.cornerRadius = 12
button.addTarget(self, action: #selector(startPayment), for: .touchUpInside).buy.setUp.inStore.donate.checkout.book.subscribe.reload.addMoney.topUp.order.rent.support.contribute.tipPKPaymentRequestfunc createPaymentRequest() -> PKPaymentRequest {
let request = PKPaymentRequest()
request.merchantIdentifier = "merchant.com.example.app"
request.countryCode = "US"
request.currencyCode = "USD"
request.supportedNetworks = [.visa, .masterCard, .amex, .discover]
request.merchantCapabilities = .threeDSecure
request.paymentSummaryItems = [
PKPaymentSummaryItem(label: "Widget", amount: 9.99),
PKPaymentSummaryItem(label: "Shipping", amount: 4.99),
PKPaymentSummaryItem(label: "My Store", amount: 14.98) // Total (last item)
]
return request
}paymentSummaryItemsPKPaymentRequestfunc createPaymentRequest() -> PKPaymentRequest {
let request = PKPaymentRequest()
request.merchantIdentifier = "merchant.com.example.app"
request.countryCode = "US"
request.currencyCode = "USD"
request.supportedNetworks = [.visa, .masterCard, .amex, .discover]
request.merchantCapabilities = .threeDSecure
request.paymentSummaryItems = [
PKPaymentSummaryItem(label: "小部件", amount: 9.99),
PKPaymentSummaryItem(label: "配送费", amount: 4.99),
PKPaymentSummaryItem(label: "我的商店", amount: 14.98) // 总计(最后一项)
]
return request
}paymentSummaryItemsrequest.requiredShippingContactFields = [.postalAddress, .emailAddress, .name]
request.requiredBillingContactFields = [.postalAddress]
request.shippingMethods = [
PKShippingMethod(label: "Standard", amount: 4.99),
PKShippingMethod(label: "Express", amount: 9.99),
]
request.shippingMethods?[0].identifier = "standard"
request.shippingMethods?[0].detail = "5-7 business days"
request.shippingMethods?[1].identifier = "express"
request.shippingMethods?[1].detail = "1-2 business days"
request.shippingType = .shipping // .delivery, .storePickup, .servicePickuprequest.requiredShippingContactFields = [.postalAddress, .emailAddress, .name]
request.requiredBillingContactFields = [.postalAddress]
request.shippingMethods = [
PKShippingMethod(label: "标准配送", amount: 4.99),
PKShippingMethod(label: "加急配送", amount: 9.99),
]
request.shippingMethods?[0].identifier = "standard"
request.shippingMethods?[0].detail = "5-7个工作日"
request.shippingMethods?[1].identifier = "express"
request.shippingMethods?[1].detail = "1-2个工作日"
request.shippingType = .shipping // .delivery, .storePickup, .servicePickup| Network | Constant |
|---|---|
| Visa | |
| Mastercard | |
| American Express | |
| Discover | |
| China UnionPay | |
| JCB | |
| Maestro | |
| Electron | |
| Interac | |
PKPaymentRequest.availableNetworks()| 支付网络 | 常量 |
|---|---|
| Visa | |
| Mastercard | |
| American Express | |
| Discover | |
| 中国银联 | |
| JCB | |
| Maestro | |
| Electron | |
| Interac | |
PKPaymentRequest.availableNetworks()PKPaymentAuthorizationController@MainActor
func startPayment() {
let request = createPaymentRequest()
let controller = PKPaymentAuthorizationController(paymentRequest: request)
controller.delegate = self
controller.present()
}PKPaymentAuthorizationController@MainActor
func startPayment() {
let request = createPaymentRequest()
let controller = PKPaymentAuthorizationController(paymentRequest: request)
controller.delegate = self
controller.present()
}PKPaymentAuthorizationControllerDelegateextension CheckoutCoordinator: PKPaymentAuthorizationControllerDelegate {
func paymentAuthorizationController(
_ controller: PKPaymentAuthorizationController,
didAuthorizePayment payment: PKPayment,
handler completion: @escaping (PKPaymentAuthorizationResult) -> Void
) {
// Send payment.token.paymentData to your payment processor
Task {
do {
try await paymentService.process(payment.token)
completion(PKPaymentAuthorizationResult(status: .success, errors: nil))
} catch {
completion(PKPaymentAuthorizationResult(status: .failure, errors: [error]))
}
}
}
func paymentAuthorizationControllerDidFinish(
_ controller: PKPaymentAuthorizationController
) {
controller.dismiss()
}
}PKPaymentAuthorizationControllerDelegateextension CheckoutCoordinator: PKPaymentAuthorizationControllerDelegate {
func paymentAuthorizationController(
_ controller: PKPaymentAuthorizationController,
didAuthorizePayment payment: PKPayment,
handler completion: @escaping (PKPaymentAuthorizationResult) -> Void
) {
// 将payment.token.paymentData发送至你的支付处理服务商
Task {
do {
try await paymentService.process(payment.token)
completion(PKPaymentAuthorizationResult(status: .success, errors: nil))
} catch {
completion(PKPaymentAuthorizationResult(status: .failure, errors: [error]))
}
}
}
func paymentAuthorizationControllerDidFinish(
_ controller: PKPaymentAuthorizationController
) {
controller.dismiss()
}
}func paymentAuthorizationController(
_ controller: PKPaymentAuthorizationController,
didSelectShippingMethod shippingMethod: PKShippingMethod,
handler completion: @escaping (PKPaymentRequestShippingMethodUpdate) -> Void
) {
let updatedItems = recalculateItems(with: shippingMethod)
let update = PKPaymentRequestShippingMethodUpdate(paymentSummaryItems: updatedItems)
completion(update)
}func paymentAuthorizationController(
_ controller: PKPaymentAuthorizationController,
didSelectShippingMethod shippingMethod: PKShippingMethod,
handler completion: @escaping (PKPaymentRequestShippingMethodUpdate) -> Void
) {
let updatedItems = recalculateItems(with: shippingMethod)
let update = PKPaymentRequestShippingMethodUpdate(paymentSummaryItems: updatedItems)
completion(update)
}.pkpassPKAddPassesViewControllerfunc addPassToWallet(data: Data) {
guard let pass = try? PKPass(data: data) else { return }
if let addController = PKAddPassesViewController(pass: pass) {
addController.delegate = self
present(addController, animated: true)
}
}.pkpassPKAddPassesViewControllerfunc addPassToWallet(data: Data) {
guard let pass = try? PKPass(data: data) else { return }
if let addController = PKAddPassesViewController(pass: pass) {
addController.delegate = self
present(addController, animated: true)
}
}import PassKit
import SwiftUI
struct AddPassButton: View {
let passData: Data
var body: some View {
Button("Add to Wallet") {
addPass()
}
}
func addPass() {
guard let pass = try? PKPass(data: passData) else { return }
let library = PKPassLibrary()
library.addPasses([pass]) { status in
switch status {
case .shouldReviewPasses:
// Present review UI
break
case .didAddPasses:
// Passes added successfully
break
case .didCancelAddPasses:
break
@unknown default:
break
}
}
}
}import PassKit
import SwiftUI
struct AddPassButton: View {
let passData: Data
var body: some View {
Button("添加至Wallet") {
addPass()
}
}
func addPass() {
guard let pass = try? PKPass(data: passData) else { return }
let library = PKPassLibrary()
library.addPasses([pass]) { status in
switch status {
case .shouldReviewPasses:
// 展示审核界面
break
case .didAddPasses:
// 凭证添加成功
break
case .didCancelAddPasses:
break
@unknown default:
break
}
}
}
}PKPassLibrarylet library = PKPassLibrary()
// Check if a specific pass is already in Wallet
let hasPass = library.containsPass(pass)
// Retrieve passes your app can access
let passes = library.passes()
// Check if pass library is available
guard PKPassLibrary.isPassLibraryAvailable() else { return }PKPassLibrarylet library = PKPassLibrary()
// 检查特定凭证是否已在Wallet中
let hasPass = library.containsPass(pass)
// 获取你的应用可访问的凭证
let passes = library.passes()
// 检查凭证库是否可用
guard PKPassLibrary.isPassLibraryAvailable() else { return }// WRONG: Using StoreKit to sell a physical product
let product = try await Product.products(for: ["com.example.tshirt"])
// CORRECT: Use Apple Pay for physical goods
let request = PKPaymentRequest()
request.paymentSummaryItems = [
PKPaymentSummaryItem(label: "T-Shirt", amount: 29.99),
PKPaymentSummaryItem(label: "My Store", amount: 29.99)
]// 错误:使用StoreKit售卖实体产品
let product = try await Product.products(for: ["com.example.tshirt"])
// 正确:使用Apple Pay售卖实体商品
let request = PKPaymentRequest()
request.paymentSummaryItems = [
PKPaymentSummaryItem(label: "T恤", amount: 29.99),
PKPaymentSummaryItem(label: "我的商店", amount: 29.99)
]// WRONG: Merchant ID scattered across the codebase
let request1 = PKPaymentRequest()
request1.merchantIdentifier = "merchant.com.example.app"
// ...elsewhere:
let request2 = PKPaymentRequest()
request2.merchantIdentifier = "merchant.com.example.app" // easy to get out of sync
// CORRECT: Centralize configuration
enum PaymentConfig {
static let merchantIdentifier = "merchant.com.example.app"
static let countryCode = "US"
static let currencyCode = "USD"
static let supportedNetworks: [PKPaymentNetwork] = [.visa, .masterCard, .amex]
}// 错误:商户ID分散在代码各处
let request1 = PKPaymentRequest()
request1.merchantIdentifier = "merchant.com.example.app"
// ...在其他地方:
let request2 = PKPaymentRequest()
request2.merchantIdentifier = "merchant.com.example.app" // 容易出现不一致
// 正确:集中管理配置
enum PaymentConfig {
static let merchantIdentifier = "merchant.com.example.app"
static let countryCode = "US"
static let currencyCode = "USD"
static let supportedNetworks: [PKPaymentNetwork] = [.visa, .masterCard, .amex]
}paymentSummaryItems// WRONG: No total item
request.paymentSummaryItems = [
PKPaymentSummaryItem(label: "Widget", amount: 9.99)
]
// CORRECT: Last item is the total with your merchant name
request.paymentSummaryItems = [
PKPaymentSummaryItem(label: "Widget", amount: 9.99),
PKPaymentSummaryItem(label: "My Store", amount: 9.99) // Total
]paymentSummaryItems// 错误:没有总计项
request.paymentSummaryItems = [
PKPaymentSummaryItem(label: "小部件", amount: 9.99)
]
// 正确:最后一项是包含商户显示名称的总计
request.paymentSummaryItems = [
PKPaymentSummaryItem(label: "小部件", amount: 9.99),
PKPaymentSummaryItem(label: "我的商店", amount: 9.99) // 总计
]// WRONG: Show Apple Pay button without checking
PayWithApplePayButton(.buy) { startPayment() }
// CORRECT: Only show when available
if PKPaymentAuthorizationController.canMakePayments(
usingNetworks: PaymentConfig.supportedNetworks
) {
PayWithApplePayButton(.buy) { startPayment() }
} else {
// Show alternative checkout or setup button
Button("Set Up Apple Pay") { /* guide user */ }
}// 错误:未检查就显示Apple Pay按钮
PayWithApplePayButton(.buy) { startPayment() }
// 正确:仅在支持时显示
if PKPaymentAuthorizationController.canMakePayments(
usingNetworks: PaymentConfig.supportedNetworks
) {
PayWithApplePayButton(.buy) { startPayment() }
} else {
// 显示替代结账方式或配置按钮
Button("设置Apple Pay") { /* 引导用户 */ }
}// WRONG: Dismissing inside didAuthorizePayment
func paymentAuthorizationController(
_ controller: PKPaymentAuthorizationController,
didAuthorizePayment payment: PKPayment,
handler completion: @escaping (PKPaymentAuthorizationResult) -> Void
) {
controller.dismiss() // Too early -- causes blank sheet
completion(.init(status: .success, errors: nil))
}
// CORRECT: Dismiss only in paymentAuthorizationControllerDidFinish
func paymentAuthorizationControllerDidFinish(
_ controller: PKPaymentAuthorizationController
) {
controller.dismiss()
}// 错误:在didAuthorizePayment中关闭控制器
func paymentAuthorizationController(
_ controller: PKPaymentAuthorizationController,
didAuthorizePayment payment: PKPayment,
handler completion: @escaping (PKPaymentAuthorizationResult) -> Void
) {
controller.dismiss() // 时机过早 -- 会导致表单空白
completion(.init(status: .success, errors: nil))
}
// 正确:仅在paymentAuthorizationControllerDidFinish中关闭控制器
func paymentAuthorizationControllerDidFinish(
_ controller: PKPaymentAuthorizationController
) {
controller.dismiss()
}canMakePayments(usingNetworks:)paymentSummaryItemspaymentAuthorizationControllerDidFinish.pkpassPKPassLibrary.isPassLibraryAvailable()PKPaymentButtonPayWithApplePayButtoncanMakePayments(usingNetworks:)paymentSummaryItemspaymentAuthorizationControllerDidFinish.pkpassPKPassLibrary.isPassLibraryAvailable()PKPaymentButtonPayWithApplePayButtonreferences/wallet-passes.mdreferences/wallet-passes.md