Stripe と Apple Pay の連携について調べているので、その調査結果です。
Apple Pay in Apps - stripe.com
Stripe で Apple Pay を使うときの概要。
ApplePay に必要なもの
- merchant ID
- entitlements to your app
必須条件
- iOS8.1 以上
- a newer iOS device (iPhone 6 or 6+, iPad Air 2, or iPad mini 3)
Stripe.deviceSupportsApplePay()
などのメソッドがあるのでそれで判断できる。
手数料
- Stripe を使うので手数料がかかる(3.6%)
- IAP ではないので 30% は取られない
Apple Merchant ID
http://developer.apple.com/account/ios/identifiers/merchant/merchantCreate.action
ここで Merchant ID が 取得できる。
Apple Pay vs. In-App Purchases
Apple Pay は IAP の置き換えにはならない。
Apple Pay は物理商品を買うため、 IAP はデジタル商品を買うためなどの役割がある。
Creating a new Apple Pay certificate
3ステップあって、
- Stripe から CSR を入手
- それを使って Apple の certificate を生成
- http://developer.apple.com/account/ios/certificate/certificateCreate.action
- ここで DL した certificate を stripe にアップロードするから、これは使わない
- その certificate を stripe に登録

Integrating with Xcode
Capabilities の Apple Pay を ON にして merchant id を stripe に渡す。
stripeConfig.appleMerchantIdentifier = "merchant id"
実行する
Stripe Starndard Integration のサンプルを動かすと Apple Pay が有効になってる、購入直前まで行けた(購入はサーバサイドなので検証にちょっと手間)。
しかし Standard だと Stripe 側に住所入力をした後に Apple Pay 支払いになるため、 Apple Pay に登録した住所を利用することができなかった。
そのため Custom Integration をやる必要がありそう。
Custom iOS Integration#apple-pay - Stripe
Stripe に縛られずに Apple Pay を使う。
PKPaymentRequest
let merchantIdentifier = "merchant id"
let paymentRequest = Stripe.paymentRequest(withMerchantIdentifier: merchantIdentifier, country: "JP", currency: "JPY")
これで PKPaymentRequest
を取得できる。
これは Apple が提供しているもので、Apple Pay でユーザに入力して欲しい設定などを追加できる。 PKPaymentRequest - PassKit | Apple Developer Documentation
Apple Payプログラミングガイド:ペイメントリクエストの作成 に詳しい説明がある。
アイテムと合計を設定
paymentRequest.paymentSummaryItems = [
PKPaymentSummaryItem(label: "Fancy Hat", amount: 500.00),
PKPaymentSummaryItem(label: "iHats, Inc", amount: 1000.00),
PKPaymentSummaryItem(label: "Total", amount: 1500.00),
]
合計金額は最後の行に設定すること。
入力必須項目の設定
paymentRequest.requiredShippingContactFields = [.postalAddress]
配送先住所も入力して欲しいので、 .postalAddress
を設定。
なお、 requiredShippingContactFields
は iOS11 からので、iOS10 以下は requiredShippingAddressFields
を使う必要がある。
Apple Pay の View を表示
let paymentAuthorizationViewController = PKPaymentAuthorizationViewController(paymentRequest: paymentRequest)!
paymentAuthorizationViewController.delegate = self
present(paymentAuthorizationViewController, animated: true)
これで画面下からニュッっと Apple Pay の支払い画面が出てくる。
Payment Token を受け取る
paymentAuthorizationViewController(_:didAuthorizePayment:handler:) - PKPaymentAuthorizationViewControllerDelegate | Apple Developer Documentation の Delegate を実装する。
ユーザが Apple Pay での支払いを行うと、 PKPayment オブジェクトを取得できる。 PKPayment にはユーザが入力した住所情報が含まれているため、このタイミングで Apple Pay で設定した住所を取得できる。
この PKPayment を Stripe SDK に渡してカードトークンを取得し、サーバサイドで決済を行う。
func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewController, didAuthorizePayment payment: PKPayment, completion: @escaping (PKPaymentAuthorizationStatus) -> Void) {
STPAPIClient.shared().createToken(with: payment) { (token: STPToken?, error: Error?) in
guard let token = token else {
print(error?.localizedDescription ?? "")
return
}
print(token)
// サーバにトークンを送信して支払いを行う。
// 失敗した場合は completion(.failure)
// 成功した場合は ↓
completion(.success)
}
}
全体像

extension StripeSamplesTableViewController: PKPaymentAuthorizationViewControllerDelegate {
private func applePay() {
print(#function)
let merchantIdentifier = "merchant id"
let paymentRequest = Stripe.paymentRequest(withMerchantIdentifier: merchantIdentifier, country: "JP", currency: "JPY")
// Configure the line items on the payment request
paymentRequest.paymentSummaryItems = [
PKPaymentSummaryItem(label: "Fancy Hat", amount: 500.00),
PKPaymentSummaryItem(label: "iHats, Inc", amount: 1000.00),
PKPaymentSummaryItem(label: "Total", amount: 1500.00),
]
paymentRequest.merchantCapabilities = .capability3DS
paymentRequest.requiredShippingContactFields = [.postalAddress]
if Stripe.canSubmitPaymentRequest(paymentRequest) {
// Setup payment authorization view controller
let paymentAuthorizationViewController = PKPaymentAuthorizationViewController(paymentRequest: paymentRequest)!
paymentAuthorizationViewController.delegate = self
// Present payment authorization view controller
present(paymentAuthorizationViewController, animated: true)
}
else {
// There is a problem with your Apple Pay configuration
}
}
func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewController, didAuthorizePayment payment: PKPayment, completion: @escaping (PKPaymentAuthorizationStatus) -> Void) {
print(#function)
print(payment.shippingContact?.postalAddress?.country ?? "")
print(payment.shippingContact?.postalAddress?.city ?? "")
STPAPIClient.shared().createToken(with: payment) { (token: STPToken?, error: Error?) in
guard let token = token else {
print(error?.localizedDescription ?? "")
return
}
print(token)
completion(.success)
// submitTokenToBackend(token, completion: { (error: Error?) in
// if let error = error {
// // Present error to user...
//
// // Notify payment authorization view controller
// completion(.failure)
// }
// else {
// // Save payment success
// paymentSucceeded = true
//
// // Notify payment authorization view controller
// completion(.success)
// }
// })
}
}
func paymentAuthorizationViewControllerDidFinish(_ controller: PKPaymentAuthorizationViewController) {
print(#function)
dismiss(animated: true, completion: nil)
// dismiss(animated: true, completion: {
// if (paymentSucceeded) {
// // Show a receipt page...
// }
// })
}
}