Stripe で Apple Pay に対応する

# 概要
Stripe iOS SDKを使用することで Apple Pay決済に簡単に対応することができました。
公式ドキュメントが公開されていますが、日本語の情報がまとまっていないようなので備忘録的にまとめました。
参考になれば幸いです。

# 前提条件
- Stripe
    - クレジットカード決済に対応していること
    - アカウントのROLEが Developer であること （または Administrator であること）
- Apple
    - Certificates, Identifiers & Profiles（証明書、ID、プロファイル）へのアクセスができること

# 設定方法

## Apple Merchant ID を発行する

### Merchant ID とは？
Merchant IDとはApple Payに対して身元を証明するものになります。
Merchant IDに紐づく支払い処理証明書を使い、支払い情報が暗号化されます。
開発時に Merchant ID の発行とそれに紐づく支払い処理証明書を作成する必要があります。

### Merchant IDを発行する
https://developer.apple.com/account/ios/identifier/merchant/create
この画面から Merchant ID を発行することができます。

## Stripe から stripe.certSigningRequest をダウンロードする
https://dashboard.stripe.com/account/apple_pay
+ Add new application をクリックし認証が完了すると stripe.certSigningRequest がダウンロードされます。
これを使用して支払い証明書を作成します。

ダウンロードが完了するとこのような表示なります。Continueをクリックして次にすすめます。
<img width="394" alt="スクリーンショット 2019-05-13 18.53.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68702/bc6eca75-7306-061a-5e59-e09a3db7d0b5.png">
※このときに表示されるポップアップに従い進めることで設定が完了するようになっています。

## Apple Certificate を生成
https://developer.apple.com/account/ios/certificate/
この画面から支払い証明書を作成します。
Apple Pay Merchant Identity Certificateを選択し、CSRファイルのアップロード画面になったら
さきほどの stripe.certSigningRequest をアップロードします。
支払い証明書の作成が完了したらダウンロードします。

## Apple Certificate を Stripe へアップロード
StripeのDashboardに戻り、さきほどポップアップでContinueをクリックします。
<img width="392" alt="スクリーンショット 2019-05-13 18.53.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68702/cc94cc04-f781-4e1a-982d-63176f0baec2.png">

このような表示になったら支払い証明書を Stripe へアップロードします。
<img width="395" alt="スクリーンショット 2019-05-13 18.53.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68702/2c010408-8911-ad68-22ae-b8ede3608ffc.png">


Apple Payの対応は以上で完了になります。


# 実装方法

## Xcode上で設定を変更する
Xcode > TARGETS > Capabilities > Apple Pay
設定をONにし、Merchant ID を追加します。
![ss.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68702/f87f6ba4-37ff-0585-4ef9-cde9b30190ff.png)

## Stripe Configuration に Merchant ID を設定する

```swift
STPPaymentConfiguration.shared().appleMerchantIdentifier = "Your Merchant ID"
```

## Apple Payに対応している端末か判定する
```swift
if PKPaymentAuthorizationViewController.canMakePayments() {
    // Apple Payに対応している端末
} else {
    // Apple Payに対応していない端末
}
```

## 利用可能なクレジットカードが Wallet に登録されているか判定する
SDKで用意されているメソッドを利用することで判定をおこなうことができます。
このメソッドを利用してUIの出し分けなどをおこないます。

```swift
if Stripe.deviceSupportsApplePay() {
    // Walletに利用可能なカードが登録されている
} else {
    // Walletに利用可能なカードが登録されていない
}
```

## Apple Pay ボタンを設置する
PKPaymentButtonType と PKPaymentButtonStyleを指定してボタンを作成します。
Apple Payの設定が完了していない場合は、 PKPaymentButtonType.setUp を指定します。

```swift
PKPaymentButton (paymentButtonType: PKPaymentButtonType.plain, paymentButtonStyle: PKPaymentButtonStyle.black)
```

> plain
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68702/d37d3a2e-c3c0-92a5-ae66-38fd83626e55.png" width=30%>


> setUp
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68702/ada6e863-057a-37c0-ee60-719e927f19bb.png" width=30%>

Apple Payボタンは用意されているものから最適なものを選ぶ必要があります。
iOSのバージョンによって利用できるものが異なるので出し分け処理が必要になります。

## PKPaymentAuthorizationViewControllerを表示
Apple Payボタン押下時にペイメントシートを表示させます。

```swift
let request = Stripe.paymentRequest(withMerchantIdentifier: "Your Merchant ID", country: "JP", currency: "JPY")
let item = PKPaymentSummaryItem(label: "Total", amount: 10000)
request.paymentSummaryItems = [item]
let vc = PKPaymentAuthorizationViewController(paymentRequest: request)!
vc.delegate = self
self.present(vc, animated: true)
```

## PKPaymentAuthorizationViewControllerDelegateを実装
ペイメントシートのイベントをハンドリングするDelegateがいくつか用意されています。
今回は必須 Delegate のみ記載します。詳しくはAppleのドキュメント参照。

ペイメントシートを承認した際に以下のメソッドが呼ばれます。
Token生成後の処理の流れは通常のクレジットカード決済と同じ流れになります。

```swift
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, error == nil else {
            return
        }
        // サーバに必要なデータをPOST
    }
}
```



決済処理が完了した場合もしくはキャンセルされた場合は以下のメソッドが呼ばれます。
PKPaymentAuthorizationViewControllerを dismiss し、必要に応じて完了後の処理をおこないます。

```swift
func paymentAuthorizationViewControllerDidFinish(_ controller: PKPaymentAuthorizationViewController) {
    controller.dismiss(animated: true, completion: nil)
}
```

# テスト方法
Stripeが提供しているテスト用のクレジットカードは Apple Pay 決済に利用できません。
Apple が提供しているものを使用する必要があります。
https://developer.apple.com/apple-pay/sandbox-testing/

# JCBクレジットカードへの対応
v15.0.1でJCBクレジットカードへの対応が追加されました。
https://github.com/stripe/stripe-ios/releases/tag/v15.0.1

```objective_c
+ (void)setJCBPaymentNetworkSupported:(BOOL)JCBPaymentNetworkSupported;
```
このメソッドを使用することでJCBクレジットカードに対応することができます。
※JCBクレジットカードは別途審査が必要になります。

# 関連ドキュメント
https://stripe.com/docs/apple-pay/apps
https://developer.apple.com/design/human-interface-guidelines/apple-pay/overview/introduction/
https://developer.apple.com/apple-pay/
https://developer.apple.com/apple-pay/sandbox-testing/
https://developer.apple.com/documentation/passkit/apple_pay
https://developer.apple.com/documentation/passkit/pkpaymentauthorizationviewcontrollerdelegate
https://developer.apple.com/documentation/passkit/pkpaymentbutton
https://developer.apple.com/documentation/passkit/pkpaymentbuttontype
https://developer.apple.com/documentation/passkit/pkpaymentbuttonstyle