# サーバーで決済を確定 PaymentIntent または SetupIntent を作成する前にモバイル決済要素をレンダリングする組み込みを構築し、サーバーからインテントを確認します。 # 支払いを受け入れる > This is a 支払いを受け入れる for when platform is ios and type is payment. View the full page at https://docs.stripe.com/payments/mobile/finalize-payments-on-the-server?platform=ios&type=payment. Payment Element を使用すると、一度の導入で複数の決済手段を受け付けることができます。この実装では、Payment Element をレンダリングし、*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) を作成して、購入者のサーバーで支払いを確定するカスタム決済フローを構築します。 ## Stripe を設定する [サーバー側] [クライアント側] ### サーバー側 この組み込みは、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)して、新しいリリースの公開時に通知を受け取ることも可能です。 また、SDK が Stripe への API コールを実行できるように、[公開可能キー](https://dashboard.stripe.com/apikeys)を設定する必要もあります。開始するには、導入中にクライアント側で公開可能キーをハードコード化できますが、本番環境ではサーバーから公開可能キーを取得します。 ```swift // Set your publishable key: remember to change this to your live publishable key in production // See your keys here: https://dashboard.stripe.com/apikeys STPAPIClient.shared.publishableKey = "<>" ``` ## 支払い方法を有効にする [支払い方法の設定](https://dashboard.stripe.com/settings/payment_methods)を表示して、サポートする支払い方法を有効にします。*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) を作成するには、少なくとも 1 つは支払い方法を有効にする必要があります。 多くの顧客から決済を受け付けられるよう、Stripe では、カードやその他一般的な決済手段がデフォルトで有効になっていますが、ビジネスや顧客に適した追加の決済手段を有効にすることをお勧めします。プロダクトと決済手段のサポートについては[決済手段のサポート](https://docs.stripe.com/payments/payment-methods/payment-method-support.md)を、手数料については[料金体系ページ](https://stripe.com/pricing/local-payment-methods)をご覧ください。 ## 戻り先 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 } } } } } ``` さらに、[PaymentSheet.Configuration](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html) オブジェクトの [returnURL](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:6Stripe12PaymentSheetC13ConfigurationV9returnURLSSSgvp) をアプリの URL に設定します。 ```swift var configuration = PaymentSheet.Configuration() configuration.returnURL = "your-app://stripe-redirect" ``` ## 支払いの詳細を収集する [クライアント側] 実装には 2 つのスタイルを利用できます。いずれかを選択して、続行してください。 | PaymentSheet | PaymentSheet.FlowController | | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | | ![PaymentSheet](https://b.stripecdn.com/docs-statics-srv/assets/ios-overview.9e0d68d009dc005f73a6f5df69e00458.png) | ![PaymentSheet.FlowController](https://b.stripecdn.com/docs-statics-srv/assets/ios-multi-step.cd631ea4f1cd8cf3f39b6b9e1e92b6c5.png) | | 支払いの詳細を徴収して支払いを完了するためのシートを表示します。シートには、金額と通貨が記載された * *支払う* ボタンが表示され、支払いが完了します。 | 支払い情報の収集のみを行う画面を表示します。画面に**続行する**というボタンが表示され、顧客はアプリに戻され、ご自身のボタンで支払いが完了されます。 | #### PaymentSheet ### PaymentSheet を初期化する 支払いを受け付ける 準備ができたら (顧客が決済ボタンをタップしたときなど)、`PaymentSheet.Configuration` と [PaymentSheet.IntentConfiguration](https://github.com/stripe/stripe-ios/blob/master/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheetIntentConfiguration.swift) を使用して PaymentSheet を初期化します。[Configuration](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/configuration-swift.struct) オブジェクトには、通常、`returnURL` など、支払い間で変更されない PaymentSheet の一般的な設定が含まれます。[IntentConfiguration](https://github.com/stripe/stripe-ios/blob/master/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheetIntentConfiguration.swift) オブジェクトには、 ```swift import StripePaymentSheet class MyCheckoutVC: UIViewController { func didTapCheckoutButton() {let intentConfig = PaymentSheet.IntentConfiguration(mode: .payment(amount: 1099, currency: "USD",)) { [weak self] confirmationToken in try await self?.handleConfirmationToken(confirmationToken) } var configuration = PaymentSheet.Configuration() configuration.returnURL = "your-app://stripe-redirect" // Use the return url you set up in the previous step let paymentSheet = PaymentSheet(intentConfiguration: intentConfig, configuration: configuration) } func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // ...explained later } } ``` ### PaymentSheet を提示する 次に、PaymentSheet を提示します。`present` メソッドは、顧客が支払いを完了して画面が非表示になったときに呼び出される完了ブロックを使用します。結果を処理する完了ブロックを実装します (たとえば、`.completed` のケースで領収書や確認画面を表示するなど)。 ```swift class MyCheckoutVC: UIViewController { func didTapCheckoutButton() { // ...paymentSheet.present(from: self) { result in switch result { case .completed: //Paymentcompleted - show a confirmation screen. case .failed(let error): print(error) // PaymentSheet encountered an unrecoverable error. You can display the error to the user, log it, and so on case .canceled: // Customer canceled - you should probably do nothing. } } } } ``` ### 支払いを確定する 顧客が PaymentSheet で Pay をタップすると、`PaymentSheet.IntentConfiguration` に渡されたコールバックが、顧客の支払い詳細と設定を表す [STPConfirmationToken](https://stripe.dev/stripe-ios/stripepayments/documentation/stripepayments/stpconfirmationtoken) オブジェクトで呼び出されます。 このコールバックを実装して、`confirmationToken.stripeId` を渡して、サーバーにリクエストを送信します。サーバーは SetupIntent を作成して確認し、Client Secret を返します。 リクエストが返されたら、サーバー応答のClient Secretを返すか、エラーをスローします。PaymentSheet は、Client Secretを使用して the PaymentIntentを完了するために必要な次のアクションを完了するか、ローカライズされたエラーメッセージをUIに表示します ([errorDescription](https://developer.apple.com/documentation/foundation/localizederror/2946895-errordescription) または [localizedDescription](https://developer.apple.com/documentation/foundation/nserror/1414418-localizeddescription))。 ```swift class MyCheckoutVC: UIViewController { // ... func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // Make a request to your own server. Pass confirmationToken.stripeId if using server-side confirmation. // Return the client secret or throw an error. return try await MyAPIClient.shared.createIntent(confirmationTokenId: confirmationToken.stripeId) } } ``` #### PaymentSheet.FlowController この実装では、決済画面に支払い情報を収集する PaymentSheet に対応する「**支払い方法**」ボタンと、支払いを完了する「**購入**」ボタンが配置されていると想定しています。 ### PaymentSheet.FlowController を初期化する Checkout 画面が読み込まれたら、`PaymentSheet.Configuration` と `PaymentSheet.IntentConfiguration` を使用して `PaymentSheet.FlowController` を初期化します。[Configuration](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/configuration-swift.struct) オブジェクトには、`returnURL` など、通常は支払い間で変更されない PaymentSheet の汎用的な設定が含まれます。[IntentConfiguration](https://github.com/stripe/stripe-ios/blob/master/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheetIntentConfiguration.swift) オブジェクトには、金額や通貨設定 (通貨など) などの特定の支払い、および `confirmationTokenConfirmHandler` コールバックの詳細が含まれます。現時点では、実装は空のままにします。 `PaymentSheet.FlowController` が初期化されたら、`paymentOption` を指定して「**支払い方法**」ボタンを更新します。このプロパティには、顧客が最初に選択したデフォルトの支払い方法を表す画像とラベルが含まれています。 ```swift class MyCheckoutVC: UIViewController { func loadCheckout() {let intentConfig = PaymentSheet.IntentConfiguration(mode: .payment(amount: 1099, currency: "USD",)) { [weak self] confirmationToken in try await self?.handleConfirmationToken(confirmationToken) } var configuration = PaymentSheet.Configuration() configuration.returnURL = "your-app://stripe-redirect" // Use the return url you set up in the previous step PaymentSheet.FlowController.create( intentConfiguration: intentConfig, configuration: configuration ) { [weak self] result in switch result { case .failure(let error): print(error) case .success(let paymentSheetFlowController): self?.paymentSheetFlowController = paymentSheetFlowController // Update your UI paymentSheetFlowController.paymentOption.image and paymentSheetFlowController.paymentOption.label } } } func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // ...explained later } } ``` ### PaymentSheet を表示する 顧客が「**支払い方法**」ボタンをタップしたら、`presentPaymentOptions` を呼び出して、支払い情報を収集します。完了したら、`paymentOption` プロパティで UI を再び更新します。 ```swift paymentSheetFlowController.presentPaymentOptions(from: self) { // Update your UI using paymentSheetFlowController.paymentOption } ``` ### (任意)支払いの詳細を更新する 顧客が支払い情報を変更するアクション (割引コードの適用やカートの編集など) を実行したら、新しい値を指定して PaymentSheet.FlowController インスタンスを更新します。こうすると、UI に正確な値が表示され ( **Pay** ボタンや Apple Pay UI など)、適切な決済手段などを表示できます。PaymentSheet.FlowController を再初期化するのではなく、インスタンスを更新することで、決済画面に顧客の支払い情報が保存されます。 更新された IntentConfiguration オブジェクトを指定して `update` メソッドを呼び出します。更新の進行中は、PaymentSheet.FlowController で `present` または `confirm` を呼び出さないでください (たとえば、「**購入**」ボタンと「**支払い方法**」ボタンを無効にするなど)。 更新が完了したら、顧客が以前に選択した支払い方法が使用できなくなっている場合には、`paymentOption` プロパティを指定して UI を更新します。更新が失敗した場合は、再試行してください。 ```swift // Create an updated IntentConfiguration var updatedIntentConfig = oldIntentConfig updatedIntentConfig.amount = 999 // Disable your "Buy" and "Payment method" buttons and call `update` paymentSheetFlowController.update(intentConfiguration: updatedIntentConfig) { [weak self] error in if error != nil { // You must retry - until the update succeeds, the customer can't pay or select a payment method. // For example, you can automatically retry the update with an exponential back-off, or present the user with an alert that retries the update. } else { // Re-enable your "Buy" and "Payment method" buttons // Update your UI using paymentSheetFlowController.paymentOption.image and paymentSheetFlowController.paymentOption.label } } ``` ### 支払いを確定する 顧客が **購入** ボタンをタップしたら、[paymentSheetFlowController.confirm](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/flowcontroller/confirm(from:completion:) を呼び出します)。これにより、顧客の支払いの詳細と設定を表す [STPConfirmationToken](https://stripe.dev/stripe-ios/stripepayments/documentation/stripepayments/stpconfirmationtoken) オブジェクトを使用して、`PaymentSheet.IntentConfiguration` に渡した `confirmationTokenConfirmHandler` コールバックが呼び出されます。 このコールバックを実装して、`confirmationToken.stripeId` を渡して、サーバーにリクエストを送信します。サーバーは SetupIntent を作成して確認し、Client Secret を返します。 リクエストが返されるときに、サーバーレスポンスの client secret またはエラーをスローします。PaymentSheet は、client secret を使用して PaymentIntentを完了するために必要な次のアクションを実行します。 ```swift class MyCheckoutVC: UIViewController { // ...func didTapBuyButton() { paymentSheetFlowController.confirm(from: self) { paymentResult in switch paymentResult { case .completed: //Paymentcompleted - show a confirmation screen. case .failed(let error): // PaymentSheet encountered an unrecoverable error. You can display the error to the user, log it, and so on print(error) case .canceled: // Customer canceled - you should probably do nothing. } } } func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // Make a request to your own server. Pass confirmationToken.stripeId if using server-side confirmation. return try await fetchIntentClientSecret(...) } } ``` サーバーコードについては以下のステップで説明します。 ## 決済を作成して Stripe に送信する [サーバー側] サーバー側で、金額と通貨を指定して *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) を作成し、確定します。支払い方法は[ダッシュボード](https://dashboard.stripe.com/settings/payment_methods)で管理できます。Stripe は取引額、通貨、決済フローなどの要素に基づいて、適切な支払い方法が返されるように処理します。悪意のある顧客が金額を恣意的に選択できないようにするために、請求額はクライアント側ではなく、常にサーバー側 (信頼性の高い環境) で指定してください。 コールが成功した場合は、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)) を返します。コールが失敗した場合は、[エラーを処理](https://docs.stripe.com/error-handling.md)して、エラーメッセージと顧客向けの簡単な説明を返します。 > すべての IntentConfiguration プロパティが PaymentIntent (`setup_future_usage`、`amount`、`currency` など) と一致していることを確認します。 ### クライアント側の引数の処理: - `confirmation_token_id`: この ID を使用して ConfirmationToken オブジェクトを取得し、独自の検証またはビジネスロジックを実行できます。 #### Ruby ```ruby require 'stripe' Stripe.api_key = '<>' post '/create-intent' do data = JSON.parse request.body.read params = { amount: 1099, currency: 'usd', # In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. automatic_payment_methods: {enabled: true}, confirm: true, confirmation_token: data['confirmation_token_id'], # the ConfirmationToken ID sent by your client } begin intent = Stripe::PaymentIntent.create(params) {client_secret: intent.client_secret}.to_json rescue Stripe::StripeError => e {error: e.error.message}.to_json end end ``` ## 支払い後のイベントを処理する [サーバー側] 支払いが完了すると、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)をご覧ください。 ## カードのスキャンを有効にする iOS をサポートするカードスキャン機能を有効にするには、アプリケーションの `Info.plist` の `NSCameraUsageDescription` (**プライバシー - カメラ利用の詳細**)を設定し、カメラにアクセスする理由を入力して下さい (例:「カードをスキャンするため」)。 ## Optional: 保存済みのカードを有効にする [サーバー側] [クライアント側] PaymentSheet では、**今後の支払いのためにこのカードを保存する**チェックボックスを表示して顧客のカードを保存し、保存済みのカードを表示できます。このチェックボックスを有効にするには、`payment_method_save` を `enabled` に設定して、サーバーで [Customer (顧客)](https://docs.stripe.com/api/customers.md) オブジェクトと、関連する [CustomerSession](https://docs.stripe.com/api/customer_sessions.md) を作成します。 > #### Customers v1 と Accounts v2 のリファレンスを比較する > > Connect プラットフォームが [customer-configured Accounts](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) を使用している場合は、Stripe の [ガイド](https://docs.stripe.com/connect/use-accounts-as-customers.md)をご確認の上、コード内の `Customer` およびイベント参照を同等の Accounts v2 API リファレンスに置き換えてください。 ```javascript const stripe = require('stripe')('sk_test_your_secret_key'); app.post('/mobile-payment-element', async (req, res) => { // Use an existing Customer ID if this is a returning customer. const customer = await stripe.customers.create(); const customerSession = await stripe.customerSessions.create({ customer: customer.id, components: { mobile_payment_element: { enabled: true, features: { payment_method_save: 'enabled', payment_method_redisplay: 'enabled', payment_method_remove: 'enabled' } }, }, }); res.json({ customerSessionClientSecret: customerSession.client_secret, customer: customer.id, }); }); ``` 次に、顧客の ID と CustomerSession の client secret を指定して PaymentSheet を設定します。 ```swift @_spi(CustomerSessionBetaAccess) import StripePaymentSheet var configuration = PaymentSheet.Configuration() configuration.customer = .init(id: customerId, customerSessionClientSecret: customerSessionClientSecret) self.paymentSheet = PaymentSheet(..., configuration: configuration) ``` ## Optional: 遅延型の支払い方法を許可する [クライアント側] *遅延型の決済手段* (A payment method that can't immediately return payment status when a customer attempts a transaction (for example, ACH debits). Businesses commonly hold an order in a pending state until payment is successful with these payment methods)では、購入の終了時に顧客から売上を受け取ることが保証されません。これは、決済に時間がかかる (アメリカの銀行口座、SEPA デビット、iDEAL、Bancontact など) 場合や、完了に顧客の対応を必要とする (OXXO、コンビニ決済、Boleto など) 場合があるためです。 デフォルトの場合、PaymentSheet には遅延型の決済手段は表示されません。オプトインするには、`PaymentSheet.Configuration` で `allowsDelayedPaymentMethods` を true に設定します。このステップのみでは、特定の決済手段を有効にすることはできませんが、アプリがその決済手段に対応できることが示されます。たとえば、OXXO は PaymentSheet でサポートされていませんが、サポートされるようになり、最新の SDK バージョンに更新すると、実装に関する追加の変更なしで、アプリに OXXO を決済オプションとして表示でます。 ```swift var configuration = PaymentSheet.Configuration() configuration.allowsDelayedPaymentMethods = true self.paymentSheet = PaymentSheet(..., configuration: configuration) ``` 顧客がいずれかの遅延型の支払い方法を PaymentSheet で正常に使用すると、`.completed` の支払い結果が返されます。 ## 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) ``` ## 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: 確定時のセキュリティコードの再収集を有効にする PaymentIntent の確定時に保存されたカードのセキュリティコードを再徴収するには、統合で PaymentIntent を作成する前に決済詳細を徴収する必要があります。 ### インテントの設定を更新する `PaymentSheet.IntentConfiguration` では、保存されたカードのセキュリティコードを再収集する時期を管理するオプションパラメーターを使用できます。 ```swift let intentConfig = PaymentSheet.IntentConfiguration( mode: .payment(amount: 1099, currency: "USD"), confirmHandler: { confirmationToken in // Handle ConfirmationToken...}, requireCVCRecollection: true) ``` ### インテント作成のパラメーターを更新する 支払いの確定時にセキュリティコードを再収集するには、PaymentIntent の作成時に `customerId` パラメーターと `require_cvc_recollection` パラメーターの両方を含めます。 #### Ruby ```ruby require 'stripe' Stripe.api_key = '<>' post '/create-intent' do data = JSON.parse request.body.read params = { amount: 1099, currency: 'usd', # In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. automatic_payment_methods: {enabled: true},customer: customer.id, payment_method_options: { card: {require_cvc_recollection: true} } } begin intent = Stripe::PaymentIntent.create(params) {client_secret: intent.client_secret}.to_json rescue Stripe::StripeError => e {error: e.error.message}.to_json end end ``` # 決済手段を収集して保存する > This is a 決済手段を収集して保存する for when platform is ios and type is setup. View the full page at https://docs.stripe.com/payments/mobile/finalize-payments-on-the-server?platform=ios&type=setup. SetupIntent フローを使用すると、決済手段の詳細を収集し、請求を作成せずに今後の支払いのために保存できます。この実装では、Payment Element をレンダリングし、*SetupIntent* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method) を作成して、購入者のサーバーで設定を確定するカスタムフローを構築します。 ## Stripe を設定する [サーバー側] [クライアント側] ### サーバー側 この組み込みは、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)して、新しいリリースの公開時に通知を受け取ることも可能です。 また、SDK が Stripe への API コールを実行できるように、[公開可能キー](https://dashboard.stripe.com/apikeys)を設定する必要もあります。開始するには、導入中にクライアント側で公開可能キーをハードコード化できますが、本番環境ではサーバーから公開可能キーを取得します。 ```swift // Set your publishable key: remember to change this to your live publishable key in production // See your keys here: https://dashboard.stripe.com/apikeys STPAPIClient.shared.publishableKey = "<>" ``` ## 支払い方法を有効にする [支払い方法の設定](https://dashboard.stripe.com/settings/payment_methods)を表示して、サポートする支払い方法を有効にします。*SetupIntent* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method) を作成するには、少なくとも 1 つは支払い方法を有効にする必要があります。 多くの顧客から決済を受け付けられるよう、Stripe では、カードやその他一般的な決済手段がデフォルトで有効になっていますが、ビジネスや顧客に適した追加の決済手段を有効にすることをお勧めします。プロダクトと決済手段のサポートについては[決済手段のサポート](https://docs.stripe.com/payments/payment-methods/payment-method-support.md)を、手数料については[料金体系ページ](https://stripe.com/pricing/local-payment-methods)をご覧ください。 ## 戻り先 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 } } } } } ``` さらに、[PaymentSheet.Configuration](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html) オブジェクトの [returnURL](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:6Stripe12PaymentSheetC13ConfigurationV9returnURLSSSgvp) をアプリの URL に設定します。 ```swift var configuration = PaymentSheet.Configuration() configuration.returnURL = "your-app://stripe-redirect" ``` ## Customer を作成する [サーバー側] 将来の支払いに備えて支払い方法を設定するには、その手段を *Customer (顧客)* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) に関連付ける必要があります。顧客がビジネスでアカウントを作成する際に、`Customer` オブジェクトを作成します。`Customer` オブジェクトを使用すると、支払い方法を再利用したり、複数の支払いを追跡したりできます。 > #### Customers v1 と Accounts v2 のリファレンスを比較する > > Connect プラットフォームが [customer-configured Accounts](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) を使用している場合は、Stripe の [ガイド](https://docs.stripe.com/connect/use-accounts-as-customers.md)をご確認の上、コード内の `Customer` およびイベント参照を同等の Accounts v2 API リファレンスに置き換えてください。 ```curl curl -X POST https://api.stripe.com/v1/customers \ -u "<>:" ``` ## 支払いの詳細を収集する [クライアント側] 実装には 2 つのスタイルを利用できます。いずれかを選択して、続行してください。 | PaymentSheet | PaymentSheet.FlowController | | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | | ![PaymentSheet](https://b.stripecdn.com/docs-statics-srv/assets/ios-overview.9e0d68d009dc005f73a6f5df69e00458.png) | ![PaymentSheet.FlowController](https://b.stripecdn.com/docs-statics-srv/assets/ios-multi-step.cd631ea4f1cd8cf3f39b6b9e1e92b6c5.png) | | 支払い情報を収集して設定を完了する画面を表示します。画面に**設定**というボタンが表示され、支払い方法が設定されます。 | 支払い情報の収集のみを行う画面を表示します。画面に**続行する**というボタンが表示され、購入者はアプリに戻されて、そのアプリ内のお客様の自社設定のボタンで設定が完了します。 | #### PaymentSheet ### PaymentSheet を初期化する 決済手段を設定する 準備ができたら (顧客が決済ボタンをタップしたときなど)、`PaymentSheet.Configuration` と [PaymentSheet.IntentConfiguration](https://github.com/stripe/stripe-ios/blob/master/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheetIntentConfiguration.swift) を使用して PaymentSheet を初期化します。[Configuration](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/configuration-swift.struct) オブジェクトには、通常、`returnURL` など、支払い間で変更されない PaymentSheet の一般的な設定が含まれます。[IntentConfiguration](https://github.com/stripe/stripe-ios/blob/master/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheetIntentConfiguration.swift) オブジェクトには、 決済 (金額や通貨など) ```swift import StripePaymentSheet class MyCheckoutVC: UIViewController { func didTapCheckoutButton() {let intentConfig = PaymentSheet.IntentConfiguration(mode: .setup(currency: "USD")) { [weak self] confirmationToken in try await self?.handleConfirmationToken(confirmationToken) } var configuration = PaymentSheet.Configuration() configuration.returnURL = "your-app://stripe-redirect" // Use the return url you set up in the previous step let paymentSheet = PaymentSheet(intentConfiguration: intentConfig, configuration: configuration) } func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // ...explained later } } ``` ### PaymentSheet を提示する 次に、PaymentSheet を提示します。`present` メソッドは、顧客が決済手段の設定を完了して画面が非表示になったときに呼び出される完了ブロックを使用します。結果を処理する完了ブロックを実装します (たとえば、`.completed` のケースで確認画面を表示するなど)。 ```swift class MyCheckoutVC: UIViewController { func didTapCheckoutButton() { // ...paymentSheet.present(from: self) { result in switch result { case .completed: //Setupcompleted - show a confirmation screen. case .failed(let error): print(error) // PaymentSheet encountered an unrecoverable error. You can display the error to the user, log it, and so on case .canceled: // Customer canceled - you should probably do nothing. } } } } ``` ### 支払い情報を確定する 顧客が PaymentSheet で Setup をタップすると、`PaymentSheet.IntentConfiguration` に渡されたコールバックが、顧客の支払い詳細と設定を表す [STPConfirmationToken](https://stripe.dev/stripe-ios/stripepayments/documentation/stripepayments/stpconfirmationtoken) オブジェクトで呼び出されます。 このコールバックを実装して、`confirmationToken.stripeId` を渡して、サーバーにリクエストを送信します。サーバーは SetupIntent を作成して確認し、Client Secret を返します。 リクエストが返されたら、サーバー応答のClient Secretを返すか、エラーをスローします。PaymentSheet は、Client Secretを使用して the SetupIntentを完了するために必要な次のアクションを完了するか、ローカライズされたエラーメッセージをUIに表示します ([errorDescription](https://developer.apple.com/documentation/foundation/localizederror/2946895-errordescription) または [localizedDescription](https://developer.apple.com/documentation/foundation/nserror/1414418-localizeddescription))。 ```swift class MyCheckoutVC: UIViewController { // ... func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // Make a request to your own server. Pass confirmationToken.stripeId if using server-side confirmation. // Return the client secret or throw an error. return try await MyAPIClient.shared.createIntent(confirmationTokenId: confirmationToken.stripeId) } } ``` #### PaymentSheet.FlowController この実装では、決済画面に支払い情報を収集する PaymentSheet に対応する「**支払い方法**」ボタンと、設定を完了する「**購入**」ボタンが配置されていると想定しています。 ### PaymentSheet.FlowController を初期化する Checkout 画面が読み込まれたら、`PaymentSheet.Configuration` と `PaymentSheet.IntentConfiguration` を使用して `PaymentSheet.FlowController` を初期化します。[Configuration](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/configuration-swift.struct) オブジェクトには、`returnURL` など、通常は支払い間で変更されない PaymentSheet の汎用的な設定が含まれます。[IntentConfiguration](https://github.com/stripe/stripe-ios/blob/master/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheetIntentConfiguration.swift) オブジェクトには、金額や通貨設定 (通貨など) などの特定の `PaymentSheet.FlowController` が初期化されたら、`paymentOption` を指定して「**支払い方法**」ボタンを更新します。このプロパティには、顧客が最初に選択したデフォルトの支払い方法を表す画像とラベルが含まれています。 ```swift class MyCheckoutVC: UIViewController { func loadCheckout() {let intentConfig = PaymentSheet.IntentConfiguration(mode: .setup(currency: "USD")) { [weak self] confirmationToken in try await self?.handleConfirmationToken(confirmationToken) } var configuration = PaymentSheet.Configuration() configuration.returnURL = "your-app://stripe-redirect" // Use the return url you set up in the previous step PaymentSheet.FlowController.create( intentConfiguration: intentConfig, configuration: configuration ) { [weak self] result in switch result { case .failure(let error): print(error) case .success(let paymentSheetFlowController): self?.paymentSheetFlowController = paymentSheetFlowController // Update your UI paymentSheetFlowController.paymentOption.image and paymentSheetFlowController.paymentOption.label } } } func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // ...explained later } } ``` ### PaymentSheet を表示する 顧客が「**支払い方法**」ボタンをタップしたら、`presentPaymentOptions` を呼び出して、支払い情報を収集します。完了したら、`paymentOption` プロパティで UI を再び更新します。 ```swift paymentSheetFlowController.presentPaymentOptions(from: self) { // Update your UI using paymentSheetFlowController.paymentOption } ``` ### (任意)支払いの詳細を更新する 顧客が支払い情報を変更するアクション (割引コードの適用やカートの編集など) を実行したら、新しい値を指定して PaymentSheet.FlowController インスタンスを更新します。こうすると、UI に正確な値が表示され ( **Pay** ボタンや Apple Pay UI など)、適切な決済手段などを表示できます。PaymentSheet.FlowController を再初期化するのではなく、インスタンスを更新することで、決済画面に顧客の支払い情報が保存されます。 更新された IntentConfiguration オブジェクトを指定して `update` メソッドを呼び出します。更新の進行中は、PaymentSheet.FlowController で `present` または `confirm` を呼び出さないでください (たとえば、「**購入**」ボタンと「**支払い方法**」ボタンを無効にするなど)。 更新が完了したら、顧客が以前に選択した支払い方法が使用できなくなっている場合には、`paymentOption` プロパティを指定して UI を更新します。更新が失敗した場合は、再試行してください。 ```swift // Create an updated IntentConfiguration var updatedIntentConfig = oldIntentConfig updatedIntentConfig.amount = 999 // Disable your "Buy" and "Payment method" buttons and call `update` paymentSheetFlowController.update(intentConfiguration: updatedIntentConfig) { [weak self] error in if error != nil { // You must retry - until the update succeeds, the customer can't pay or select a payment method. // For example, you can automatically retry the update with an exponential back-off, or present the user with an alert that retries the update. } else { // Re-enable your "Buy" and "Payment method" buttons // Update your UI using paymentSheetFlowController.paymentOption.image and paymentSheetFlowController.paymentOption.label } } ``` ### 支払い情報を確定する 顧客が **購入** ボタンをタップしたら、[paymentSheetFlowController.confirm](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/flowcontroller/confirm(from:completion:) を呼び出します)。これにより、顧客の支払いの詳細と設定を表す [STPConfirmationToken](https://stripe.dev/stripe-ios/stripepayments/documentation/stripepayments/stpconfirmationtoken) オブジェクトを使用して、`PaymentSheet.IntentConfiguration` に渡した `confirmationTokenConfirmHandler` コールバックが呼び出されます。 このコールバックを実装して、`confirmationToken.stripeId` を渡して、サーバーにリクエストを送信します。サーバーは SetupIntent を作成して確認し、Client Secret を返します。 リクエストが返されるときに、サーバーレスポンスの client secret またはエラーをスローします。PaymentSheet は、client secret を使用して SetupIntentを完了するために必要な次のアクションを実行します。 ```swift class MyCheckoutVC: UIViewController { // ...func didTapBuyButton() { paymentSheetFlowController.confirm(from: self) { paymentResult in switch paymentResult { case .completed: //Setupcompleted - show a confirmation screen. case .failed(let error): // PaymentSheet encountered an unrecoverable error. You can display the error to the user, log it, and so on print(error) case .canceled: // Customer canceled - you should probably do nothing. } } } func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // Make a request to your own server. Pass confirmationToken.stripeId if using server-side confirmation. return try await fetchIntentClientSecret(...) } } ``` サーバーコードについては以下のステップで説明します。 ## Stripe に支払いの詳細を送信する [サーバー側] サーバー側で *SetupIntent* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method) を作成し、これを確定します。決済手段は[ダッシュボード](https://dashboard.stripe.com/settings/payment_methods)から管理できます。Stripe は、決済手段の制約とその他のパラメーターを評価して、利用可能な決済手段のリストを決定します。 コールが成功した場合は、SetupIntent *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)) を返します。コールが失敗した場合は、[エラーを処理](https://docs.stripe.com/error-handling.md)して、エラーメッセージと顧客向けの簡単な説明を返します。 > すべての IntentConfiguration プロパティが SetupIntent ([usage](https://docs.stripe.com/api/setup_intents/object.md#setup_intent_object-usage) など) と一致していることを確認します。 ### クライアント側の引数の処理: - `confirmation_token_id`: この ID を使用して ConfirmationToken オブジェクトを取得し、独自の検証またはビジネスロジックを実行できます。 #### Ruby ```ruby require 'stripe' Stripe.api_key = '<>' post '/create-intent' do data = JSON.parse request.body.read params = { customer: ..., # The Customer ID you previously created # In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. automatic_payment_methods: {enabled: true}, confirm: true, confirmation_token: data['confirmation_token_id'], # the ConfirmationToken ID sent by your client } begin intent = Stripe::SetupIntent.create(params) {client_secret: intent.client_secret}.to_json rescue Stripe::StripeError => e {error: e.error.message}.to_json end end ``` ## 保存された支払い方法に後で請求する [サーバー側] > `bancontact` と `ideal` は、デフォルトでは 1 回限りの支払い方法です。以降も使用できるように設定すると、再利用可能な支払い方法タイプ `sepa_debit` が生成されます。このため、保存された支払い方法を照会するには `sepa_debit` を使用する必要があります。 > #### 法令遵守 > > 顧客の支払いの詳細を保存する際、お客様は適用されるすべての法律、規制、ネットワークの規則に準拠する責任があります。将来の購入に備えて顧客に過去の決済手段を提供する際は、必ず、特定の将来の使用に備えて決済手段の詳細を保存することについての同意を顧客から収集した決済手段をリストアップします。顧客に関連付けられた決済手段のうち、将来の購入用の保存済みの決済手段として顧客に提示できるものと提示できないものを区別するには、[allow_redisplay](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay) パラメーターを使用します。 購入者に*オフセッション* (A payment is described as off-session if it occurs without the direct involvement of the customer, using previously-collected payment information)で請求する準備ができたら、Customer ID と PaymentMethod ID を使用して、PaymentIntent を作成します。請求する決済手段を見つけるには、顧客に関連付けられた決済手段を一覧表示します。この例ではカードが一覧表示されますが、サポートされているすべての[タイプ](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-type)を一覧表示できます。 ```curl curl -G https://api.stripe.com/v1/payment_methods \ -u "<>:" \ -d "customer={{CUSTOMER_ID}}" \ -d type=card ``` Customer ID と PaymentMethod ID を取得したら、支払いの金額と通貨を使用して PaymentIntent を作成します。その他のいくつかのパラメーターを設定して、オフセッションの支払いを行います。 - [off_session](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-off_session) を `true` に設定して、支払いの試行時に購入者が決済フローを実行中でないことと、カード発行会社、銀行、その他の決済機関などのパートナーからの認証リクエストに対応できないことを示します。決済フローの実行時にパートナーが認証をリクエストした場合、Stripe は前回の*オンセッション* (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)取引の顧客情報を使用して免除をリクエストします。免除の条件を満していない場合は PaymentIntent からエラーが返されることがあります。 - PaymentIntent の [confirm](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-confirm) プロパティの値を `true` に設定します。これにより、PaymentIntent が作成されると直ちに確定されます。 - [payment_method](https://docs.stripe.com/api.md#create_payment_intent-payment_method) を PaymentMethod の ID に設定し、[customer](https://docs.stripe.com/api.md#create_payment_intent-customer) を Customer の ID に設定します。 #### Accounts v2 ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=usd \ -d "automatic_payment_methods[enabled]=true" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d payment_method={{PAYMENT_METHOD_ID}} \ --data-urlencode "return_url=https://example.com/order/123/complete" \ -d off_session=true \ -d confirm=true ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=usd \ -d "automatic_payment_methods[enabled]=true" \ -d "customer={{CUSTOMER_ID}}" \ -d payment_method={{PAYMENT_METHOD_ID}} \ --data-urlencode "return_url=https://example.com/order/123/complete" \ -d off_session=true \ -d confirm=true ``` ## 実装をテストする #### カード | カード番号 | シナリオ | テスト方法 | | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | | 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)をご覧ください。 ## カードのスキャンを有効にする iOS をサポートするカードスキャン機能を有効にするには、アプリケーションの `Info.plist` の `NSCameraUsageDescription` (**プライバシー - カメラ利用の詳細**)を設定し、カメラにアクセスする理由を入力して下さい (例:「カードをスキャンするため」)。 ## Optional: 保存済みのカードを有効にする [サーバー側] [クライアント側] PaymentSheet では、**今後の支払いのためにこのカードを保存する**チェックボックスを表示して顧客のカードを保存し、保存済みのカードを表示できます。このチェックボックスを有効にするには、`payment_method_save` を `enabled` に設定して、サーバーで [Customer (顧客)](https://docs.stripe.com/api/customers.md) オブジェクトと、関連する [CustomerSession](https://docs.stripe.com/api/customer_sessions.md) を作成します。 > #### Customers v1 と Accounts v2 のリファレンスを比較する > > Connect プラットフォームが [customer-configured Accounts](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) を使用している場合は、Stripe の [ガイド](https://docs.stripe.com/connect/use-accounts-as-customers.md)をご確認の上、コード内の `Customer` およびイベント参照を同等の Accounts v2 API リファレンスに置き換えてください。 ```javascript const stripe = require('stripe')('sk_test_your_secret_key'); app.post('/mobile-payment-element', async (req, res) => { // Use an existing Customer ID if this is a returning customer. const customer = await stripe.customers.create(); const customerSession = await stripe.customerSessions.create({ customer: customer.id, components: { mobile_payment_element: { enabled: true, features: { payment_method_save: 'enabled', payment_method_redisplay: 'enabled', payment_method_remove: 'enabled' } }, }, }); res.json({ customerSessionClientSecret: customerSession.client_secret, customer: customer.id, }); }); ``` 次に、顧客の ID と CustomerSession の client secret を指定して PaymentSheet を設定します。 ```swift @_spi(CustomerSessionBetaAccess) import StripePaymentSheet var configuration = PaymentSheet.Configuration() configuration.customer = .init(id: customerId, customerSessionClientSecret: customerSessionClientSecret) self.paymentSheet = PaymentSheet(..., configuration: configuration) ``` ## Optional: 遅延型の支払い方法を許可する [クライアント側] *遅延型の決済手段* (A payment method that can't immediately return payment status when a customer attempts a transaction (for example, ACH debits). Businesses commonly hold an order in a pending state until payment is successful with these payment methods)では、購入の終了時に顧客から売上を受け取ることが保証されません。これは、決済に時間がかかる (アメリカの銀行口座、SEPA デビット、iDEAL、Bancontact など) 場合や、完了に顧客の対応を必要とする (OXXO、コンビニ決済、Boleto など) 場合があるためです。 デフォルトの場合、PaymentSheet には遅延型の決済手段は表示されません。オプトインするには、`PaymentSheet.Configuration` で `allowsDelayedPaymentMethods` を true に設定します。このステップのみでは、特定の決済手段を有効にすることはできませんが、アプリがその決済手段に対応できることが示されます。たとえば、OXXO は PaymentSheet でサポートされていませんが、サポートされるようになり、最新の SDK バージョンに更新すると、実装に関する追加の変更なしで、アプリに OXXO を決済オプションとして表示でます。 ```swift var configuration = PaymentSheet.Configuration() configuration.allowsDelayedPaymentMethods = true self.paymentSheet = PaymentSheet(..., configuration: configuration) ``` 顧客がいずれかの遅延型の支払い方法を PaymentSheet で正常に使用すると、`.completed` の支払い結果が返されます。 ## 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) ``` ## 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 ``` > 情報の収集に適用される法律については、弁護士に相談してください。電話番号は、取引に必要な場合にのみ収集してください。 # 支払いを受け入れる > This is a 支払いを受け入れる for when platform is android and type is payment. View the full page at https://docs.stripe.com/payments/mobile/finalize-payments-on-the-server?platform=android&type=payment. Payment Element を使用すると、1 つのシステムを使用して複数の決済手段を受け付けることができます。この組み込みでは、Payment Element をレンダリングし、*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) を作成して、サーバーから支払いを確認します。 ## 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.2.0") // Include the financial connections SDK to support US bank account as a payment method implementation("com.stripe:financial-connections:23.2.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)してください。 また、SDK が Stripe への API コールを実行できるように、[公開可能キー](https://dashboard.stripe.com/apikeys)を設定する必要もあります。すぐに開始するには、導入中にクライアント側でこれをハードコード化できますが、本番環境ではサーバーから公開可能キーを取得します。 ```kotlin // Set your publishable key: remember to change this to your live publishable key in production // See your keys here: https://dashboard.stripe.com/apikeys PaymentConfiguration.init(context, publishableKey = "<>") ``` ## 支払い方法を有効にする [支払い方法の設定](https://dashboard.stripe.com/settings/payment_methods)を表示して、サポートする支払い方法を有効にします。*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) を作成するには、少なくとも 1 つは支払い方法を有効にする必要があります。 多くの顧客から決済を受け付けられるよう、Stripe では、カードやその他一般的な決済手段がデフォルトで有効になっていますが、ビジネスや顧客に適した追加の決済手段を有効にすることをお勧めします。プロダクトと決済手段のサポートについては[決済手段のサポート](https://docs.stripe.com/payments/payment-methods/payment-method-support.md)を、手数料については[料金体系ページ](https://stripe.com/pricing/local-payment-methods)をご覧ください。 ## 支払い情報を収集する [クライアント側] 2 つの導入スタイルを用意しています。 | PaymentSheet | PaymentSheet.FlowController | | ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | ![PaymentSheet](https://b.stripecdn.com/docs-statics-srv/assets/android-overview.471eaf89a760f5b6a757fd96b6bb9b60.png) | ![PaymentSheet.FlowController](https://b.stripecdn.com/docs-statics-srv/assets/android-multi-step.84d8a0a44b1baa596bda491322b6d9fd.png) | | 決済情報を収集して支払いを完了する画面を表示します。**支払う**というラベルと金額が表示されたボタンをクリックすると、支払いが完了します。 | 決済情報の収集のみを行う画面を表示します。**続行**というラベルのボタンをクリックすると顧客はお客様のアプリに戻され、自社で設定したボタンで支払いが完了されます。 | #### PaymentSheet #### ビュー (クラシック) ### PaymentSheet を初期化する PaymentSheet を初期化して `CreateIntentCallback` を渡します。ここでは、実装を空のままにします。 ```kotlin class MyCheckoutActivity : AppCompatActivity() { private lateinit var paymentSheet: PaymentSheet override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... paymentSheet = PaymentSheet.Builder(::onPaymentSheetResult) .createIntentCallback { confirmationToken -> TODO() // You'll implement this later } .build(this) } fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) { // You'll implement this later } } ``` ### PaymentSheet を表示する 次に、`presentWithIntentConfiguration()` を呼び出して PaymentSheet を表示し、[IntentConfiguration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-intent-configuration/index.html) を渡します。`IntentConfiguration` には、`PaymentIntent` (金額や通貨など) の詳細が含まれます。 ```kotlin class MyCheckoutActivity : AppCompatActivity() { // ... private fun handleCheckoutButtonPressed() {val intentConfig = PaymentSheet.IntentConfiguration(mode = PaymentSheet.IntentConfiguration.Mode.Payment( amount = 1099, currency = "usd",),// Other configuration options... ) paymentSheet.presentWithIntentConfiguration( intentConfiguration = intentConfig, // Optional configuration - See the "Customize the sheet" section in this guide configuration = PaymentSheet.Configuration.Builder( merchantDisplayName = "Example Inc.", ).build() ) } } ``` ### インテントを確定する 顧客が PaymentSheet で **Pay** ボタンをタップすると、顧客の決済の詳細と設定を表す [ConfirmationToken](https://stripe.dev/stripe-android/payments-core/com.stripe.android.model/-confirmation-token/index.html) を使用して、前述の `CreateIntentCallback` が呼び出されます。 このメソッドを実装して、`confirmationToken.id` を使用してサーバーにリクエストを送信します。サーバーは PaymentIntent を作成して確定し、client secret を返します。 レスポンスを受け取ったら、レスポンスの client secret またはエラーを返します。PaymentSheet は client secret を使用して PaymentIntent を 完了するために必要なアクションを実行 するか、UI にエラーを表示します。 ```kotlin class MyCheckoutActivity : AppCompatActivity() { private lateinit var paymentSheet: PaymentSheet override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... paymentSheet = PaymentSheet.Builder(::onPaymentSheetResult) .createIntentCallback { confirmationToken ->// Make a request to your server to create aPaymentIntentand return its client secret val networkResult = myNetworkClient.createIntent( confirmationTokenId = confirmationToken.id, ) if (networkResult.isSuccess) { CreateIntentResult.Success(networkResult.clientSecret) } else { CreateIntentResult.Failure(networkResult.exception) } } .build(this) } fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) { // You'll implement this later } } ``` 顧客が決済を完了すると、シートが閉じ、PaymentSheet は [PaymentSheetResult](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result/index.html) を使用して指定した [PaymentSheetResultCallback](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result-callback/index.html) を呼び出します。 ```kotlin class MyCheckoutActivity : AppCompatActivity() { // ... fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) {when(paymentSheetResult) { is PaymentSheetResult.Canceled -> { // Customer canceled - you should probably do nothing. } is PaymentSheetResult.Failed -> { print("Error: ${paymentSheetResult.error}") // PaymentSheet encountered an unrecoverable error. You can display the error to the user, log it, and so on } is PaymentSheetResult.Completed -> { // Display, for example, an order confirmation screen print("Completed") } } } } ``` #### Jetpack Compose ### PaymentSheet を初期化する `remember` を使用して PaymentSheet を初期化し、`PaymentSheet.Builder` を渡します。ここでは、`resultCallback` と `createIntentCallback` の実装を空のままにします。 ```kotlin import androidx.compose.runtime.* import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.rememberPaymentSheet @Composable fun CheckoutScreen() { val paymentSheet = remember { Builder( resultCallback = { paymentSheetResult -> // You'll implement this later } ).createIntentCallback { confirmationToken -> // You'll implement this later } }.build() } ``` ### PaymentSheet を表示する 次に、`presentWithIntentConfiguration()` を呼び出して PaymentSheet を表示し、[IntentConfiguration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-intent-configuration/index.html) を渡します。`IntentConfiguration` には、`PaymentIntent` (金額や通貨など) の詳細が含まれます。 ```kotlin @Composable fun CheckoutScreen() { val paymentSheet = remember { ... }.build() Button( onClick = { val intentConfig = PaymentSheet.IntentConfiguration( mode = PaymentSheet.IntentConfiguration.Mode.Payment( amount = 1099, currency = "usd", ), ) } ) { Text("Checkout") } } ``` ### インテントを確定する 顧客が PaymentSheet で **支払う** ボタンをタップすると、顧客の決済の詳細と設定を表す [ConfirmationToken](https://stripe.dev/stripe-android/payments-core/com.stripe.android.model/-confirmation-token/index.html) オブジェクトで `createIntentCallback` が呼び出されます。 このコールバックを実装して、`confirmationToken.id` を使用してサーバーにリクエストを送信します。サーバーは PaymentIntent を作成して確定し、client secret を返します。 レスポンスを受け取ったら、client secret またはエラーを返します。PaymentSheet は client secret を使用して PaymentIntent を 完了するために必要なアクションを実行 するか、UI にエラーを表示します。 ```kotlin @Composable fun CheckoutScreen() { val paymentSheet = remember { Builder( resultCallback = { paymentSheetResult -> // You'll implement this later } ).createIntentCallback { confirmationToken -> // Make a request to your server to create a PaymentIntent and return its client secret try { val response = myNetworkClient.createIntent( confirmationTokenId = confirmationToken.id, ) CreateIntentResult.Success(response.clientSecret) } catch (e: Exception) { CreateIntentResult.Failure( cause = e, displayMessage = e.message ) } } }.build() Button( onClick = { val intentConfig = PaymentSheet.IntentConfiguration( mode = PaymentSheet.IntentConfiguration.Mode.Payment( amount = 1099, currency = "usd", ), ) paymentSheet.presentWithIntentConfiguration( intentConfiguration = intentConfig, configuration = PaymentSheet.Configuration.Builder( merchantDisplayName = "Example Inc.", ).build() ) } ) { Text("Checkout") } } ``` 顧客が決済を完了するとシートが閉じ、`PaymentSheet.Builder.resultCallback` に渡すコールバックが [PaymentSheetResult](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result/index.html) とともに呼び出されます。 ```kotlin @Composable fun CheckoutScreen() { val paymentSheet = remember { Builder( resultCallback = { paymentSheetResult -> when(paymentSheetResult) { is PaymentSheetResult.Canceled -> { // Customer canceled - you should probably do nothing. } is PaymentSheetResult.Failed -> { println("Error: ${paymentSheetResult.error}") // PaymentSheet encountered an unrecoverable error. You can display the error to the user, log it, and so on } is PaymentSheetResult.Completed -> { // Display, for example, an order confirmation screen println("Completed") } } } ).createIntentCallback { confirmationToken -> ... // previously implemented confirm intent code } }.build() ... // other code } ``` #### PaymentSheet.FlowController この実装では、Checkout 画面に 2 つのボタンがあります。1 つは支払い情報の収集に対応する **決済手段** ボタンで、もう 1 つは 支払いを完了する **購入** ボタンです。 #### ビュー (クラシック) ### PaymentSheet を初期化する `PaymentSheet.FlowController` を初期化して `CreateIntentCallback` を渡します。ここでは、実装を空のままにします。 ```kotlin class MyCheckoutActivity : AppCompatActivity() { private lateinit var flowController: PaymentSheet.FlowController override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... flowController = PaymentSheet.FlowController.Builder( resultCallback = ::onPaymentSheetResult, paymentOptionCallback = ::onPaymentOption ) .createIntentCallback { confirmationToken -> TODO() // You'll implement this later } .build(this) } fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) { // Explained later } fun onPaymentOption(paymentOption: PaymentOption?) { // Explained later } } ``` 決済画面が読み込まれたら、[IntentConfiguration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-intent-configuration/index.html) を使用して `PaymentSheet.FlowController` を設定します。`IntentConfiguration` には、 `PaymentIntent` (金額や通貨など) の詳細が含まれます。 ```kotlin fun handleCheckoutLoaded(cartTotal: Long, currency: String) {flowController.configureWithIntentConfiguration( intentConfiguration = PaymentSheet.IntentConfiguration(mode = PaymentSheet.IntentConfiguration.Mode.Payment( amount = cartTotal, currency = currency,),), // Optional configuration - See the "Customize the sheet" section in this guide configuration = PaymentSheet.Configuration.Builder( merchantDisplayName = "Example Inc.", ).build(), callback = { success, error -> // If success, the FlowController was initialized correctly. // Use flowController.getPaymentOption() to populate your payment // method button. }, ) } ``` `PaymentSheet.FlowController` の設定が完了すると、コールバックが呼び出されます。次に、`flowController.getPaymentOption()` を使用して **決済手段** ボタンに値を設定できます。これには、顧客が最初に選択した決済手段を表す画像とラベルが含まれます。 ### PaymentSheet を表示する 顧客が **決済手段** ボタンをタップしたら、`presentPaymentOptions()` を呼び出して決済の詳細を収集します。次に、`paymentOption` プロパティを使用して UI を更新します。 ```kotlin // ... flowController.presentPaymentOptions() // ... fun onPaymentOption(paymentOption: PaymentOption?) { if (paymentOption != null) { paymentMethodButton.text = paymentOption.label paymentMethodButton.setCompoundDrawablesRelativeWithIntrinsicBounds( paymentOption.drawableResourceId, 0, 0, 0 ) } else { paymentMethodButton.text = "Select" paymentMethodButton.setCompoundDrawablesRelativeWithIntrinsicBounds( null, null, null, null ) } } ``` ### 決済の詳細を更新する 顧客が決済の詳細を変更した場合 (割引コードの適用やカートの編集など)、`configureWithIntentConfiguration()` を再度呼び出して `PaymentSheet.FlowController` インスタンスを更新し、新しい値を反映させます。これにより、UI に表示される値の同期が維持されます。 > Google Pay などの一部の決済手段では、UI に金額が表示されます。顧客が決済を変更し、`EmbeddedPaymentElement` を更新しない場合、UI に正しくない値が表示されます。 設定中は、`PaymentSheet.FlowController` で `presentPaymentOptions()` や `confirm()` を呼び出さないでください。**購入** ボタンと **決済手段** ボタンを無効にしてから、`ConfigCallback` の実行時に有効にします。 更新が成功した場合は、`flowController.getPaymentOption()` を使用して UI を更新します。これは、顧客が以前に選択した決済手段を使用できない場合があるためです。更新が失敗した場合は、再試行してください。 ```kotlin fun handleCartChanged( newCartTotal: Long, currency: String, ) { // Disable your "Buy" and "Payment method" buttons paymentMethodSelectionButton.isEnabled = false payButton.isEnabled = false // Update FlowController by configuring it again flowController.configureWithIntentConfiguration( intentConfiguration = PaymentSheet.IntentConfiguration( mode = PaymentSheet.IntentConfiguration.Mode.Payment( amount = newCartTotal, currency = currency ), ), configuration = PaymentSheet.Configuration.Builder( merchantDisplayName = "Example Inc.", ).build(), callback = { success, error -> // If success, the FlowController was updated correctly if (success) { paymentMethodSelectionButton.isEnabled = true val canPay = flowController.getPaymentOption() != null payButton.isEnabled = canPay } else { // You must retry - until the update succeeds, the customer can't pay or select a payment method. // For example, you can automatically retry the update with an exponential back-off, or present the user with an alert that retries the update. } }, ) } ``` ### インテントを確定する 顧客が **購入** ボタンをタップしたら、`confirm()` を呼び出して、顧客の決済の詳細と設定を表す [ConfirmationToken](https://stripe.dev/stripe-android/payments-core/com.stripe.android.model/-confirmation-token/index.html) オブジェクトを使用して渡した `CreateIntentCallback` を呼び出します。 このメソッドを実装して、`confirmationToken.id` を使用してサーバーにリクエストを送信します。サーバーは PaymentIntent を作成して確定し、client secret を返します。 レスポンスを受け取ったら、client secret またはエラーを返します。PaymentSheet は client secret を使用して PaymentIntent を完了するために必要なアクションを実行するか、UI にエラーを表示します。 ```kotlin class MyCheckoutActivity : AppCompatActivity() { private lateinit var flowController: PaymentSheet.FlowController override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // … flowController = PaymentSheet.FlowController.Builder( resultCallback = ::onPaymentSheetResult, paymentOptionCallback = ::onPaymentOption ) .createIntentCallback { confirmationToken ->// Make a request to your server to create aPaymentIntentand return its client secret try { val response = myNetworkClient.createIntent( confirmationTokenId = confirmationToken.id, // only required for server-side confirmation ) CreateIntentResult.Success(response.clientSecret) } catch (e: Exception) { CreateIntentResult.Failure( cause = e, displayMessage = e.message ) } } .build(this) } } ``` 顧客が決済を完了すると、シートが閉じ、[PaymentSheetResult](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result/index.html) とともに [PaymentSheetResultCallback](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result-callback/index.html) が呼び出されます。 ```kotlin class MyCheckoutActivity : AppCompatActivity() { // ... fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) {when(paymentSheetResult) { is PaymentSheetResult.Canceled -> { // Customer canceled - you should probably do nothing. } is PaymentSheetResult.Failed -> { print("Error: ${paymentSheetResult.error}") // PaymentSheet encountered an unrecoverable error. You can display the error to the user, log it, and so on } is PaymentSheetResult.Completed -> { // Display, for example, an order confirmation screen print("Completed") } } } } ``` 次のステップでは、サーバーコードについて説明します。 #### Jetpack Compose ### PaymentSheet.FlowController を初期化する `PaymentSheet.FlowController` を初期化し、コールバックを `PaymentSheet.FlowController.Builder` に渡します。ここでは、実装を空のままにします。 ```kotlin import androidx.compose.runtime.* import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.PaymentSheet.FlowController.Builder import com.stripe.android.paymentsheet.PaymentSheetResult import com.stripe.android.paymentsheet.model.PaymentOption private fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) { // You'll implement this later } private fun onPaymentOption(paymentOption: PaymentOption?) { // You'll implement this later } @Composable fun CheckoutScreen() { val flowController = remember{ Builder( resultCallback = ::onPaymentSheetResult, paymentOptionCallback = ::onPaymentOption, ).createIntentCallback { confirmationToken -> // You'll implement this later } }.build() } ``` 決済画面が読み込まれたら、[IntentConfiguration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-intent-configuration/index.html) を使用して `PaymentSheet.FlowController` インスタンスを設定します。`IntentConfiguration` には、`PaymentIntent` (金額や通貨など) の詳細が含まれます。 ```kotlin @Composable fun CheckoutScreen() { val flowController = remember{ ... }.build() LaunchedEffect(Unit) { flowController.configureWithIntentConfiguration( intentConfiguration = PaymentSheet.IntentConfiguration( mode = PaymentSheet.IntentConfiguration.Mode.Payment( amount = 1099, currency = "usd", ), ), configuration = PaymentSheet.Configuration.Builder( merchantDisplayName = "Example Inc.", ).build(), callback = { success, error -> // If success, the FlowController was initialized correctly. // Use flowController.getPaymentOption() to populate your payment // method button. }, ) } } ``` `PaymentSheet.FlowController` インスタンスは、設定を完了すると、`paymentOptionCallback` を呼び出します。この時点で、`paymentOption` には、顧客が最初に選択した決済手段を表す画像とラベルが含まれます。 ### PaymentSheet を表示する 顧客が **決済手段** ボタンをタップしたら、`presentPaymentOptions()` を呼び出して決済の詳細を収集します。完了後、`paymentOptionCallback` は `paymentOption` を更新します。次に、UI を更新します。 ```kotlin ... flowController.presentPaymentOptions() ... fun onPaymentOption(paymentOption: PaymentOption?) { if (paymentOption != null) { paymentMethodButton.text = paymentOption.label paymentMethodButton.setCompoundDrawablesRelativeWithIntrinsicBounds( paymentOption.drawableResourceId, 0, 0, 0 ) } else { paymentMethodButton.text = "Select" paymentMethodButton.setCompoundDrawablesRelativeWithIntrinsicBounds( null, null, null, null ) } } ``` ### 決済の詳細を更新する 顧客が決済の詳細を変更した場合 (割引コードの適用やカートの編集など)、`configureWithIntentConfiguration()` を再度呼び出して `PaymentSheet.FlowController` インスタンスを更新し、新しい値を反映させます。これにより、UI に表示される値の同期が維持されます。 > Google Pay などの一部の決済手段では、UI に金額が表示されます。顧客が決済を変更し、`PaymentSheet.FlowController` を更新しない場合、UI に正しくない値が表示されます。 設定中は、`PaymentSheet.FlowController` で `presentPaymentOptions()` や `confirm()` を呼び出さないでください。 更新が成功すると、更新された決済オプションを使用して `paymentOptionCallback` が実行されます。顧客が以前に選択した決済手段を使用できなくなった場合、選択が変更されることがあります。更新が失敗した場合は、再試行してください。 ```kotlin fun updateCart( flowController: PaymentSheet.FlowController, newAmount: Long, onComplete: (Boolean) -> Unit ) { flowController.configureWithIntentConfiguration( intentConfiguration = PaymentSheet.IntentConfiguration( mode = PaymentSheet.IntentConfiguration.Mode.Payment( amount = newAmount, currency = "usd" ), ), configuration = PaymentSheet.Configuration.Builder( merchantDisplayName = "Example Inc.", ).build(), callback = { success, error -> // If success, the FlowController was updated correctly if (success) { paymentMethodSelectionButton.isEnabled = true val canPay = flowController.getPaymentOption() != null payButton.isEnabled = canPay } else { // You must retry - until the update succeeds, the customer can't pay or select a payment method. // For example, you can automatically retry the update with an exponential back-off, or present the user with an alert that retries the update. } }, ) } ``` ### インテントを確定する 顧客が **購入** ボタンをタップしたら、`confirm()` を呼び出します。PaymentSheet は、顧客の決済の詳細と設定を表す [ConfirmationToken](https://stripe.dev/stripe-android/payments-core/com.stripe.android.model/-confirmation-token/index.html) を使用して、渡した `createIntentCallback` を呼び出します。 ```kotlin @Composable fun CheckoutScreen() { val flowController = remember{ Builder( resultCallback = ::onPaymentSheetResult, paymentOptionCallback = ::onPaymentOption, ).createIntentCallback { confirmationToken -> // Make a request to your server to create a PaymentIntent and return its client secret try { val response = myNetworkClient.createIntent( confirmationTokenId = confirmationToken.id, ) CreateIntentResult.Success(response.clientSecret) } catch (e: Exception) { CreateIntentResult.Failure( cause = e, displayMessage = e.message ) } } }.build() // Previous flowcontroller configuration code Column { // Payment method button... Button( onClick = { flowController.confirm() }, enabled = paymentOption != null ) { Text("Buy") } } } ``` 顧客が決済を完了すると、シートが閉じ、`PaymentSheet.FlowController` は `PaymentSheet.FlowController.Builder.resultCallback` に渡すコールバックを [PaymentSheetResult](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result/index.html) とともに呼び出します。 ```kotlin private fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) { when(paymentSheetResult) { is PaymentSheetResult.Canceled -> { // Customer canceled - you should probably do nothing. } is PaymentSheetResult.Failed -> { println("Error: ${(paymentSheetResult as PaymentSheetResult.Failed).error}") // PaymentSheet encountered an unrecoverable error. You can display the error to the user, log it, and so on } is PaymentSheetResult.Completed -> { // Display, for example, an order confirmation screen println("Completed") } null -> { // No result yet } } } ``` 次のステップでは、サーバーコードについて説明します。 ## 決済を作成して Stripe に送信する [サーバー側] サーバー側で、金額と通貨を指定して *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) を作成し、確定します。支払い方法は[ダッシュボード](https://dashboard.stripe.com/settings/payment_methods)で管理できます。Stripe は取引額、通貨、決済フローなどの要素に基づいて、適切な支払い方法が返されるように処理します。悪意のある顧客が金額を恣意的に選択できないようにするために、請求額はクライアント側ではなく、常にサーバー側 (信頼性の高い環境) で指定してください。 コールが成功した場合は、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)) を返します。コールが失敗した場合は、[エラーを処理](https://docs.stripe.com/error-handling.md)して、エラーメッセージと顧客向けの簡単な説明を返します。 > すべての IntentConfiguration プロパティが PaymentIntent (`setup_future_usage`、`amount`、`currency` など) と一致していることを確認します。 ### クライアント側の引数の処理: - `confirmation_token_id`: この ID を使用して ConfirmationToken オブジェクトを取得し、独自の検証またはビジネスロジックを実行できます。 #### Ruby ```ruby require 'stripe' Stripe.api_key = '<>' post '/create-intent' do data = JSON.parse request.body.read params = { amount: 1099, currency: 'usd', # In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. automatic_payment_methods: {enabled: true}, confirm: true, confirmation_token: data['confirmation_token_id'], # the ConfirmationToken ID sent by your client } begin intent = Stripe::PaymentIntent.create(params) {client_secret: intent.client_secret}.to_json rescue Stripe::StripeError => e {error: e.error.message}.to_json end end ``` ## 支払い後のイベントを処理する [サーバー側] 支払いが完了すると、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: 保存済みのカードを有効にする [サーバー側] [クライアント側] `PaymentSheet` を使用すると、顧客はカードを保存して、利用可能な決済手段に顧客の保存済みのカードを含めることができます。サーバーには、顧客に関連付けられた [Customer (顧客)](https://docs.stripe.com/api/customers.md) オブジェクトが必要です。顧客がカードを保存できるようにするチェックボックスを有効にするには、`payment_method_save` を `enabled` に設定して [CustomerSession](https://docs.stripe.com/api/customer_sessions.md) を作成します。 ```javascript const stripe = require("stripe")("<>"); const express = require('express'); const app = express(); app.set('trust proxy', true); app.use(express.json()); app.post('/payment-sheet', async (req, res) => { // Use an existing Customer ID if this is a returning customer. const customer = await stripe.customers.create(); const customerSession = await stripe.customerSessions.create({ customer: customer.id, components: { mobile_payment_element: { enabled: true, features: { payment_method_save: 'enabled', payment_method_redisplay: 'enabled', payment_method_remove: 'enabled' } }, }, }); res.json({ customerSessionClientSecret: customerSession.client_secret, customer: customer.id, }); }); ``` 次に、Customer の ID と `CustomerSession` client secret を使用して、`PaymentSheet` を表示します。 ```kotlin val configuration = PaymentSheet.Configuration.Builder(merchantDisplayName = "Powdur") .customer( PaymentSheet.CustomerConfiguration.createWithCustomerSession( id = customerId, clientSecret = customerSessionClientSecret, ) ) .build() paymentSheet.presentWithIntentConfiguration( intentConfiguration = // ... , configuration = configuration, ) ``` ## Optional: 遅延型の支払い方法を許可する [クライアント側] *遅延型の決済手段* (A payment method that can't immediately return payment status when a customer attempts a transaction (for example, ACH debits). Businesses commonly hold an order in a pending state until payment is successful with these payment methods)では、購入の終了時に顧客から売上を受け取ることが保証されません。これは、決済に時間がかかる (アメリカの銀行口座、SEPA デビット、iDEAL、Bancontact、Sofort など) か、完了に顧客の対応を必要とする (OXXO、コンビニ決済、Boleto など) という理由によります。 デフォルトでは、`PaymentSheet` は遅延型の決済手段を表示しません。`PaymentSheet` がサポートしている遅延型の決済手段を含めるには、`PaymentSheet.Configuration` で `allowsDelayedPaymentMethods` を true に設定します。 ```kotlin val configuration = PaymentSheet.Configuration.Builder(merchantDisplayName = "Powdur") .allowsDelayedPaymentMethods(true) .build() ``` 顧客が `PaymentSheet` で遅延型の決済手段を適切に使用すると、`PaymentSheetResult.Completed` の支払い結果が返されます。 ## Optional: Google Pay を有効にする > 決済画面に専用の **Google Pay** ボタンがある場合は、[Google Pay ガイド](https://docs.stripe.com/google-pay.md?platform=android)の内容に従ってください。Embedded Payment Element を使用して、他のタイプの決済手段を処理することも可能です。 ### 実装方法を設定する Google Pay を使用するには、まず以下を **AndroidManifest.xml** の `` に追加し、Google Pay API を有効化します。 ```xml ... ``` 詳細は、Google Pay の Android 向け [Google Pay API を設定する](https://developers.google.com/pay/api/android/guides/setup) を参照してください。 ### Google Pay を追加する 組み込みに Google Pay を追加するには、[PaymentSheet.Configuration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-google-pay-configuration/index.html) を初期化する際に、お客様の Google Pay 環境 (本番またはテスト) と[ビジネスの国コード](https://dashboard.stripe.com/settings/account)を指定して [PaymentSheet.GooglePayConfiguration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/index.html) を渡します。 #### Kotlin ```kotlin val googlePayConfiguration = PaymentSheet.GooglePayConfiguration( environment = PaymentSheet.GooglePayConfiguration.Environment.Test, countryCode = "US", currencyCode = "USD" // Required for Setup Intents, optional for Payment Intents ) val configuration = PaymentSheet.Configuration.Builder(merchantDisplayName = "My merchant name") .googlePay(googlePayConfiguration) .build() ``` ### Google Pay をテストする Google では、[テストクレジットカードスイート](https://developers.google.com/pay/api/android/guides/resources/test-card-suite) を使用してテスト決済を行うことができます。Stripe [テストカード](https://docs.stripe.com/testing.md) をテストスイートと併用できます。 Google Pay がサポートされている国では、シミュレーションされたデバイスではなく、物理的な Android デバイスを使用して Google Pay をテストする必要があります。Google ウォレットに保存した実際のクレジットカードを使用して、テスト用デバイスの Google アカウントにログインします。 ## Optional: カードのスキャンを有効にする カードスキャンサポートを有効にするには、[Google Pay & Wallet Console](https://pay.google.com/business/console?utm_source=devsite&utm_medium=devsite&utm_campaign=devsite) から Google Pay API への[本番アクセスをリクエスト](https://developers.google.com/pay/api/android/guides/test-and-deploy/request-prod-access)します。 - Google Pay を有効にしている場合、対象のデバイスの UI でカードスキャン機能が自動的に利用可能になります。対象のデバイスの詳細については、[Google Pay API の制約](https://developers.google.com/pay/payment-card-recognition/debit-credit-card-recognition)をご覧ください。 - **重要:** カードスキャン機能は、[Google Pay & Wallet Console](https://pay.google.com/business/console) に登録された同じ署名キーで署名されたビルドにのみ表示されます。異なる署名キーを使用したテストまたはデバッグビルド (Firebase App Tester を通じて配布されたビルドなど) では、 **カードをスキャン** オプションは表示されません。プレリリースビルドでカードスキャンをテストするには、以下のいずれかを行う必要があります。 - 本番環境の署名キーを使用してテストビルドに署名する - Google Pay & Wallet Console にテスト署名キーのフィンガープリントを追加する ## Optional: 画面をカスタマイズする すべてのカスタマイズは、[PaymentSheet.Configuration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/index.html) オブジェクトを使用して設定されます。 ### デザイン アプリの見た目や使い心地に合わせて、[appearance API](https://docs.stripe.com/elements/appearance-api/mobile.md?platform=android) を使用して色やフォントなどをカスタマイズできます。 ### 決済手段のレイアウト [paymentMethodLayout](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/-builder/index.html#2123253356%2FFunctions%2F2002900378) を使用して、画面上の決済手段のレイアウトを設定します。横や縦に表示することも、Stripe がレイアウトを自動で最適化するように設定することもできます。 ![](https://b.stripecdn.com/docs-statics-srv/assets/android-mpe-payment-method-layouts.3bcfe828ceaad1a94e0572a22d91733f.png) #### Kotlin ```kotlin PaymentSheet.Configuration.Builder("Example, Inc.") .paymentMethodLayout(PaymentSheet.PaymentMethodLayout.Automatic) .build() ``` ### ユーザーの住所を収集する [Address Element](https://docs.stripe.com/elements/address-element.md?platform=android) を使用して、顧客から国内および国外の配送先住所や請求先住所を収集します。 ### ビジネス表示名 [merchantDisplayName](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/index.html#-191101533%2FProperties%2F2002900378) を設定し、顧客に表示するビジネス名を指定します。デフォルトではアプリ名になります。 #### Kotlin ```kotlin PaymentSheet.Configuration.Builder( merchantDisplayName = "My app, Inc." ).build() ``` ### ダークモード `PaymentSheet` は、ユーザーのシステム全体の表示設定 (ライト/ダークモード) に合わせてデフォルトで自動的に調整されます。これを変更するには、アプリでライトモードまたはダークモードを設定します。 #### Kotlin ```kotlin // force dark AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) // force light AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) ``` ### デフォルトの請求詳細 支払い画面で収集される請求詳細のデフォルト値を設定するには、`defaultBillingDetails` プロパティーを設定します。`PaymentSheet` の各フィールドに、指定したそれらの値が事前に読み込まれます。 #### Kotlin ```kotlin val address = PaymentSheet.Address(country = "US") val billingDetails = PaymentSheet.BillingDetails( address = address, email = "foo@bar.com" ) val configuration = PaymentSheet.Configuration.Builder(merchantDisplayName = "Merchant, Inc.") .defaultBillingDetails(billingDetails) .build() ``` ### 請求先情報の収集を設定する `BillingDetailsCollectionConfiguration` を使用して、PaymentSheet で請求詳細を収集する方法を指定します。 顧客の名前、メールアドレス、電話番号、住所を収集できます。 UI でデフォルトの請求詳細が収集されない場合でも、それらの詳細を PaymentMethod オブジェクトに関連付けるには、`billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` を `true` に設定します。 #### Kotlin ```kotlin val billingDetails = PaymentSheet.BillingDetails( email = "foo@bar.com" ) val billingDetailsCollectionConfiguration = BillingDetailsCollectionConfiguration( attachDefaultsToPaymentMethod = true, name = BillingDetailsCollectionConfiguration.CollectionMode.Always, email = BillingDetailsCollectionConfiguration.CollectionMode.Never, address = BillingDetailsCollectionConfiguration.AddressCollectionMode.Full, ) val configuration = PaymentSheet.Configuration.Builder(merchantDisplayName = "Merchant, Inc.") .defaultBillingDetails(billingDetails) .billingDetailsCollectionConfiguration(billingDetailsCollectionConfiguration) .build() ``` > 情報の収集に適用される法律については、弁護士に相談してください。電話番号は、取引に必要な場合にのみ収集してください。 ## Optional: 確定時のセキュリティコードの再収集を有効にする PaymentIntent の確定時に保存されたカードのセキュリティコードを再徴収するには、統合で PaymentIntent を作成する前に決済詳細を徴収する必要があります。 ### インテントの設定を更新する `PaymentSheet.IntentConfiguration` では、保存されたカードのセキュリティコードを再収集する時期を管理するオプションパラメーターを使用できます。 ```kotlin val intentConfig = PaymentSheet.IntentConfiguration( mode = PaymentSheet.IntentConfiguration.Mode.Payment( amount = 1099, currency = "usd", ),requireCvcRecollection = true, ) ``` ### インテント作成のパラメーターを更新する 支払いの確定時にセキュリティコードを再収集するには、PaymentIntent の作成時に `customerId` パラメーターと `require_cvc_recollection` パラメーターの両方を含めます。 #### Ruby ```ruby require 'stripe' Stripe.api_key = '<>' post '/create-intent' do data = JSON.parse request.body.read params = { amount: 1099, currency: 'usd', # In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. automatic_payment_methods: {enabled: true},customer: customer.id, payment_method_options: { card: {require_cvc_recollection: true} }, } begin intent = Stripe::PaymentIntent.create(params) {client_secret: intent.client_secret}.to_json rescue Stripe::StripeError => e {error: e.error.message}.to_json end end ``` # 決済手段を収集して保存する > This is a 決済手段を収集して保存する for when platform is android and type is setup. View the full page at https://docs.stripe.com/payments/mobile/finalize-payments-on-the-server?platform=android&type=setup. SetupIntent フローを使用すると、決済手段の詳細を収集し、請求を作成せずに今後の支払いのために保存できます。この実装では、Payment Element をレンダリングし、*SetupIntent* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method) を作成して、購入者のサーバーで設定を確定するカスタムフローを構築します。 ## 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.2.0") // Include the financial connections SDK to support US bank account as a payment method implementation("com.stripe:financial-connections:23.2.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)してください。 また、SDK が Stripe への API コールを実行できるように、[公開可能キー](https://dashboard.stripe.com/apikeys)を設定する必要もあります。すぐに開始するには、導入中にクライアント側でこれをハードコード化できますが、本番環境ではサーバーから公開可能キーを取得します。 ```kotlin // Set your publishable key: remember to change this to your live publishable key in production // See your keys here: https://dashboard.stripe.com/apikeys PaymentConfiguration.init(context, publishableKey = "<>") ``` ## 支払い方法を有効にする [支払い方法の設定](https://dashboard.stripe.com/settings/payment_methods)を表示して、サポートする支払い方法を有効にします。*SetupIntent* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method) を作成するには、少なくとも 1 つは支払い方法を有効にする必要があります。 多くの顧客から決済を受け付けられるよう、Stripe では、カードやその他一般的な決済手段がデフォルトで有効になっていますが、ビジネスや顧客に適した追加の決済手段を有効にすることをお勧めします。プロダクトと決済手段のサポートについては[決済手段のサポート](https://docs.stripe.com/payments/payment-methods/payment-method-support.md)を、手数料については[料金体系ページ](https://stripe.com/pricing/local-payment-methods)をご覧ください。 ## Customer を作成する [サーバー側] 将来の支払いに備えて支払い方法を設定するには、その手段を *Customer (顧客)* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) に関連付ける必要があります。顧客がビジネスでアカウントを作成する際に、`Customer` オブジェクトを作成します。`Customer` オブジェクトを使用すると、支払い方法を再利用したり、複数の支払いを追跡したりできます。 > #### Customers v1 と Accounts v2 のリファレンスを比較する > > Connect プラットフォームが [customer-configured Accounts](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) を使用している場合は、Stripe の [ガイド](https://docs.stripe.com/connect/use-accounts-as-customers.md)をご確認の上、コード内の `Customer` およびイベント参照を同等の Accounts v2 API リファレンスに置き換えてください。 ```curl curl -X POST https://api.stripe.com/v1/customers \ -u "<>:" ``` ## 支払い情報を収集する [クライアント側] 2 つの導入スタイルを用意しています。 | PaymentSheet | PaymentSheet.FlowController | | ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | ![PaymentSheet](https://b.stripecdn.com/docs-statics-srv/assets/android-overview.471eaf89a760f5b6a757fd96b6bb9b60.png) | ![PaymentSheet.FlowController](https://b.stripecdn.com/docs-statics-srv/assets/android-multi-step.84d8a0a44b1baa596bda491322b6d9fd.png) | | 決済情報を収集して保存するための画面を表示します。**設定**というラベルのボタンをクリックすると、決済情報が保存されます。 | 決済情報の収集のみを行う画面を表示します。**続行**というラベルのボタンをクリックすると、顧客はお客様のアプリに戻され、設定したボタンで決済情報が保存されます。 | #### PaymentSheet #### ビュー (クラシック) ### PaymentSheet を初期化する PaymentSheet を初期化して `CreateIntentCallback` を渡します。ここでは、実装を空のままにします。 ```kotlin class MyCheckoutActivity : AppCompatActivity() { private lateinit var paymentSheet: PaymentSheet override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... paymentSheet = PaymentSheet.Builder(::onPaymentSheetResult) .createIntentCallback { confirmationToken -> TODO() // You'll implement this later } .build(this) } fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) { // You'll implement this later } } ``` ### PaymentSheet を表示する 次に、`presentWithIntentConfiguration()` を呼び出して PaymentSheet を表示し、[IntentConfiguration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-intent-configuration/index.html) を渡します。`IntentConfiguration` には、`SetupIntent` (通貨など) の詳細が含まれます。 ```kotlin class MyCheckoutActivity : AppCompatActivity() { // ... private fun handleCheckoutButtonPressed() {val intentConfig = PaymentSheet.IntentConfiguration(mode = PaymentSheet.IntentConfiguration.Mode.Setup( currency = "usd", ),// Other configuration options... ) paymentSheet.presentWithIntentConfiguration( intentConfiguration = intentConfig, // Optional configuration - See the "Customize the sheet" section in this guide configuration = PaymentSheet.Configuration.Builder( merchantDisplayName = "Example Inc.", ).build() ) } } ``` ### インテントを確定する 顧客が PaymentSheet で **Setup** ボタンをタップすると、顧客の決済の詳細と設定を表す [ConfirmationToken](https://stripe.dev/stripe-android/payments-core/com.stripe.android.model/-confirmation-token/index.html) を使用して、前述の `CreateIntentCallback` が呼び出されます。 このメソッドを実装して、`confirmationToken.id` を使用してサーバーにリクエストを送信します。サーバーは SetupIntent を作成して確定し、client secret を返します。 レスポンスを受け取ったら、レスポンスの client secret またはエラーを返します。PaymentSheet は client secret を使用して SetupIntent を 完了するために必要なアクションを実行 するか、UI にエラーを表示します。 ```kotlin class MyCheckoutActivity : AppCompatActivity() { private lateinit var paymentSheet: PaymentSheet override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... paymentSheet = PaymentSheet.Builder(::onPaymentSheetResult) .createIntentCallback { confirmationToken ->// Make a request to your server to create aSetupIntentand return its client secret val networkResult = myNetworkClient.createIntent( confirmationTokenId = confirmationToken.id, ) if (networkResult.isSuccess) { CreateIntentResult.Success(networkResult.clientSecret) } else { CreateIntentResult.Failure(networkResult.exception) } } .build(this) } fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) { // You'll implement this later } } ``` 顧客が決済手段を保存すると、シートが閉じ、PaymentSheet は [PaymentSheetResult](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result/index.html) を使用して指定した [PaymentSheetResultCallback](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result-callback/index.html) を呼び出します。 ```kotlin class MyCheckoutActivity : AppCompatActivity() { // ... fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) {when(paymentSheetResult) { is PaymentSheetResult.Canceled -> { // Customer canceled - you should probably do nothing. } is PaymentSheetResult.Failed -> { print("Error: ${paymentSheetResult.error}") // PaymentSheet encountered an unrecoverable error. You can display the error to the user, log it, and so on } is PaymentSheetResult.Completed -> { // Display, for example, an order confirmation screen print("Completed") } } } } ``` #### Jetpack Compose ### PaymentSheet を初期化する `remember` を使用して PaymentSheet を初期化し、`PaymentSheet.Builder` を渡します。ここでは、`resultCallback` と `createIntentCallback` の実装を空のままにします。 ```kotlin import androidx.compose.runtime.* import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.rememberPaymentSheet @Composable fun CheckoutScreen() { val paymentSheet = remember { Builder( resultCallback = { paymentSheetResult -> // You'll implement this later } ).createIntentCallback { confirmationToken -> // You'll implement this later } }.build() } ``` ### PaymentSheet を表示する 次に、`presentWithIntentConfiguration()` を呼び出して PaymentSheet を表示し、[IntentConfiguration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-intent-configuration/index.html) を渡します。`IntentConfiguration` には、`SetupIntent` (通貨など) の詳細が含まれます。 ```kotlin @Composable fun CheckoutScreen() { val paymentSheet = remember { ... }.build() Button( onClick = { val intentConfig = PaymentSheet.IntentConfiguration( mode = PaymentSheet.IntentConfiguration.Mode.Setup( currency = "usd", ), ) } ) { Text("Checkout") } } ``` ### インテントを確定する 顧客が PaymentSheet で **設定** ボタンをタップすると、顧客の決済の詳細と設定を表す [ConfirmationToken](https://stripe.dev/stripe-android/payments-core/com.stripe.android.model/-confirmation-token/index.html) オブジェクトで `createIntentCallback` が呼び出されます。 このコールバックを実装して、`confirmationToken.id` を使用してサーバーにリクエストを送信します。サーバーは SetupIntent を作成して確定し、client secret を返します。 レスポンスを受け取ったら、client secret またはエラーを返します。PaymentSheet は client secret を使用して SetupIntent を 完了するために必要なアクションを実行 するか、UI にエラーを表示します。 ```kotlin @Composable fun CheckoutScreen() { val paymentSheet = remember { Builder( resultCallback = { paymentSheetResult -> // You'll implement this later } ).createIntentCallback { confirmationToken -> // Make a request to your server to create a PaymentIntent and return its client secret try { val response = myNetworkClient.createIntent( confirmationTokenId = confirmationToken.id, ) CreateIntentResult.Success(response.clientSecret) } catch (e: Exception) { CreateIntentResult.Failure( cause = e, displayMessage = e.message ) } } }.build() Button( onClick = { val intentConfig = PaymentSheet.IntentConfiguration( mode = PaymentSheet.IntentConfiguration.Mode.Setup( currency = "usd", ), ) paymentSheet.presentWithIntentConfiguration( intentConfiguration = intentConfig, configuration = PaymentSheet.Configuration.Builder( merchantDisplayName = "Example Inc.", ).build() ) } ) { Text("Checkout") } } ``` 顧客が決済手段を保存すると、シートが閉じ、`PaymentSheet.Builder.resultCallback` に渡したコールバックが [PaymentSheetResult](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result/index.html) とともに呼び出されます。 ```kotlin @Composable fun CheckoutScreen() { val paymentSheet = remember { Builder( resultCallback = { paymentSheetResult -> when(paymentSheetResult) { is PaymentSheetResult.Canceled -> { // Customer canceled - you should probably do nothing. } is PaymentSheetResult.Failed -> { println("Error: ${paymentSheetResult.error}") // PaymentSheet encountered an unrecoverable error. You can display the error to the user, log it, and so on } is PaymentSheetResult.Completed -> { // Display, for example, an order confirmation screen println("Completed") } } } ).createIntentCallback { confirmationToken -> ... // previously implemented confirm intent code } }.build() ... // other code } ``` #### PaymentSheet.FlowController この実装では、Checkout 画面に 2 つのボタンがあります。1 つは支払い情報の収集に対応する **決済手段** ボタンで、もう 1 つは **決済手段を設定する** ボタンです。 #### ビュー (クラシック) ### PaymentSheet を初期化する `PaymentSheet.FlowController` を初期化して `CreateIntentCallback` を渡します。ここでは、実装を空のままにします。 ```kotlin class MyCheckoutActivity : AppCompatActivity() { private lateinit var flowController: PaymentSheet.FlowController override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... flowController = PaymentSheet.FlowController.Builder( resultCallback = ::onPaymentSheetResult, paymentOptionCallback = ::onPaymentOption ) .createIntentCallback { confirmationToken -> TODO() // You'll implement this later } .build(this) } fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) { // Explained later } fun onPaymentOption(paymentOption: PaymentOption?) { // Explained later } } ``` 決済画面が読み込まれたら、[IntentConfiguration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-intent-configuration/index.html) を使用して `PaymentSheet.FlowController` を設定します。`IntentConfiguration` には、`SetupIntent` (通貨など) の詳細が含まれます。 ```kotlin fun handleCheckoutLoaded(currency: String) {flowController.configureWithIntentConfiguration( intentConfiguration = PaymentSheet.IntentConfiguration(mode = PaymentSheet.IntentConfiguration.Mode.Setup( currency = currency, ),), // Optional configuration - See the "Customize the sheet" section in this guide configuration = PaymentSheet.Configuration.Builder( merchantDisplayName = "Example Inc.", ).build(), callback = { success, error -> // If success, the FlowController was initialized correctly. // Use flowController.getPaymentOption() to populate your payment // method button. }, ) } ``` `PaymentSheet.FlowController` の設定が完了すると、コールバックが呼び出されます。次に、`flowController.getPaymentOption()` を使用して **決済手段** ボタンに値を設定できます。これには、顧客が最初に選択した決済手段を表す画像とラベルが含まれます。 ### PaymentSheet を表示する 顧客が **決済手段** ボタンをタップしたら、`presentPaymentOptions()` を呼び出して決済の詳細を収集します。次に、`paymentOption` プロパティを使用して UI を更新します。 ```kotlin // ... flowController.presentPaymentOptions() // ... fun onPaymentOption(paymentOption: PaymentOption?) { if (paymentOption != null) { paymentMethodButton.text = paymentOption.label paymentMethodButton.setCompoundDrawablesRelativeWithIntrinsicBounds( paymentOption.drawableResourceId, 0, 0, 0 ) } else { paymentMethodButton.text = "Select" paymentMethodButton.setCompoundDrawablesRelativeWithIntrinsicBounds( null, null, null, null ) } } ``` ### 決済の詳細を更新する 顧客が決済の詳細を変更した場合 (割引コードの適用やカートの編集など)、`configureWithIntentConfiguration()` を再度呼び出して `PaymentSheet.FlowController` インスタンスを更新し、新しい値を反映させます。これにより、UI に表示される値の同期が維持されます。 > Google Pay などの一部の決済手段では、UI に金額が表示されます。顧客が決済を変更し、`EmbeddedPaymentElement` を更新しない場合、UI に正しくない値が表示されます。 設定中は、`PaymentSheet.FlowController` で `presentPaymentOptions()` や `confirm()` を呼び出さないでください。**購入** ボタンと **決済手段** ボタンを無効にしてから、`ConfigCallback` の実行時に有効にします。 更新が成功した場合は、`flowController.getPaymentOption()` を使用して UI を更新します。これは、顧客が以前に選択した決済手段を使用できない場合があるためです。更新が失敗した場合は、再試行してください。 ```kotlin fun handleCartChanged( currency: String, ) { // Disable your "Buy" and "Payment method" buttons paymentMethodSelectionButton.isEnabled = false payButton.isEnabled = false // Update FlowController by configuring it again flowController.configureWithIntentConfiguration( intentConfiguration = PaymentSheet.IntentConfiguration( mode = PaymentSheet.IntentConfiguration.Mode.Setup( currency = currency, ), ), configuration = PaymentSheet.Configuration.Builder( merchantDisplayName = "Example Inc.", ).build(), callback = { success, error -> // If success, the FlowController was updated correctly if (success) { paymentMethodSelectionButton.isEnabled = true val canPay = flowController.getPaymentOption() != null payButton.isEnabled = canPay } else { // You must retry - until the update succeeds, the customer can't pay or select a payment method. // For example, you can automatically retry the update with an exponential back-off, or present the user with an alert that retries the update. } }, ) } ``` ### インテントを確定する 顧客が **購入** ボタンをタップしたら、`confirm()` を呼び出して、顧客の決済の詳細と設定を表す [ConfirmationToken](https://stripe.dev/stripe-android/payments-core/com.stripe.android.model/-confirmation-token/index.html) オブジェクトを使用して渡した `CreateIntentCallback` を呼び出します。 このメソッドを実装して、`confirmationToken.id` を使用してサーバーにリクエストを送信します。サーバーは SetupIntent を作成して確定し、client secret を返します。 レスポンスを受け取ったら、client secret またはエラーを返します。PaymentSheet は client secret を使用して SetupIntent を完了するために必要なアクションを実行するか、UI にエラーを表示します。 ```kotlin class MyCheckoutActivity : AppCompatActivity() { private lateinit var flowController: PaymentSheet.FlowController override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // … flowController = PaymentSheet.FlowController.Builder( resultCallback = ::onPaymentSheetResult, paymentOptionCallback = ::onPaymentOption ) .createIntentCallback { confirmationToken ->// Make a request to your server to create aSetupIntentand return its client secret try { val response = myNetworkClient.createIntent( confirmationTokenId = confirmationToken.id, // only required for server-side confirmation ) CreateIntentResult.Success(response.clientSecret) } catch (e: Exception) { CreateIntentResult.Failure( cause = e, displayMessage = e.message ) } } .build(this) } } ``` 顧客が決済手段の保存を完了すると、シートが閉じ、[PaymentSheetResult](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result/index.html) とともに [PaymentSheetResultCallback](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result-callback/index.html) が呼び出されます。 ```kotlin class MyCheckoutActivity : AppCompatActivity() { // ... fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) {when(paymentSheetResult) { is PaymentSheetResult.Canceled -> { // Customer canceled - you should probably do nothing. } is PaymentSheetResult.Failed -> { print("Error: ${paymentSheetResult.error}") // PaymentSheet encountered an unrecoverable error. You can display the error to the user, log it, and so on } is PaymentSheetResult.Completed -> { // Display, for example, an order confirmation screen print("Completed") } } } } ``` 次のステップでは、サーバーコードについて説明します。 #### Jetpack Compose ### PaymentSheet.FlowController を初期化する `PaymentSheet.FlowController` を初期化し、コールバックを `PaymentSheet.FlowController.Builder` に渡します。ここでは、実装を空のままにします。 ```kotlin import androidx.compose.runtime.* import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.PaymentSheet.FlowController.Builder import com.stripe.android.paymentsheet.PaymentSheetResult import com.stripe.android.paymentsheet.model.PaymentOption private fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) { // You'll implement this later } private fun onPaymentOption(paymentOption: PaymentOption?) { // You'll implement this later } @Composable fun CheckoutScreen() { val flowController = remember{ Builder( resultCallback = ::onPaymentSheetResult, paymentOptionCallback = ::onPaymentOption, ).createIntentCallback { confirmationToken -> // You'll implement this later } }.build() } ``` 決済画面が読み込まれたら、[IntentConfiguration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-intent-configuration/index.html) を使用して `PaymentSheet.FlowController` インスタンスを設定します。`IntentConfiguration` には、`SetupIntent` (通貨など) の詳細が含まれます。 ```kotlin @Composable fun CheckoutScreen() { val flowController = remember{ ... }.build() LaunchedEffect(Unit) { flowController.configureWithIntentConfiguration( intentConfiguration = PaymentSheet.IntentConfiguration( mode = PaymentSheet.IntentConfiguration.Mode.Setup( currency = "usd", ), ), configuration = PaymentSheet.Configuration.Builder( merchantDisplayName = "Example Inc.", ).build(), callback = { success, error -> // If success, the FlowController was initialized correctly. // Use flowController.getPaymentOption() to populate your payment // method button. }, ) } } ``` `PaymentSheet.FlowController` インスタンスは、設定を完了すると、`paymentOptionCallback` を呼び出します。この時点で、`paymentOption` には、顧客が最初に選択した決済手段を表す画像とラベルが含まれます。 ### PaymentSheet を表示する 顧客が **決済手段** ボタンをタップしたら、`presentPaymentOptions()` を呼び出して決済の詳細を収集します。完了後、`paymentOptionCallback` は `paymentOption` を更新します。次に、UI を更新します。 ```kotlin ... flowController.presentPaymentOptions() ... fun onPaymentOption(paymentOption: PaymentOption?) { if (paymentOption != null) { paymentMethodButton.text = paymentOption.label paymentMethodButton.setCompoundDrawablesRelativeWithIntrinsicBounds( paymentOption.drawableResourceId, 0, 0, 0 ) } else { paymentMethodButton.text = "Select" paymentMethodButton.setCompoundDrawablesRelativeWithIntrinsicBounds( null, null, null, null ) } } ``` ### 決済の詳細を更新する 顧客が決済の詳細を変更した場合 (割引コードの適用やカートの編集など)、`configureWithIntentConfiguration()` を再度呼び出して `PaymentSheet.FlowController` インスタンスを更新し、新しい値を反映させます。これにより、UI に表示される値の同期が維持されます。 > Google Pay などの一部の決済手段では、UI に金額が表示されます。顧客が決済を変更し、`PaymentSheet.FlowController` を更新しない場合、UI に正しくない値が表示されます。 設定中は、`PaymentSheet.FlowController` で `presentPaymentOptions()` や `confirm()` を呼び出さないでください。 更新が成功すると、更新された決済オプションを使用して `paymentOptionCallback` が実行されます。顧客が以前に選択した決済手段を使用できなくなった場合、選択が変更されることがあります。更新が失敗した場合は、再試行してください。 ```kotlin fun updateCart( flowController: PaymentSheet.FlowController, onComplete: (Boolean) -> Unit ) { flowController.configureWithIntentConfiguration( intentConfiguration = PaymentSheet.IntentConfiguration( mode = PaymentSheet.IntentConfiguration.Mode.Setup( currency = "usd", ), ), configuration = PaymentSheet.Configuration.Builder( merchantDisplayName = "Example Inc.", ).build(), callback = { success, error -> // If success, the FlowController was updated correctly if (success) { paymentMethodSelectionButton.isEnabled = true val canPay = flowController.getPaymentOption() != null payButton.isEnabled = canPay } else { // You must retry - until the update succeeds, the customer can't pay or select a payment method. // For example, you can automatically retry the update with an exponential back-off, or present the user with an alert that retries the update. } }, ) } ``` ### インテントを確定する 顧客が **購入** ボタンをタップしたら、`confirm()` を呼び出します。PaymentSheet は、顧客の決済の詳細と設定を表す [ConfirmationToken](https://stripe.dev/stripe-android/payments-core/com.stripe.android.model/-confirmation-token/index.html) を使用して、渡した `createIntentCallback` を呼び出します。 ```kotlin @Composable fun CheckoutScreen() { val flowController = remember{ Builder( resultCallback = ::onPaymentSheetResult, paymentOptionCallback = ::onPaymentOption, ).createIntentCallback { confirmationToken -> // Make a request to your server to create a SetupIntent and return its client secret try { val response = myNetworkClient.createIntent( confirmationTokenId = confirmationToken.id, ) CreateIntentResult.Success(response.clientSecret) } catch (e: Exception) { CreateIntentResult.Failure( cause = e, displayMessage = e.message ) } } }.build() // Previous flowcontroller configuration code Column { // Payment method button... Button( onClick = { flowController.confirm() }, enabled = paymentOption != null ) { Text("Set up") } } } ``` 顧客が決済手段を保存すると、シートが閉じ、`PaymentSheet.FlowController` は `PaymentSheet.FlowController.resultCallback` に渡すコールバックを [PaymentSheetResult](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result/index.html) とともに呼び出します。 ```kotlin private fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) { when(paymentSheetResult) { is PaymentSheetResult.Canceled -> { // Customer canceled - you should probably do nothing. } is PaymentSheetResult.Failed -> { println("Error: ${(paymentSheetResult as PaymentSheetResult.Failed).error}") // PaymentSheet encountered an unrecoverable error. You can display the error to the user, log it, and so on } is PaymentSheetResult.Completed -> { // Display, for example, an order confirmation screen println("Completed") } null -> { // No result yet } } } ``` 次のステップでは、サーバーコードについて説明します。 ## Stripe に支払いの詳細を送信する [サーバー側] サーバー側で *SetupIntent* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method) を作成し、これを確定します。決済手段は[ダッシュボード](https://dashboard.stripe.com/settings/payment_methods)から管理できます。Stripe は、決済手段の制約とその他のパラメーターを評価して、利用可能な決済手段のリストを決定します。 コールが成功した場合は、SetupIntent *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)) を返します。コールが失敗した場合は、[エラーを処理](https://docs.stripe.com/error-handling.md)して、エラーメッセージと顧客向けの簡単な説明を返します。 > すべての IntentConfiguration プロパティが SetupIntent ([usage](https://docs.stripe.com/api/setup_intents/object.md#setup_intent_object-usage) など) と一致していることを確認します。 ### クライアント側の引数の処理: - `confirmation_token_id`: この ID を使用して ConfirmationToken オブジェクトを取得し、独自の検証またはビジネスロジックを実行できます。 #### Ruby ```ruby require 'stripe' Stripe.api_key = '<>' post '/create-intent' do data = JSON.parse request.body.read params = { customer: ..., # The Customer ID you previously created # In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. automatic_payment_methods: {enabled: true}, confirm: true, confirmation_token: data['confirmation_token_id'], # the ConfirmationToken ID sent by your client } begin intent = Stripe::SetupIntent.create(params) {client_secret: intent.client_secret}.to_json rescue Stripe::StripeError => e {error: e.error.message}.to_json end end ``` ## 保存された支払い方法に後で請求する [サーバー側] > `bancontact` と `ideal` は、デフォルトでは 1 回限りの支払い方法です。以降も使用できるように設定すると、再利用可能な支払い方法タイプ `sepa_debit` が生成されます。このため、保存された支払い方法を照会するには `sepa_debit` を使用する必要があります。 > #### 法令遵守 > > 顧客の支払いの詳細を保存する際、お客様は適用されるすべての法律、規制、ネットワークの規則に準拠する責任があります。将来の購入に備えて顧客に過去の決済手段を提供する際は、必ず、特定の将来の使用に備えて決済手段の詳細を保存することについての同意を顧客から収集した決済手段をリストアップします。顧客に関連付けられた決済手段のうち、将来の購入用の保存済みの決済手段として顧客に提示できるものと提示できないものを区別するには、[allow_redisplay](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay) パラメーターを使用します。 購入者に*オフセッション* (A payment is described as off-session if it occurs without the direct involvement of the customer, using previously-collected payment information)で請求する準備ができたら、Customer ID と PaymentMethod ID を使用して、PaymentIntent を作成します。請求する決済手段を見つけるには、顧客に関連付けられた決済手段を一覧表示します。この例ではカードが一覧表示されますが、サポートされているすべての[タイプ](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-type)を一覧表示できます。 ```curl curl -G https://api.stripe.com/v1/payment_methods \ -u "<>:" \ -d "customer={{CUSTOMER_ID}}" \ -d type=card ``` Customer ID と PaymentMethod ID を取得したら、支払いの金額と通貨を使用して PaymentIntent を作成します。その他のいくつかのパラメーターを設定して、オフセッションの支払いを行います。 - [off_session](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-off_session) を `true` に設定して、支払いの試行時に購入者が決済フローを実行中でないことと、カード発行会社、銀行、その他の決済機関などのパートナーからの認証リクエストに対応できないことを示します。決済フローの実行時にパートナーが認証をリクエストした場合、Stripe は前回の*オンセッション* (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)取引の顧客情報を使用して免除をリクエストします。免除の条件を満していない場合は PaymentIntent からエラーが返されることがあります。 - PaymentIntent の [confirm](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-confirm) プロパティの値を `true` に設定します。これにより、PaymentIntent が作成されると直ちに確定されます。 - [payment_method](https://docs.stripe.com/api.md#create_payment_intent-payment_method) を PaymentMethod の ID に設定し、[customer](https://docs.stripe.com/api.md#create_payment_intent-customer) を Customer の ID に設定します。 #### Accounts v2 ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=usd \ -d "automatic_payment_methods[enabled]=true" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d payment_method={{PAYMENT_METHOD_ID}} \ --data-urlencode "return_url=https://example.com/order/123/complete" \ -d off_session=true \ -d confirm=true ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=usd \ -d "automatic_payment_methods[enabled]=true" \ -d "customer={{CUSTOMER_ID}}" \ -d payment_method={{PAYMENT_METHOD_ID}} \ --data-urlencode "return_url=https://example.com/order/123/complete" \ -d off_session=true \ -d confirm=true ``` ## 実装をテストする #### カード | カード番号 | シナリオ | テスト方法 | | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | | 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: 保存済みのカードを有効にする [サーバー側] [クライアント側] `PaymentSheet` を使用すると、顧客はカードを保存して、利用可能な決済手段に顧客の保存済みのカードを含めることができます。サーバーには、顧客に関連付けられた [Customer (顧客)](https://docs.stripe.com/api/customers.md) オブジェクトが必要です。顧客がカードを保存できるようにするチェックボックスを有効にするには、`payment_method_save` を `enabled` に設定して [CustomerSession](https://docs.stripe.com/api/customer_sessions.md) を作成します。 ```javascript const stripe = require("stripe")("<>"); const express = require('express'); const app = express(); app.set('trust proxy', true); app.use(express.json()); app.post('/payment-sheet', async (req, res) => { // Use an existing Customer ID if this is a returning customer. const customer = await stripe.customers.create(); const customerSession = await stripe.customerSessions.create({ customer: customer.id, components: { mobile_payment_element: { enabled: true, features: { payment_method_save: 'enabled', payment_method_redisplay: 'enabled', payment_method_remove: 'enabled' } }, }, }); res.json({ customerSessionClientSecret: customerSession.client_secret, customer: customer.id, }); }); ``` 次に、Customer の ID と `CustomerSession` client secret を使用して、`PaymentSheet` を表示します。 ```kotlin val configuration = PaymentSheet.Configuration.Builder(merchantDisplayName = "Powdur") .customer( PaymentSheet.CustomerConfiguration.createWithCustomerSession( id = customerId, clientSecret = customerSessionClientSecret, ) ) .build() paymentSheet.presentWithIntentConfiguration( intentConfiguration = // ... , configuration = configuration, ) ``` ## Optional: 遅延型の支払い方法を許可する [クライアント側] *遅延型の決済手段* (A payment method that can't immediately return payment status when a customer attempts a transaction (for example, ACH debits). Businesses commonly hold an order in a pending state until payment is successful with these payment methods)では、購入の終了時に顧客から売上を受け取ることが保証されません。これは、決済に時間がかかる (アメリカの銀行口座、SEPA デビット、iDEAL、Bancontact、Sofort など) か、完了に顧客の対応を必要とする (OXXO、コンビニ決済、Boleto など) という理由によります。 デフォルトでは、`PaymentSheet` は遅延型の決済手段を表示しません。`PaymentSheet` がサポートしている遅延型の決済手段を含めるには、`PaymentSheet.Configuration` で `allowsDelayedPaymentMethods` を true に設定します。 ```kotlin val configuration = PaymentSheet.Configuration.Builder(merchantDisplayName = "Powdur") .allowsDelayedPaymentMethods(true) .build() ``` 顧客が `PaymentSheet` で遅延型の決済手段を適切に使用すると、`PaymentSheetResult.Completed` の支払い結果が返されます。 ## Optional: Google Pay を有効にする > 決済画面に専用の **Google Pay** ボタンがある場合は、[Google Pay ガイド](https://docs.stripe.com/google-pay.md?platform=android)の内容に従ってください。Embedded Payment Element を使用して、他のタイプの決済手段を処理することも可能です。 ### 実装方法を設定する Google Pay を使用するには、まず以下を **AndroidManifest.xml** の `` に追加し、Google Pay API を有効化します。 ```xml ... ``` 詳細は、Google Pay の Android 向け [Google Pay API を設定する](https://developers.google.com/pay/api/android/guides/setup) を参照してください。 ### Google Pay を追加する 組み込みに Google Pay を追加するには、[PaymentSheet.Configuration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-google-pay-configuration/index.html) を初期化する際に、お客様の Google Pay 環境 (本番またはテスト) と[ビジネスの国コード](https://dashboard.stripe.com/settings/account)を指定して [PaymentSheet.GooglePayConfiguration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/index.html) を渡します。 #### Kotlin ```kotlin val googlePayConfiguration = PaymentSheet.GooglePayConfiguration( environment = PaymentSheet.GooglePayConfiguration.Environment.Test, countryCode = "US", currencyCode = "USD" // Required for Setup Intents, optional for Payment Intents ) val configuration = PaymentSheet.Configuration.Builder(merchantDisplayName = "My merchant name") .googlePay(googlePayConfiguration) .build() ``` ### Google Pay をテストする Google では、[テストクレジットカードスイート](https://developers.google.com/pay/api/android/guides/resources/test-card-suite) を使用してテスト決済を行うことができます。Stripe [テストカード](https://docs.stripe.com/testing.md) をテストスイートと併用できます。 Google Pay がサポートされている国では、シミュレーションされたデバイスではなく、物理的な Android デバイスを使用して Google Pay をテストする必要があります。Google ウォレットに保存した実際のクレジットカードを使用して、テスト用デバイスの Google アカウントにログインします。 ## Optional: カードのスキャンを有効にする カードスキャンサポートを有効にするには、[Google Pay & Wallet Console](https://pay.google.com/business/console?utm_source=devsite&utm_medium=devsite&utm_campaign=devsite) から Google Pay API への[本番アクセスをリクエスト](https://developers.google.com/pay/api/android/guides/test-and-deploy/request-prod-access)します。 - Google Pay を有効にしている場合、対象のデバイスの UI でカードスキャン機能が自動的に利用可能になります。対象のデバイスの詳細については、[Google Pay API の制約](https://developers.google.com/pay/payment-card-recognition/debit-credit-card-recognition)をご覧ください。 - **重要:** カードスキャン機能は、[Google Pay & Wallet Console](https://pay.google.com/business/console) に登録された同じ署名キーで署名されたビルドにのみ表示されます。異なる署名キーを使用したテストまたはデバッグビルド (Firebase App Tester を通じて配布されたビルドなど) では、 **カードをスキャン** オプションは表示されません。プレリリースビルドでカードスキャンをテストするには、以下のいずれかを行う必要があります。 - 本番環境の署名キーを使用してテストビルドに署名する - Google Pay & Wallet Console にテスト署名キーのフィンガープリントを追加する ## Optional: 画面をカスタマイズする すべてのカスタマイズは、[PaymentSheet.Configuration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/index.html) オブジェクトを使用して設定されます。 ### デザイン アプリの見た目や使い心地に合わせて、[appearance API](https://docs.stripe.com/elements/appearance-api/mobile.md?platform=android) を使用して色やフォントなどをカスタマイズできます。 ### 決済手段のレイアウト [paymentMethodLayout](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/-builder/index.html#2123253356%2FFunctions%2F2002900378) を使用して、画面上の決済手段のレイアウトを設定します。横や縦に表示することも、Stripe がレイアウトを自動で最適化するように設定することもできます。 ![](https://b.stripecdn.com/docs-statics-srv/assets/android-mpe-payment-method-layouts.3bcfe828ceaad1a94e0572a22d91733f.png) #### Kotlin ```kotlin PaymentSheet.Configuration.Builder("Example, Inc.") .paymentMethodLayout(PaymentSheet.PaymentMethodLayout.Automatic) .build() ``` ### ユーザーの住所を収集する [Address Element](https://docs.stripe.com/elements/address-element.md?platform=android) を使用して、顧客から国内および国外の配送先住所や請求先住所を収集します。 ### ビジネス表示名 [merchantDisplayName](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/index.html#-191101533%2FProperties%2F2002900378) を設定し、顧客に表示するビジネス名を指定します。デフォルトではアプリ名になります。 #### Kotlin ```kotlin PaymentSheet.Configuration.Builder( merchantDisplayName = "My app, Inc." ).build() ``` ### ダークモード `PaymentSheet` は、ユーザーのシステム全体の表示設定 (ライト/ダークモード) に合わせてデフォルトで自動的に調整されます。これを変更するには、アプリでライトモードまたはダークモードを設定します。 #### Kotlin ```kotlin // force dark AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) // force light AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) ``` ### デフォルトの請求詳細 支払い画面で収集される請求詳細のデフォルト値を設定するには、`defaultBillingDetails` プロパティーを設定します。`PaymentSheet` の各フィールドに、指定したそれらの値が事前に読み込まれます。 #### Kotlin ```kotlin val address = PaymentSheet.Address(country = "US") val billingDetails = PaymentSheet.BillingDetails( address = address, email = "foo@bar.com" ) val configuration = PaymentSheet.Configuration.Builder(merchantDisplayName = "Merchant, Inc.") .defaultBillingDetails(billingDetails) .build() ``` ### 請求先情報の収集を設定する `BillingDetailsCollectionConfiguration` を使用して、PaymentSheet で請求詳細を収集する方法を指定します。 顧客の名前、メールアドレス、電話番号、住所を収集できます。 UI でデフォルトの請求詳細が収集されない場合でも、それらの詳細を PaymentMethod オブジェクトに関連付けるには、`billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` を `true` に設定します。 #### Kotlin ```kotlin val billingDetails = PaymentSheet.BillingDetails( email = "foo@bar.com" ) val billingDetailsCollectionConfiguration = BillingDetailsCollectionConfiguration( attachDefaultsToPaymentMethod = true, name = BillingDetailsCollectionConfiguration.CollectionMode.Always, email = BillingDetailsCollectionConfiguration.CollectionMode.Never, address = BillingDetailsCollectionConfiguration.AddressCollectionMode.Full, ) val configuration = PaymentSheet.Configuration.Builder(merchantDisplayName = "Merchant, Inc.") .defaultBillingDetails(billingDetails) .billingDetailsCollectionConfiguration(billingDetailsCollectionConfiguration) .build() ``` > 情報の収集に適用される法律については、弁護士に相談してください。電話番号は、取引に必要な場合にのみ収集してください。 # 支払いを受け入れる > This is a 支払いを受け入れる for when platform is react-native and type is payment. View the full page at https://docs.stripe.com/payments/mobile/finalize-payments-on-the-server?platform=react-native&type=payment. ## Stripe を設定する [サーバー側] [クライアント側] ### サーバー側 この接続方法では、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' ``` ### クライアント側 [React Native SDK](https://github.com/stripe/stripe-react-native) はオープンソースであり、詳細なドキュメントが提供されています。内部では、[ネイティブの iOS](https://github.com/stripe/stripe-ios) および [Android](https://github.com/stripe/stripe-android) の SDK を使用します。Stripe の React Native SDK をインストールするには、プロジェクトのディレクトリーで (使用するパッケージマネージャーによって異なる) 次のいずれかのコマンドを実行します。 #### yarn ```bash yarn add @stripe/stripe-react-native ``` #### npm ```bash npm install @stripe/stripe-react-native ``` 次に、その他の必要な依存関係をインストールします。 - iOS の場合は、**ios** ディレクトリに移動して `pod install` を実行し、必要なネイティブ依存関係もインストールします。 - Android の場合は、依存関係をインストールする必要はありません。 > [公式の TypeScript ガイド](https://reactnative.dev/docs/typescript#adding-typescript-to-an-existing-project)に従って TypeScript のサポートを追加することをお勧めします。 ### Stripe の初期化 React Native アプリで Stripe を初期化するには、決済画面を `StripeProvider` コンポーネントでラップするか、`initStripe` 初期化メソッドを使用します。`publishableKey` の API [公開可能キー](https://docs.stripe.com/keys.md#obtain-api-keys)のみが必要です。次の例は、`StripeProvider` コンポーネントを使用して Stripe を初期化する方法を示しています。 ```jsx import { useState, useEffect } from 'react'; import { StripeProvider } from '@stripe/stripe-react-native'; function App() { const [publishableKey, setPublishableKey] = useState(''); const fetchPublishableKey = async () => { const key = await fetchKey(); // fetch key from your server here setPublishableKey(key); }; useEffect(() => { fetchPublishableKey(); }, []); return ( {/* Your app code here */} ); } ``` > テストおよび開発時には API の[テストキー](https://docs.stripe.com/keys.md#obtain-api-keys)を使用し、アプリの公開時には[本番環境](https://docs.stripe.com/keys.md#test-live-modes)キーを使用します。 ## 支払い方法を有効にする [支払い方法の設定](https://dashboard.stripe.com/settings/payment_methods)を表示して、サポートする支払い方法を有効にします。*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) を作成するには、少なくとも 1 つは支払い方法を有効にする必要があります。 多くの顧客から決済を受け付けられるよう、Stripe では、カードやその他一般的な決済手段がデフォルトで有効になっていますが、ビジネスや顧客に適した追加の決済手段を有効にすることをお勧めします。プロダクトと決済手段のサポートについては[決済手段のサポート](https://docs.stripe.com/payments/payment-methods/payment-method-support.md)を、手数料については[料金体系ページ](https://stripe.com/pricing/local-payment-methods)をご覧ください。 ## 戻り先 URL を設定する [クライアント側] 顧客がアプリを終了すると (Safari やバンキングアプリで認証するなど)、自動的にアプリに戻るための方法を提供します。多くの決済手段タイプで、戻り先 URL の指定が「必須」です。戻り先 URL を有効にしていても、指定がされていないと、戻り先 URL が必要な決済手段をユーザーに提示できません。 戻り先 URL を指定するには、以下のようにします。 1. カスタム URL を[登録](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app#Register-your-URL-scheme)します。ユニバーサルリンクはサポートされていません。 1. カスタム URL を[設定](https://reactnative.dev/docs/linking) します。 1. 以下のように、URL を Stripe SDK に転送するようにルートコンポーネントを設定します。 > Expo を使用している場合は、`app.json` ファイルで[スキームを設定](https://docs.expo.io/guides/linking/#in-a-standalone-app)します。 ```jsx import { useEffect, useCallback } from 'react'; import { Linking } from 'react-native'; import { useStripe } from '@stripe/stripe-react-native'; export default function MyApp() { const { handleURLCallback } = useStripe(); const handleDeepLink = useCallback( async (url: string | null) => { if (url) { const stripeHandled = await handleURLCallback(url); if (stripeHandled) { // This was a Stripe URL - you can return or add extra handling here as you see fit } else { // This was NOT a Stripe URL – handle as you normally would } } }, [handleURLCallback] ); useEffect(() => { const getUrlAsync = async () => { const initialUrl = await Linking.getInitialURL(); handleDeepLink(initialUrl); }; getUrlAsync(); const deepLinkListener = Linking.addEventListener( 'url', (event: { url: string }) => { handleDeepLink(event.url); } ); return () => deepLinkListener.remove(); }, [handleDeepLink]); return ( ); } ``` さらに、`initPaymentSheet` メソッドを呼び出す際に `returnURL` を設定します。 ```js await initPaymentSheet({ ... returnURL: 'your-app://stripe-redirect', ... }); ``` ネイティブ URL スキームの詳細については、[Android](https://developer.android.com/training/app-links/deep-linking) および [iOS](https://developer.apple.com/documentation/xcode/allowing_apps_and_websites_to_link_to_your_content/defining_a_custom_url_scheme_for_your_app) のドキュメントをご覧ください。 ## 支払いの詳細を収集する [クライアント側] 導入ではデフォルトの決済フローまたはカスタムフローを使用できます。 | デフォルト | カスタムフロー | | ------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | | ![PaymentSheet](https://b.stripecdn.com/docs-statics-srv/assets/ios-overview.9e0d68d009dc005f73a6f5df69e00458.png) | ![カスタムフロー](https://b.stripecdn.com/docs-statics-srv/assets/ios-multi-step.cd631ea4f1cd8cf3f39b6b9e1e92b6c5.png) | | 支払い情報を収集して支払いを完了する画面を表示します。画面に **$X を支払う**というボタンが表示され、支払いが完了します。 | 支払い情報の収集のみを行う画面を表示します。画面に**続行する**というボタンが表示され、顧客はアプリに戻され、ご自身のボタンで支払いが完了されます。 | #### デフォルト ### PaymentSheet を初期化する 顧客が購入する場合など、支払いを受け取る準備ができたときに、PaymentSheet を `intentConfiguration` で初期化します。 `intentConfiguration` オブジェクトには、金額や通貨などの支払い固有の詳細と `confirmHandler` コールバックが格納されています。 ```jsx import {View, Button} from 'react-native'; import { useStripe, useEffect, IntentCreationCallbackParams } from '@stripe/stripe-react-native'; export default function CheckoutScreen() {const { initPaymentSheet, presentPaymentSheet } = useStripe(); const initializePaymentSheet = async () => { const { error } = await initPaymentSheet({ merchantDisplayName: "Example, Inc.", intentConfiguration: {mode: { amount: 1099, currencyCode: 'USD',},confirmHandler: confirmHandler } }); if (error) { // handle error } }; useEffect(() => { initializePaymentSheet(); }, []); const confirmHandler = async ( confirmationToken, intentCreationCallback: (params: IntentCreationCallbackParams) => void ) => { // explained later } const didTapCheckoutButton = async () => { // implement later } return (