# Issuing でデジタルウォレットを使用する Issuing を使用してデジタルウォレットにカードを追加する方法をご紹介します。 > デジタルウォレットトークンは本番環境でのみご利用いただけます。この機能を完全にテストするには、本番のユースケースが承認され、実際のカードを使用する必要があります。 Issuing を使用すると、ユーザーは Apple Pay や Google Pay などのデジタルウォレットにカードを追加できます。Stripe は、以下の 2 つの方法でカードの追加をサポートしています。 1. **手動のプロビジョニング:** カード保有者は、スマホのウォレットアプリケーションにカード情報を入力して、デジタルウォレットに追加します。 1. **プッシュプロビジョニング:** モバイルアプリケーションでは、ユーザーがアプリから直接、デジタルウォレットにカードを追加できます。 カードがデジタルウォレットに追加されると、そのカードのトークン化された表記が作成されます。ネットワークトークンは、カードとは別に管理されます。ネットワークトークンとその仕組みについて、詳細は[トークン管理](https://docs.stripe.com/issuing/controls/token-management.md)をご覧ください。 ## 手動のプロビジョニング カード保有者は、手動のプロビジョニングを使用して、Stripe Issuing の[バーチャルカード](https://docs.stripe.com/issuing/cards/virtual.md)と[物理カード](https://docs.stripe.com/issuing/cards/physical.md)を Apple Pay、Google Pay、Samsung Pay のウォレットに追加できます。 これを行うには、カード保有者はスマートフォンでウォレットアプリを開いてカード詳細を入力します。Stripe は、カードに関連付けられたカード保有者の `phone_number` または `email` に 6 桁の確認コードを送信します。 カードのプロビジョニング時にカード会員にいずれのフィールドも設定されていない場合は、`card not supported` (カードはサポートされていません) というエラーが表示されます。 手動のプロビジョニングの実装にコードは必要ありませんが、設定のプロセスは、デジタルウォレットのプロバイダーと本拠を置く国によって異なることがあります。 ### アメリカ Apple Pay ウォレットは Apple の承認が必要です。[デジタルウォレットの設定](https://dashboard.stripe.com/settings/issuing/digital-wallets) でお客様のアカウントの Apple Pay のステータスをご確認ください。Apple Pay のご利用前に申し込みが必要な場合があります。申し込みから承認まで 1 ~ 2 週間かかる場合があります。 Google Pay と Samsung Pay では、これ以外のステップは必要ありません。 ### EU およびイギリス デジタルウォレットを導入するには、Stripe パートナーシップチームからの追加承認が必要です。詳細については、アカウント代表者に連絡するか、[Stripe にお問い合わせください](https://stripe.com/contact/sales)。 Apple Pay ウォレットには、追加の承認が必要です。アカウントの Apple Pay のステータスを確認するには、[デジタルウォレット設定](https://dashboard.stripe.com/settings/issuing/digital-wallets)を確認します。Apple Pay のご利用前に、申請書の提出が必要になる場合があります。 ## プッシュプロビジョニング プッシュプロビジョニングは、カード会員が下図のように「ウォレットに追加」ボタンをタップすることで、Stripe Issuing のカードを貴社のアプリから自信のデジタルウォレットに直接追加できる機能です。 アメリカでプッシュプロビジョニングを有効にするには、ユーザーは最初に手動のプロビジョニング手順を完了する必要があります。プッシュプロビジョニングでは、手動でのプロビジョニングの承認に加え、Stripe SDK を導入しなければなりません。 そのためには、プッシュプロビジョニングのサポートを希望するプラットフォームごとに、Stripe の承認プロセスと、Stripe SDK によるコード実装の両方が必要になります。プラットフォームでの承認は、その連結アカウントのすべてに段階的に適用されます。 Samsung Pay のプッシュプロビジョニングは、Stripe の SDK ではサポートされていません。 # iOS > This is a iOS for when platform is ios. View the full page at https://docs.stripe.com/issuing/cards/digital-wallets?platform=ios. ![「Add to Apple Wallet」という黒色の UI ボタン。テキストの左側には Apple Wallet ロゴイメージがあります。青、黄、緑、赤のカードが少しずつずれて重なっているグレーのウォレットです。](https://b.stripecdn.com/docs-statics-srv/assets/add_to_apple_wallet.fe8cd234760a7478e34f5e91d22677bb.png) ## アクセスをリクエストする > プッシュプロビジョニングをリクエストする前に[手動のプロビジョニング](https://docs.stripe.com/issuing/cards/digital-wallets.md?platform=android#manual-provisioning)にアクセスする必要があります。 プッシュプロビジョニングには、`com.apple.developer.payment-pass-provisioning` と呼ばれる Apple からの特別なエンタイトルメントが必要です。これは [support-issuing@stripe.com](mailto:support-issuing@stripe.com) にメールを送信して、リクエストすることができます。メールには、以下の内容を含めてください。 - **カードネットワーク**: Visa または MasterCard。 - **カード名**:ウォレットに表示されるカードの名前。 - **アプリ名**: お使いのアプリの名前。 - **開発者チーム ID**: [メンバーシップ](https://developer.apple.com/account/#/membership) (例: `2A23JCNA5E`) の Apple 開発者アカウント設定にあります。 - **ADAM ID**: アプリの固有の数字 ID。[App Store Connect](https://appstoreconnect.apple.com)、または App Store のアプリリンク (例: `https://apps.apple.com/app/id123456789`) で確認できます。 - **バンドル ID**: アプリのバンドル ID。App Store Connect (例: `com.example.yourapp`) にも記載されています。 上記の属性に関する別のフィールドが設定されたアプリ (テストアプリなど) が複数ある場合は、アクセス権を個別にリクエストする必要があります。 リクエストが承認されて適用されると、Wallet アプリのプロビジョニングされたカードの詳細ページにアプリが表示され、`PKPassLibrary().passes()` を呼び出すことで `PKSecureElementPass` オブジェクトをアプリで使用できるようになります。変更を有効にするために、カードを削除して再びプロビジョニングする必要が生じる場合があります。 ## 利用資格を確認 [クライアント側] 最新バージョンの [Stripe iOS SDK](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=mobile&platform=ios) を貴社のアプリに統合していることをご確認ください。 デバイスにプッシュプロビジョニングを使用する資格があるかどうかを判断します。 1. 発行されたカードの `wallets[apple_pay][eligible]` の値が `true` であることを確認します。 1. カードの `wallets[primary_account_identifier]` を指定して `PKPassLibrary().canAddSecureElementPass(primaryAccountIdentifier:)` を呼び出し、結果が `true` であることを確認します。`primary_account_identifier` が空である場合は、空の文字列を `canAddSecureElementPass()` に渡します。 これらの値をバックエンドで取得し、アプリに渡して利用資格を確認します。 > `PKAddPassButton` を表示する前に、サーバー側の `wallets[apple_pay][eligible]` フラグと `canAddSecureElementPass()` の結果を確認する必要があります。これらの値を確認せずに **Apple Wallet に追加**ボタンを表示すると、アプリの審査でアプリが拒否される場合があります。 #### Swift ```swift import Stripe class MyViewController: UIViewController { @IBOutlet weak var addPassButton: PKAddPassButton! // ... func handleEligibilityResponse(eligible: Bool, primaryAccountIdentifier: String?) { if eligible && PKPassLibrary().canAddSecureElementPass(primaryAccountIdentifier: primaryAccountIdentifier ?? "") { addPassButton.isHidden = false } else { addPassButton.isHidden = true } } } ``` 詳細については、サンプルアプリの各ステップのコードスニペットとリファレンスをご覧ください。このステップについては、[サンプルアプリ](https://github.com/stripe-samples/push-provisioning-samples/blob/main/client/ios/Code/ViewController.swift#L201-L218)で適格性を確認する方法をご覧ください。 ## カードをプロビジョニングする [クライアント側] ユーザーが `PKAddPassButton` をタップしたら、プッシュプロビジョニングフローのための Apple UI が含まれる `PKAddPaymentPassViewController` を作成して表示します。 `PKAddPaymentPassViewController` は、前のステップの `primaryAccountIdentifier` を使用して、カードが特定のデバイスですでにプロビジョニングされているかどうかを判断できます。たとえば、カードがすでに iPhone に追加されている場合は、Apple UI はペアリングされた Apple Watch にカードを追加することを提案します。 #### Swift ```swift import Stripe class MyViewController: UIViewController { // ... func beginPushProvisioning() { let config = STPPushProvisioningContext.requestConfiguration( withName: "Jenny Rosen", // the cardholder's name description: "RocketRides Card", // optional; a description of your card last4: "4242", // optional; the last 4 digits of the card brand: .visa, // optional; the brand of the card primaryAccountIdentifier: self.primaryAccountIdentifier // the primary_account_identifier value from the previous step ) let controller = PKAddPaymentPassViewController(requestConfiguration: config, delegate: self) self.present(controller!, animated: true, completion: nil) } } ``` 詳細については、[サンプルアプリ](https://github.com/stripe-samples/push-provisioning-samples/blob/main/client/ios/Code/ViewController.swift#L280-L288)で `PKAddPaymentPassViewController` を使用する方法をご覧ください。 `PKAddPaymentPassViewController`のイニシャライザーは、実装が必要なデリゲートを受け取ります。これは通常、それを表示するビューコントローラーにのみできます。Stripe では、 `STPPushProvisioningContext` と呼ばれるクラスを提供し、これらのメソッドを実装できるようにしています。 #### Swift ```swift class MyViewController: UIViewController { var pushProvisioningContext: STPPushProvisioningContext? = nil // ... } extension MyViewController: PKAddPaymentPassViewControllerDelegate { func addPaymentPassViewController(_ controller: PKAddPaymentPassViewController, generateRequestWithCertificateChain certificates: [Data], nonce: Data, nonceSignature: Data, completionHandler handler: @escaping (PKAddPaymentPassRequest) -> Void) { self.pushProvisioningContext = STPPushProvisioningContext(keyProvider: self) // STPPushProvisioningContext implements this delegate method for you, by retrieving encrypted card details from the Stripe API. self.pushProvisioningContext?.addPaymentPassViewController(controller, generateRequestWithCertificateChain: certificates, nonce: nonce, nonceSignature: nonceSignature, completionHandler: handler); } func addPaymentPassViewController(_ controller: PKAddPaymentPassViewController, didFinishAdding pass: PKPaymentPass?, error: Error?) { // Depending on if `error` is present, show a success or failure screen. self.dismiss(animated: true, completion: nil) } } ``` 詳細については、[サンプルアプリ](https://github.com/stripe-samples/push-provisioning-samples/blob/main/client/ios/Code/ViewController.swift#L293-L349)で `PKAddPaymentPassViewControllerDelegate` を実装する方法をご覧ください。 `STPPushProvisioningContext` のイニシャライザーが `keyProvider` を要求していることがわかります。これは、`STPIssuingCardEphemeralKeyProvider` プロトコルを実装するクラスのインスタンスです。 このプロトコルは、単一の必須メソッド `createIssuingCardKeyWithAPIVersion:completion` を定義します。このメソッドを実装するには、バックエンドに API コールを実行します。バックエンドが Stripe API を使用して一時キーオブジェクトを作成し、アプリに返します。次に、アプリはバックエンドの API レスポンスを使用して、指定された完了ハンドラを呼び出します。 #### Swift ```swift extension MyViewController: STPIssuingCardEphemeralKeyProvider { func createIssuingCardKey(withAPIVersion apiVersion: String, completion: @escaping STPJSONResponseCompletionBlock) { // This example uses Alamofire for brevity, but you can make the request however you want AF.request("https://myapi.com/ephemeral_keys", method: .post, parameters: ["api_version": apiVersion]) .responseJSON { response in switch response.result { case .success: if let data = response.data { do { let obj = try JSONSerialization.jsonObject(with: data, options: []) as! [AnyHashable: Any] completion(obj, nil) } catch { completion(nil, error) } } case .failure(let error): completion(nil, error) } } } } ``` 詳細については、[サンプルアプリ](https://github.com/stripe-samples/push-provisioning-samples/blob/main/client/ios/Code/ViewController.swift#L379-L394)で `STPIssuingCardEphemeralKeyProvider` を実装する方法をご覧ください。 ## バックエンドを更新する [サーバ側] プッシュプロビジョニングの実装によって公開されるメソッドでは、お客様が自身のバックエンドとやり取りをし、Stripe の一時キーを作成してその JSON をアプリに返すことが求められます。このキーは有効期間の短い API 認証情報で、暗号化されたカード詳細の取得に使用でき、それがカードオブジェクトの単一インスタンスに使用されます。 Stripe API によって返されるオブジェクトがお使いの iOS または Android の SDK と互換性があることを確認するために、Stripe SDK では、優先される API バージョンを確認できます。キーを作成する際は、Stripe API に対してこの API バージョンを明示的に渡す必要があります。 #### curl ```bash curl https://api.stripe.com/v1/ephemeral_keys \ -u <>: \ -d "issuing_card"="{{ISSUING_CARD_ID}}" \ -H "Stripe-Version: {{API_VERSION}}" ``` ```json { "id": "ephkey_1G4V6eEEs6YsaMZ2P1diLWdj", "object": "ephemeral_key", "associated_objects": [ { "id": "{{CARD_ID}}", "type": "issuing.card" } ], "created": 1586556828, "expires": 1586560428, "livemode": false, "secret": "ek_test_YWNjdF8xRmdlTjZFRHelWWxwWVo5LEtLWFk0amJ2N0JOa0htU1JzEZkd2RpYkpJdnM_00z2ftxCGG" } ``` 詳細については、[サンプルバックエンド](https://github.com/stripe-samples/push-provisioning-samples/blob/main/server/ruby/README.md)で [Stripe の一時キー](https://github.com/stripe-samples/push-provisioning-samples/blob/main/server/ruby/server.rb#L68-L88)を作成する方法をご覧ください。 ## テスト `com.apple.developer.payment-pass-provisioning` エンタイトルメントは、配信プロビジョニングプロファイルでのみ機能します。このため、エンタイトルメントの取得後も、エンドツーエンドのプッシュプロビジョニングのフローをテストする唯一の方法は、アプリを TestFlight または App Store で配信することです。 テストを支援するために、テスト中に同じ意味で使用できる`STPFakeAddPaymentPassViewController`と呼ばれる`PKAddPaymentPassViewController`のダミーバージョンを提供しています。これは、テストモードカードを使用した[テストモード](https://docs.stripe.com/testing-use-cases.md#test-versus-live-mode)でのみ動作します。 #### Swift ```swift import Stripe class MyViewController: UIViewController { // ... func beginPushProvisioning() { let config = STPPushProvisioningContext.requestConfiguration( withName: "Jenny Rosen", // the cardholder's name description: "RocketRides Card", // optional; a description of your card last4: "4242", // optional; the last 4 digits of the card brand: .visa // optional; the brand of the card )let controller = STPFakeAddPaymentPassViewController(requestConfiguration: config, delegate: self) self.present(controller!, animated: true, completion: nil) } } ``` サンプルアプリを作成するには、[readme](https://github.com/stripe-samples/push-provisioning-samples/blob/main/client/ios/README.md) の手順に従います。上記の手順に従うために、アプリを作成する必要はありません。 # Android > This is a Android for when platform is android. View the full page at https://docs.stripe.com/issuing/cards/digital-wallets?platform=android. ![「Google ウォレットに追加」という黒い UI ボタン。テキストの左側に Google ウォレットのロゴ画像があります。](https://b.stripecdn.com/docs-statics-srv/assets/add_to_google_pay_black.2df6c169bbc605123ec73d37dc73a86e.png) ## アクセスをリクエストする > プッシュプロビジョニングをリクエストする前に[手動のプロビジョニング](https://docs.stripe.com/issuing/cards/digital-wallets.md?platform=android#manual-provisioning)にアクセスする必要があります。 Stripe はプッシュプロビジョニング用にプライベート Google ライブラリで SDK ラッパーを提供しています。プッシュプロビジョニングを使用して Google Pay Store でアプリを配信するには、以下を行う必要があります。 1. [Google Pay へのアクセスをリクエスト](https://developers.google.com/pay/issuers/requesting-access?api=true)します。フォームに入力した後、数時間~ 1 日以内に承認されます。 1. 承認を受けた後、Google の [TapAndPay プライベート SDK](https://developers.google.com/pay/issuers/apis/push-provisioning/android/releases) をダウンロードします。TapAndPay SDK のテスト済みの最新バージョンはバージョン 18 です。 1. アプリの[Push Provisioning API Access Request (Push Provisioning API へのアクセスをリクエスト)](https://support.google.com/faqs/contact/pp_api_allowlist) を行います。Google の許可リストに追加する[アプリケーション ID](https://developer.android.com/studio/build/application-id) を指定する必要があります。このプロセスの詳細については、Google の[ドキュメント](https://developers.google.com/pay/issuers/apis/push-provisioning/android/allowlist)をご覧ください。このプロセスが完了すると、Google から Push Provisioning の資格が付与されます。 1. Google がプッシュプロビジョニングの資格を付与したら、アプリケーション名、アプリケーション ID、カード ネットワーク、カード名を [Stripe に連絡](mailto:support-issuing@stripe.com)して、このステップを完了してください。 ## アプリを更新する [クライアント側] アプリを更新するには、以下の手順を実行します。 1. Google の[プライベート SDK](https://developers.google.com/pay/issuers/apis/push-provisioning/android/setup) をインポートします。 1. Stripe の SDK をインポートします。 ```java dependencies { [... your dependencies] implementation 'com.stripe:stripe-android-issuing-push-provisioning:1.2.2' } ``` 詳細については、サンプルアプリの各ステップのコードスニペットとリファレンスをご覧ください。このステップについては、[サンプルアプリ](https://github.com/stripe-samples/push-provisioning-samples/blob/main/client/android/app/build.gradle.kts#L111-L118)でこれらの SDK をインポートする方法をご覧ください。 - カード用の一時キーを作成するため、バックエンドを準備します。[以下のセクションを参照してください](https://docs.stripe.com/issuing/cards/digital-wallets.md#backend-changes)。 - `PushProvisioningEphemeralKeyProvider` を拡張する `EphemeralKeyProvider` を作成します。一時キープロバイダーは別のアクティビティに渡されるため、`Parcelable` も実装する必要があります ([Parcelable](https://developer.android.com/reference/android/os/Parcelable) を参照)。詳細については、[サンプルアプリ](https://github.com/stripe-samples/push-provisioning-samples/blob/main/client/android/app/src/main/java/com/stripe/android/pushprovisioning/network/BackendPushProvisioningEphemeralKeyProvider.kt#L20-L43)を使用して `EphemeralKeyProvider` を定義する方法をご覧ください。 - [Google の仕様に合わせて](https://developers.google.com/pay/issuers/apis/push-provisioning/android/branding-guidelines) **Google Pay に追加**ボタンを実装します。[サンプルアプリ](https://github.com/stripe-samples/push-provisioning-samples/blob/main/client/android/app/src/main/res/layout/card_picker_item.xml#L19-L25)では、ブランディングガイドラインに従うボタンの例が提供されています。 > Google で[推奨](https://developers.google.com/pay/issuers/apis/push-provisioning/android/faq#implementation_questions)されているように、ユーザーに Google Pay アプリのインストールを要求したり、またはアプリがあるかどうかをプログラムで確認しないでください。このアプリはフロントエンドにすぎず、これがなくても Google Pay は機能します。ユーザーは、「設定」アプリの Google 設定内でカードを管理できます。 Google では、カードがまだユーザーのデバイスに登録されていない場合にのみ **Google Pay に追加**ボタンが表示され、カードが検証されていないユーザーは、ガイドに従って最終的な有効化プロセスを完了させる必要があります。Google の[チェックポイントのリスト](https://developers.google.com/pay/issuers/apis/push-provisioning/android/test-cases)を使用して、実装が正しいことを確認してください。 ユーザーのカードのステータスを確認するには、[listTokens()](https://developers.google.com/pay/issuers/apis/push-provisioning/android/reading-wallet#listtokens) を使用して、デバイスにすでに表示されているすべてのカードのリストを取得します。返された各オブジェクトの `getFpanLastFour()` の値を、追加するカードの[発行済みの Card オブジェクト](https://docs.stripe.com/api/issuing/cards/object.md)にある Stripe の [last4](https://docs.stripe.com/api/issuing/cards/object.md#issuing_card_object-last4) プロパティと比較します。一致しないオブジェクトはすべてレスポンスリストから破棄します。 - 結果のリストが空の場合は、追加しようとしているカードがまだデバイスで提示されていないことを意味します。後述のように、ボタンを表示するための処理を行うことができます。 - 結果リストに `TokenInfo` オブジェクトが含まれている場合は、`getTokenState()` を呼び出して、[TokenState](https://developers.google.com/pay/issuers/apis/push-provisioning/android/enumerated-values#token_status) を確認してください。 - ステータスが `TOKEN_STATE_NEEDS_IDENTITY_VERIFICATION` である場合、ユーザーはすでに特定のカードを手動でデバイスへ追加しようと試みています。**Google Pay に追加**ボタンは表示しますが、[Google のドキュメントに概要が示されている](https://developers.google.com/pay/issuers/apis/push-provisioning/android/wallet-operations#resolving_yellow_path)ように、`onActivityResult` リスナーを `tokenize()` メソッドにワイヤリングすることにより、ユーザーがこの状況から回復できるようにします。 - その他のステータスの場合は、クレジットカードはすでにデバイスに登録されています。**「Google Pay」ボタンを表示しないでください。** 内部テストを開始する前に、必ず、アプリケーション ID を Stripe に提供してください。設定には 1 週間以上かかり、設定が不完全である場合には、これらの 2 つのメソッドに対して矛盾したレスポンスを受信するといった結果が生じます。`listTokens()` の結果には、Stripe で設定が完了した**後に追加されたカードのみが含まれます**。 ユーザがボタンをタップしたときに、`PushProvisioningActivityStarter` を使用して Stripe の `PushProvisioningActivity` を起動します。 ```java new PushProvisioningActivityStarter( this, // The Activity or Fragment you are initiating the push provisioning from new PushProvisioningActivityStarter.Args( "Stripe Card", // The name that will appear on the push provisioning UI ephemeralKeyProvider, // Your instance of EphemeralKeyProvider false // If you want to enable logs or not )).startForResult(); ``` 詳細については、[サンプルアプリ](https://github.com/stripe-samples/push-provisioning-samples/blob/main/client/android/app/src/main/java/com/stripe/android/pushprovisioning/MainActivity.kt#L119-L124)を使用して `PushProvisioningActivity` を開始する方法をご覧ください。 これによってプッシュプロビジョニングが準備され、カードをウォレットに追加する UI が起動されます。`onActivityResult` にコールバックを実装してください。 ```java protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { if (requestCode == PushProvisioningActivityStarter.REQUEST_CODE) { if (resultCode == PushProvisioningActivity.RESULT_OK) { PushProvisioningActivityStarter.Result success = PushProvisioningActivityStarter.Result.fromIntent(data); } else if (resultCode == PushProvisioningActivity.RESULT_ERROR) { PushProvisioningActivityStarter.Error error = PushProvisioningActivityStarter.Error.fromIntent(data); } } } ``` 詳細については、[サンプルアプリ](https://github.com/stripe-samples/push-provisioning-samples/blob/main/client/android/app/src/main/java/com/stripe/android/pushprovisioning/MainActivity.kt#L132-L167)を使用して `onActivityResult` を実装する方法をご覧ください。 プロビジョニングが成功すると、`PushProvisioningActivityStarter.Result` が受信されます。ここには、アクティブなウォレットのカードの Google ID である、`cardTokenId` が含まれます。この ID を使用してウォレットのその他の機能を使用できます。 プロビジョニングでエラーが発生すると、`code` と `message` とともに `PushProvisioningActivityStarter.Error` が返されます。`message` は開発者にとって分かりやすく書かれた、エラーを説明するテキストです。 `code` の値は以下のいずれかです。 | 列挙値 | 意味 | | ------------------------------------------------- | ---------------------------------------------------------------- | | **USER\_CANCELED** | ユーザはプロビジョニングをキャンセルしました。 | | **CARD\_CANCELED** | そのカードはキャンセルされたか、紛失または盗難が報告されており、プロビジョニングできません。 | | **EPHEMERAL\_KEY\_ERROR** | 一時キーの取得中にエラーが発生しました。 | | **TAP\_AND\_PAY\_UNAVAILABLE** | TapAndPay ライブラリを使用できません。理由はおそらく、アプリが許可リストに追加されていないためです。 | | **NO\_STABLE\_HARDWARE\_ID** | これは開発エミュレータで発生することがあります。アプリが安定したハードウェア ID を取得できません。 | | **NO\_ACTIVE\_WALLET\_FOUND** | アクティブなウォレットがありません。一般にエミュレータには Google Pay がありません。 | | **PUSH\_PROVISIONING\_ENCRYPTED\_PAYLOAD\_ERROR** | プッシュプロビジョニング用の暗号化されたペイロードを取得するために Stripe のサーバに接続する際に、エラーが発生しました。 | | **UNKNOWN\_ERROR** | 予期しないエラーが発生しました。`message` に追加情報が示されています。 | ## バックエンドを更新する [サーバ側] プッシュプロビジョニングの実装によって公開されるメソッドでは、お客様が自身のバックエンドとやり取りをし、Stripe の一時キーを作成してその JSON をアプリに返すことが求められます。このキーは有効期間の短い API 認証情報で、暗号化されたカード詳細の取得に使用でき、それがカードオブジェクトの単一インスタンスに使用されます。 Stripe API によって返されるオブジェクトがお使いの iOS または Android の SDK と互換性があることを確認するために、Stripe SDK では、優先される API バージョンを確認できます。キーを作成する際は、Stripe API に対してこの API バージョンを明示的に渡す必要があります。 #### curl ```bash curl https://api.stripe.com/v1/ephemeral_keys \ -u <>: \ -d "issuing_card"="{{ISSUING_CARD_ID}}" \ -H "Stripe-Version: {{API_VERSION}}" ``` ```json { "id": "ephkey_1G4V6eEEs6YsaMZ2P1diLWdj", "object": "ephemeral_key", "associated_objects": [ { "id": "{{CARD_ID}}", "type": "issuing.card" } ], "created": 1586556828, "expires": 1586560428, "livemode": false, "secret": "ek_test_YWNjdF8xRmdlTjZFRHelWWxwWVo5LEtLWFk0amJ2N0JOa0htU1JzEZkd2RpYkpJdnM_00z2ftxCGG" } ``` 詳細については、[サンプルバックエンド](https://github.com/stripe-samples/push-provisioning-samples/blob/main/server/ruby/README.md)で [Stripe の一時キー](https://github.com/stripe-samples/push-provisioning-samples/blob/main/server/ruby/server.rb#L68-L88)を作成する方法をご覧ください。 ## テスト テストはすべて、本番環境で本番の Issuing カードを実際のデバイスで使用して行ってください。 サンプルアプリを作成するには、[readme](https://github.com/stripe-samples/push-provisioning-samples/blob/main/client/android/README.md) の手順に従います。上記の手順に従うために、アプリを作成する必要はありません。 # React Native > This is a React Native for when platform is react-native. View the full page at https://docs.stripe.com/issuing/cards/digital-wallets?platform=react-native. ![「Add to Apple Wallet」という黒色の UI ボタン。テキストの左側には Apple Wallet ロゴイメージがあります。青、黄、緑、赤のカードが少しずつずれて重なっているグレーのウォレットです。](https://b.stripecdn.com/docs-statics-srv/assets/add_to_apple_wallet.fe8cd234760a7478e34f5e91d22677bb.png) ![「Google ウォレットに追加」という黒い UI ボタン。テキストの左側に Google ウォレットのロゴ画像があります。](https://b.stripecdn.com/docs-statics-srv/assets/add_to_google_pay_black.2df6c169bbc605123ec73d37dc73a86e.png) ## アクセスをリクエストする > プッシュプロビジョニングをリクエストする前に[手動のプロビジョニング](https://docs.stripe.com/issuing/cards/digital-wallets.md?platform=android#manual-provisioning)にアクセスする必要があります。 ### iOS のアクセスをリクエストする プッシュプロビジョニングには、`com.apple.developer.payment-pass-provisioning` と呼ばれる Apple からの特別なエンタイトルメントが必要です。これは [support-issuing@stripe.com](mailto:support-issuing@stripe.com) にメールを送信して、リクエストすることができます。メールには、以下の内容を含めてください。 - **カードネットワーク**: Visa または MasterCard。 - **カード名**:ウォレットに表示されるカードの名前。 - **アプリ名**: お使いのアプリの名前。 - **開発者チーム ID**: [メンバーシップ](https://developer.apple.com/account/#/membership)の Apple 開発者アカウント設定にあります。 - **ADAM ID**: アプリの固有の数字 ID。[App Store Connect](https://appstoreconnect.apple.com)、または App Store のアプリリンク (例: `https://apps.apple.com/app/id123456789`) で確認できます。 - **バンドル ID**: アプリのバンドル ID。App Store Connect (例: `com.example.yourapp`) にも記載されています。 ### Android のアクセスをリクエストする Stripe はプッシュプロビジョニング用にプライベート Google ライブラリで SDK ラッパーを提供しています。プッシュプロビジョニングを使用して Google Pay Store でアプリを配信するには、このライブラリへのアクセスをリクエストする必要があります。 - [Google Pay へのアクセスをリクエストする](https://developers.google.com/pay/issuers/requesting-access?api=true) - Google の [TapAndPay プライベート SDK](https://developers.google.com/pay/issuers/apis/push-provisioning/android/releases) をダウンロードする (現在互換性のあるバージョンは [17.1.2](https://developers.google.com/static/pay/issuers/apis/push-provisioning/android/downloads/tapandpay_sdk.m2repo_2021-07-19_v17.1.2.zip)) - [アプリのプッシュプロビジョニング API へのアクセスをリクエストします](https://support.google.com/faqs/contact/pp_api_allowlist)。Google の許可リストに追加するための[アプリケーション ID](https://developer.android.com/studio/build/application-id) を指定する必要があります。このプロセスの詳細については、Google の[ドキュメント](https://developers.google.com/pay/issuers/apis/push-provisioning/android/allowlist)をご覧ください。 - 同じアプリケーション ID、アプリ名、カードネットワーク、カード名を [support-issuing@stripe.com](mailto:support-issuing@stripe.com) に提出します。 ## アプリを設定する [クライアント側] [React Native SDK](https://github.com/stripe/stripe-react-native) はオープンソースであり、詳細なドキュメントが提供されています。内部では、[ネイティブの iOS](https://github.com/stripe/stripe-ios) および [Android](https://github.com/stripe/stripe-android) の SDK を使用します。Stripe の React Native SDK をインストールするには、プロジェクトのディレクトリーで (使用するパッケージマネージャーによって異なる) 次のいずれかのコマンドを実行します。 #### yarn ```bash yarn add @stripe/stripe-react-native ``` #### npm ```bash npm install @stripe/stripe-react-native ``` 次に、その他の必要な依存関係をインストールします。 - iOS の場合は、**ios** ディレクトリに移動して `pod install` を実行し、必要なネイティブ依存関係もインストールします。 - Android の場合は、依存関係をインストールする必要はありません。 > [公式の TypeScript ガイド](https://reactnative.dev/docs/typescript#adding-typescript-to-an-existing-project)に従って TypeScript のサポートを追加することをお勧めします。 ### Stripe の初期化 React Native アプリで Stripe を初期化するには、決済画面を `StripeProvider` コンポーネントでラップするか、`initStripe` 初期化メソッドを使用します。`publishableKey` の API [公開可能キー](https://docs.stripe.com/keys.md#obtain-api-keys)のみが必要です。次の例は、`StripeProvider` コンポーネントを使用して Stripe を初期化する方法を示しています。 ```jsx import { useState, useEffect } from 'react'; import { StripeProvider } from '@stripe/stripe-react-native'; function App() { const [publishableKey, setPublishableKey] = useState(''); const fetchPublishableKey = async () => { const key = await fetchKey(); // fetch key from your server here setPublishableKey(key); }; useEffect(() => { fetchPublishableKey(); }, []); return ( {/* Your app code here */} ); } ``` > テストおよび開発時には API の[テストキー](https://docs.stripe.com/keys.md#obtain-api-keys)を使用し、アプリの公開時には[本番環境](https://docs.stripe.com/keys.md#test-live-modes)キーを使用します。 ### Android に固有の設定 Android でプッシュプロビジョニングを有効にするには、TapAndPay SDK にアクセスできるようになった後 (上記を参照)、[それをネイティブ Android プロジェクトに含める](https://developers.google.com/pay/issuers/apis/push-provisioning/android/setup)必要があります。 次に、以下を `android/app/build.gradle` ファイルに追加して、Stripe のネイティブ Android プッシュプロビジョニングライブラリをインポートする必要があります。 #### Groovy ```groovy dependencies { // ...implementation 'com.stripe:stripe-android-issuing-push-provisioning:1.1.0' } ``` ### iOS 固有の設定 iOS でプッシュプロビジョニングを有効にするには、Stripe がエンタイトルメントの付与を確認した後に、[App Store Connect でプロビジョニングプロファイルにケイパビリティを追加する](https://developer.apple.com/account/resources/profiles/list)必要があります。 次に、新しいエンタイトルメントを `ios/app.config.js` ファイルに追加する必要があります。 ``` "entitlements": { "com.apple.developer.payment-pass-provisioning": true } ``` ## バックエンドを更新する [サーバー側] プッシュプロビジョニングの実装によって公開されるメソッドでは、お客様が自身のバックエンドとやり取りをし、Stripe の一時キーを作成してその JSON をアプリに返すことが求められます。このキーは有効期間の短い API 認証情報で、暗号化されたカード詳細の取得に使用でき、それがカードオブジェクトの単一インスタンスに使用されます。 Stripe API によって返されるオブジェクトがお使いの SDK のバージョンと互換性があることを確認するために、キーを作成する際、React Native SDK によってエクスポートされた API バージョンを Stripe API に対して明示的に渡す必要があります。 #### curl ```bash curl https://api.stripe.com/v1/ephemeral_keys \ -u <>: \ -d "issuing_card"="{{ISSUING_CARD_ID}}" \ -H "Stripe-Version: {{API_VERSION}}" ``` ```json { "id": "ephkey_1G4V6eEEs6YsaMZ2P1diLWdj", "object": "ephemeral_key", "associated_objects": [ { "id": "{{CARD_ID}}", "type": "issuing.card" } ], "created": 1586556828, "expires": 1586560428, "livemode": false, "secret": "ek_test_YWNjdF8xRmdlTjZFRHelWWxwWVo5LEtLWFk0amJ2N0JOa0htU1JzEZkd2RpYkpJdnM_00z2ftxCGG" } ``` `` コンポーネントに渡す必要がある、Issuing カードの詳細を取得するためのエンドポイントも作成する必要があります。 ```curl curl https://api.stripe.com/v1/issuing/cards/ISSUING_CARD_ID \ -u "<>:" ``` ## アプリを更新する [クライアント側] まず、発行されたクレジットカードの `wallets.apple_pay.eligible` の値 (上記のステップ 3 で作成した 2 番目のエンドポイントから取得) が `true` であるかを確認して、デバイスがプッシュプロビジョニングの使用対象であるかどうかを判断します。対象である場合は、後で使用するためにカード詳細をコンポーネントで保存して続行します。`wallets.apple_pay.eligible` が `false` の場合は、iOS で``を表示しないでください。これは、Android の `wallets.google_pay.eligible` でも同様です。 ```javascript import React, {useEffect, useState} from 'react'; import {Constants} from '@stripe/stripe-react-native'; import {View} from 'react-native'; export default function MyScreen() { const [key, setKey] = useState(null);const [card, setCard] = useState(null); useEffect(() => { fetchEphemeralKey();fetchIssuingCard(); }, []); const fetchIssuingCard = async () => { const response = await fetch(`${API_URL}/issuing-card`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ ISSUING_CARD_ID: '{{ISSUING_CARD_ID}}', }), }); const card = await response.json(); if (!card.wallets.apple_pay.eligible) { // Do not show component on iOS. See card.wallets.apple_pay.ineligible_reason for details } else if (!card.wallets.google_pay.eligible) { // Do not show component on Android. See card.wallets.google_pay.ineligible_reason for details } else { setCard(card); } }; const fetchEphemeralKey = async () => { // See above }; return ; } ``` 次に、上記のステップ 3 で作成した最初のエンドポイントから一時キーを取得して保存します。 ```javascript import React, {useEffect, useState} from 'react'; import {Constants} from '@stripe/stripe-react-native'; import {View} from 'react-native'; export default function MyScreen() { const [key, setKey] = useState(null); useEffect(() => { fetchEphemeralKey(); }, []); const fetchEphemeralKey = async () => { const response = await fetch(`${API_URL}/ephemeral-key`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ ISSUING_CARD_ID: '{{ISSUING_CARD_ID}}', API_VERSION: Constants.API_VERSIONS.ISSUING, }), }); const myKey = await response.json(); setKey(myKey); }; return ; } ``` これ以上のサーバー通信は不要です。次に、ウォレットにカードを追加_「できる」_かを確認する必要があります。これは、`canAddCardToWallet` メソッドで確認でき、ブール値の `canAddCard` フィールドを含むオブジェクトが返されます。`canAddCard` が `false` の場合は、`AddToWalletButton` を表示しないでください。表示すると、アプリが Apple によって拒否される可能性があります。 Android では、カードがすでにウォレットにある場合でも、不適切な状態で止まっている可能性があります。`canAddCardToWallet` で返される `details` オブジェクトの `token` を確認することで、このようなケースに対処するロジックを追加できます。レスポンスが null 以外で、`token.status` が `"TOKEN_STATE_NEEDS_IDENTITY_VERIFICATION"` の場合は、この `token` を `` のプロパティに渡します。 ```javascript import React, {useEffect, useState} from 'react'; import {Constants, canAddCardToWallet, GooglePayCardToken} from '@stripe/stripe-react-native'; import {View} from 'react-native'; export default function MyScreen() { const [key, setKey] = useState(null); const [card, setCard] = useState(null);const [showAddToWalletButton, setShowAddToWalletButton] = useState(false); const [androidCardToken, setAndroidCardToken] = useState(null); useEffect(() => { fetchEphemeralKey(); fetchIssuingCard(); }, []); const checkIfCanAddCard = async () => { const { canAddCard, details, error } = await canAddCardToWallet({ primaryAccountIdentifier: card?.wallets?.primary_account_identifier, cardLastFour: card.last4, hasPairedAppleWatch: // Pass a boolean indicating whether or not the device has a paired Apple Watch. iOS only. }); if (error) { Alert.alert(error.code, error.message); } else { setShowAddToWalletButton(canAddCard); if (details?.token?.status === 'TOKEN_STATE_NEEDS_IDENTITY_VERIFICATION') { setAndroidCardToken(details.token); } } }; const fetchIssuingCard = async () => { // See aboveawait checkIfCanAddCard(); }; const fetchEphemeralKey = async () => { // See above }; return ; } ``` これで、ボタンを表示するために必要なすべての情報が揃いました。 ```javascript import React, {useEffect, useState} from 'react'; import { Constants, canAddCardToWallet, AddToWalletButton, GooglePayCardToken, } from '@stripe/stripe-react-native'; import {View, Image, Alert, StyleSheet} from 'react-native'; import AddToGooglePayPNG from '../assets/Add-to-Google-Pay-Button-dark-no-shadow.png'; export default function MyScreen() { const [key, setKey] = useState(null); const [card, setCard] = useState(null); const [showAddToWalletButton, setShowAddToWalletButton] = useState(false); const [androidCardToken, setAndroidCardToken] = useState(null); useEffect(() => { fetchEphemeralKey(); fetchIssuingCard(); }, []); const canAddCard = async () => { // See above }; const fetchIssuingCard = async () => { // See above }; const fetchEphemeralKey = async () => { // See above }; return ( {showAddToWalletButton && ( { Alert.alert( error ? error.code : 'Success', error ? error.message : 'Card was successfully added to the wallet.', ); }} /> )} ); } const styles = StyleSheet.create({ payButton: { // You may add custom styles to your button, but make sure it complies // with the relevant platform guidelines: // iOS : https://developer.apple.com/wallet/add-to-apple-wallet-guidelines/ // Android : https://developers.google.com/pay/issuers/apis/push-provisioning/android/branding-guidelines }, }); ``` ユーザーがボタンをタップすると、カードをウォレットに追加するための UI が起動します。`onComplete` プロパティにコールバックを実装します。`error` フィールドが null 以外の場合は、エラーが発生しておりカードはウォレットに追加されていません。`error` が null である場合は、カードは正常にプロビジョニングされています。 ### ボタンのスタイル iOS では、ボタンのスタイルは `iOSButtonStyle` プロパティによって決定されます。このプロパティーを以下のように設定します。 - `onLightBackground` は、明るい色または白の背景の上にボタンを表示する場合です。 - `onDarkBackground` は、暗い色または黒の背景の上にボタンを表示する場合です。 Android では、実際の画像アセットを `androidAssetSource` プロパティに渡す必要があります。利用可能なアセットオプションは、[Google から直接](https://developers.google.com/static/pay/issuers/apis/push-provisioning/android/downloads/add-to-wallet-png.zip)ダウンロードできます。ボタンを実装する際は、[Google のブランディングガイドライン](https://developers.google.com/pay/issuers/apis/push-provisioning/android/branding-guidelines#style)に従って作業を行ってください。 選択した PNG を `AddToWalletButton` コンポーネントに渡すには、プロジェクトに追加して、他のアセットと同様にインポートし、ソースを `Image.resolveAssetSource` で解決します。 ```javascript import {Image} from 'react-native'; import AddToGooglePayPNG from '../assets/Add-to-Google-Pay-Button-dark-no-shadow.png'; ... ``` ## テスト ### iOS iOS では、`testEnv={true}` を `AddToWalletButton` コンポーネントに渡す限り、開発、シミュレーター、およびテストカードでプッシュプロビジョニングをテストできます。`testEnv` プロパティが`true` に設定されている場合、カードは実際にはデバイスのウォレットに追加されないことに注意してください。テスト環境では、`com.apple.developer.payment-pass-provisioning` エンタイトルメントは必要ありません。 ### Android Android では、`testEnv` プロパティには効果がありません。テストはすべて、本番環境で本番の Issuing カードを実際のデバイスで使用して行ってください。 内部テストを開始する前に、必ずアプリケーション ID を Stripe に提供してください。