# Issuing でデジタルウォレットを使用する Issuing を使用してデジタルウォレットにカードを追加する方法をご紹介します。 Issuing を使用すると、ユーザーは Apple Pay や Google Pay などのデジタルウォレットにカードを追加できます。 デジタルウォレットトークンは本番環境でのみ使用できるため、サンドボックスではこの機能をテストできません。デジタルウォレットトークンを使用してテストするには、本番環境のユースケースの承認を受け、実際のカードを使用する必要があります。Stripe では、次の 2 つの方法でカードを追加できます: 1. **手動のプロビジョニング:** カード保有者は、スマホのウォレットアプリケーションにカード情報を入力して、デジタルウォレットに追加します。 2. **プッシュプロビジョニング:** モバイルアプリケーションでは、ユーザーがアプリから直接、デジタルウォレットにカードを追加できます。 カードがデジタルウォレットに追加されると、そのカードのトークン化された表記が作成されます。ネットワークトークンは、カードとは別に管理されます。ネットワークトークンとその仕組みについて、詳細は[トークン管理](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/embedded-finance)ください。 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 ではサポートされていません。 # 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=ios#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 のアクセスをリクエストする > このガイドは、Google Wallet の Unified Push Provisioning (UPP) フローに関するものです。このフローにより、カード会員はモバイルデバイスからウェアラブルデバイスに直接カードをプロビジョニングできます。また、カード会員はカード情報を Google Wallet アカウントに保存して、Google Chrome などの他の Google デバイスやアプリケーションで使用できるようになります。 Stripe はプッシュプロビジョニング用にプライベート Google ライブラリで SDK ラッパーを提供しています。プッシュプロビジョニングを使用して Google Pay Store でアプリを配信するには、以下を行う必要があります。 1. [Google Issuer Console アカウントを設定します](https://pay.google.com/business/console?business_type=financial_institution)。事業形態として **Financial Institution** を選択します。 2. Google Issuer Console のダッシュボードで、 **Push Provisioning API** タブに移動し、ビジネスプロファイルを完了させます。Visa BID または Mastercard CID が不明な場合は、`Unknown` に設定します。Google により 24 〜 48 時間以内にイシュアの詳細が審査され、NDA と完了すべき対応を記載したメールが送信されます。 3. Google とのキーの交換は不要です。代わりに、[Unified Push Provisioning API Intake Request](https://support.google.com/googlepay/contact/upp_api_onboarding) を完了させ、 **Aggregator/Program Manager linking** を選択して、管理するイシュアアカウントを Stripe のプログラムマネージャーアカウントにリンクします。Stripe の Aggregator Merchant ID は `BCR2DN7TWDCZDZJC` です。 > Google では、各 Issuer Console アカウントを 1 つのプログラムマネージャーのみにリンクできます。複数のプログラムマネージャーがある場合は、[support-issuing@stripe.com](mailto:support-issuing@stripe.com) にお問い合わせください。 4. [Google のプッシュプロビジョニングに関するドキュメント](https://developers.google.com/pay/issuers/apis/push-provisioning/android)へのアクセスをリクエストし、[プライベート TapAndPay SDK](https://developers.google.com/pay/issuers/apis/push-provisioning/android/releases) をダウンロードします。最近テストされたバージョン、および必要な最小バージョンは `18.8.0` です。 5. [以下のセクション](https://docs.stripe.com/issuing/cards/digital-wallets.md#update-your-app)のガイダンスに従って、クライアントアプリとサーバーバックエンドを更新します。 6. Google Issuer Console でアプリのユーザーフローのスクリーンショットを提出します。[Google のブランドガイドライン](https://developers.google.com/pay/issuers/apis/push-provisioning/android/branding-guidelines)に従ってください。 7. Google Issuer Console でアプリ ID とフィンガープリントを提出して、Google の Push Provisioning API へのアクセス権を取得します。このステップを完了するまで、**Add to Google Wallet** はエラーを返します。アプリの許可リストへの追加に関する詳細は、[Google のドキュメント](https://developers.google.com/pay/issuers/apis/push-provisioning/android/allowlist)をご覧ください。 8. アプリケーション名、アプリケーション ID、カードネットワーク、カード名を記載して、[support-issuing@stripe.com にお問い合わせ](mailto:support-issuing@stripe.com)ください。 9. [Testing セクション](https://docs.stripe.com/issuing/cards/digital-wallets.md#testing)を使用し、本番環境へ移行する前に Google から最終承認を得てください。 ## アプリを設定する [クライアント側] [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)必要があります。必要な最小バージョンはバージョン `18.8.0` です。 次に、以下を `android/app/build.gradle` ファイルに追加して、Stripe のネイティブ Android プッシュプロビジョニングライブラリをインポートする必要があります。 #### Groovy ```groovy dependencies { // ...implementation 'com.stripe:stripe-android-issuing-push-provisioning:1.3.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 または Google によって拒否される可能性があります。 Android では、カードはすでにウォレットにあるものの、問題のある状態に陥っている場合があります。`canAddCardToWallet` から返されるオブジェクトに `token` があるか確認することで、このケースに対処するロジックを追加できます。そのレスポンスが null ではなく、`token.status` が `"TOKEN_STATE_NEEDS_IDENTITY_VERIFICATION"` である場合は、その `token` を``の props に渡します。 > Android の場合、内部テストを開始する前にアプリケーション ID を Stripe に提供してください。セットアップには 1 週間以上かかる場合があり、セットアップが不完全な場合、これらのメソッドから一貫性のないレスポンスが返される可能性があります。`canAddCardToWallet` によって返されるトークンには、Stripe がセットアップを完了した後に追加されたカードのみが含まれます。 ```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, cardBrand: card.brand, 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` prop でコールバックを実装します。`error` フィールドが null でない場合、エラーが発生しており、カードはウォレットに追加されていません。`error` が `null` の場合、カードのプロビジョニングは正常に完了しています。プロビジョニングが成功したら、ユーザーに成功メッセージを表示します。Google はユーザーフローの審査の一環としてこの画面を確認します。 バウンスプロビジョニングをサポートしている場合は、`AddToWalletButton` で `isBounceProvisioned` を動的に設定できます。アプリ内でバウンスプロビジョニングをサポートする方法の詳細については、[Google のドキュメント](https://developers.google.com/pay/issuers/apis/push-provisioning/android/bounce_provisioning)をご覧ください。 ### ボタンのスタイル 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 カードを実際のデバイスで使用して行ってください。 Google の[テストケース](https://developers.google.com/pay/issuers/apis/push-provisioning/android/test-cases)が正常に完了したことを示す動画を、Issuer Console から提出します。本番環境へ移行する前に、[フィールドテスト](https://developers.google.com/pay/issuers/apis/push-provisioning/android/launch-process#field_testing)も完了してください。詳細については、[Google のローンチプロセス](https://developers.google.com/pay/issuers/apis/push-provisioning/android/launch-process#app_review)をご覧ください。 内部テストを開始する前に、必ずアプリケーション ID を Stripe に提供してください。