# Accounts v1 を使用して SaaS プラットフォームを構築する アカウント v1 を使用して連結アカウントを作成し、SaaS プラットフォームからの直接支払いを容易にします。 > #### Accounts v2 API のシステム連携 > > このガイドは、Accounts v1 API を使用する既存の Connect プラットフォームにのみ該当します。新規の Connect ユーザー、または Accounts v2 API をご利用の場合は、[v2 SaaS platform guide](https://docs.stripe.com/connect/saas.md) をご覧ください。 このガイドでは、ユーザー が決済を受け付けられるようにし、ユーザーの利益の一部をお客様の残高に移し、残りをユーザーの銀行口座に入金する方法について説明します。これらの概念について、自社のオンラインストアを構築できるようにする、サンプルプラットフォームを使用して説明します。 # Web > This is a Web for when platform is web. View the full page at https://docs.stripe.com/connect/end-to-end-saas-platform?platform=web. ## 前提条件 1. [プラットフォームを登録](https://dashboard.stripe.com/connect)します。 1. [ダッシュボードでビジネスの詳細の確認と追加](https://dashboard.stripe.com/account/onboarding)。 1. [プラットフォームプロフィールを完成](https://dashboard.stripe.com/connect/settings/profile)させます。 1. [ブランド設定をカスタマイズ](https://dashboard.stripe.com/settings/connect/stripe-dashboard/branding)します。ビジネス名、アイコン、ブランドカラーを追加します。 ## Stripe を設定する [サーバー側] Stripe の公式ライブラリをインストールして、アプリケーションから API にアクセスできるようにします。 #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ## 連結アカウントを作成する ユーザー (売り手またはサービスプロバイダー) がプラットフォームに登録したら、ユーザーの [Account (アカウント)](https://docs.stripe.com/api/accounts.md) (「連結アカウント」と呼ばれる) を作成し、決済を受け付けて売上をユーザーの銀行口座に入金できるようにします。連結アカウントは Stripe の API でユーザーを表し、アカウント登録要件の収集を簡単にして Stripe がユーザーの本人確認を実行できるようにします。ストアビルダーの例では、連結アカウントはオンラインストアを設定するビジネスを表します。 ![Connect アカウント登録フォームのスクリーンショット](https://b.stripecdn.com/docs-statics-srv/assets/Kavholm-Seamless-Standard.78b64d90c0bf87130c8b6ba1ef53df7f.png) ### 連結アカウントを作成して情報を事前入力する `/v1/accounts` API を使用して連結アカウントを[作成](https://docs.stripe.com/api/accounts/create.md)します。[デフォルトの連結アカウントのパラメーター](https://docs.stripe.com/connect/migrate-to-controller-properties.md)を指定するか、アカウントタイプを指定して、連結アカウントを作成できます。 #### デフォルトのプロパティを使用 ```curl curl -X POST https://api.stripe.com/v1/accounts \ -u "<>:" ``` #### アカウントタイプを使用した場合 ```curl curl https://api.stripe.com/v1/accounts \ -u "<>:" \ -d type=standard ``` 連結アカウントの情報をすでに収集している場合は、`Account` オブジェクトにその情報を事前入力できます。個人情報や事業情報、外部のアカウント情報など、あらゆるアカウント情報を事前に入力できます。 `Account` を作成したら、`relationship.representative` を true に設定した [Person](https://docs.stripe.com/api/persons/create.md) を作成して、アカウント開設の責任者と、事前に入力したいアカウント情報 (氏名など) を表します。 ```curl curl https://api.stripe.com/v1/accounts/{{ACCOUNT_ID}}/persons \ -u "<>:" \ -d first_name=Jenny \ -d last_name=Rosen \ -d "relationship[representative]=true" ``` Connect アカウント登録で、事前入力された情報が要求されることはありません。ただし、アカウント所有者は [Connect 利用規約](https://docs.stripe.com/connect/service-agreement-types.md)に同意する前に、事前入力された情報を確認するよう求められます。 実装内容をテストする場合、[テストデータ](https://docs.stripe.com/connect/testing.md)を使用してアカウント情報を事前入力します。 ### アカウントリンクを作成する 以下のパラメーターを使用して [Account Links](https://docs.stripe.com/api/account_links.md) API を呼び出すことで、アカウントリンクを作成できます。 - `account` - `refresh_url` - `return_url` - `type` = `account_onboarding` ```curl curl https://api.stripe.com/v1/account_links \ -u "<>:" \ -d "account={{CONNECTEDACCOUNT_ID}}" \ --data-urlencode "refresh_url=https://example.com/reauth" \ --data-urlencode "return_url=https://example.com/return" \ -d type=account_onboarding ``` ### ユーザーをアカウントリンク URL にリダイレクトする [Account Links (アカウントリンク)](https://docs.stripe.com/api/account_links.md) リクエストへのレスポンスには、キー `url` の値が含まれます。ユーザーをこのリンクにリダイレクトして、処理を進めることができるようにします。Account Links は一時的なものであり、連結アカウントユーザーの個人情報へのアクセスを許可するため、使用できるのは 1 回限りです。この URL にリダイレクトする前に、アプリケーションでユーザーを認証してください。情報の事前入力は、アカウントリンクを生成する前に行う必要があります。アカウントリンクを作成した後は、そのアカウントの情報を読み書きできなくなります。 > アカウントリンクの URL をメールやショートメッセージ、またはその他の方法で、プラットフォームのアプリケーション外に送信しないでください。URL は、アプリケーション内で認証済みのアカウント所有者に提供してください。 ### プラットフォームに戻るユーザーを処理する Connect アカウント登録では、ユーザーがプラットフォームにリダイレクトされるすべてのケースを処理するために、`return_url` と `refresh_url` の両方を渡す必要があります。ユーザーが快適に操作できるようにするには、これらを正しく実装することが重要です。 > テスト環境 (たとえば localhost でテストする場合) では、`return_url` と `refresh_url` に HTTP を使用できますが、本番環境で受け付けられるのは HTTPS のみです。本番環境へ移行する前に、テスト用 URL を HTTPS URL に更新する必要があります。 #### return_url ユーザーが Connect アカウント登録フローを完了すると、Stripe はこの URL へのリダイレクトを行います。ただしこれは、すべての情報が収集されたことを意味するものでも、アカウントの要件がすべて満たされたことを意味するものでもありません。ユーザーがフローに正常に入り、そこから正常に出たことのみを意味します。 パラメーターの状態がこの URL を通じて渡されることはありません。ユーザーが `return_url` にリダイレクトされたら、以下のいずれかを行い、アカウントの `details_submitted` パラメーターの状態を確認します。 - `account.updated` Webhook をリッスンする - [Accounts](https://docs.stripe.com/api/accounts.md) API を呼び出して、返されたオブジェクトを調べる #### refresh_url 以下のケースでは、ユーザーが `refresh_url` にリダイレクトされます。 - リンクの期限が切れている (リンクが作成されてから数分が経過した) - ユーザーがすでにリンクにアクセスしている (ユーザーがページを更新したか、ブラウザーで戻るボタンまたは進むボタンをクリックした) - プラットフォームがアカウントにアクセスできなくなった - アカウントが拒否された `refresh_url` はサーバでメソッドをトリガーし、同じパラメータを使用して [Account Link (アカウントリンク)](https://docs.stripe.com/api/account_links.md) を再度呼び出し、シームレスな体験を作成するためにユーザを Connect アカウント登録フローにリダイレクトする必要があります。 ### アカウント登録を完了していないユーザーを処理する ユーザーが `return_url` にリダイレクトされた場合、アカウント登録プロセスを完了していないことがあります。`/v1/accounts` エンドポイントを使用してユーザーのアカウントを取得し、`charges_enabled` を確認します。アカウント登録が完全でない場合は、UI プロンプトを表示し、ユーザーが後でアカウント登録を続行できるようにします。ユーザーは、システムで生成された新しいアカウントリンクで本番環境利用の申請を完了できます。ユーザーがアカウント登録プロセスを完了したかどうかを確認するには、アカウントの `details_submitted` パラメーターの状態をチェックします。 ## 支払い方法を有効にする [決済手段の設定](https://dashboard.stripe.com/settings/connect/payment_methods)を表示して、サポートする決済手段を有効にします。カード支払いはデフォルトで有効になっていますが、その他の決済手段は必要に応じて有効または無効にできます。このガイドでは、Bancontact、クレジットカード、EPS、iDEAL、Przelewy24、SEPA ダイレクトデビット、Sofort が有効化されていることを前提としています。 決済フォームを表示する前に、Stripe は通貨、決済手段の制約、その他のパラメーターを評価し、対応可能な決済手段のリストを決定します。購入完了率の向上につながり、使用通貨と顧客の所在地に最も適した決済手段が、優先的に表示されます。優先度の低い決済手段は、オーバーフローメニューに隠れた状態になります。 > **埋め込み支払い方法設定コンポーネント**を使用すると、接続アカウントは Stripe ダッシュボードにアクセスすることなく、Checkout で提供する支払い方法を設定できます。[埋め込み支払い方法設定コンポーネント](https://docs.stripe.com/connect/supported-embedded-components/payment-method-settings.md)の詳細を確認し、利用可能になった際に通知を受け取ってください。 ## 決済を受け付ける [Stripe Checkout](https://stripe.com/payments/checkout) を決済フォームとして直接ウェブサイトに埋め込むか、ユーザーを Stripe ホストのページにリダイレクトして決済を受け付けます。Checkout は複数の決済手段をサポートし、最も関連性の高いものを自動的に顧客に表示します。Payment Elementを使用して、1 つのフロントエンドの連携で複数の決済手段を受け付けることができます。これは、決済フォームに iframe として埋め込まれる事前構築済みの UI コンポーネントです。 #### Stripe がオンラインで提供するページ ### Checkout セッションを作成する (クライアント側) (サーバー側) Checkout セッションは、ラインアイテム、注文金額と通貨、および受け付け可能な支払い方法など、埋め込み可能な支払いフォームで顧客に表示する内容を制御します。ダイレクト支払いを実行するとき、Checkout では連結アカウントのブランディング設定を使用します。詳細については、[ブランディングをカスタマイズする](https://docs.stripe.com/connect/direct-charges.md?platform=web&ui=stripe-hosted#branding)セクションをご覧ください。 デスティネーション支払いや支払いと送金別方式とは異なり、ダイレクト支払いの不審請求の申請に対処する責任は、ユーザー (連結アカウント) が負います。プラットフォームは責任を負いません。 サーバー側で、Stripe API に以下の呼び出しを行います。Checkout セッションを作成したら、レスポンスで返された [URL](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-url) に顧客をリダイレクトします。 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -H "Stripe-Account: {{CONNECTEDACCOUNT_ID}}" \ -d mode=payment \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d "payment_intent_data[application_fee_amount]=123" \ --data-urlencode "success_url=https://example.com/success" ``` - `line_items`: この引数は、顧客が購入し、オンラインユーザーインターフェイスに表示されるアイテムを表します。 - `success_url`: この引数は、支払いを完了したユーザーのリダイレクト先を示します。 - `Stripe-Account`: このヘッダーは、連結アカウントの[ダイレクトチャージ](https://docs.stripe.com/connect/direct-charges.md)を示します。ダイレクトチャージの場合、連結アカウントは Stripe 手数料、返金、およびチャージバックに対する責任を負います。Checkout では連結アカウントのブランディングが使用されます。これにより、プラットフォームではなく連結アカウントと直接やり取りしているような印象を顧客に与えることができます。 - (オプション) `payment_intent_data[application_fee_amount]`: この引数は、プラットフォームが取引から受け取る予定の金額を指定します。連結アカウントで支払いが処理された後に、`application_fee_amount` がプラットフォームに送金され、連結アカウントの残高から Stripe 手数料が差し引かれます。 ![アカウントの作成フロー](https://b.stripecdn.com/docs-statics-srv/assets/direct_charges.a2a8b68037ac95fe22140d6dde9740d3.svg) ### 支払い後のイベントを処理する (サーバー側) 支払いが完了すると Stripe は [checkout.session.completed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.completed) イベントを送信します。[Webhook を使用してこのイベントを受信](https://docs.stripe.com/webhooks/quickstart.md)し、顧客への注文確認メールの送信、データベースへの売上の記録、配送ワークフローの開始などのアクションを実行します。 クライアントからのコールバックを待つのではなく、これらのイベントをリッスンします。クライアント側では、コールバックの実行前に顧客がブラウザーのウィンドウを閉じたり、アプリケーションを終了したりする可能性があります。また、支払い方法によっては支払いの確定までに 2 ~ 14 日かかることがあります。自社の構築済みのシステムで非同期イベントをリッスンするように設定すると、一度の導入で複数の[支払い方法](https://stripe.com/payments/payment-methods-guide)に対応できるようになります。 Checkout で支払いを回収するときは、`checkout.session.completed` イベントの処理に加えて、以下の 2 つのイベントも処理することをお勧めします。 | イベント | 説明 | 次のステップ | | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | ---------------------------- | | [checkout.session.completed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.completed) | 顧客が Checkout フォームを送信して、支払いを正常に承認しました。 | 支払いが成功するか、失敗するかの結果を待ちます。 | | [checkout.session.async_payment_succeeded](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.async_payment_succeeded) | 顧客の支払いが成功しました。 | 購入された商品やサービスのフルフィルメントを行います。 | | [checkout.session.async_payment_failed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.async_payment_failed) | 何らかの理由により支払いが拒否されたか、失敗しました。 | 顧客にメールで連絡して、新たに注文するように依頼します。 | これらのイベントのすべてに、[Checkout Session (Checkout セッション)](https://docs.stripe.com/api/checkout/sessions.md) オブジェクトが含まれています。支払いが成功すると、基となる *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) のステータスが `processing` から `succeeded` に変わります。 #### 完全埋め込みページ ### Checkout セッションを作成する (クライアント側) (サーバー側) Checkout セッションは、ラインアイテム、注文金額と通貨、および受け付け可能な支払い方法など、Stripe のオンライン決済ページで顧客に表示する内容を制御します。ダイレクト支払いを実行するとき、Checkout では連結アカウントのブランディング設定を使用します。詳細については、[ブランディングをカスタマイズする](https://docs.stripe.com/connect/direct-charges.md?platform=web&ui=stripe-hosted#branding)セクションをご覧ください。 デスティネーション支払いや支払いと送金別方式とは異なり、ダイレクト支払いの不審請求の申請に対処する責任は、ユーザー (連結アカウント) が負います。プラットフォームは責任を負いません。自社のサーバーで、Stripe の API に対して以下の呼び出しを実行します。Checkout セッションの作成のレスポンスには、次のステップで Checkout のマウントに使用する `client_secret` が含まれています。 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -H "Stripe-Account: {{CONNECTEDACCOUNT_ID}}" \ -d mode=payment \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d "payment_intent_data[application_fee_amount]=123" \ -d ui_mode=embedded_page \ --data-urlencode "return_url=https://example.com/checkout/return?session_id={CHECKOUT_SESSION_ID}" ``` - `line_items` - この引数は、顧客が購入する商品を示すものであり、オンラインユーザーインターフェイスに表示されます。 - `return_url`: この引数は、支払いを完了したユーザーのリダイレクト先を示します。 - `Stripe-Account`: このヘッダーは、連結アカウントの[ダイレクト支払い](https://docs.stripe.com/connect/direct-charges.md)を示します。ダイレクト支払いの場合、連結アカウントは Stripe 手数料、返金、およびチャージバックに対する責任を負います。Checkout では連結アカウントのブランディングが使用されます。これにより、プラットフォームではなく加盟店と直接やり取りしているような印象を顧客に与えることができます。 - (オプション) `payment_intent_data[application_fee_amount]` - この引数は、プラットフォームが取引から受け付ける予定の金額を指定します。Stripe の [Platform Pricing Tool](https://docs.stripe.com/connect/platform-pricing-tools.md) を使用して[ダッシュボード](https://dashboard.stripe.com/test/settings/connect/platform_pricing/payments)でプラットフォーム手数料の料金を管理している場合、設定された価格設定ロジックがツールによって上書きされるため、この引数は含めないようにしてください。連結アカウントで支払いが処理された後、`application_fee_amount` がプラットフォームに送金され、Stripe 手数料が連結アカウントの残高から差し引かれます。 `return_url` は、決済のステータスが表示されるウェブサイト上のページと一致している必要があります。Stripe が顧客を `return_url` にリダイレクトする際、`{CHECKOUT_SESSION_ID}` の文字列は Checkout セッションの ID に置き換えられます。この ID を使用して Checkout セッションを取得し、ステータスを確認して、顧客に表示する内容を決定してください。`return_url` を指定するときに、自社で使用するクエリパラメーターを追加することもできます。このパラメーターはリダイレクトプロセス全体にわたって存続します。 ![アカウントの作成フロー](https://b.stripecdn.com/docs-statics-srv/assets/direct_charges.a2a8b68037ac95fe22140d6dde9740d3.svg) ### Checkout をマウントする (クライアント側) #### HTML + JS Checkout は [Stripe.js](https://docs.stripe.com/js.md) の一部として利用できます。HTML ファイルのヘッダーに Stripe.js スクリプトを追加してページに含めます。次に、マウンティングに使用する空の DOM ノード (コンテナー) を作成します。 ```html
``` 公開可能な API キーで Stripe.js を初期化します。 Checkout セッションの作成、および client secret の取得をサーバーにリクエストする、非同期の `fetchClientSecret` 関数を作成します。 Checkout インスタンスを作成する際に、この関数を `options` に渡します。 ```javascript // Initialize Stripe.js const stripe = Stripe('<>', { stripeAccount: '{{CONNECTED_ACCOUNT_ID}}', }); initialize(); // Fetch Checkout Session and retrieve the client secret async function initialize() { const fetchClientSecret = async () => { const response = await fetch("/create-checkout-session", { method: "POST", }); const { clientSecret } = await response.json(); return clientSecret; }; // Initialize Checkout const checkout = await stripe.createEmbeddedCheckoutPage({ fetchClientSecret, }); // Mount Checkout checkout.mount('#checkout'); } ``` #### React Connect.js と React Connect.js のライブラリを [npm のパブリックレジストリー](https://www.npmjs.com/package/@stripe/react-connect-js)からインストールします。 ```bash npm install --save @stripe/connect-js @stripe/react-connect-js ``` 埋め込みの Checkout コンポーネントを使用するには、`EmbeddedCheckoutProvider` を作成します。公開可能 API キーを使用して `loadStripe` を呼び出し、返された `Promise` をプロバイダーに渡します。 Checkout セッションの作成、および client secret の取得をサーバーにリクエストする、非同期の `fetchClientSecret` 関数を作成します。この関数をプロバイダーで受け入れられる `options` プロパティに渡します。 ```jsx import * as React from 'react'; import {loadStripe} from '@stripe/stripe-js'; import { EmbeddedCheckoutProvider, EmbeddedCheckout } from '@stripe/react-stripe-js'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe('pk_test_123'); const App = ({fetchClientSecret}) => { const options = {fetchClientSecret}; return ( ) } ``` Checkout は、HTTPS 接続を介して支払い情報を Stripe に安全に送信する iframe に表示されます。一部の支払い方法では、支払いを確定するために別のページにリダイレクトする必要があるため、Checkout を別の iframe 内に配置しないでください。 ### デザインをカスタマイズする アカウントの[ブランディング設定](https://dashboard.stripe.com/settings/branding)で、背景色、ボタンの色、枠線の角丸半径、フォントを設定して、サイトのデザインに合わせて Checkout をカスタマイズします。 デフォルトでは、Checkout は外側に余白やマージンが追加されずに表示されます。必要なマージンを適用するには (四方すべてに 16px など)、目的の余白を適用するコンテナー要素 (div など) を使用することをお勧めします。 ### 支払い後のイベントを処理する (サーバー側) 支払いが完了すると Stripe は [checkout.session.completed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.completed) イベントを送信します。[Webhook を使用してこのイベントを受信](https://docs.stripe.com/webhooks/quickstart.md)し、顧客への注文確認メールの送信、データベースへの売上の記録、配送ワークフローの開始などのアクションを実行します。 クライアントからのコールバックを待つのではなく、これらのイベントをリッスンします。クライアント側では、コールバックの実行前に顧客がブラウザーのウィンドウを閉じたり、アプリケーションを終了したりする可能性があります。また、支払い方法によっては支払いの確定までに 2 ~ 14 日かかることがあります。自社の構築済みのシステムで非同期イベントをリッスンするように設定すると、一度の導入で複数の[支払い方法](https://stripe.com/payments/payment-methods-guide)に対応できるようになります。 Checkout で支払いを回収するときは、`checkout.session.completed` イベントの処理に加えて、以下の 2 つのイベントも処理することをお勧めします。 | イベント | 説明 | 次のステップ | | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | ---------------------------- | | [checkout.session.completed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.completed) | 顧客が Checkout フォームを送信して、支払いを正常に承認しました。 | 支払いが成功するか、失敗するかの結果を待ちます。 | | [checkout.session.async_payment_succeeded](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.async_payment_succeeded) | 顧客の支払いが成功しました。 | 購入された商品やサービスのフルフィルメントを行います。 | | [checkout.session.async_payment_failed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.async_payment_failed) | 何らかの理由により支払いが拒否されたか、失敗しました。 | 顧客にメールで連絡して、新たに注文するように依頼します。 | これらのイベントのすべてに、[Checkout Session (Checkout セッション)](https://docs.stripe.com/api/checkout/sessions.md) オブジェクトが含まれています。支払いが成功すると、基となる *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) のステータスが `processing` から `succeeded` に変わります。 #### カスタムフロー ### PaymentIntent を作成する (サーバー側) Stripe は [PaymentIntent (支払いインテント)](https://docs.stripe.com/api/payment_intents.md) オブジェクトを使用して、顧客から支払いを回収する意図を示し、プロセス全体を通して請求の実施と支払い状態の変化を追跡します。 > 最初に PaymentIntent を作成せずに Payment Element をレンダリングする場合は、[インテントを作成する前に支払いの詳細を収集する](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=payment)をご覧ください。 ![決済フロー全体の概要図](https://b.stripecdn.com/docs-statics-srv/assets/accept-a-payment-payment-element.5cf6795a02f864923f9953611493d735.svg) 購入プロセスで顧客に表示される支払い方法は、PaymentIntent にも含まれています。Stripe によってダッシュボードの設定から支払い方法を自動的に取得することも、手動でリスト化することもできます。 貴社の構築済みのシステムで、決済手段の提供にコードベースのオプションを必要とする場合を除き、決済手段を手動でリスト化しないでください。Stripe は通貨、決済手段の制約、その他のパラメーターを評価し、対応可能な決済手段のリストを決定します。購入完了率の上昇につながり、使用通貨と顧客の所在地に最も適した決済手段が、優先的に表示されます。優先度の低い決済手段は、オーバーフローメニューに隠れた状態になります。 #### ダッシュボードで支払い方法を管理する ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -H "Stripe-Account: {{CONNECTEDACCOUNT_ID}}" \ -d amount=1099 \ -d currency=eur \ -d "automatic_payment_methods[enabled]=true" \ -d application_fee_amount=123 ``` PaymentIntent を作成する際は、特定のパラメーターを指定する必要があります。 - `amount` と `currency` - 金額と通貨を指定してサーバー上に PaymentIntent を作成します。 - (オプション) `automatic_payment_methods` - 最新バージョンの API では、Stripe がデフォルトで機能を有効にするため、このパラメーターを指定する必要はありません。決済手段は[ダッシュボード](https://dashboard.stripe.com/settings/payment_methods)から管理できます。Stripe は、取引金額、通貨、決済フローなどの要素に基づいて、対象となる決済手段を自動的に返します。 - (オプション) `payment_intent_data[application_fee_amount]` - この引数は、プラットフォームが取引から受け付ける予定の金額を指定します。Stripe の [Platform Pricing Tool](https://docs.stripe.com/connect/platform-pricing-tools.md) を使用して[ダッシュボード](https://dashboard.stripe.com/test/settings/connect/platform_pricing/payments)でプラットフォーム手数料の料金を管理している場合、設定された価格設定ロジックがツールによって上書きされるため、この引数は含めないようにしてください。連結アカウントで支払いが処理された後、`application_fee_amount` がプラットフォームに送金され、Stripe 手数料が連結アカウントの残高から差し引かれます。 #### 支払い方法を手動でリスト化する ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -H "Stripe-Account: {{CONNECTEDACCOUNT_ID}}" \ -d amount=1099 \ -d currency=eur \ -d "payment_method_types[]=bancontact" \ -d "payment_method_types[]=card" \ -d "payment_method_types[]=eps" \ -d "payment_method_types[]=ideal" \ -d "payment_method_types[]=p24" \ -d "payment_method_types[]=sepa_debit" \ -d "payment_method_types[]=sofort" \ -d application_fee_amount=123 ``` PaymentIntent を作成する際は、特定のパラメーターを指定する必要があります。 - `amount`: 指定した金額でサーバー上に PaymentIntent を作成します。請求金額は、信頼できる環境であるサーバー側で常に決定するようにしてください。このアプローチによって、悪意のある顧客が価格を操作できないようにします。 - `currency`: 顧客に表示される決済手段は、PaymentIntent に含める通貨によって絞り込まれるため、提供する決済手段に基づいて選択します。たとえば、`eur` を渡し、ダッシュボードで OXXO を有効にしている場合、OXXO は `eur` での支払いに対応していないため、顧客に表示されません。一部の決済手段は、複数の通貨と国に対応しています。このガイドのサンプルコードでは、Bancontact、クレジットカード、EPS、iDEAL、Przelewy24、SEPA ダイレクトデビット、Sofort を使用します。 - `"payment_method_types[]"`: 対応しているすべての決済手段を手動で一覧表示します。 - (オプション) `payment_intent_data[application_fee_amount]`: この引数は、プラットフォームが取引から受け付ける予定の金額を指定します。Stripe の[プラットフォームの料金設定ツール](https://docs.stripe.com/connect/platform-pricing-tools.md)を使用して、[ダッシュボード](https://dashboard.stripe.com/test/settings/connect/platform_pricing/payments)でプラットフォーム手数料の料金を管理している場合、設定された価格設定ロジックがツールによって上書きされるため、この引数は含めないようにしてください。連結アカウントで支払いが処理された後、`application_fee_amount` がプラットフォームに送金され、Stripe 手数料が連結アカウントの残高から差し引かれます。 > 各支払い方法は PaymentIntent で渡された通貨に対応している必要があり、ビジネスは、各支払い方法を使用できる国のいずれかに所在する必要があります。対応状況について、詳細は[支払い方法の導入オプション](https://docs.stripe.com/payments/payment-methods/integration-options.md)をご覧ください。 ### client secret を取得する PaymentIntent には、*client secret* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)) が含まれています。これは、支払いプロセスを安全に完了するためにクライアント側で使用されます。client secret をクライアント側に渡す際は、いくつかの方法を使用できます。 #### 1 ページのアプリケーション ブラウザーの `fetch` 関数を使用して、サーバーのエンドポイントから client secret を取得します。この方法は、クライアント側が 1 ページのアプリケーションで、特に React などの最新のフロントエンドフレームワークで構築されている場合に最適です。client secret を処理するサーバーのエンドポイントを作成します。 #### Ruby ```ruby get '/secret' do intent = # ... Create or retrieve the PaymentIntent {client_secret: intent.client_secret}.to_json end ``` その後、クライアント側で JavaScript を使用して client secret を取得します。 ```javascript (async () => { const response = await fetch('/secret'); const {client_secret: clientSecret} = await response.json(); // Render the form using the clientSecret })(); ``` #### サーバ側のレンダリング サーバーからクライアントに client secret を渡します。この方法は、アプリケーションがブラウザーへの送信前に静的なコンテンツをサーバーで生成する場合に最適です。 決済フォームに [client_secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) を追加します。サーバー側のコードで、PaymentIntent から client secret を取得します。 #### Ruby ```erb
``` ```ruby get '/checkout' do @intent = # ... Fetch or create the PaymentIntent erb :checkout end ``` ### 支払い情報を収集する (クライアント側) Payment Element を使用してクライアント側で支払い詳細を収集します。Payment Element は事前構築された UI コンポーネントであり、さまざまな支払い方法の支払い詳細の収集を容易にします。 Payment Element には、HTTPS 接続を介して支払い情報を Stripe に安全に送信する iframe が含まれています。一部の支払い方法では、支払いを確定するために別のページにリダイレクトする必要があるため、Payment Element を別の iframe 内に配置しないでください。 構築済みのシステムを機能させるには、決済ページのアドレスの先頭を `http://` ではなく `https://` にする必要があります。HTTPS を使用しなくてもシステムをテストできますが、本番環境で決済を受け付ける準備が整ったら、必ず、HTTPS を[有効](https://docs.stripe.com/security/guide.md#tls)にしてください。 #### Stripe.js を設定する #### HTML + JS Payment Element は Stripe.js の機能として自動的に使用できるようになります。決済ページに Stripe.js スクリプトを含めるには、HTML ファイルの `head` にスクリプトを追加します。常に js.stripe.com から Stripe.js を直接読み込むことにより、PCI 準拠が維持されます。スクリプトをバンドルに含めたり、そのコピーを自身でホストしたりしないでください。 ```html Checkout ``` 購入ページで以下の JavaScript を使用して、`Stripe` のインスタンスを作成します。 ```javascript // Initialize Stripe.js with the same connected account ID used when creating // the PaymentIntent. const stripe = Stripe('<>', { stripeAccount: '{{CONNECTED_ACCOUNT_ID}}' }); ``` #### Stripe Elements と Payment Element を決済ページに追加する 決済ページには Payment Element を配置する場所が必要です。決済フォームで、一意の ID を持つ空の DOM ノード (コンテナー) を作成します。 ```html
``` フォームが読み込まれたら、Payment Element のインスタンスを作成して、それを前のステップの [client secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) とともに、コンテナーの DOM ノードにマウントします。[Elements](https://docs.stripe.com/js/elements_object/create) インスタンスの作成時に、オプションとしてこの値を渡します。 client secret は支払いを完了できるため、慎重に扱う必要があります。記録したり、URL に埋め込んだり、当該の顧客以外に漏洩したりすることがないようにしてください。 ```javascript const options = { clientSecret: '{{CLIENT_SECRET}}', // Fully customizable with the Appearance API appearance: {/*...*/}, }; // Set up Stripe.js and Elements to use in checkout form using the client secret const elements = stripe.elements(options); // Create and mount the Payment Element const paymentElement = elements.create("payment"); paymentElement.mount("#payment-element"); ``` Payment Element によって動的なフォームが表示され、顧客が支払い方法を選択できるようになります。顧客が選択した支払い方法に必要なすべての支払い詳細が、フォームで自動的に収集されます。`Elements` オブジェクトを設定するときに、自社のサイトのデザインに合わせて [Payment Element のデザインをカスタマイズ](https://docs.stripe.com/elements/appearance-api.md)できます。 #### React 次の npm パブリックレジストリから [React Stripe.js](https://www.npmjs.com/package/@stripe/react-stripe-js) と [Stripe.js ローダー](https://www.npmjs.com/package/@stripe/stripe-js)をインストールします。 ```bash npm install --save @stripe/react-stripe-js @stripe/stripe-js ``` ### Elements プロバイダーを決済ページに追加して設定する Payment Element コンポーネントを使用するには、[Elements プロバイダー](https://docs.stripe.com/sdks/stripejs-react.md#elements-provider)で購入ページのコンポーネントをラップします。公開可能キーを使用して `loadStripe` を呼び出し、返された `Promise` と、前のステップの [client secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) を `options` として `Elements` プロバイダーに渡します。 ```jsx import React from 'react'; import ReactDOM from 'react-dom'; import {Elements} from '@stripe/react-stripe-js'; import {loadStripe} from '@stripe/stripe-js'; import CheckoutForm from './CheckoutForm'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe("<>", { stripeAccount: '{{CONNECTED_ACCOUNT_ID}}' }); function App() { const options = { // pass the client secret from the previous step clientSecret: '{{CLIENT_SECRET}}', // Fully customizable with the Appearance API appearance: {/*...*/}, }; return ( ); }; ReactDOM.render(, document.getElementById('root')); ``` #### PaymentElement コンポーネントを追加する `PaymentElement` コンポーネントを使用して、フォームを構築します。 ```jsx import React from 'react'; import {PaymentElement} from '@stripe/react-stripe-js'; const CheckoutForm = () => { return (
); }; export default CheckoutForm; ``` Payment Element によって動的なフォームが表示され、顧客は支払い方法のタイプを選択できます。このフォームは、顧客が選択した支払い方法に必要なすべての支払い詳細を自動的に収集します。`Elements` プロバイダーを設定するときに、自社のサイトのデザインに合わせて [Payment Element のデザインをカスタマイズ](https://docs.stripe.com/elements/appearance-api.md)できます。 ### Stripe に支払いを送信する (クライアント側) Payment Element からの詳細を指定して [stripe.confirmPayment](https://docs.stripe.com/js/payment_intents/confirm_payment) を使用し、支払いを完了します。ユーザーが支払いを完了した後に Stripe がユーザーをリダイレクトする場所を指定するには、この関数に [return_url](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-return_url) を指定します。ユーザーはまず、銀行のオーソリページなどの中間サイトにリダイレクトされ、その後 `return_url` にリダイレクトされます。カード支払いでは、支払いが正常に完了するとすぐに `return_url` にリダイレクトします。 カード決済で支払いの完了後にリダイレクトを行わない場合は、[redirect](https://docs.stripe.com/js/payment_intents/confirm_payment#confirm_payment_intent-options-redirect) に `if_required` を設定できます。これで、リダイレクトベースの決済手段で購入する顧客のみがリダイレクトされます。 #### HTML + JS ```javascript const form = document.getElementById('payment-form'); form.addEventListener('submit', async (event) => { event.preventDefault(); const {error} = await stripe.confirmPayment({ //`Elements` instance that was used to create the Payment Element elements, confirmParams: { return_url: 'https://example.com/order/123/complete', }, }); if (error) { // This point will only be reached if there is an immediate error when // confirming the payment. Show error to your customer (for example, payment // details incomplete) const messageContainer = document.querySelector('#error-message'); messageContainer.textContent = error.message; } else { // Your customer will be redirected to your `return_url`. For some payment // methods like iDEAL, your customer will be redirected to an intermediate // site first to authorize the payment, then redirected to the `return_url`. } }); ``` #### React 支払いフォームコンポーネントから [stripe.confirmPayment](https://docs.stripe.com/js/payment_intents/confirm_payment) を呼び出すには、[useStripe](https://docs.stripe.com/sdks/stripejs-react.md#usestripe-hook) フックと [useElements](https://docs.stripe.com/sdks/stripejs-react.md#useelements-hook) フックを使用します。 フックではなく従来のクラスコンポーネントを使用する場合は、代わりに [ElementsConsumer](https://docs.stripe.com/sdks/stripejs-react.md#elements-consumer) を使用します。 ```jsx import React, {useState} from 'react'; import {useStripe, useElements, PaymentElement} from '@stripe/react-stripe-js'; const CheckoutForm = () => { const stripe = useStripe(); const elements = useElements(); const [errorMessage, setErrorMessage] = useState(null); const handleSubmit = async (event) => { // We don't want to let default form submission happen here, // which would refresh the page. event.preventDefault(); if (!stripe || !elements) { // Stripe.js hasn't yet loaded. // Make sure to disable form submission until Stripe.js has loaded. return; } const {error} = await stripe.confirmPayment({ //`Elements` instance that was used to create the Payment Element elements, confirmParams: { return_url: 'https://example.com/order/123/complete', }, }); if (error) { // This point will only be reached if there is an immediate error when // confirming the payment. Show error to your customer (for example, payment // details incomplete) setErrorMessage(error.message); } else { // Your customer will be redirected to your `return_url`. For some payment // methods like iDEAL, your customer will be redirected to an intermediate // site first to authorize the payment, then redirected to the `return_url`. } }; return (
{/* Show error message to your customers */} {errorMessage &&
{errorMessage}
} ); }; export default CheckoutForm; ``` `return_url` が、Web サイト上の支払いステータスを表示するページと対応していることを確認します。Stripe が顧客を `return_url` にリダイレクトするときは、以下の URL クエリーパラメーターが指定されます。 | パラメーター | 説明 | | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | | `payment_intent` | `PaymentIntent` の一意の識別子。 | | `payment_intent_client_secret` | `PaymentIntent` オブジェクトの [client secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret)。 | > 顧客のブラウザーセッションを追跡するツールを利用している場合、リファラー除外リストに `stripe.com` ドメインの追加が必要になる場合があります。リダイレクトを行うと、一部のツールでは新しいセッションが作成され、セッション全体の追跡ができなくなります。 クエリパラメーターのいずれか 1 つを使用して PaymentIntent を取得します。[PaymentIntent のステータス](https://docs.stripe.com/payments/paymentintents/lifecycle.md)を調べて、顧客に表示する内容を決定します。また、`return_url` を指定するときにカスタムのクエリパラメーターを追加することもできます。このパラメーターはリダイレクトプロセスの間維持されます。 #### HTML + JS ```javascript // Initialize Stripe.js using your publishable key const stripe = Stripe('<>'); // Retrieve the "payment_intent_client_secret" query parameter appended to // your return_url by Stripe.js const clientSecret = new URLSearchParams(window.location.search).get( 'payment_intent_client_secret' ); // Retrieve the PaymentIntent stripe.retrievePaymentIntent(clientSecret).then(({paymentIntent}) => { const message = document.querySelector('#message') // Inspect the PaymentIntent `status` to indicate the status of the payment // to your customer. // // Some payment methods will [immediately succeed or fail][0] upon // confirmation, while others will first enter a `processing` state. // // [0]: https://stripe.com/docs/payments/payment-methods#payment-notification switch (paymentIntent.status) { case 'succeeded': message.innerText = 'Success! Payment received.'; break; case 'processing': message.innerText = "Payment processing. We'll update you when payment is received."; break; case 'requires_payment_method': message.innerText = 'Payment failed. Please try another payment method.'; // Redirect your user back to your payment page to attempt collecting // payment again break; default: message.innerText = 'Something went wrong.'; break; } }); ``` #### React ```jsx import React, {useState, useEffect} from 'react'; import {useStripe} from '@stripe/react-stripe-js'; const PaymentStatus = () => { const stripe = useStripe(); const [message, setMessage] = useState(null); useEffect(() => { if (!stripe) { return; } // Retrieve the "payment_intent_client_secret" query parameter appended to // your return_url by Stripe.js const clientSecret = new URLSearchParams(window.location.search).get( 'payment_intent_client_secret' ); // Retrieve the PaymentIntent stripe .retrievePaymentIntent(clientSecret) .then(({paymentIntent}) => { // Inspect the PaymentIntent `status` to indicate the status of the payment // to your customer. // // Some payment methods will [immediately succeed or fail][0] upon // confirmation, while others will first enter a `processing` state. // // [0]: https://stripe.com/docs/payments/payment-methods#payment-notification switch (paymentIntent.status) { case 'succeeded': setMessage('Success! Payment received.'); break; case 'processing': setMessage("Payment processing. We'll update you when payment is received."); break; case 'requires_payment_method': // Redirect your user back to your payment page to attempt collecting // payment again setMessage('Payment failed. Please try another payment method.'); break; default: setMessage('Something went wrong.'); break; } }); }, [stripe]); return message; }; export default PaymentStatus; ``` ### 支払い後のイベントを処理する (サーバー側) 支払いが完了すると、Stripe は [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) イベントを送信します。[ダッシュボードの Webhook ツール](https://dashboard.stripe.com/webhooks)を使用するか [Webhook のガイド](https://docs.stripe.com/webhooks/quickstart.md)に従ってこれらのイベントを受信し、顧客への注文確認メールの送信、データベースでの売上の記録、配送ワークフローの開始などのアクションを実行します。 クライアントからのコールバックを待つのではなく、これらのイベントをリッスンします。クライアントでは、コールバックが実行される前に顧客がブラウザーのウィンドウを閉じたり、アプリを終了する場合、また悪意を持つクライアントがレスポンスを不正操作する場合もあります。非同期型のイベントをリッスンするよう組み込みを設定すると、単一の組み込みで[複数の異なるタイプの支払い方法](https://stripe.com/payments/payment-methods-guide)を受け付けることができます。 Payment Element を使用して支払いを回収する場合は、`payment_intent.succeeded` イベントのほかにこれらのイベントを処理することをお勧めします。 | イベント | 説明 | アクション | | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.succeeded) | 顧客が正常に支払いを完了したときに送信されます。 | 顧客に注文の確定を送信し、顧客の注文の*フルフィルメント* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected)を実行します。 | | [payment_intent.processing](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.processing) | 顧客が正常に支払いを開始したが、支払いがまだ完了していない場合に送信されます。このイベントは、多くの場合、顧客が口座引き落としを開始するときに送信されます。その後、`payment_intent.succeeded` イベント、また、失敗の場合は `payment_intent.payment_failed` イベントが送信されます。 | 顧客に注文確認メールを送信し、支払いが保留中であることを示します。デジタル商品では、支払いの完了を待たずに注文のフルフィルメントを行うことが必要になる場合があります。 | | [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.payment_failed) | 顧客が支払いを試みたが、支払いに失敗する場合に送信されます。 | 支払いが `processing` から `payment_failed` に変わった場合は、顧客に再度支払いを試すように促します。 | ## テスト [アカウントを作成](https://docs.stripe.com/connect/testing.md#creating-accounts)し、[OAuth を使用](https://docs.stripe.com/connect/testing.md#using-oauth)して、アカウント作成フローをテストします。いずれかのテストアカウントにログインして[支払い方法の設定](https://dashboard.stripe.com/settings/payment_methods)に移動し、連結アカウントの**支払い方法**の設定をテストします。テストキーとテストアカウントを使用して、決済フローをテストします。Stripe の[テストカード](https://docs.stripe.com/testing.md)を使用して支払いフローをテストし、さまざまな支払い結果をシミュレーションできます。 # 決済画面 > This is a 決済画面 for when platform is ios and mobile-ui is payment-sheet. View the full page at https://docs.stripe.com/connect/end-to-end-saas-platform?platform=ios&mobile-ui=payment-sheet. ![](https://b.stripecdn.com/docs-statics-srv/assets/ios-overview.9e0d68d009dc005f73a6f5df69e00458.png) [PaymentSheet](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet.html) クラスを使用して、Stripe の構築済み決済 UI を iOS アプリの決済フローに組み込みます。[GitHub](https://github.com/stripe/stripe-ios/tree/master/Example/PaymentSheet%20Example) のサンプル実装をご覧ください。 > #### Accounts v2 API サポート > > Payment Sheet は*顧客設定のアカウント* (Account configurations represent role-based functionality that you can enable for accounts, such as merchant, customer, or recipient)をサポートしていません。`Customer`オブジェクトのみをサポートしています。 ## 前提条件 1. [プラットフォームを登録](https://dashboard.stripe.com/connect)します。 1. [ダッシュボードでビジネスの詳細の確認と追加](https://dashboard.stripe.com/account/onboarding)。 1. [プラットフォームプロフィールを完成](https://dashboard.stripe.com/connect/settings/profile)させます。 1. [ブランド設定をカスタマイズ](https://dashboard.stripe.com/settings/connect/stripe-dashboard/branding)します。ビジネス名、アイコン、ブランドカラーを追加します。 ## Stripe を設定する [サーバー側] [クライアント側] まず、Stripe アカウントが必要です。[今すぐ登録](https://dashboard.stripe.com/register)してください。 ### サーバー側 この組み込みは、Stripe API と通信するサーバー上にエンドポイントを必要とします。サーバーから Stripe API にアクセスするには、次のように Stripe の公式ライブラリーを使用します。 #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ### クライアント側 [Stripe iOS SDK](https://github.com/stripe/stripe-ios) はオープンソースです。[詳細なドキュメントが提供されており](https://stripe.dev/stripe-ios/index.html)、iOS 13 以降をサポートするアプリと互換性があります。 #### Swift Package Manager SDK をインストールするには、以下のステップに従います。 1. Xcode で、**File (ファイル)** > **Add Package Dependencies… (パッケージ依存関係を追加)** を選択し、リポジトリー URL として `https://github.com/stripe/stripe-ios-spm` を入力します。 1. [リリースページ](https://github.com/stripe/stripe-ios/releases)から最新のバージョン番号を選択します。 1. **StripePaymentSheet** 製品を[アプリのターゲット](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app)に追加します。 #### CocoaPods 1. まだインストールしていない場合は、[CocoaPods](https://guides.cocoapods.org/using/getting-started.html) の最新バージョンをインストールします。 1. 既存の [Podfile](https://guides.cocoapods.org/syntax/podfile.html) がない場合は、以下のコマンドを実行して作成します。 ```bash pod init ``` 1. この行を `Podfile` に追加します。 ```podfile pod 'StripePaymentSheet' ``` 1. 以下のコマンドを実行します。 ```bash pod install ``` 1. これ以降は、Xcode でプロジェクトを開く際に、`.xcodeproj` ファイルではなく、必ず `.xcworkspace` ファイルを使用するということを忘れないでください。 1. 今後、SDK の最新バージョンに更新するには、以下を実行します。 ```bash pod update StripePaymentSheet ``` #### Carthage 1. まだインストールしていない場合は、[Carthage](https://github.com/Carthage/Carthage#installing-carthage) の最新バージョンをインストールします。 1. この行を `Cartfile` に追加します。 ```cartfile github "stripe/stripe-ios" ``` 1. [Carthage のインストール手順](https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos)に従います。必ず、[こちら](https://github.com/stripe/stripe-ios/tree/master/StripePaymentSheet/README.md#manual-linking)にリストされている必要なフレームワークのすべてを埋め込んでください。 1. 今後、SDK の最新バージョンに更新するには、以下のコマンドを実行します。 ```bash carthage update stripe-ios --platform ios ``` #### 手動のフレームワーク 1. Stripe の [GitHub リリースページ](https://github.com/stripe/stripe-ios/releases/latest)に移動して、**Stripe.xcframework.zip** をダウンロードして解凍します。 1. **StripePaymentSheet.xcframework** を、Xcode プロジェクトの **General (一般) ** 設定の **Embedded Binaries (埋め込みバイナリー)** セクションにドラッグします。**Copy items if needed (必要に応じてアイテムをコピーする)** を必ず選択してください。 1. [こちら](https://github.com/stripe/stripe-ios/tree/master/StripePaymentSheet/README.md#manual-linking)にリストされている必要なフレームワークのすべてに対して、ステップ 2 を繰り返します。 1. 今後、Stripe の SDK の最新バージョンに更新するには、ステップ 1 から 3 を繰り返します。 > SDK の最新リリースおよび過去バージョンの詳細については、GitHub の [Releases (リリース)](https://github.com/stripe/stripe-ios/releases) ページをご覧ください。リポジトリの[リリースをウォッチ](https://help.github.com/en/articles/watching-and-unwatching-releases-for-a-repository#watching-releases-for-a-repository)して、新しいリリースの公開時に通知を受け取ることも可能です。 アプリの起動時に Stripe [公開可能キー](https://dashboard.stripe.com/test/apikeys)を使用して SDK を設定します。これにより、アプリが Stripe API にリクエストを送信できるようになります。 #### Swift ```swift import UIKitimportStripePaymentSheet @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {StripeAPI.defaultPublishableKey = "<>" // do any other necessary launch configuration return true } } ``` > テストおよび開発時には[テストキー](https://docs.stripe.com/keys.md#obtain-api-keys)を使用し、アプリの公開時には[本番環境](https://docs.stripe.com/keys.md#test-live-modes)キーを使用します。 ## 連結アカウントを作成する ユーザー (売り手またはサービスプロバイダー) がプラットフォームに登録したら、ユーザーの [Account (アカウント)](https://docs.stripe.com/api/accounts.md) (「連結アカウント」と呼ばれる) を作成し、決済を受け付けて売上をユーザーの銀行口座に入金できるようにします。連結アカウントは Stripe の API でユーザーを表し、アカウント登録要件の収集を簡単にして Stripe がユーザーの本人確認を実行できるようにします。ストアビルダーの例では、連結アカウントはオンラインストアを設定するビジネスを表します。 ![アカウントの作成フロー](https://b.stripecdn.com/docs-statics-srv/assets/standard-ios.10c6b24cef1d683d36f2264c726beb1d.png) ### Step 2.1: 連結アカウントを作成し、情報を事前入力する(サーバー側) `/v1/accounts` API を使用して連結アカウントを[作成](https://docs.stripe.com/api/accounts/create.md)します。[デフォルトの連結アカウントのパラメーター](https://docs.stripe.com/connect/migrate-to-controller-properties.md)を指定するか、アカウントタイプを指定して、連結アカウントを作成できます。 #### デフォルトのプロパティを使用 ```curl curl -X POST https://api.stripe.com/v1/accounts \ -u "<>:" ``` #### アカウントタイプを使用した場合 ```curl curl https://api.stripe.com/v1/accounts \ -u "<>:" \ -d type=standard ``` 連結アカウントの情報をすでに収集している場合は、`Account` オブジェクトにその情報を事前入力できます。個人情報や事業情報、外部のアカウント情報など、あらゆるアカウント情報を事前に入力できます。 `Account` を作成したら、`relationship.representative` を true に設定した [Person](https://docs.stripe.com/api/persons/create.md) を作成して、アカウント開設の責任者と、事前に入力したいアカウント情報 (氏名など) を表します。 ```curl curl https://api.stripe.com/v1/accounts/{{ACCOUNT_ID}}/persons \ -u "<>:" \ -d first_name=Jenny \ -d last_name=Rosen \ -d "relationship[representative]=true" ``` Connect アカウント登録で、事前入力された情報が要求されることはありません。ただし、アカウント所有者は [Connect 利用規約](https://docs.stripe.com/connect/service-agreement-types.md)に同意する前に、事前入力された情報を確認するよう求められます。 実装内容をテストする場合、[テストデータ](https://docs.stripe.com/connect/testing.md)を使用してアカウント情報を事前入力します。 ### ステップ 2.2: アカウントリンクを作成する (サーバー側) 以下のパラメーターを使用して [Account Links](https://docs.stripe.com/api/account_links.md) API を呼び出すことで、アカウントリンクを作成できます。 - `account` - `refresh_url` - `return_url` - `type` = `account_onboarding` ```curl curl https://api.stripe.com/v1/account_links \ -u "<>:" \ -d "account={{CONNECTEDACCOUNT_ID}}" \ --data-urlencode "refresh_url=https://example.com/reauth" \ --data-urlencode "return_url=https://example.com/return" \ -d type=account_onboarding ``` ### ステップ 2.3: ユーザーをアカウントリンク URL にリダイレクトする (クライアント側) [Account Links](https://docs.stripe.com/api/account_links.md) リクエストへのレスポンスには、キー `url` の値が含まれます。ユーザーをこのリンクにリダイレクトして、処理を進めることができるようにします。Account Links は一時的なものであり、連結アカウントユーザーの個人情報へのアクセスを許可するため、使用できるのは 1 回限りです。この URL にリダイレクトする前に、アプリケーションでユーザーを認証してください。情報の事前入力は、アカウントリンクを生成する前に行う必要があります。Standard アカウントのアカウントリンクを作成した後は、そのアカウントの情報を読み書きできなくなります。 > アカウントリンクの URL をメールやショートメッセージ、またはその他の方法で、プラットフォームのアプリケーション外に送信しないでください。URL は、アプリケーション内で認証済みのアカウント所有者に提供してください。 #### Swift ```swift import UIKit import SafariServices let BackendAPIBaseURL: String = "" // Set to the URL of your backend server class ConnectOnboardViewController: UIViewController { // ... override func viewDidLoad() { super.viewDidLoad() let connectWithStripeButton = UIButton(type: .system) connectWithStripeButton.setTitle("Connect with Stripe", for: .normal) connectWithStripeButton.addTarget(self, action: #selector(didSelectConnectWithStripe), for: .touchUpInside) view.addSubview(connectWithStripeButton) // ... } @objc func didSelectConnectWithStripe() { if let url = URL(string: BackendAPIBaseURL)?.appendingPathComponent("onboard-user") { var request = URLRequest(url: url) request.httpMethod = "POST" let task = URLSession.shared.dataTask(with: request) { (data, response, error) in guard let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any], let accountURLString = json["url"] as? String, let accountURL = URL(string: accountURLString) else { // handle error } let safariViewController = SFSafariViewController(url: accountURL) safariViewController.delegate = self DispatchQueue.main.async { self.present(safariViewController, animated: true, completion: nil) } } } } // ... } extension ConnectOnboardViewController: SFSafariViewControllerDelegate { func safariViewControllerDidFinish(_ controller: SFSafariViewController) { // the user may have closed the SFSafariViewController instance before a redirect // occurred. Sync with your backend to confirm the correct state } } ``` ### ステップ 2.4: ユーザーがプラットフォームに戻るように処理する (クライアント側) *Connect* (Connect is Stripe's solution for multi-party businesses, such as marketplace or software platforms, to route payments between sellers, customers, and other recipients) アカウント登録では、ユーザーがプラットフォームにリダイレクトされるすべてのケースを処理するために、`return_url` と `refresh_url` の両方を渡す必要があります。ユーザーが快適に操作できるようにするには、これらを正しく実装することが重要です。[ユニバーサルリンク](https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content)を設定して、iOS がアプリに自動的にリダイレクトするようにできます。 #### return_url ユーザーが Connect アカウント登録フローを完了すると、Stripe はこの URL へのリダイレクトを行います。ただしこれは、すべての情報が収集されたことを意味するものでも、アカウントの要件がすべて満たされたことを意味するものでもありません。ユーザーがフローに正常に入り、そこから正常に出たことのみを意味します。 パラメーターの状態がこの URL を通じて渡されることはありません。ユーザーが `return_url` にリダイレクトされたら、以下のいずれかを行い、アカウントの `details_submitted` パラメーターの状態を確認します。 - `account.updated` *Webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) をリッスンする - [Accounts](https://docs.stripe.com/api/accounts.md) API を呼び出して、返されたオブジェクトを調べる #### refresh_url 以下のケースでは、ユーザーが `refresh_url` にリダイレクトされます。 - リンクの期限が切れた (リンク作成後、数分が経過した) - ユーザーがすでにリンクを使用した (ユーザーがページを更新したか、ブラウザーで戻るボタンまたは進むボタンをクリックした) - プラットフォームがアカウントにアクセスできなくなった - アカウントが拒否された `refresh_url` はサーバでメソッドをトリガーし、同じパラメータを使用して [Account Link (アカウントリンク)](https://docs.stripe.com/api/account_links.md) を再度呼び出し、シームレスな体験を作成するためにユーザを Connect アカウント登録フローにリダイレクトする必要があります。 ### ステップ 2.5: アカウント登録を完了していないユーザーを処理する `return_url` にリダイレクトされたユーザーは、アカウント登録プロセスを完了していないことがあります。`/v1/accounts` エンドポイントを使用してユーザーのアカウントを取得し、`charges_enabled` を確認します。アカウント登録が完全でない場合は、UI プロンプトを表示し、ユーザーが後でアカウント登録を続行できるようにします。ユーザーは、新しいアカウントリンク (システムで生成された) で本番環境利用の申請を完了できます。アカウントの `details_submitted` パラメーターの状態を確認すると、ユーザーがアカウント登録プロセスを完了したかどうかを調べることができます。 ## 支払い方法を有効にする [支払い方法の設定](https://dashboard.stripe.com/settings/connect/payment_methods)を表示し、サポートする支払い方法を有効にします。カード支払いはデフォルトで有効化されていますが、支払い方法は必要に応じて有効か無効かを設定できます。 ## エンドポイントを追加する [サーバー側] > #### 注 > > PaymentIntent の作成前に PaymentSheet を表示するには、[インテントを作成する前に支払いの詳細を収集する](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=payment)をご覧ください。 この接続方法では、以下の 3 つの Stripe API オブジェクトを使用します。 1. [PaymentIntent (支払いインテント)](https://docs.stripe.com/api/payment_intents.md): Stripe はこれを使用して、顧客から支払いを回収する意図を示し、プロセス全体を通して支払いの試行と支払い状態の変化を追跡します。 1. (オプション) [顧客設定アカウント](https://docs.stripe.com/api/v2/core/accounts/object.md#v2_account_object-applied_configurations) または [Customer](https://docs.stripe.com/api/customers.md) オブジェクト。今後の支払いに備えて決済手段を設定するには、顧客に関連付ける必要があります。顧客がビジネスでアカウントを作成するときに、顧客を表すオブジェクトを作成します。顧客がゲストとして支払いを行う場合は、支払いの前に `Account` または `Customer` オブジェクトを作成し、後で顧客のアカウントを表す独自の内部表現に関連付けることができます。 1. (オプション) [CustomerSession](https://docs.stripe.com/api/customer_sessions.md)。顧客を表すオブジェクトの情報は機密情報であるため、アプリから直接取得することはできません。`CustomerSession` により、SDK に `Account` または `Customer` への範囲を設定した一時的なアクセス権が付与され、追加の設定オプションも提供されます。すべての [設定オプション](https://docs.stripe.com/api/customer_sessions/create.md#create_customer_session-components) のリストをご覧ください。 > 顧客にカードを保存したことがなく、リピート顧客に保存されたカードの再利用を許可しない場合は、導入で `Account` または `Customer` オブジェクトおよび `CustomerSession` オブジェクトを省略できます。 セキュリティ上の理由により、アプリでこれらのオブジェクトを作成することはできません。代わりに、サーバー側で以下を行うエンドポイントを追加します。 1. `Account` または `Customer` を取得するか、新規作成します。 1. `Account` または `Customer` の [CustomerSession](https://docs.stripe.com/api/customer_sessions.md) を作成します。 1. [金額](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-amount)、[通貨](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-currency)、および [customer_account](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer_account) または [customer](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer) を使用して `PaymentIntent` を作成します。 1. `PaymentIntent` の *Client Secret* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer))、`CustomerSession` の `client_secret`、`Account` または `Customer` の ID、およびアプリの [公開可能キー](https://dashboard.stripe.com/apikeys) を返します。 決済プロセス中に顧客に表示される支払い方法は、PaymentIntent にも含まれています。Stripe にダッシュボードの設定から支払い方法を取得するよう指定することも、手動でリストに表示することもできます。選択したオプションにかかわらず、顧客に表示される支払い方法は、PaymentIntent で渡す通貨によって絞り込まれることにご注意ください。たとえば、PaymentIntent で `eur` を渡し、ダッシュボードで OXXO が有効になっている場合、OXXO は `eur` による決済に対応していないため、顧客に表示されません。 構築済みのシステムで、決済手段を提供するためにコードベースのオプションが必要になる場合を除き、自動化されたオプションを使用することをお勧めします。これは、Stripe が通貨、決済手段の制約、その他のパラメーターを評価して、対応可能な決済手段を決定するためです。自動化されたオプションでは、購入完了率の向上につながり、使用通貨と顧客の所在地に最適な決済手段が優先的に表示されます。 #### ダッシュボードで支払い方法を管理する 支払い方法は[ダッシュボード](https://dashboard.stripe.com/settings/payment_methods)で管理できます。Stripe は取引額、通貨、決済フローなどの要素に基づいて、適切な支払い方法が返されるように処理します。PaymentIntent は、ダッシュボードで設定された支払い方法を使用して作成されます。ダッシュボードを使用しない場合や、支払い方法を手動で指定する場合は、`payment_method_types` 属性を使用して支払い方法を一覧表示することができます。 #### curl ```bash # Create a Customer (use an existing Customer ID if this is a returning customer) curl https://api.stripe.com/v1/customers \ -u <>: \ -X "POST" \ -H "Stripe-Account: {{CONNECTED_ACCOUNT_ID}}" # Create an CustomerSession for the Customer curl https://api.stripe.com/v1/customer_sessions \ -u <>: \ -X "POST" \ -d "customer"="{{CUSTOMER_ID}}" \ -d "components[mobile_payment_element][enabled]"=true \ -d "components[mobile_payment_element][features][payment_method_save]"=enabled \ -d "components[mobile_payment_element][features][payment_method_redisplay]"=enabled \ -d "components[mobile_payment_element][features][payment_method_remove]"=enabled # Create a PaymentIntent curl https://api.stripe.com/v1/payment_intents \ -u <>: \ -H "Stripe-Account: {{CONNECTED_ACCOUNT_ID}}" -X "POST" \ -d "customer"="{{CUSTOMER_ID}}" \ -d "amount"=1099 \ -d "currency"="eur" \ -d "automatic_payment_methods[enabled]"=true \ -d application_fee_amount="123" \ ``` #### 支払い方法を手動で一覧表示する #### curl ```bash # Create a Customer (use an existing Customer ID if this is a returning customer) curl https://api.stripe.com/v1/customers \ -u <>: \ -X "POST" \ -H "Stripe-Account: {{CONNECTED_ACCOUNT_ID}}" # Create an CustomerSession for the Customer curl https://api.stripe.com/v1/customer_sessions \ -u <>: \ -X "POST" \ -d "customer"="{{CUSTOMER_ID}}" \ -d "components[mobile_payment_element][enabled]"=true \ -d "components[mobile_payment_element][features][payment_method_save]"=enabled \ -d "components[mobile_payment_element][features][payment_method_redisplay]"=enabled \ -d "components[mobile_payment_element][features][payment_method_remove]"=enabled # Create a PaymentIntent curl https://api.stripe.com/v1/payment_intents \ -u <>: \ -H "Stripe-Account: {{CONNECTED_ACCOUNT_ID}}" -X "POST" \ -d "customer"="{{CUSTOMER_ID}}" \ -d "amount"=1099 \ -d "currency"="eur" \ -d "payment_method_types[]"="bancontact" \ -d "payment_method_types[]"="card" \ -d "payment_method_types[]"="ideal" \ -d "payment_method_types[]"="klarna" \ -d "payment_method_types[]"="sepa_debit" \ -d application_fee_amount="123" \ ``` > 各決済手段は PaymentIntent で渡された通貨に対応している必要があり、ビジネスは、各決済手段を使用できる国のいずれかに所在する必要があります。対応状況について、詳細は[決済手段の導入オプション](https://docs.stripe.com/payments/payment-methods/integration-options.md)ページをご覧ください。 ## 支払い画面を組み込む [クライアント側] 決済画面にモバイル Payment Element を表示するには、以下を実行します。 - 顧客が購入している商品を合計金額とともに表示する - [Address Element](https://docs.stripe.com/elements/address-element.md?platform=ios) を使用して、必要な配送先情報を顧客から収集する - Stripe の UI を表示する購入ボタンを追加する #### UIKit #### Accounts v2 アプリの決済画面で、前のステップで作成したエンドポイントから PaymentIntent の Client Secret、`CustomerSession` の Client Secret、顧客設定の`Account` ID、公開可能キーを取得します。`STPAPIClient.shared` を使用して公開可能キーを設定し、[PaymentSheet](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet.html) を初期化します。 次に、`STPAPIClient.shared.stripeAccount` を連結アカウントの ID に設定します。 #### iOS (Swift) ```swift import UIKit@_spi(CustomerSessionBetaAccess) import StripePaymentSheet class CheckoutViewController: UIViewController { @IBOutlet weak var checkoutButton: UIButton! var paymentSheet: PaymentSheet? let backendCheckoutUrl = URL(string: "Your back-end endpoint/payment-sheet")! // Your back-end endpoint override func viewDidLoad() { super.viewDidLoad() checkoutButton.addTarget(self, action: #selector(didTapCheckoutButton), for: .touchUpInside) checkoutButton.isEnabled = false // MARK: Fetch the PaymentIntent client secret, CustomerSession client secret, customer-configured Account ID, and publishable key var request = URLRequest(url: backendCheckoutUrl) request.httpMethod = "POST" let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (data, response, error) in guard let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any], let customerAccountId = json["customerAccount"] as? String, let customerSessionClientSecret = json["customerSessionClientSecret"] as? String, let paymentIntentClientSecret = json["paymentIntent"] as? String, let publishableKey = json["publishableKey"] as? String, let self = self else { // Handle error return } STPAPIClient.shared.publishableKey = publishableKeySTPAPIClient.shared.stripeAccount = ""{{CONNECTED_ACCOUNT_ID}}""// MARK: Create a PaymentSheet instance var configuration = PaymentSheet.Configuration() configuration.merchantDisplayName = "Example, Inc." configuration.customerAccount = .init(id: customerAccountId, customerSessionClientSecret: customerSessionClientSecret) // Set `allowsDelayedPaymentMethods` to true if your business handles // delayed notification payment methods like US bank accounts. configuration.allowsDelayedPaymentMethods = true self.paymentSheet = PaymentSheet(paymentIntentClientSecret:paymentIntentClientSecret, configuration: configuration) DispatchQueue.main.async { self.checkoutButton.isEnabled = true } }) task.resume() } } ``` #### Customers v1 アプリの決済画面で、前のステップで作成したエンドポイントから PaymentIntent の Client Secret、`CustomerSession` の Client Secret、`Customer` ID、公開可能キーを取得します。`STPAPIClient.shared` を使用して公開可能キーを設定し、[PaymentSheet](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet.html) を初期化します。 次に、`STPAPIClient.shared.stripeAccount` を連結アカウントの ID に設定します。 #### iOS (Swift) ```swift import UIKit@_spi(CustomerSessionBetaAccess) import StripePaymentSheet class CheckoutViewController: UIViewController { @IBOutlet weak var checkoutButton: UIButton! var paymentSheet: PaymentSheet? let backendCheckoutUrl = URL(string: "Your backend endpoint/payment-sheet")! // Your backend endpoint override func viewDidLoad() { super.viewDidLoad() checkoutButton.addTarget(self, action: #selector(didTapCheckoutButton), for: .touchUpInside) checkoutButton.isEnabled = false // MARK: Fetch the PaymentIntent client secret, CustomerSession client secret, Customer ID, and publishable key var request = URLRequest(url: backendCheckoutUrl) request.httpMethod = "POST" let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (data, response, error) in guard let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any], let customerId = json["customer"] as? String, let customerSessionClientSecret = json["customerSessionClientSecret"] as? String, let paymentIntentClientSecret = json["paymentIntent"] as? String, let publishableKey = json["publishableKey"] as? String, let self = self else { // Handle error return } STPAPIClient.shared.publishableKey = publishableKeySTPAPIClient.shared.stripeAccount = ""{{CONNECTED_ACCOUNT_ID}}""// MARK: Create a PaymentSheet instance var configuration = PaymentSheet.Configuration() configuration.merchantDisplayName = "Example, Inc." configuration.customer = .init(id: customerId, customerSessionClientSecret: customerSessionClientSecret) // Set `allowsDelayedPaymentMethods` to true if your business handles // delayed notification payment methods like US bank accounts. configuration.allowsDelayedPaymentMethods = true self.paymentSheet = PaymentSheet(paymentIntentClientSecret:paymentIntentClientSecret, configuration: configuration) DispatchQueue.main.async { self.checkoutButton.isEnabled = true } }) task.resume() } } ``` 顧客が**購入**ボタンをタップしたら、`present` を呼び出して PaymentSheet を表示します。顧客が支払いを完了したら、Stripe は PaymentSheet を閉じ、[PaymentSheetResult](https://stripe.dev/stripe-ios/stripe-paymentsheet/Enums/PaymentSheetResult.html) とともに完了ブロックを呼び出します。 #### iOS (Swift) ```swift @objc func didTapCheckoutButton() { // MARK: Start the checkout process paymentSheet?.present(from: self) { paymentResult in // MARK: Handle the payment result switch paymentResult { case .completed: print("Your order is confirmed") case .canceled: print("Canceled!") case .failed(let error): print("Payment failed: \(error)") } } } ``` #### SwiftUI #### Accounts v2 決済画面用の `ObservableObject` モデルを作成します。このモデルは、[PaymentSheet](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet.html) と [PaymentSheetResult](https://stripe.dev/stripe-ios/stripe-paymentsheet/Enums/PaymentSheetResult.html) を公開します。 ```swift import StripePaymentSheet import SwiftUI class CheckoutViewModel: ObservableObject { let backendCheckoutUrl = URL(string: "Your back-end endpoint/payment-sheet")! // Your back-end endpoint @Published var paymentSheet: PaymentSheet? @Published var paymentResult: PaymentSheetResult? } ``` 前のステップで作成したエンドポイントから PaymentIntent の Client Secret、`CustomerSession` の Client Secret、顧客設定の`Account` ID、公開可能キーを取得します。`STPAPIClient.shared` を使用して公開可能キーを設定し、[PaymentSheet](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet.html) を初期化します。 次に、`STPAPIClient.shared.stripeAccount` を連結アカウントの ID に設定します。 ```swift @_spi(CustomerSessionBetaAccess) import StripePaymentSheet import SwiftUI class CheckoutViewModel: ObservableObject { let backendCheckoutUrl = URL(string: "Your back-end endpoint/payment-sheet")! // Your back-end endpoint @Published var paymentSheet: PaymentSheet? @Published var paymentResult: PaymentSheetResult? func preparePaymentSheet() { // MARK: Fetch thePaymentIntent and customer information from the back end var request = URLRequest(url: backendCheckoutUrl) request.httpMethod = "POST" let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (data, response, error) in guard let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any], let customerAccountId = json["customerAccount"] as? String, let customerSessionClientSecret = json["customerSessionClientSecret"] as? String, letpaymentIntentClientSecret = json["paymentIntent"] as? String, let publishableKey = json["publishableKey"] as? String, let self = self else { // Handle error return } STPAPIClient.shared.publishableKey = publishableKeySTPAPIClient.shared.stripeAccount = ""{{CONNECTED_ACCOUNT_ID}}""// MARK: Create a PaymentSheet instance var configuration = PaymentSheet.Configuration() configuration.merchantDisplayName = "Example, Inc." configuration.customerAccount = .init(id: customerAccountId, customerSessionClientSecret: customerSessionClientSecret) // Set `allowsDelayedPaymentMethods` to true if your business handles // delayed notification payment methods like US bank accounts. configuration.allowsDelayedPaymentMethods = true DispatchQueue.main.async { self.paymentSheet = PaymentSheet(paymentIntentClientSecret:paymentIntentClientSecret, configuration: configuration) } }) task.resume() } } struct CheckoutView: View { @ObservedObject var model = CheckoutViewModel() var body: some View { VStack { if model.paymentSheet != nil { Text("Ready to pay.") } else { Text("Loading…") } }.onAppear { model.preparePaymentSheet() } } } ``` [PaymentSheet.PaymentButton](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/PaymentButton.html) を `View` に追加します。これは、SwiftUI の `Button` と同様に動作し、`View` を追加することでカスタマイズされます。ボタンをタップすると PaymentSheet が表示されます。支払いが完了すると、Stripe は PaymentSheet を閉じ、[PaymentSheetResult](https://stripe.dev/stripe-ios/stripe-paymentsheet/Enums/PaymentSheetResult.html) オブジェクトとともに `onCompletion` ハンドラが呼び出されます。 ```swift @_spi(CustomerSessionBetaAccess) import StripePaymentSheet import SwiftUI class CheckoutViewModel: ObservableObject { let backendCheckoutUrl = URL(string: "Your back-end endpoint/payment-sheet")! // Your back-end endpoint @Published var paymentSheet: PaymentSheet? @Published var paymentResult: PaymentSheetResult? func preparePaymentSheet() { // MARK: Fetch the PaymentIntent and customer information from the back end var request = URLRequest(url: backendCheckoutUrl) request.httpMethod = "POST" let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (data, response, error) in guard let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any], let customerAccountId = json["customerAccount"] as? String, let customerSessionClientSecret = json["customerSessionClientSecret"] as? String, let paymentIntentClientSecret = json["paymentIntent"] as? String, let publishableKey = json["publishableKey"] as? String, let self = self else { // Handle error return } STPAPIClient.shared.publishableKey = publishableKey STPAPIClient.shared.stripeAccount = ""{{CONNECTED_ACCOUNT_ID}}"" // MARK: Create a PaymentSheet instance var configuration = PaymentSheet.Configuration() configuration.merchantDisplayName = "Example, Inc." configuration.customerAccount = .init(id: customerAccountId, customerSessionClientSecret: customerSessionClientSecret) // Set `allowsDelayedPaymentMethods` to true if your business can handle payment methods // that complete payment after a delay, like SEPA Debit and Sofort. configuration.allowsDelayedPaymentMethods = true DispatchQueue.main.async { self.paymentSheet = PaymentSheet(paymentIntentClientSecret: paymentIntentClientSecret, configuration: configuration) } }) task.resume() } func onPaymentCompletion(result: PaymentSheetResult) { self.paymentResult = result } } struct CheckoutView: View { @ObservedObject var model = CheckoutViewModel() var body: some View { VStack {if let paymentSheet = model.paymentSheet { PaymentSheet.PaymentButton( paymentSheet: paymentSheet, onCompletion: model.onPaymentCompletion ) { Text("Buy") } } else { Text("Loading…") }if let result = model.paymentResult { switch result { case .completed: Text("Payment complete") case .failed(let error): Text("Payment failed: \(error.localizedDescription)") case .canceled: Text("Payment canceled.") } } }.onAppear { model.preparePaymentSheet() } } } ``` #### Customers v1 決済画面用の `ObservableObject` モデルを作成します。このモデルは、[PaymentSheet](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet.html) と [PaymentSheetResult](https://stripe.dev/stripe-ios/stripe-paymentsheet/Enums/PaymentSheetResult.html) を公開します。 ```swift import StripePaymentSheet import SwiftUI class CheckoutViewModel: ObservableObject { let backendCheckoutUrl = URL(string: "Your back-end endpoint/payment-sheet")! // Your back-end endpoint @Published var paymentSheet: PaymentSheet? @Published var paymentResult: PaymentSheetResult? } ``` 前のステップで作成したエンドポイントから PaymentIntent の Client Secret、CustomerSession の Client Secret、`Customer` ID、公開可能キーを取得します。`STPAPIClient.shared` を使用して公開可能キーを設定し、[PaymentSheet](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet.html) を初期化します。 次に、`STPAPIClient.shared.stripeAccount` を連結アカウントの ID に設定します。 ```swift @_spi(CustomerSessionBetaAccess) import StripePaymentSheet import SwiftUI class CheckoutViewModel: ObservableObject { let backendCheckoutUrl = URL(string: "Your back-end endpoint/payment-sheet")! // Your back-end endpoint @Published var paymentSheet: PaymentSheet? @Published var paymentResult: PaymentSheetResult? func preparePaymentSheet() { // MARK: Fetch thePaymentIntent and Customer information from the back end var request = URLRequest(url: backendCheckoutUrl) request.httpMethod = "POST" let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (data, response, error) in guard let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any], let customerId = json["customer"] as? String, let customerSessionClientSecret = json["customerSessionClientSecret"] as? String, letpaymentIntentClientSecret = json["paymentIntent"] as? String, let publishableKey = json["publishableKey"] as? String, let self = self else { // Handle error return } STPAPIClient.shared.publishableKey = publishableKeySTPAPIClient.shared.stripeAccount = ""{{CONNECTED_ACCOUNT_ID}}""// MARK: Create a PaymentSheet instance var configuration = PaymentSheet.Configuration() configuration.merchantDisplayName = "Example, Inc." configuration.customer = .init(id: customerId, customerSessionClientSecret: customerSessionClientSecret) // Set `allowsDelayedPaymentMethods` to true if your business handles // delayed notification payment methods like US bank accounts. configuration.allowsDelayedPaymentMethods = true DispatchQueue.main.async { self.paymentSheet = PaymentSheet(paymentIntentClientSecret:paymentIntentClientSecret, configuration: configuration) } }) task.resume() } } struct CheckoutView: View { @ObservedObject var model = CheckoutViewModel() var body: some View { VStack { if model.paymentSheet != nil { Text("Ready to pay.") } else { Text("Loading…") } }.onAppear { model.preparePaymentSheet() } } } ``` [PaymentSheet.PaymentButton](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/PaymentButton.html) を `View` に追加します。これは、SwiftUI の `Button` と同様に動作し、`View` を追加することでカスタマイズされます。ボタンをタップすると PaymentSheet が表示されます。支払いが完了すると、Stripe は PaymentSheet を閉じ、[PaymentSheetResult](https://stripe.dev/stripe-ios/stripe-paymentsheet/Enums/PaymentSheetResult.html) オブジェクトとともに `onCompletion` ハンドラが呼び出されます。 ```swift @_spi(CustomerSessionBetaAccess) import StripePaymentSheet import SwiftUI class CheckoutViewModel: ObservableObject { let backendCheckoutUrl = URL(string: "Your back-end endpoint/payment-sheet")! // Your back-end endpoint @Published var paymentSheet: PaymentSheet? @Published var paymentResult: PaymentSheetResult? func preparePaymentSheet() { // MARK: Fetch the PaymentIntent and Customer information from the back end var request = URLRequest(url: backendCheckoutUrl) request.httpMethod = "POST" let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (data, response, error) in guard let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any], let customerId = json["customer"] as? String, let customerSessionClientSecret = json["customerSessionClientSecret"] as? String, let paymentIntentClientSecret = json["paymentIntent"] as? String, let publishableKey = json["publishableKey"] as? String, let self = self else { // Handle error return } STPAPIClient.shared.publishableKey = publishableKey STPAPIClient.shared.stripeAccount = ""{{CONNECTED_ACCOUNT_ID}}"" // MARK: Create a PaymentSheet instance var configuration = PaymentSheet.Configuration() configuration.merchantDisplayName = "Example, Inc." configuration.customer = .init(id: customerId, customerSessionClientSecret: customerSessionClientSecret) // Set `allowsDelayedPaymentMethods` to true if your business can handle payment methods // that complete payment after a delay, like SEPA Debit and Sofort. configuration.allowsDelayedPaymentMethods = true DispatchQueue.main.async { self.paymentSheet = PaymentSheet(paymentIntentClientSecret: paymentIntentClientSecret, configuration: configuration) } }) task.resume() } func onPaymentCompletion(result: PaymentSheetResult) { self.paymentResult = result } } struct CheckoutView: View { @ObservedObject var model = CheckoutViewModel() var body: some View { VStack {if let paymentSheet = model.paymentSheet { PaymentSheet.PaymentButton( paymentSheet: paymentSheet, onCompletion: model.onPaymentCompletion ) { Text("Buy") } } else { Text("Loading…") }if let result = model.paymentResult { switch result { case .completed: Text("Payment complete") case .failed(let error): Text("Payment failed: \(error.localizedDescription)") case .canceled: Text("Payment canceled.") } } }.onAppear { model.preparePaymentSheet() } } } ``` `PaymentSheetResult` が `.completed` の場合は、顧客に通知します (注文確認画面を表示するなど)。 `allowsDelayedPaymentMethods` を true に設定すると、アメリカの銀行口座などの [遅延通知型](https://docs.stripe.com/payments/payment-methods.md#payment-notification)の支払い方法を使用できます。これらの支払い方法では、`PaymentSheet` が完了した時点では最終的な支払いステータスが判明せず、後になって成功または失敗が確定します。このようなタイプの支払い方法に対応する場合は、注文が確定済みであることを顧客に通知し、支払いが成功した場合にのみ注文のフルフィルメント (商品の発送など) を実行するようにします。 ## 戻り先 URL を設定する [クライアント側] 顧客はお客様のアプリから離れて、(Safari やバンキングアプリなどで) 認証する場合があります。ユーザーが認証後にアプリに自動的に戻れるようにするには、[カスタム URL スキームを構成](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app)し、URL を SDK に転送するようにアプリのデリゲートを設定します。Stripe は[ユニバーサルリンク](https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content)には対応していません。 #### SceneDelegate #### Swift ```swift // This method handles opening custom URL schemes (for example, "your-app://stripe-redirect") func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { guard let url = URLContexts.first?.url else { return } let stripeHandled = StripeAPI.handleURLCallback(with: url) if (!stripeHandled) { // This was not a Stripe url – handle the URL normally as you would } } ``` #### AppDelegate #### Swift ```swift // This method handles opening custom URL schemes (for example, "your-app://stripe-redirect") func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool { let stripeHandled = StripeAPI.handleURLCallback(with: url) if (stripeHandled) { return true } else { // This was not a Stripe url – handle the URL normally as you would } return false } ``` #### SwiftUI #### Swift ```swift @main struct MyApp: App { var body: some Scene { WindowGroup { Text("Hello, world!").onOpenURL { incomingURL in let stripeHandled = StripeAPI.handleURLCallback(with: incomingURL) if (!stripeHandled) { // This was not a Stripe url – handle the URL normally as you would } } } } } ``` ## 支払い後のイベントを処理する [サーバー側] 支払いが完了すると、Stripe は [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) イベントを送信します。[ダッシュボードの Webhook ツール](https://dashboard.stripe.com/webhooks)を使用するか [Webhook のガイド](https://docs.stripe.com/webhooks/quickstart.md)に従ってこれらのイベントを受信し、顧客への注文確認メールの送信、データベースでの売上の記録、配送ワークフローの開始などのアクションを実行します。 クライアントからのコールバックを待つのではなく、これらのイベントをリッスンします。クライアントでは、コールバックが実行される前に顧客がブラウザーのウィンドウを閉じたり、アプリを終了する場合、また悪意を持つクライアントがレスポンスを不正操作する場合もあります。非同期型のイベントをリッスンするよう組み込みを設定すると、単一の組み込みで[複数の異なるタイプの支払い方法](https://stripe.com/payments/payment-methods-guide)を受け付けることができます。 Payment Element を使用して支払いを回収する場合は、`payment_intent.succeeded` イベントのほかにこれらのイベントを処理することをお勧めします。 | イベント | 説明 | アクション | | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.succeeded) | 顧客が正常に支払いを完了したときに送信されます。 | 顧客に注文の確定を送信し、顧客の注文の*フルフィルメント* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected)を実行します。 | | [payment_intent.processing](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.processing) | 顧客が正常に支払いを開始したが、支払いがまだ完了していない場合に送信されます。このイベントは、多くの場合、顧客が口座引き落としを開始するときに送信されます。その後、`payment_intent.succeeded` イベント、また、失敗の場合は `payment_intent.payment_failed` イベントが送信されます。 | 顧客に注文確認メールを送信し、支払いが保留中であることを示します。デジタル商品では、支払いの完了を待たずに注文のフルフィルメントを行うことが必要になる場合があります。 | | [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.payment_failed) | 顧客が支払いを試みたが、支払いに失敗する場合に送信されます。 | 支払いが `processing` から `payment_failed` に変わった場合は、顧客に再度支払いを試すように促します。 | ## 組み込みをテストする #### カード | カード番号 | シナリオ | テスト方法 | | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | | 4242424242424242 | カード支払いは成功し、認証は必要とされません。 | クレジットカード番号と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 | | 4000002500003155 | カード支払いには*認証* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase)が必要です。 | クレジットカード番号と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 | | 4000000000009995 | カードは、`insufficient_funds` などの拒否コードで拒否されます。 | クレジットカード番号と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 | | 6205500000000000004 | UnionPay カードは、13 ~ 19 桁の可変長です。 | クレジットカード番号と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 | #### 銀行へのリダイレクト | 決済手段 | シナリオ | テスト方法 | | ---------------- | ---------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | | Bancontact、iDEAL | 顧客は、リダイレクトベースの即時通知型の支払い方法のリダイレクトページで、認証に失敗しました。 | リダイレクトベースの任意の支払い方法を選択し、必要な情報を入力して、支払いを確定します。その後、リダイレクトページで **Fail test payment (テスト支払い失敗)** をクリックします。 | | Pay by Bank | 顧客はリダイレクトベースの、[遅延通知型](https://docs.stripe.com/payments/payment-methods.md#payment-notification)の支払い方法で支払いに成功します。 | 支払い方法を選択し、必要な情報を入力して、支払いを確定します。その後、リダイレクトページで **Complete test payment (テスト支払い完了)** をクリックします。 | | Pay by Bank | 顧客は、リダイレクトベースの遅延通知型の支払い方法のリダイレクトページで、認証に失敗しました。 | 支払い方法を選択し、必要な情報を入力して、支払いを確定します。その後、リダイレクトページで **Fail test payment (テスト支払いを失敗させる)** をクリックします。 | | BLIK | BLIK による支払いはさまざまな理由で失敗します。即時の失敗 (コードの有効期限切れや無効など)、遅延型のエラー (銀行による拒否など)、またはタイムアウト (顧客が時間内に応答しなかったなど) などがあります。 | メールパターンを使用して[さまざまな失敗をシミュレーションします。](https://docs.stripe.com/payments/blik/accept-a-payment.md#simulate-failures) | #### 口座引き落とし | 決済手段 | シナリオ | テスト方法 | | -------------- | ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | | SEPA ダイレクトデビット | 顧客が SEPA ダイレクトデビットによる支払いに成功しました。 | 口座番号 `AT321904300235473204` を使用して、フォームに入力します。確定された PaymentIntent のステータスはまず、processing に移行し、3 分後に succeeded ステータスに移行します。 | | SEPA ダイレクトデビット | 顧客の Payment Intent のステータスが、`processing` から `requires_payment_method` に移行します。 | 口座番号 `AT861904300235473202` を使用して、フォームに入力します。 | 実装内容をテストするためのその他の情報については、[テスト](https://docs.stripe.com/testing.md)をご覧ください。 ## Optional: Apple Pay を有効にする > 決済画面に専用の **Apple Pay** ボタンがある場合は、[Apple Pay ガイド](https://docs.stripe.com/apple-pay.md#present-payment-sheet)に従い、`ApplePayContext` を使用して Apple Pay ボタンからの支払いを回収します。その他の種類の支払い方法を処理するには、`PaymentSheet` を使用できます。 ### Apple 加盟店 ID を登録する Apple Developer Web サイトで [新規 ID を登録](https://developer.apple.com/account/resources/identifiers/add/merchant) して、Apple 加盟店 ID を取得します。 フォームに説明と ID を入力します。説明はお客様の記録用であり、後で変更できます。アプリの名前を ID として使用することをお勧めします (`merchant.com.{{YOUR_APP_NAME}}` など)。 ### 新しい Apple Pay 証明書を作成する 支払いデータを暗号化するためのアプリの証明書を作成します。 ダッシュボードの [iOS certificate settings (iOS 証明書の設定)](https://dashboard.stripe.com/settings/ios_certificates) に移動して、**新規アプリケーションを追加**をクリックし、表示されるガイドに従います。 証明書署名リクエスト (CSR) ファイルをダウンロードして、Apple Pay の利用を可能にする安全な証明書を Apple から取得します。 1 つの CSR ファイルを使用して証明書を 1 つだけ発行する必要があります。Apple 加盟店 ID を切り替えた場合、ダッシュボードの [iOS Certificate Settings (iOS 証明書の設定)](https://dashboard.stripe.com/settings/ios_certificates) に移動して、新しい CSR と証明書を取得する必要があります。 ### Xcode を使用して組み込む Apple Pay ケイパビリティをアプリに追加します。Xcode でプロジェクト設定を開き、**Signing & Capabilities (署名およびケイパビリティ)** タブを選択して、**Apple Pay** ケイパビリティを追加します。この段階で開発者アカウントへのログインを要求される場合があります。前の手順で作成した加盟店 ID を選択すると、アプリで Apple Pay を受け付けられるようになります。 ![](https://b.stripecdn.com/docs-statics-srv/assets/xcode.a701d4c1922d19985e9c614a6f105bf1.png) Xcode で Apple Pay ケイパビリティを有効化する ### Apple Pay を追加する #### 1 回限りの支払い Apple Pay を PaymentSheet に追加するには、Apple 加盟店 ID と[お客様のビジネスの国コード](https://dashboard.stripe.com/settings/account)で `PaymentSheet.Configuration` を初期化してから、[applePay](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:6Stripe12PaymentSheetC13ConfigurationV8applePayAC05ApplefD0VSgvp) を設定します。 #### iOS (Swift) ```swift var configuration = PaymentSheet.Configuration() configuration.applePay = .init( merchantId: "merchant.com.your_app_name", merchantCountryCode: "US" ) ``` #### 継続支払い Apple Pay を PaymentSheet に追加するには、Apple 加盟店 ID と[お客様のビジネスの国コード](https://dashboard.stripe.com/settings/account)で `PaymentSheet.Configuration` を初期化してから、[applePay](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:6Stripe12PaymentSheetC13ConfigurationV8applePayAC05ApplefD0VSgvp) を設定します。 継続支払いに関する [Apple のガイドライン](https://developer.apple.com/design/human-interface-guidelines/apple-pay#Supporting-subscriptions)に従い、`PKPaymentRequest` で追加の属性を設定する必要もあります。[ApplePayConfiguration.paymentRequestHandlers](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/applepayconfiguration/handlers/paymentrequesthandler) にハンドラーを追加して、請求する予定の金額 (たとえば月額 9.95 USD) を指定して [PKPaymentRequest.paymentSummaryItems](https://developer.apple.com/documentation/passkit/pkpaymentrequest/1619231-paymentsummaryitems) を設定します。 `PKPaymentRequest` で `recurringPaymentRequest` または `automaticReloadPaymentRequest` プロパティを設定することで、[加盟店トークン](https://developer.apple.com/apple-pay/merchant-tokens/)を導入することもできます。 Apple Pay で継続支払いを使用する方法の詳細については、[Apple の PassKit に関するドキュメント](https://developer.apple.com/documentation/passkit/pkpaymentrequest)をご覧ください。 #### iOS (Swift) ```swift let customHandlers = PaymentSheet.ApplePayConfiguration.Handlers( paymentRequestHandler: { request in // PKRecurringPaymentSummaryItem is available on iOS 15 or later if #available(iOS 15.0, *) { let billing = PKRecurringPaymentSummaryItem(label: "My Subscription", amount: NSDecimalNumber(string: "59.99")) // Payment starts today billing.startDate = Date() // Payment ends in one year billing.endDate = Date().addingTimeInterval(60 * 60 * 24 * 365) // Pay once a month. billing.intervalUnit = .month billing.intervalCount = 1 // recurringPaymentRequest is only available on iOS 16 or later if #available(iOS 16.0, *) { request.recurringPaymentRequest = PKRecurringPaymentRequest(paymentDescription: "Recurring", regularBilling: billing, managementURL: URL(string: "https://my-backend.example.com/customer-portal")!) request.recurringPaymentRequest?.billingAgreement = "You'll be billed $59.99 every month for the next 12 months. To cancel at any time, go to Account and click 'Cancel Membership.'" } request.paymentSummaryItems = [billing] request.currencyCode = "USD" } else { // On older iOS versions, set alternative summary items. request.paymentSummaryItems = [PKPaymentSummaryItem(label: "Monthly plan starting July 1, 2022", amount: NSDecimalNumber(string: "59.99"), type: .final)] } return request } ) var configuration = PaymentSheet.Configuration() configuration.applePay = .init(merchantId: "merchant.com.your_app_name", merchantCountryCode: "US", customHandlers: customHandlers) ``` ### 注文の追跡 iOS 16 以降で[注文の追跡](https://developer.apple.com/design/human-interface-guidelines/technologies/wallet/designing-order-tracking)情報を追加するには、`PaymentSheet.ApplePayConfiguration.Handlers` で [authorizationResultHandler](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/applepayconfiguration/handlers/authorizationresulthandler) を設定します。支払いの完了後、Stripe は iOS が Apple Pay の決済画面を閉じる前に実装を呼び出します。 `authorizationResultHandler` の実装で、完了した注文の注文の詳細をサーバーから取得します。提供された [PKPaymentAuthorizationResult](https://developer.apple.com/documentation/passkit/pkpaymentauthorizationresult) に詳細を追加し、変更された結果を返します。 注文の追跡の詳細については、[Apple のウォレットでの注文に関するドキュメント](https://developer.apple.com/documentation/walletorders)をご覧ください。 #### iOS (Swift) ```swift let customHandlers = PaymentSheet.ApplePayConfiguration.Handlers( authorizationResultHandler: { result in do { // Fetch the order details from your service let myOrderDetails = try await MyAPIClient.shared.fetchOrderDetails(orderID: orderID) result.orderDetails = PKPaymentOrderDetails( orderTypeIdentifier: myOrderDetails.orderTypeIdentifier, // "com.myapp.order" orderIdentifier: myOrderDetails.orderIdentifier, // "ABC123-AAAA-1111" webServiceURL: myOrderDetails.webServiceURL, // "https://my-backend.example.com/apple-order-tracking-backend" authenticationToken: myOrderDetails.authenticationToken) // "abc123" // Return your modified PKPaymentAuthorizationResult return result } catch { return PKPaymentAuthorizationResult(status: .failure, errors: [error]) } } ) var configuration = PaymentSheet.Configuration() configuration.applePay = .init(merchantId: "merchant.com.your_app_name", merchantCountryCode: "US", customHandlers: customHandlers) ``` ## カードのスキャンを有効にする iOS をサポートするカードスキャン機能を有効にするには、アプリケーションの `Info.plist` の `NSCameraUsageDescription` (**プライバシー - カメラ利用の詳細**)を設定し、カメラにアクセスする理由を入力して下さい (例:「カードをスキャンするため」)。 ## Optional: 画面をカスタマイズする カスタマイズはすべて、[PaymentSheet.Configuration](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html) オブジェクトで設定されます。 ### デザイン 色やフォントなどをアプリの見た目や雰囲気に合わせてカスタマイズするには、[appearance API](https://docs.stripe.com/elements/appearance-api/mobile.md?platform=ios) を使用します。 ### 決済手段のレイアウト [paymentMethodLayout](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/configuration-swift.struct/paymentmethodlayout) を使用して、画面上の決済手段のレイアウトを設定します。横や縦に表示することも、Stripe がレイアウトを自動で最適化するように設定することもできます。 ![](https://b.stripecdn.com/docs-statics-srv/assets/ios-mpe-payment-method-layouts.9d0513e2fcec5660378ba1824d952054.png) #### Swift ```swift var configuration = PaymentSheet.Configuration() configuration.paymentMethodLayout = .automatic ``` ### ユーザーの住所を収集する [Address Element](https://docs.stripe.com/elements/address-element.md?platform=ios) を使用して、顧客から国内および国外の配送先住所や請求先住所を収集します。 ### 加盟店の表示名 [merchantDisplayName](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:18StripePaymentSheet0bC0C13ConfigurationV19merchantDisplayNameSSvp) を設定し、顧客に表示するビジネス名を指定します。デフォルトではアプリ名になります。 #### Swift ```swift var configuration = PaymentSheet.Configuration() configuration.merchantDisplayName = "My app, Inc." ``` ### ダークモード `PaymentSheet` は、ユーザーのシステム全体の表示設定 (ライト / ダークモード) に合わせて自動的に調整されます。アプリがダークモードに対応していない場合は、[style](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:18StripePaymentSheet0bC0C13ConfigurationV5styleAC18UserInterfaceStyleOvp) を `alwaysLight` または `alwaysDark` モードに設定できます。 ```swift var configuration = PaymentSheet.Configuration() configuration.style = .alwaysLight ``` ### デフォルトの請求詳細 支払い画面で収集される請求詳細のデフォルト値を設定するには、`defaultBillingDetails` プロパティーを設定します。`PaymentSheet` の各フィールドに、指定したそれらの値が事前に読み込まれます。 ```swift var configuration = PaymentSheet.Configuration() configuration.defaultBillingDetails.address.country = "US" configuration.defaultBillingDetails.email = "foo@bar.com" ``` ### 請求の詳細の収集 `billingDetailsCollectionConfiguration` を使用して、決済画面で請求の詳細を収集する方法を指定します。 顧客の名前、メールアドレス、電話番号、住所を収集できます。 支払い方法で必須の請求詳細のみを収集する場合は、`billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` を true に設定します。その場合、`PaymentSheet.Configuration.defaultBillingDetails` が支払い方法の[請求詳細](https://docs.stripe.com/api/payment_methods/object.md?lang=node#payment_method_object-billing_details)として設定されます。 支払い方法で必ずしも必須ではない追加の請求詳細を収集する場合は、`billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` を false に設定します。 その場合、`PaymentSheet` で収集した請求詳細が支払い方法の請求詳細として設定されます。 ```swift var configuration = PaymentSheet.Configuration() configuration.defaultBillingDetails.email = "foo@bar.com" configuration.billingDetailsCollectionConfiguration.name = .always configuration.billingDetailsCollectionConfiguration.email = .never configuration.billingDetailsCollectionConfiguration.address = .full configuration.billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod = true ``` > 情報の収集に適用される法律については、弁護士に相談してください。電話番号は、取引に必要な場合にのみ収集してください。 ## Optional: UI で支払いを完了する 支払い方法の詳細を収集するためにのみ支払い画面を表示して、後で `confirm` メソッドを呼び出して、アプリの UI で支払いを完了できます。これは、カスタムの購入ボタンがある場合や、支払いの詳細を収集した後で追加のステップが必要な場合に便利です。 ![](https://b.stripecdn.com/docs-statics-srv/assets/ios-multi-step.cd631ea4f1cd8cf3f39b6b9e1e92b6c5.png) アプリの UI で支払いを完了する #### UIKit 以下のステップでは、アプリの UI で支払いを完了する方法を説明します。[GitHub](https://github.com/stripe/stripe-ios/blob/master/Example/PaymentSheet%20Example/PaymentSheet%20Example/ExampleCustomCheckoutViewController.swift) でサンプルの実装をご覧下さい。 1. 最初に、`PaymentSheet` ではなく、[PaymentSheet.FlowController](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/flowcontroller) を初期化し、その `paymentOption` プロパティで UI を更新します。このプロパティには、顧客が最初に選択したデフォルトの支払い方法を表す画像とラベルが含まれています。 ```swift PaymentSheet.FlowController.create(paymentIntentClientSecret: paymentIntentClientSecret, configuration: configuration) { [weak self] result in switch result { case .failure(let error): print(error) case .success(let paymentSheetFlowController): self?.paymentSheetFlowController = paymentSheetFlowController // Update your UI using paymentSheetFlowController.paymentOption } } ``` 1. 次に、`presentPaymentOptions` を呼び出し、支払いの詳細を収集します。完了したら、`paymentOption` プロパティで再度 UI を更新します。 ```swift paymentSheetFlowController.presentPaymentOptions(from: self) { // Update your UI using paymentSheetFlowController.paymentOption } ``` 1. 最後に、`confirm` を呼び出します。 ```swift paymentSheetFlowController.confirm(from: self) { paymentResult in // MARK: Handle the payment result switch paymentResult { case .completed: print("Payment complete!") case .canceled: print("Canceled!") case .failed(let error): print(error) } } ``` #### SwiftUI 以下のステップでは、アプリの UI で支払いを完了する方法を説明します。[GitHub](https://github.com/stripe/stripe-ios/blob/master/Example/PaymentSheet%20Example/PaymentSheet%20Example/ExampleSwiftUICustomPaymentFlow.swift) でサンプルの実装をご覧下さい。 1. 最初に、`PaymentSheet` ではなく、[PaymentSheet.FlowController](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/flowcontroller) を初期化します。その `paymentOption` プロパティには、顧客が現在選択している支払い方法を表す画像とラベルが含まれており、これを UI で使用することができます。 ```swift PaymentSheet.FlowController.create(paymentIntentClientSecret: paymentIntentClientSecret, configuration: configuration) { [weak self] result in switch result { case .failure(let error): print(error) case .success(let paymentSheetFlowController): self?.paymentSheetFlowController = paymentSheetFlowController // Use the paymentSheetFlowController.paymentOption properties in your UI myPaymentMethodLabel = paymentSheetFlowController.paymentOption?.label ?? "Select a payment method" myPaymentMethodImage = paymentSheetFlowController.paymentOption?.image ?? UIImage(systemName: "square.and.pencil")! } } ``` 1. [PaymentSheet.FlowController.PaymentOptionsButton](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/flowcontroller/paymentoptionsbutton) を使用して、支払いの詳細を収集するための画面を表示するボタンをラップします。`PaymentSheet.FlowController` が `onSheetDismissed` 引数を呼び出すと、`PaymentSheet.FlowController` インスタンスの `paymentOption` に現在選択されている支払い方法が反映されます。 ```swift PaymentSheet.FlowController.PaymentOptionsButton( paymentSheetFlowController: paymentSheetFlowController, onSheetDismissed: { myPaymentMethodLabel = paymentSheetFlowController.paymentOption?.label ?? "Select a payment method" myPaymentMethodImage = paymentSheetFlowController.paymentOption?.image ?? UIImage(systemName: "square.and.pencil")! }, content: { /* An example button */ HStack { Text(myPaymentMethodLabel) Image(uiImage: myPaymentMethodImage) } } ) ``` 1. [PaymentSheet.FlowController.PaymentOptionsButton](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/flowcontroller/paymentoptionsbutton) を使用して、支払いを確定するボタンをラップします。 ```swift PaymentSheet.FlowController.ConfirmButton( paymentSheetFlowController: paymentSheetFlowController, onCompletion: { result in // MARK: Handle the payment result switch result { case .completed: print("Payment complete!") case .canceled: print("Canceled!") case .failed(let error): print(error) } }, content: { /* An example button */ Text("Pay") } ) ``` `PaymentSheetResult` が `.completed` の場合は、顧客に通知します (注文確認画面を表示するなど)。 `allowsDelayedPaymentMethods` を true に設定すると、アメリカの銀行口座などの [遅延通知型](https://docs.stripe.com/payments/payment-methods.md#payment-notification)の支払い方法を使用できます。これらの支払い方法では、`PaymentSheet` が完了した時点では最終的な支払いステータスが判明せず、後になって成功または失敗が確定します。このようなタイプの支払い方法に対応する場合は、注文が確定済みであることを顧客に通知し、支払いが成功した場合にのみ注文のフルフィルメント (商品の発送など) を実行するようにします。 ## テスト [アカウントを作成](https://docs.stripe.com/connect/testing.md#creating-accounts)し、[OAuth を使用](https://docs.stripe.com/connect/testing.md#using-oauth)して、アカウント作成フローをテストします。いずれかのテストアカウントにログインして[支払い方法の設定](https://dashboard.stripe.com/settings/payment_methods)に移動し、連結アカウントの**支払い方法**の設定をテストします。テストキーとテストアカウントを使用して、決済フローをテストします。Stripe の[テストカード](https://docs.stripe.com/testing.md)を使用して支払いフローをテストし、さまざまな支払い結果をシミュレーションできます。 # カード Element のみ > This is a カード Element のみ for when platform is ios and mobile-ui is card-element. View the full page at https://docs.stripe.com/connect/end-to-end-saas-platform?platform=ios&mobile-ui=card-element. SDK が提供し、カード番号、有効期限、セキュリティコード、郵便番号を収集するドロップイン UI コンポーネントである [STPPaymentCardTextField](https://stripe.dev/stripe-ios/stripe-payments-ui/Classes/STPPaymentCardTextField.html) を使用して、クライアント側でカード情報を安全に収集します。 ![](https://d37ugbyn3rpeym.cloudfront.net/docs/mobile/ios/card-field.mp4) ## 前提条件 1. [プラットフォームを登録](https://dashboard.stripe.com/connect)します。 1. [ダッシュボードでビジネスの詳細の確認と追加](https://dashboard.stripe.com/account/onboarding)。 1. [プラットフォームプロフィールを完成](https://dashboard.stripe.com/connect/settings/profile)させます。 1. [ブランド設定をカスタマイズ](https://dashboard.stripe.com/settings/connect/stripe-dashboard/branding)します。ビジネス名、アイコン、ブランドカラーを追加します。 ## Stripe を設定する [サーバ側] [クライアント側] まず、Stripe アカウントが必要です。[今すぐ登録](https://dashboard.stripe.com/register)してください。 ### サーバ側 この組み込みには、サーバ上に Stripe API と通信するエンドポイントが必要です。サーバから Stripe API にアクセスするには、Stripe の公式ライブラリを使用します。 #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ### クライアント側 [Stripe iOS SDK](https://github.com/stripe/stripe-ios) はオープンソースです。[詳細なドキュメントが提供されており](https://stripe.dev/stripe-ios/index.html)、iOS 13 以降をサポートするアプリと互換性があります。 #### Swift Package Manager SDK をインストールするには、以下のステップに従います。 1. Xcode で、**File (ファイル)** > **Add Package Dependencies… (パッケージ依存関係を追加)** を選択し、リポジトリー URL として `https://github.com/stripe/stripe-ios-spm` を入力します。 1. [リリースページ](https://github.com/stripe/stripe-ios/releases)から最新のバージョン番号を選択します。 1. **StripePaymentsUI** 製品を[アプリのターゲット](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app)に追加します。 #### CocoaPods 1. まだインストールしていない場合は、[CocoaPods](https://guides.cocoapods.org/using/getting-started.html) の最新バージョンをインストールします。 1. 既存の [Podfile](https://guides.cocoapods.org/syntax/podfile.html) がない場合は、以下のコマンドを実行して作成します。 ```bash pod init ``` 1. この行を `Podfile` に追加します。 ```podfile pod 'StripePaymentsUI' ``` 1. 以下のコマンドを実行します。 ```bash pod install ``` 1. これ以降は、Xcode でプロジェクトを開く際に、`.xcodeproj` ファイルではなく、必ず `.xcworkspace` ファイルを使用するということを忘れないでください。 1. 今後、SDK の最新バージョンに更新するには、以下を実行します。 ```bash pod update StripePaymentsUI ``` #### Carthage 1. まだインストールしていない場合は、[Carthage](https://github.com/Carthage/Carthage#installing-carthage) の最新バージョンをインストールします。 1. この行を `Cartfile` に追加します。 ```cartfile github "stripe/stripe-ios" ``` 1. [Carthage のインストール手順](https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos)に従います。必ず、[こちら](https://github.com/stripe/stripe-ios/tree/master/StripePaymentsUI/README.md#manual-linking)にリストされている必要なフレームワークのすべてを埋め込んでください。 1. 今後、SDK の最新バージョンに更新するには、以下のコマンドを実行します。 ```bash carthage update stripe-ios --platform ios ``` #### 手動のフレームワーク 1. Stripe の [GitHub リリースページ](https://github.com/stripe/stripe-ios/releases/latest)に移動して、**Stripe.xcframework.zip** をダウンロードして解凍します。 1. **StripePaymentsUI.xcframework** を、Xcode プロジェクトの **General (一般) ** 設定の **Embedded Binaries (埋め込みバイナリー)** セクションにドラッグします。**Copy items if needed (必要に応じてアイテムをコピーする)** を必ず選択してください。 1. [こちら](https://github.com/stripe/stripe-ios/tree/master/StripePaymentsUI/README.md#manual-linking)にリストされている必要なフレームワークのすべてに対して、ステップ 2 を繰り返します。 1. 今後、Stripe の SDK の最新バージョンに更新するには、ステップ 1 から 3 を繰り返します。 > SDK の最新リリースおよび過去バージョンの詳細については、GitHub の [Releases (リリース)](https://github.com/stripe/stripe-ios/releases) ページをご覧ください。リポジトリの[リリースをウォッチ](https://help.github.com/en/articles/watching-and-unwatching-releases-for-a-repository#watching-releases-for-a-repository)して、新しいリリースの公開時に通知を受け取ることも可能です。 アプリの起動時に Stripe [公開可能キー](https://dashboard.stripe.com/test/apikeys)を使用して SDK を設定します。これにより、アプリが Stripe API にリクエストを送信できるようになります。 #### Swift ```swift import UIKitimportStripePaymentsUI @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {StripeAPI.defaultPublishableKey = "<>" // do any other necessary launch configuration return true } } ``` > テストおよび開発時には[テストキー](https://docs.stripe.com/keys.md#obtain-api-keys)を使用し、アプリの公開時には[本番環境](https://docs.stripe.com/keys.md#test-live-modes)キーを使用します。 ## 連結アカウントを作成する このガイドを使用して、コードを使用して連結アカウントを作成する方法を確認します。まだ導入する準備ができていない場合は、[ダッシュボードから](https://docs.stripe.com/connect/dashboard/managing-individual-accounts.md)連結アカウントの作成を開始できます。 ユーザー (売り手またはサービスプロバイダー) がプラットフォームに登録したら、ユーザーの [Account (アカウント)](https://docs.stripe.com/api/accounts.md) (「連結アカウント」と呼ばれる) を作成し、決済を受け付けて売上をユーザーの銀行口座に入金できるようにします。連結アカウントは Stripe の API でユーザーを表し、アカウント登録要件の収集を簡単にして Stripe がユーザーの本人確認を実行できるようにします。ストアビルダーの例では、連結アカウントはオンラインストアを設定するビジネスを表します。 ![](https://b.stripecdn.com/docs-statics-srv/assets/standard-ios.10c6b24cef1d683d36f2264c726beb1d.png) ### Step 2.1: 連結アカウントを作成し、情報を事前入力する(サーバー側) `/v1/accounts` API を使用して連結アカウントを[作成](https://docs.stripe.com/api/accounts/create.md)します。[デフォルトの連結アカウントのパラメーター](https://docs.stripe.com/connect/migrate-to-controller-properties.md)を指定するか、アカウントタイプを指定して、連結アカウントを作成できます。 #### デフォルトのプロパティを使用 ```curl curl -X POST https://api.stripe.com/v1/accounts \ -u "<>:" ``` #### アカウントタイプを使用した場合 ```curl curl https://api.stripe.com/v1/accounts \ -u "<>:" \ -d type=standard ``` 連結アカウントの情報をすでに収集している場合は、`Account` オブジェクトにその情報を事前入力できます。個人情報や事業情報、外部のアカウント情報など、あらゆるアカウント情報を事前に入力できます。 `Account` を作成したら、`relationship.representative` を true に設定した [Person](https://docs.stripe.com/api/persons/create.md) を作成して、アカウント開設の責任者と、事前に入力したいアカウント情報 (氏名など) を表します。 ```curl curl https://api.stripe.com/v1/accounts/{{ACCOUNT_ID}}/persons \ -u "<>:" \ -d first_name=Jenny \ -d last_name=Rosen \ -d "relationship[representative]=true" ``` Connect アカウント登録で、事前入力された情報が要求されることはありません。ただし、アカウント所有者は [Connect 利用規約](https://docs.stripe.com/connect/service-agreement-types.md)に同意する前に、事前入力された情報を確認するよう求められます。 実装内容をテストする場合、[テストデータ](https://docs.stripe.com/connect/testing.md)を使用してアカウント情報を事前入力します。 ### ステップ 2.2: アカウントリンクを作成する (サーバー側) 以下のパラメーターを使用して [Account Links](https://docs.stripe.com/api/account_links.md) API を呼び出すことで、アカウントリンクを作成できます。 - `account` - `refresh_url` - `return_url` - `type` = `account_onboarding` ```curl curl https://api.stripe.com/v1/account_links \ -u "<>:" \ -d "account={{CONNECTEDACCOUNT_ID}}" \ --data-urlencode "refresh_url=https://example.com/reauth" \ --data-urlencode "return_url=https://example.com/return" \ -d type=account_onboarding ``` ### ステップ 2.3: ユーザーをアカウントリンク URL にリダイレクトする (クライアント側) [アカウントリンク](https://docs.stripe.com/api/account_links.md)のリクエストへの応答には、キー `url` の値が含まれます。このリンクにリダイレクトしてユーザーをフローに送ります。[アカウントリンク](https://docs.stripe.com/api/account_links.md) API からの URL は一時的なもので、アカウント所有者の個人情報へのアクセスを許可するため、1 回しか使用できません。この URL にリダイレクトする前に、アプリケーションでユーザーを認証します。情報を事前入力する場合は、アカウントリンクを生成する前に行う必要があります。Standard アカウントのアカウントリンクを作成した後で、そのアカウントの情報を読み書きすることはできません。 > アカウントリンクの URL をメールやショートメッセージ、またはその他の方法で、プラットフォームのアプリケーション外に送信しないでください。URL は、アプリケーション内で認証済みのアカウント所有者に提供してください。 #### Swift ```swift import UIKit import SafariServices let BackendAPIBaseURL: String = "" // Set to the URL of your backend server class ConnectOnboardViewController: UIViewController { // ... override func viewDidLoad() { super.viewDidLoad() let connectWithStripeButton = UIButton(type: .system) connectWithStripeButton.setTitle("Connect with Stripe", for: .normal) connectWithStripeButton.addTarget(self, action: #selector(didSelectConnectWithStripe), for: .touchUpInside) view.addSubview(connectWithStripeButton) // ... } @objc func didSelectConnectWithStripe() { if let url = URL(string: BackendAPIBaseURL)?.appendingPathComponent("onboard-user") { var request = URLRequest(url: url) request.httpMethod = "POST" let task = URLSession.shared.dataTask(with: request) { (data, response, error) in guard let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any], let accountURLString = json["url"] as? String, let accountURL = URL(string: accountURLString) else { // handle error } let safariViewController = SFSafariViewController(url: accountURL) safariViewController.delegate = self DispatchQueue.main.async { self.present(safariViewController, animated: true, completion: nil) } } } } // ... } extension ConnectOnboardViewController: SFSafariViewControllerDelegate { func safariViewControllerDidFinish(_ controller: SFSafariViewController) { // the user may have closed the SFSafariViewController instance before a redirect // occurred. Sync with your backend to confirm the correct state } } ``` ### ステップ 2.4: ユーザーがプラットフォームに戻るように処理する (クライアント側) *Connect* (Connect is Stripe's solution for multi-party businesses, such as marketplace or software platforms, to route payments between sellers, customers, and other recipients) アカウント登録では、ユーザーがプラットフォームにリダイレクトされるすべてのケースを処理するために、`return_url` と `refresh_url` の両方を渡す必要があります。ユーザーが快適に操作できるようにするには、これらを正しく実装することが重要です。[ユニバーサルリンク](https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content)を設定して、iOS がアプリに自動的にリダイレクトするようにできます。 #### return_url ユーザーが Connect ユーザー登録フローを完了すると、Stripe はこの URL へのリダイレクトを行います。ただしこれは、すべての情報が収集されたことを意味するものでも、アカウントの要件がすべて満たされたことを意味するものでもありません。ユーザーがフローに正常に入り、そこから正常に出たことのみを意味します。 パラメーターの状態がこの URL を通じて渡されることはありません。ユーザーが `return_url` にリダイレクトされたら、以下のいずれかを行い、アカウントの `details_submitted` パラメーターの状態を確認します。 - `account.updated` *Webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) をリッスンする - [Accounts](https://docs.stripe.com/api/accounts.md) API を呼び出して、返されたオブジェクトを調べる #### refresh_url 以下のケースでは、ユーザーが `refresh_url` にリダイレクトされます。 - リンクの期限が切れている (リンクが作成されてから数分が経過した) - リンクがすでに使用されている (ユーザーがページを更新したか、ブラウザで戻るまたは進むボタンをクリックした) - リンクが、URL にアクセスしてプレビューを試みる、メッセージングクライアントなどのサードパーティーアプリケーションに共有された。または、多くのクライアントが自動的にリンクにアクセスすることにより、期限切れになった場合。 - プラットフォームがアカウントにアクセスできなくなった - アカウントが拒否された `refresh_url` はサーバでメソッドをトリガーし、同じパラメータを使用して [Account Link (アカウントリンク)](https://docs.stripe.com/api/account_links.md) を再度呼び出し、シームレスな体験を作成するためにユーザを Connect アカウント登録フローにリダイレクトする必要があります。 ### ステップ 2.5: アカウント登録を完了していないユーザーを処理する `return_url` にリダイレクトされたユーザーは、アカウント登録プロセスを完了していないことがあります。`/v1/accounts` エンドポイントを使用してユーザーのアカウントを取得し、`charges_enabled` を確認します。アカウント登録が完全でない場合は、UI プロンプトを表示し、ユーザーが後でアカウント登録を続行できるようにします。ユーザーは、新しいアカウントリンク (システムで生成された) で本番環境利用の申請を完了できます。アカウントの `details_submitted` パラメーターの状態を確認すると、ユーザーがアカウント登録プロセスを完了したかどうかを調べることができます。 ## 決済を受け付ける ### ステップ 3.1: 決済ページを作成する (Client-side) SDK が提供し、カード番号、有効期限、セキュリティコード、郵便番号を収集するドロップイン UI コンポーネントである [STPPaymentCardTextField](https://stripe.dev/stripe-ios/stripe-payments-ui/Classes/STPPaymentCardTextField.html) を使用して、クライアント側でカード情報を安全に収集します。 ![](https://d37ugbyn3rpeym.cloudfront.net/docs/mobile/ios/card-field.mp4) 以下のコードを使用し、カードコンポーネントのインスタンスを作成し、**支払い** ボタンを作成します。 #### Swift ```swift import UIKit import StripePaymentsUI class CheckoutViewController: UIViewController { lazy var cardTextField: STPPaymentCardTextField = { let cardTextField = STPPaymentCardTextField() return cardTextField }() lazy var payButton: UIButton = { let button = UIButton(type: .custom) button.layer.cornerRadius = 5 button.backgroundColor = .systemBlue button.titleLabel?.font = UIFont.systemFont(ofSize: 22) button.setTitle("Pay", for: .normal) button.addTarget(self, action: #selector(pay), for: .touchUpInside) return button }() override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white let stackView = UIStackView(arrangedSubviews: [cardTextField, payButton]) stackView.axis = .vertical stackView.spacing = 20 stackView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(stackView) NSLayoutConstraint.activate([ stackView.leftAnchor.constraint(equalToSystemSpacingAfter: view.leftAnchor, multiplier: 2), view.rightAnchor.constraint(equalToSystemSpacingAfter: stackView.rightAnchor, multiplier: 2), stackView.topAnchor.constraint(equalToSystemSpacingBelow: view.topAnchor, multiplier: 2), ]) } @objc func pay() { // ... } } ``` アプリを実行し、決済ページにカードコンポーネントと支払いボタンが表示されることを確認します。 ### ステップ 3.2: PaymentIntent を作成する (Server-side) (Client-side) Stripe は [PaymentIntent (支払いインテント)](https://docs.stripe.com/api/payment_intents.md) オブジェクトを使用して、顧客から支払いを回収する意図を示し、プロセス全体を通して請求の実施と支払い状態の変化を追跡します。 ### サーバ側 サーバーで、[amount](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-amount) と [currency](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-currency) を指定して PaymentIntent を作成するエンドポイントを設定します。支払い金額は、クライアント側ではなく、常に信頼できる環境のサーバー側で指定してください。これにより、悪意のある顧客が金額を恣意的に選択できないようにします。 #### curl ```bash curl https://api.stripe.com/v1/payment_intents \ -u <>: \ -d amount=1000 \ -d currency="usd" \ -d "automatic_payment_methods[enabled]"=true \ -d application_fee_amount="123" \ -H "Stripe-Account: {{CONNECTED_STRIPE_ACCOUNT_ID}}" ``` ストアビルダーの例では、顧客が直接ビジネスに支払うビジネスを構築します。このビジネスを設定するには、次の手順に従います。 - `Stripe-Account` ヘッダーで、ビジネスからの購入がダイレクト支払いであることを指定します。 - `application_fee_amount` で、ビジネスからの購入の内、プラットフォームに送られる金額を指定します。 販売が行われたら、Stripe は連結アカウントから `application_fee_amount` をプラットフォームに送金し、連結アカウントのシェアから Stripe 手数料を差し引きます。この資金フローを以下の図で示しています。 ![](https://b.stripecdn.com/docs-statics-srv/assets/direct_charges.a2a8b68037ac95fe22140d6dde9740d3.svg) アプリケーションに PaymentIntent オブジェクト全体を渡す代わりに、*client secret* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)) のみを返してください。PaymentIntent のクライアントシークレットは、支払いを確認したりクライアント上でカード情報を更新したりするための固有キーであり、支払金額などの機密情報を操作されることを防ぎます。 ### クライアント側 連結アカウントの ID を、クライアント側ライブラリのクライアントアプリケーションへの引数として設定します。 #### Swift ```swift import UIKit import StripePayments @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { StripeAPI.defaultPublishableKey = "<>" STPAPIClient.shared.stripeAccount = ""{{CONNECTED_ACCOUNT_ID}}"" return true } } ``` クライアント側で、サーバーの PaymentIntent をリクエストし、その *client secret* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)) を保存します。 #### Swift ```swift class CheckoutViewController: UIViewController { var paymentIntentClientSecret: String? // ...continued from previous step override func viewDidLoad() { // ...continued from previous step startCheckout() } func startCheckout() { // Request a PaymentIntent from your server and store its client secret // Click View full sample to see a complete implementation } } ``` ### ステップ 3.3: Stripe に支払いを送金する (Client-side) 顧客が**支払い**ボタンをタップしたら、支払いを完了するために `PaymentIntent` を*確定* (Confirming a PaymentIntent indicates that the customer intends to pay with the current or provided payment method. Upon confirmation, the PaymentIntent attempts to initiate a payment)します。 まず、以下を使用して [STPPaymentIntentParams](https://stripe.dev/stripe-ios/stripe-payments/Classes/STPPaymentIntentParams.html) オブジェクトを作成します。 1. カードのテキストフィールドの支払い方法詳細 1. サーバから取得した `PaymentIntent` client secret PaymentIntent オブジェクト全体をクライアントに送信するのではなく、その *client secret* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)) を使用します。これは、Stripe API リクエストを認証する API キーとは異なります。client secret は、アプリで機密情報を含むフィールド (`customer` など) を非表示にしながら、PaymentIntent の重要なフィールド (`status` など) にアクセスできるようにする文字列です。 client secret は支払いを完了できるため、慎重に取り扱う必要があります。記録したり、URL に埋め込んだり、当該の顧客以外に漏洩することがないようにしてください。 次に、 [STPPaymentHandler confirmPayment](https://stripe.dev/stripe-ios/stripe-payments/Classes/STPPaymentHandler.html#/c:@M@StripePayments@objc\(cs\)STPPaymentHandler\(im\)confirmPayment:withAuthenticationContext:completion:) メソッドを呼び出して、支払いを完了します。 #### Swift ```swift class CheckoutViewController: UIViewController { // ... @objc func pay() { guard let paymentIntentClientSecret = paymentIntentClientSecret else { return } // Collect card details let paymentIntentParams = STPPaymentIntentParams(clientSecret: paymentIntentClientSecret) paymentIntentParams.paymentMethodParams = cardTextField.paymentMethodParams // Submit the payment let paymentHandler = STPPaymentHandler.shared() paymentHandler.confirmPayment(paymentIntentParams, with: self) { (status, paymentIntent, error) in switch (status) { case .failed: self.displayAlert(title: "Payment failed", message: error?.localizedDescription ?? "") break case .canceled: self.displayAlert(title: "Payment canceled", message: error?.localizedDescription ?? "") break case .succeeded: self.displayAlert(title: "Payment succeeded", message: paymentIntent?.description ?? "", restartDemo: true) break @unknown default: fatalError() break } } } } extension CheckoutViewController: STPAuthenticationContext { func authenticationPresentingViewController() -> UIViewController { return self } } ``` `PaymentIntent` に `setupFutureUsage` と `customer` の両方を指定することで、支払い確定時に[顧客の支払いカードの詳細を保存](https://docs.stripe.com/payments/payment-intents.md#future-usage)できます。サーバーで `PaymentIntent` を作成する際にも、これらのパラメーターを指定できます。 アプリケーションに適した `setupFutureUsage` 値を設定するには、顧客による追加の認証ステップが必要になる場合がありますが、今後支払いが銀行によって拒否される確率を減らすことができます。[今後の支払いのためにカードを最適化する方法を確認](https://docs.stripe.com/payments/payment-intents.md#future-usage)し、アプリケーションに使用する値を決定します。 | 予定しているカードの使用方法 | `setup_future_usage` 列挙値 | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | | *オンセッション* (A payment is described as on-session if it occurs while the customer is actively in your checkout flow and able to authenticate the payment method)支払いのみ | `on_session` | | *オフセッション* (A payment is described as on-session if it occurs while the customer is actively in your checkout flow and able to authenticate the payment method)支払いのみ | `off_session` | | オンセッション支払いとオフセッション支払いの両方 | `off_session` | オンセッション支払い用に設定されたカードをオフセッション支払いに使用することもできますが、銀行がオフセッション支払いを拒否し、カード保有者に認証を求める可能性が高くなります。 [強力な顧客認証 (SCA)](https://docs.stripe.com/strong-customer-authentication.md) などの規制によって認証が要求される場合、`STPPaymentHandler` は渡された [STPAuthenticationContext](https://stripe.dev/stripe-ios/stripe-payments/Protocols/STPAuthenticationContext.html) を使用してビューコントローラーを表示し、そのプロセスをステップごとに顧客に提示します。[iOS で 3D セキュア認証に対応する方法を確認してください](https://docs.stripe.com/payments/3d-secure.md?platform=ios)。 支払いが成功した場合、完了ハンドラが `.succeeded` ステータスで呼び出されます。失敗した場合、ステータスは `.failed` となり、ユーザに `error.localizedDescription` を表示できます。 `PaymentIntent` のステータスは、[ダッシュボード](https://dashboard.stripe.com/test/payments)で確認できるほか、オブジェクトの `status` プロパティを調べることでも確認できます。 ### ステップ 3.4: 組み込みをテストする (Client-side) ​​この実装の準備ができていることを確認するために、サンドボックスで使用できるテストカードがいくつかあります。任意のセキュリティコードおよび将来の有効期限を指定して使用します。 | 番号 | 説明 | | ---------------- | --------------------------------------- | | 4242424242424242 | 支払いが成功し、すぐに処理されます。 | | 4000002500003155 | 認証が必要です。Stripe は、顧客に認証を求めるモーダルをトリガーします。 | | 4000000000009995 | 常に支払い拒否コード `insufficient_funds` で失敗します。 | テストカードの一覧については、[テスト](https://docs.stripe.com/testing.md)に関するガイドを参照してください。 ### ステップ 3.5: フルフィルメントを実行する (Server-side) 支払いの完了後、必要な*フルフィルメント* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected)を処理する必要があります。たとえば、ストアビルダーは、購入されたアイテムを顧客に送信するようにビジネスに通知する必要があります。 [ダッシュボード](https://dashboard.stripe.com/account/webhooks)で *Webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) エンドポイントを構成します (「お客様の Connect アプリケーションから」のイベント用) 。 ![](https://b.stripecdn.com/docs-statics-srv/assets/connect_webhooks.4de92f78dcd94b36838010c85c8a051f.png) 次に、HTTP エンドポイントをサーバ上に作成し、完了した支払いを監視して、ユーザ (連結アカウント) が購入を実行できるようにします。 #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') # If you are testing your webhook locally with the Stripe CLI you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'payment_intent.succeeded' payment_intent = event['data']['object'] connected_account_id = event['account'] handle_successful_payment_intent(connected_account_id, payment_intent) end status 200 end def handle_successful_payment_intent(connected_account_id, payment_intent) # Fulfill the purchase puts 'Connected account ID: ' + connected_account_id puts payment_intent.to_s end ``` [決済向けフルフィルメントガイド](https://docs.stripe.com/webhooks/handling-payment-events.md)で詳細をご確認ください。 ### Webhook をローカルでテストする Stripe CLI を使用すると、Webhook をローカルでテストできます。 1. まず、[Stripe CLI をインストール](https://docs.stripe.com/stripe-cli/install.md)していない場合は、マシンにインストールしてください。 1. 次に、ログインするために、コマンドラインで `stripe login` を実行し、手順に従います。 1. 最後に、連結アカウントでシミュレートされたイベントをお客様のローカルホストで受信できるようにするために、1 つの端末ウィンドウで `stripe listen --forward-connect-to localhost:{PORT}/webhook` を実行し、別の端末ウィンドウで `stripe trigger --stripe-account={{CONNECTED_STRIPE_ACCOUNT_ID}} payment_intent.succeeded` を実行します (あるいはその他の[サポートされるイベント](https://github.com/stripe/stripe-cli/wiki/trigger-command#supported-events)をトリガーします) 。 ## テスト [アカウントを作成](https://docs.stripe.com/connect/testing.md#creating-accounts)し、[OAuth を使用](https://docs.stripe.com/connect/testing.md#using-oauth)して、アカウント作成フローをテストします。いずれかのテストアカウントにログインして[支払い方法の設定](https://dashboard.stripe.com/settings/payment_methods)に移動し、連結アカウントの**支払い方法**の設定をテストします。テストキーとテストアカウントを使用して、決済フローをテストします。Stripe の[テストカード](https://docs.stripe.com/testing.md)を使用して支払いフローをテストし、さまざまな支払い結果をシミュレーションできます。 # 決済画面 > This is a 決済画面 for when platform is android and mobile-ui is payment-sheet. View the full page at https://docs.stripe.com/connect/end-to-end-saas-platform?platform=android&mobile-ui=payment-sheet. ![](https://b.stripecdn.com/docs-statics-srv/assets/android-overview.471eaf89a760f5b6a757fd96b6bb9b60.png) [PaymentSheet](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/index.html) クラスを使用して、Stripe の構築済み決済 UI を Android アプリの決済フローに組み込みます。 > #### Accounts v2 API サポート > > Payment Sheet は*顧客設定のアカウント* (Account configurations represent role-based functionality that you can enable for accounts, such as merchant, customer, or recipient)をサポートしていません。`Customer`オブジェクトのみをサポートしています。 ## 前提条件 1. [プラットフォームを登録](https://dashboard.stripe.com/connect)します。 1. [ダッシュボードでビジネスの詳細の確認と追加](https://dashboard.stripe.com/account/onboarding)。 1. [プラットフォームプロフィールを完成](https://dashboard.stripe.com/connect/settings/profile)させます。 1. [ブランド設定をカスタマイズ](https://dashboard.stripe.com/settings/connect/stripe-dashboard/branding)します。ビジネス名、アイコン、ブランドカラーを追加します。 ## Stripe を設定する [サーバー側] [クライアント側] まず、Stripe アカウントが必要です。[今すぐ登録](https://dashboard.stripe.com/register)してください。 ### サーバー側 この組み込みは、Stripe API と通信するサーバー上にエンドポイントを必要とします。サーバーから Stripe API にアクセスするには、次のように Stripe の公式ライブラリーを使用します。 #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ### クライアント側 [Stripe Android SDK](https://github.com/stripe/stripe-android) はオープンソースであり、[詳細なドキュメントが提供されています](https://stripe.dev/stripe-android/)。 SDK をインストールするには、[app/build.gradle](https://developer.android.com/studio/build/dependencies) ファイルの `dependencies` ブロックに `stripe-android` を追加します。 #### Kotlin ```kotlin plugins { id("com.android.application") } android { ... } dependencies { // ... // Stripe Android SDK implementation("com.stripe:stripe-android:23.8.0") // Include the financial connections SDK to support US bank account as a payment method implementation("com.stripe:financial-connections:23.8.0") } ``` > SDK の最新リリースおよび過去バージョンの詳細については、GitHub の [Releases](https://github.com/stripe/stripe-android/releases) ページをご覧ください。新しいリリースの公開時に通知を受け取るには、[リポジトリのリリースを確認](https://docs.github.com/en/github/managing-subscriptions-and-notifications-on-github/configuring-notifications#configuring-your-watch-settings-for-an-individual-repository)してください。 Stripe の[公開可能キー](https://dashboard.stripe.com/apikeys)を使用して SDK を設定し、 `Application` サブクラスなどで、Stripe API へのリクエストを実行できるようにします。 #### Kotlin ```kotlin import com.stripe.android.PaymentConfiguration class MyApp : Application() { override fun onCreate() { super.onCreate() PaymentConfiguration.init( applicationContext, "<>" ) } } ``` > テストおよび開発時には[テストキー](https://docs.stripe.com/keys.md#obtain-api-keys)を使用し、アプリの公開時には[本番環境](https://docs.stripe.com/keys.md#test-live-modes)キーを使用します。 ## 連結アカウントを作成する ユーザー (売り手またはサービスプロバイダー) がプラットフォームに登録したら、ユーザーの [Account (アカウント)](https://docs.stripe.com/api/accounts.md) (「連結アカウント」と呼ばれる) を作成し、決済を受け付けて売上をユーザーの銀行口座に入金できるようにします。連結アカウントは Stripe の API でユーザーを表し、アカウント登録要件の収集を簡単にして Stripe がユーザーの本人確認を実行できるようにします。ストアビルダーの例では、連結アカウントはオンラインストアを設定するビジネスを表します。 ![アカウントの作成フロー](https://b.stripecdn.com/docs-statics-srv/assets/standard-android.04900ae101e927a74a6f2b0afb53bf23.png) ### Step 2.1: 連結アカウントを作成し、情報を事前入力する(サーバー側) `/v1/accounts` API を使用して連結アカウントを[作成](https://docs.stripe.com/api/accounts/create.md)します。[デフォルトの連結アカウントのパラメーター](https://docs.stripe.com/connect/migrate-to-controller-properties.md)を指定するか、アカウントタイプを指定して、連結アカウントを作成できます。 #### デフォルトのプロパティを使用 ```curl curl -X POST https://api.stripe.com/v1/accounts \ -u "<>:" ``` #### アカウントタイプを使用した場合 ```curl curl https://api.stripe.com/v1/accounts \ -u "<>:" \ -d type=standard ``` 連結アカウントの情報をすでに収集している場合は、`Account` オブジェクトにその情報を事前入力できます。個人情報や事業情報、外部のアカウント情報など、あらゆるアカウント情報を事前に入力できます。 `Account` を作成したら、`relationship.representative` を true に設定した [Person](https://docs.stripe.com/api/persons/create.md) を作成して、アカウント開設の責任者と、事前に入力したいアカウント情報 (氏名など) を表します。 ```curl curl https://api.stripe.com/v1/accounts/{{ACCOUNT_ID}}/persons \ -u "<>:" \ -d first_name=Jenny \ -d last_name=Rosen \ -d "relationship[representative]=true" ``` Connect アカウント登録で、事前入力された情報が要求されることはありません。ただし、アカウント所有者は [Connect 利用規約](https://docs.stripe.com/connect/service-agreement-types.md)に同意する前に、事前入力された情報を確認するよう求められます。 実装内容をテストする場合、[テストデータ](https://docs.stripe.com/connect/testing.md)を使用してアカウント情報を事前入力します。 ### ステップ 2.2: アカウントリンクを作成する (サーバー側) 以下のパラメーターを使用して [Account Links](https://docs.stripe.com/api/account_links.md) API を呼び出すことで、アカウントリンクを作成できます。 - `account` - `refresh_url` - `return_url` - `type` = `account_onboarding` ```curl curl https://api.stripe.com/v1/account_links \ -u "<>:" \ -d "account={{CONNECTEDACCOUNT_ID}}" \ --data-urlencode "refresh_url=https://example.com/reauth" \ --data-urlencode "return_url=https://example.com/return" \ -d type=account_onboarding ``` ### ステップ 2.3: ユーザーをアカウントリンク URL にリダイレクトする (クライアント側) [Account Links](https://docs.stripe.com/api/account_links.md) リクエストへのレスポンスには、キー `url` の値が含まれます。ユーザーをこのリンクにリダイレクトして、処理を進めることができるようにします。Account Links は一時的なものであり、連結アカウントユーザーの個人情報へのアクセスを許可するため、使用できるのは 1 回限りです。この URL にリダイレクトする前に、アプリケーションでユーザーを認証してください。情報の事前入力は、アカウントリンクを生成する前に行う必要があります。Standard アカウントのアカウントリンクを作成した後は、そのアカウントの情報を読み書きできなくなります。 > アカウントリンクの URL をメールやショートメッセージ、またはその他の方法で、プラットフォームのアプリケーション外に送信しないでください。URL は、アプリケーション内で認証済みのアカウント所有者に提供してください。 ```xml