LoginSignup
9
5

More than 5 years have passed since last update.

Stripe で Apple Pay を使う

Posted at

StripeApple 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ステップあって、

  1. Stripe から CSR を入手
  2. それを使って Apple の certificate を生成
  3. その 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...
//            }
//        })
    }
}

参考

9
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5