Integrate Apple Pay and Wallet passes with PassKit. Use for payment buttons and requests, authorization, merchant and shipping fields, pass creation or updates, Add to Wallet flows, and eligible physical-goods, service, donation, or recurring-payment checkout.
89%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Accept Apple Pay payments for physical goods, real-world services, donations, and recurring subscriptions, and manage Wallet passes. Targets Swift 6.4 / iOS 26+.
Constraint: A single
PKPaymentRequestsupports at most one optional advanced request type (recurring, automatic reload, deferred, Apple Pay Later, or multi-token). Use separate requests if a transaction requires multiple modes.
merchant.com.example).import PassKit
func isApplePayAvailable() -> Bool {
guard PKPaymentAuthorizationController.canMakePayments() else { return false }
return PKPaymentAuthorizationController.canMakePayments(
usingNetworks: [.visa, .masterCard, .amex],
capabilities: .threeDSecure
)
}If canMakePayments(usingNetworks:capabilities:) returns true, Apple HIG requires Apple Pay to be presented as a primary payment method.
Always use Apple-provided button views. Never draw custom Apple Pay logos:
// SwiftUI
import SwiftUI
import PassKit
PayWithApplePayButton(.buy) {
startPayment()
}
.payWithApplePayButtonStyle(.black)
.frame(height: 48)
// UIKit
let button = PKPaymentButton(paymentButtonType: .buy, paymentButtonStyle: .black)
button.addTarget(self, action: #selector(startPayment), for: .touchUpInside)Construct a PKPaymentRequest with required merchant details and summary items. The final summary item represents the total charged and must use the merchant or company name:
func makePaymentRequest() -> PKPaymentRequest {
let request = PKPaymentRequest()
request.merchantIdentifier = "merchant.com.example.app"
request.countryCode = "US"
request.currencyCode = "USD"
request.supportedNetworks = [.visa, .masterCard, .amex]
request.merchantCapabilities = .threeDSecure
request.paymentSummaryItems = [
PKPaymentSummaryItem(label: "Coffee Beans", amount: NSDecimalNumber(string: "18.00")),
PKPaymentSummaryItem(label: "Shipping", amount: NSDecimalNumber(string: "4.50")),
PKPaymentSummaryItem(label: "Roasters Co.", amount: NSDecimalNumber(string: "22.50")) // Merchant total
]
return request
}Present the payment sheet with PKPaymentAuthorizationController and process token data on your payment processor:
final class CheckoutCoordinator: NSObject, PKPaymentAuthorizationControllerDelegate {
func paymentAuthorizationController(
_ controller: PKPaymentAuthorizationController,
didAuthorizePayment payment: PKPayment,
handler completion: @escaping (PKPaymentAuthorizationResult) -> Void
) {
// Send payment.token.paymentData to payment gateway (e.g. Stripe, Adyen)
Task {
do {
try await PaymentGateway.charge(token: payment.token)
completion(PKPaymentAuthorizationResult(status: .success, errors: nil))
} catch {
completion(PKPaymentAuthorizationResult(status: .failure, errors: [error]))
}
}
}
func paymentAuthorizationControllerDidFinish(_ controller: PKPaymentAuthorizationController) {
controller.dismiss()
}
}Add passes (.pkpass) to Apple Wallet:
let pass = try PKPass(data: passData)
if PKPassLibrary().containsPass(pass) {
// Pass already exists in user's Wallet
} else {
let addController = PKAddPassesViewController(pass: pass)!
present(addController, animated: true)
}paymentSummaryItems MUST be the grand total and its label MUST be the business name.PKPaymentRequest can specify only one advanced mode (e.g. recurring or deferred).completion(...) handler before dismissing the payment controller.canMakePayments(usingNetworks:capabilities:) checked before rendering buttonPayWithApplePayButton or PKPaymentButton usedthienqo/ios-skills
6bf8b62
Canonical home
since May 23, 2026
Also appears in
on Oct 29, 2026
since May 22, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.