# カード支払いを回収する Stripe Terminal を使用したカード支払いの回収ができるように、アプリケーションとバックエンドを準備します。 # サーバー主導型 > This is a サーバー主導型 for when terminal-sdk-platform is server-driven. View the full page at https://docs.stripe.com/terminal/payments/collect-card-payment?terminal-sdk-platform=server-driven. BBPOS WisePOS E と Stripe Reader S700/S710 では、Terminal SDK ではなく Stripe API を使用して決済を回収するため、サーバー側の導入をお勧めします。 Payment Intents API を初めて使用する場合には、以下のリソースが役立ちます。 - [Payment Intents API](https://docs.stripe.com/payments/payment-intents.md) - [PaymentIntent (支払いインテント) オブジェクト](https://docs.stripe.com/api/payment_intents.md) - [その他の支払いシナリオ](https://docs.stripe.com/payments/more-payment-scenarios.md) Stripe Terminal で支払いを回収するには、アプリケーションに決済フローを記述する必要があります。Stripe Terminal SDK を使用して、1 つの支払いセッションを表すオブジェクトである [PaymentIntent (支払いインテント)](https://docs.stripe.com/api.md#payment_intents) を作成して更新します。 中心となる概念は、SDK ベースの導入と似ていますが、サーバー主導型の導入では使用されるステップが少し異なります。 1. [PaymentIntent を作成](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#create-payment)します。支払いを[自動](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-capture_method)と[手動](https://docs.stripe.com/payments/place-a-hold-on-a-payment-method.md)のどちらでキャプチャーするかを定義できます。 1. [支払いを処理](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#process-payment)します。顧客のカードのオーソリは、リーダーが支払いを処理すると行われます。 1. (任意) [PaymentIntent をキャプチャーする](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#capture-payment)。 > この統合形態は[オフラインカード決済](https://docs.stripe.com/terminal/features/operate-offline/collect-card-payments.md)をサポートしていません。 ## PaymentIntent を作成する - [PaymentIntent を作成する](https://docs.stripe.com/api/payment_intents/create.md) 支払い回収の最初のステップは、決済フローを開始することです。顧客が購入を開始したときに、バックエンドで [PaymentIntent (支払いインテント)](https://docs.stripe.com/api/payment_intents.md) オブジェクトを作成する必要があります。これは、Stripe で新しい決済セッションが開始されることを表します。サーバー主導型の実装では、サーバー側で PaymentIntent を作成します。 サンドボックスでは、[テスト金額](https://docs.stripe.com/terminal/references/testing.md#physical-test-cards)を使用してさまざまなエラーシナリオをシミュレーションできます。本番環境では、PaymentIntent の金額は支払いに使用されるリーダーに表示されます。 Terminal の支払いでは、`payment_method_types` パラメーターに `card_present` が含まれている必要があります。 カナダで Interac 支払いを受け付けるには、`payment_method_types` に `interac_present` を含める必要があります。詳しくは[カナダに関する地域ごとの考慮事項について](https://docs.stripe.com/terminal/payments/regional.md?integration-country=CA#create-a-paymentintent)をご確認ください。 サポート対象の国でカード以外の決済手段を受け付けるには、`payment_method_types` に希望するタイプも指定する必要があります。[その他の決済手段](https://docs.stripe.com/terminal/payments/additional-payment-methods.md)についてご覧ください。 以下のように決済フローを制御できます。 - `card_present` 決済の決済フローを完全に管理するには、`capture_method` を `manual` に設定します。これにより、決済を確定する前に照合ステップを追加できます。 - 1 ステップで支払いのオーソリとキャプチャーを行うには、`capture_method` を `automatic` に設定します。 > クレジットカードが拒否された場合は、決済インテントを再作成しないでください。代わりに、同じ決済インテントを再利用して、[二重請求を回避](https://docs.stripe.com/terminal/payments/collect-card-payment.md#avoiding-double-charges)します。 ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d currency=usd \ -d "payment_method_types[]"=card_present \ -d capture_method=manual \ -d amount=1000 ``` ## 支払いを処理する 顧客が提示したカードで決済を即時に処理するか、決済の処理に進む前にカード詳細を調べるかを選択できます。大半のユースケースでは、API コール数と Webhook イベント数が少なく抑えられ、システムがシンプルになるため、即時に処理することをお勧めします。ただし、カードの承認前に自社用のビジネスロジックを挿入する場合は、収集と確定の 2 段階のフローを使用できます。 #### 即時に処理する - [PaymentIntent を処理する](https://docs.stripe.com/api/terminal/readers/process_payment_intent.md) PaymentIntent を作成したら、次に支払いを処理します。リーダーは顧客に対してカードをタップまたは挿入するように求め、その後、その支払いがオーソリされます。 支払いを回収するには、作成した PaymentIntent の ID と、取引に使用するリーダーを指定して、Stripe にリクエストを送信します。 ```curl curl https://api.stripe.com/v1/terminal/readers/{{TERMINALREADER_ID}}/process_payment_intent \ -u "<>:" \ -d payment_intent="{{PAYMENTINTENT_ID}}" ``` 支払いの処理は非同期で行われます。カード保有者が財布からカードを取り出すのに数秒かかったり、支払い中にオペレーターに質問する場合があります。支払いを処理すると、Stripe はすぐに、リーダーがアクションを受信した確認として、HTTP `200` ステータスコードでリクエストに応答します。ほとんどの場合、リクエストは `in_progress` ステータスの [reader (リーダー)](https://docs.stripe.com/api/terminal/readers.md) を返します。ただし、処理は非同期で行われるため、支払いがすぐに完了した場合、アクションのステータスに最終状態 (`succeeded` または `failed`) がすでに反映されていることがあります。 同時に、リーダーの画面は、顧客にカードの挿入を求める UI に切り替わります。[リーダーの状態を確認](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#verify-reader)するには、`terminal.reader.action_succeeded` Webhook をリッスンするか、Reader や PaymentIntent のステータスをポーリングして、支払いのステータスを取得します。 ```curl curl https://api.stripe.com/v1/terminal/readers/{{TERMINALREADER_ID}} \ -u "<>:" ``` ```json { "id": "{{READER_ID}}", "object": "terminal.reader", ... "status": "online", "action": { "type": "process_payment_intent", "process_payment_intent": { "payment_intent": "{{PAYMENT_INTENT_ID}}" }, "status": "in_progress", "failure_code": null, "failure_message": null } } ``` #### 収集、検査、確認 PaymentIntent を作成したら、次に支払いを処理します。リーダーは顧客に対してカードをタップまたは挿入するように求め、その後 PaymentMethod を作成します。 ### PaymentMethod を収集する - [支払い方法を収集する](https://docs.stripe.com/api/terminal/readers/collect_payment_method.md) 支払いを回収するには、作成した PaymentIntent の ID と、取引に使用するリーダーを指定して、Stripe にリクエストを送信します。 ```curl curl https://api.stripe.com/v1/terminal/readers/{{TERMINALREADER_ID}}/collect_payment_method \ -u "<>:" \ -d payment_intent="{{PAYMENTINTENT_ID}}" ``` > 決済手段を収集したら、30 秒以内に支払いを承認するか、収集をキャンセルする必要があります。 支払いの回収は非同期で行われます。カード保有者が財布からカードを取り出すのに数秒かかることや、支払い中にオペレーターに質問する場合があります。支払い方法の収集を開始すると、Stripe はすぐに HTTP `200` ステータスコードでこのリクエストに応答し、`in_progress` のアクションステータスをリーダーに返します。同時に、リーダーの画面は、顧客にカードの挿入を求める UI に切り替わります。 リーダーがカードデータを収集すると、PaymentMethod はサーバー側の PaymentIntent に追加され、Reader オブジェクトに `action.collect_payment_method.payment_method` として保存されます。[リーダーの状態を確認](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#verify-reader)するには、`terminal.reader.action_updated` Webhook をリッスンするか、リーダーのアクションステータスをポーリングして、PaymentMethod を調べます。 この時点で、PaymentMethod からカードブランド、口座情報、その他の役立つデータなどの属性にアクセスできます。 Stripe は `wallet.type` 属性で示すとおり、取引でモバイルウォレットが使用されたかどうかを検出するよう試みます。ただし、カード発行会社がモバイルウォレットのリーダーによる識別に対応していない場合、この属性は自動入力されないため、正確な検出は保証されません。[確定](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven&process=inspect#confirm-the-paymentintent)ステップでオーソリが行われた後に、Stripe はネットワークから最新の情報を取得し、`wallet.type` を確実に更新します。 ### PaymentIntent を確定する - [PaymentIntent を確定する](https://docs.stripe.com/api/terminal/readers/confirm_payment_intent.md) PaymentMethod が正常に収集されると、支払いのオーソリに進むことができます。 ```curl curl https://api.stripe.com/v1/terminal/readers/{{TERMINALREADER_ID}}/confirm_payment_intent \ -u "<>:" \ -d payment_intent="{{PAYMENTINTENT_ID}}" ``` PaymentIntent の確定は非同期で行われます。`terminal.reader.action_succeeded` Webhook をリッスンするか、Reader と PaymentIntent のステータスをポーリングして、支払いのステータスを取得できます。 シミュレーションされたリーダーを使用する場合、[present_payment_method](https://docs.stripe.com/terminal/references/testing.md#simulated-card-presentment) エンドポイントを使用して、リーダーでのカード保有者のタップやカードの挿入をシミュレーションします。さまざまな成功と失敗のシナリオをシミュレーションするには、[テストカード](https://docs.stripe.com/terminal/references/testing.md#standard-test-cards)を使用します。 ## 支払いをキャプチャーする [ステップ 1](https://docs.stripe.com/terminal/payments/collect-card-payment.md#create-payment) の PaymentIntent の作成時に `capture_method` を `manual` として定義した場合、SDK はオーソリ済みでキャプチャーされていない PaymentIntent をアプリケーションに返します。[オーソリとキャプチャー](https://docs.stripe.com/payments/place-a-hold-on-a-payment-method.md)の違いについて、詳細を確認してください。アプリケーションが確定済みの PaymentIntent を受信したら、アプリケーションからバックエンドに PaymentIntent をキャプチャーするように通知されることを確認します。このようにするには、バックエンドにエンドポイントを作成し、そこで PaymentIntent ID を受け取り、それをキャプチャーするように Stripe API にリクエストを送信します。 ```curl curl -X POST https://api.stripe.com/v1/payment_intents/{{PAYMENTINTENT_ID}}/capture \ -u "<>:" ``` capture の呼び出しが成功すると、PaymentIntent のステータスが `succeeded` になります。 連結アカウントに対して取得されたプラットフォーム手数料が正確であることを確認するために、支払いを手動で確定させる前に各 PaymentIntent を確認し、必要に応じてプラットフォーム手数料を修正してください。 > 2 日以内に `PaymentIntents` を手動でキャプチャーする必要があり、キャプチャーしなければオーソリは期限切れになり、売上は顧客にリリースされます。 ### チップを徴収する (アメリカのみ) アメリカでは、対象となるユーザーは[売上確定時に領収書でチップを受け取る](https://docs.stripe.com/terminal/features/collecting-tips/on-receipt.md)ことができます。 ## リーダーの状態を確認する リーダーがアクションを完了したことを確認するには、新しいリーダーのアクションを開始したり支払いのキャプチャーに進む前に、アプリケーションでリーダーの状態を確認する必要があります。ほとんどの場合、この確認によって支払いの成功 (承認) を確認し、取引を完了するための操作画面をオペレーターに表示できるようになります。支払い拒否などの[エラーの処理](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=api#handle-errors)が必要になる場合もあります。 以下のいずれかを使用して、リーダーのステータスを確認します。 - [Webhook をリッスンする](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#webhooks) - [Stripe API をポーリングする](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#stripe-api) - [PaymentIntent を使用する](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#payment-intent) - [Reader オブジェクトを使用する](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#reader-object) #### Webhook をリッスンする (推奨) 回復力を最大限に高めるために、アプリケーションで Stripe からの [Webhook](https://docs.stripe.com/webhooks.md) をリッスンし、リーダーのステータスに関するリアルタイムの通知を受け取ることをお勧めします。Stripe は以下の 3 つの Webhook でリーダーのアクションのステータスをアプリケーションに通知します。 | ステータス | 説明 | | ---------------------------------------- | -------------------------------------------------------------------------------------- | | `terminal.reader.action_succeeded` | 支払いが正常にオーソリされた場合など、リーダーのアクションが成功したときに送信されます。 | | `terminal.reader.action_failed` | 残高不足によりカードが拒否された場合など、リーダーのアクションが失敗したときに送信されます。 | | `terminal.reader.action_updated` (プレビュー) | 支払い方法が収集されたときなど、リーダーのアクションが更新されたときに送信されます (`collect_payment_method` アクションでのみトリガーされます)。 | これらの Webhook をリッスンするには、[Webhook](https://docs.stripe.com/webhooks.md) エンドポイントを作成します。これらのイベントは優先度が高く、重要な決済パスに含まれるため、専用の Webhook エンドポイントを設定することをお勧めします。 ```curl curl https://api.stripe.com/v1/webhook_endpoints \ -u "<>:" \ -d "enabled_events[]"="terminal.reader.action_succeeded" \ -d "enabled_events[]"="terminal.reader.action_failed" \ --data-urlencode url="https://example.com/my/webhook/endpoint" ``` #### Stripe API をポーリングする Webhook の配信に問題が発生した場合に備え、必要に応じてオペレーターが呼び出せる POS インターフェイスに`check status`のボタンを追加して、Stripe API をポーリングできます。 #### PaymentIntent を使用する 処理を求めてリーダーに渡した PaymentIntent を取得できます。PaymentIntent 作成時の初期ステータスは `requires_payment_method` です。支払い方法が正常に収集されると、ステータスは `requires_confirmation` に更新されます。支払いが正常に処理されると、ステータスは `requires_capture` に更新されます。 ```curl curl https://api.stripe.com/v1/payment_intents/{{PAYMENTINTENT_ID}} \ -u "<>:" ``` #### Reader オブジェクトを使用する リーダーが受信した最新の操作とそのステータスを示す [action](https://docs.stripe.com/api/terminal/readers/object.md#terminal_reader_object-action) 属性を含む、[Reader (リーダー)](https://docs.stripe.com/api/terminal/readers/object.md) オブジェクトを使用できます。アプリケーションは[リーダーを取得](https://docs.stripe.com/api/terminal/readers/retrieve.md)して、リーダーの操作の[ステータス](https://docs.stripe.com/api/terminal/readers/object.md#terminal_reader_object-action-status)が変更されていないかを確認できます。 ```curl curl https://api.stripe.com/v1/terminal/readers/{{TERMINALREADER_ID}} \ -u "<>:" ``` Reader オブジェクトは、支払い処理ステップへのレスポンスとしても返されます。支払いを処理する際の、`action` タイプは `process_payment_intent` です。 支払いが成功すると、`action.status` は `succeeded` に更新されます。これにより取引の完了に進めることになります。その他の `action.status` には、`failed` や `in_progress` があります。 ## エラーを処理する 以下のエラーは、アプリケーションが処理する必要がある一般的なタイプです。 - [二重支払いの防止](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#avoiding-double-charges) - [支払いの失敗](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#payment-failures) - [支払いのタイムアウト](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#payment-timeout) - [支払いのキャンセル](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#payment-cancellation) - [リーダーがビジー状態](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#reader-busy) - [リーダーのタイムアウト](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#reader-timeout) - [リーダーがオフライン](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#reader-offline) - [Webhook の欠落](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#missing-webhooks) - [Webhook の遅延](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#delayed-webhooks) ### 二重支払いの防止 PaymentIntent オブジェクトは、Stripe での資金移動を可能にします。単一の PaymentIntent を使用して 1 つの取引を表します。 カードが (残高不足などのために) 拒否された後、同じ PaymentIntent を再利用して、顧客が別のカードで再試行できるようにします。 PaymentIntent を編集する場合、[process_payment_intent](https://docs.stripe.com/api/terminal/readers/process_payment_intent.md) を呼び出してリーダーの支払い情報を更新する必要があります。 Stripe で PaymentIntent を処理できるようにするには、ステータスが `requires_payment_method` である必要があります。オーソリ済み、キャプチャー済み、キャンセル済みの PaymentIntent をリーダーによって処理することはできず、`intent_invalid_state` エラーが返されます。 ```curl curl https://api.stripe.com/v1/terminal/readers/{{TERMINALREADER_ID}}/process_payment_intent \ -u "<>:" \ -d payment_intent="{{PAYMENTINTENT_ID}}" ``` ```json { "error": { "code": "intent_invalid_state", "doc_url": "https://docs.stripe.com/error-codes#intent-invalid-state", "message": "Payment intent must be in the requires_payment_method state to be processed by a reader.", "type": "invalid_request_error" } } ``` ### 支払いの失敗 最も一般的な支払いの失敗は支払いのオーソリの失敗です (残高不足により顧客の銀行から支払いが拒否されるなど)。 支払いのオーソリに失敗すると、Stripe は `terminal.reader.action_failed` Webhook を送信します。[action.failure_code](https://docs.stripe.com/api/terminal/readers/object.md#terminal_reader_object-action-failure_code) 属性と [action.failure_message](https://docs.stripe.com/api/terminal/readers/object.md#terminal_reader_object-action-failure_message) 属性を確認して、支払いが拒否された理由を確認します。 ```json { "id": "{{READER_ID}}", "object": "terminal.reader","action": { "failure_code": "card_declined", "failure_message": "Your card has insufficient funds.", "process_payment_intent": { "payment_intent": "{{PAYMENT_INTENT_ID}}" }, "status": "failed", "type": "process_payment_intent" }, ... } ``` カードが拒否された場合には、顧客に別の支払い方法を使用するように促します。同じ PaymentIntent を使用して、[process_payment_intent](https://docs.stripe.com/api/terminal/readers/object.md#terminal_reader_object-action-process_payment_intent) エンドポイントに別のリクエストを送信します。新しい PaymentIntent を作成する場合には、二重の支払いを避けるため、失敗した PaymentIntent を[キャンセル](https://docs.stripe.com/api/payment_intents/cancel.md)する必要があります。 カードの読み取りエラー (チップの読み取りエラーなど) が発生すると、顧客に再試行を促すメッセージがリーダーに自動的に表示されます。このとき、アプリケーションに通知は送られません。再試行が複数回失敗した場合、[process_payment_intent](https://docs.stripe.com/api/terminal/readers/object.md#terminal_reader_object-action-process_payment_intent) リクエストをもう一度行うことで、別の支払い方法を使用するように求めることができます。 ### 支払いのタイムアウト インターネット接続の信頼性が低いリーダーは、カードのオーソリ時のネットワーキングリクエストのタイムアウトが原因で支払いの処理が失敗する場合があります。リーダーでは、処理画面が数秒間にわたって表示された後、失敗の画面が表示され、`failure_code` が `connection_error` の `terminal.reader.action_failed` Webhook を受信します。 ```json { "id": "{{READER_ID}}", "object": "terminal.reader","action": { "failure_code": "connection_error", "failure_message": "Could not connect to Stripe.", "process_payment_intent": { "payment_intent": "{{PAYMENT_INTENT_ID}}" }, "status": "failed", "type": "process_payment_intent" }, ... } ``` 支払い確認リクエストが Stripe のバックエンドシステムで処理されていても、リーダーが Stripe からレスポンスを受信する前に切断されていることがあります。この失敗コードが設定された Webhook を受信した場合、PaymentIntent の `status` を取得して、支払いが正常にオーソリされたかどうかを確認します。 タイムアウトを最小限に抑えるには、ネットワークが Stripe の[ネットワーク要件](https://docs.stripe.com/terminal/network-requirements.md)を満たしていることを確認してください。 ### 決済のキャンセル #### プログラムによるキャンセル 処理中の支払いのキャンセルが必要になることがあります。たとえば、実装でリーダーの支払いの回収をすでに開始した後、顧客が購入アイテムを追加する場合などです。その場合は、[cancel_action](https://docs.stripe.com/api/terminal/readers/object.md#terminal_reader_object-action-cancel_action) エンドポイントを使用してリーダーをリセットします。 ```curl curl -X POST https://api.stripe.com/v1/terminal/readers/{{TERMINALREADER_ID}}/cancel_action \ -u "<>:" ``` > 支払いのオーソリの途中で支払いをキャンセルすることはできません。顧客がすでにリーダーで支払うカードを提示している場合、処理が完了するまで待機する必要があります。通常、オーソリは数秒で完了します。オーソリ中に [cancel_action](https://docs.stripe.com/api/terminal/readers/object.md#terminal_reader_object-action-cancel_action) を呼び出すと、`terminal_reader_busy` エラーが発生します。 #### 顧客によるキャンセル ユーザーは、以下のエンドポイントに `enable_customer_cancellation` の値を設定できます。 - [process_payment_intent](https://docs.stripe.com/api/terminal/readers/process_payment_intent.md) - [process_setup_intent](https://docs.stripe.com/api/terminal/readers/process_setup_intent.md) - [collect_payment_method](https://docs.stripe.com/api/terminal/readers/collect_payment_method.md) - [refund_payment](https://docs.stripe.com/api/terminal/readers/refund_payment.md) ```curl curl https://api.stripe.com/v1/terminal/readers/{{TERMINALREADER_ID}}/process_payment_intent \ -u "<>:" \ -d payment_intent="{{PAYMENTINTENT_ID}}" \ -d "process_config[enable_customer_cancellation]"=true ``` true に設定すると、スマートリーダーのユーザーにはキャンセルボタンが表示されます。 ![顧客のキャンセルボタンが表示された支払い回収画面](https://b.stripecdn.com/docs-statics-srv/assets/customer-cancellation-light-mode.c9ff8361795a2bf4d9e307eee8669775.png) キャンセルが有効になった支払いの回収 キャンセルボタンをタップすると、アクティブな取引がキャンセルされます。Stripe は failure_code を `customer_canceled` として `terminal.reader.action_failed` Webhook を送信します。 ```json { "action": { "failure_code": "customer_canceled", "failure_message": "This action could not be completed due to an error on the card reader.", "process_payment_intent": { "payment_intent": "{{PAYMENT_INTENT_ID}}", "process_config": { "enable_customer_cancellation": true } }, "status": "failed", "type": "process_payment_intent" } } ``` ### リーダーがビジー状態 リーダーが一度に処理できる支払いは 1 件のみです。決済処理中に新しい支払いを試行すると、`terminal_reader_busy` エラーで失敗します。 ```curl curl https://api.stripe.com/v1/terminal/readers/{{TERMINALREADER_ID}}/process_payment_intent \ -u "<>:" \ -d payment_intent="{{PAYMENTINTENT_ID}}" ``` ```json { "error": { "code": "terminal_reader_busy", "doc_url": "https://docs.stripe.com/error-codes#terminal-reader-timeout", "message": "Reader is currently busy processing another request. Please reference the integration guide at https://stripe.com/docs/terminal/payments/collect-card-payment?terminal-sdk-platform=server-driven#handle-errors for details on how to handle this error.", "type": "invalid_request_error" } } ``` 処理が開始されていない支払いは、新しい支払いに置き換えることができます。 リーダーは、更新の実行、設定の変更、または前の取引からクレジットカードが挿入されたときにも API リクエストを拒否します。 ### リーダーのタイムアウト 稀なケースとして、一時的なネットワークの問題が原因で、リーダーが時間内での API リクエストへの応答に失敗する可能性があります。この場合は、`terminal_reader_timeout` エラーコードを受信します。 ```curl curl https://api.stripe.com/v1/terminal/readers/{{TERMINALREADER_ID}}/process_payment_intent \ -u "<>:" \ -d payment_intent="{{PAYMENTINTENT_ID}}" ``` ```json { "error": { "code": "terminal_reader_timeout", "doc_url": "https://docs.stripe.com/error-codes#terminal-reader-timeout", "message": "There was a timeout when sending this command to the reader. Please reference the integration guide at https://stripe.com/docs/terminal/payments/collect-card-payment?terminal-sdk-platform=server-driven#handle-errors for details on how to handle this error.", "type": "invalid_request_error" } } ``` この場合は、API リクエストを再試行することをお勧めします。タイムアウトを最小限に抑えるには、ネットワークが Stripe の[ネットワーク要件](https://docs.stripe.com/terminal/network-requirements.md)を満たしていることを確認してください。 稀に、`terminal_reader_timeout` エラーコードが偽陰性になります。このシナリオでは、上記のように `terminal_reader_timeout` エラーを API から受け取りますが、リーダーは実際にはコマンドを正常に受信しています。偽陰性が起こるのは、Stripe がメッセージをリーダーに送信しても、一時的なネットワーキング障害が原因でリーダーから確認を受信していない場合です。 ### リーダーがオフライン状態 設置場所でのインターネット接続が失われ、リーダーと Stripe の間の通信が切断されることがあります。このようなケースでは、リーダーは、POS アプリケーションとバックエンドインフラから開始されたイベントに応答しません。 リーダーが API リクエストへの応答に一貫して失敗する場合は、電源が入っていない (電源コードが外れている、バッテリーが切れているなど) か、インターネットに正しく接続されていない可能性があります。 Stripe でリーダーからの信号の受信が 2 分間にわたり途切れている場合、そのリーダーはオフラインと見なされます。オフライン状態のリーダーで API メソッドを呼び出そうとすると、`terminal_reader_offline` エラーコードが返されます。 ```json { "error": { "code": "terminal_reader_offline", "doc_url": "https://docs.stripe.com/error-codes#terminal-reader-offline", "message": "Reader is currently offline, please ensure the reader is powered on and connected to the internet before retrying your request. Reference the integration guide at https://docs.stripe.com/terminal/payments/collect-card-payment?terminal-sdk-platform=server-driven#reader-offline for details on how to handle this error.", "type": "invalid_request_error" } } ``` [ネットワーク要件](https://docs.stripe.com/terminal/network-requirements.md)を参照して、リーダーがインターネットに正しく接続されていることを確認します。 ### Webhook の欠落 リーダーが支払いの途中で連結が解除された場合は、API でアクションのステータスを更新することはできません。このシナリオでは、リーダーは、カードが提示された後にエラー画面を表示します。ただし、API の Reader オブジェクトは、デバイスの失敗を反映する更新は行われず、リーダーのアクションの Webhook も受け取りません。この状況では、リーダーはアクションのステータス `in_progress` のままになる場合があり、レジ係は [cancel_action](https://docs.stripe.com/api/terminal/readers/object.md#terminal_reader_object-action-cancel_action) エンドポイントを呼び出してリーダーのステータスをリセットする必要があります。 ### Webhook の遅延 稀なケースではありますが、Stripe で障害が発生している場合、リーダーのアクションの Webhook が遅延することがあります。Reader または PaymentIntent オブジェクトのステータスをクエリすると、最新のステータスを確認することができます。 ## Webhook イベント | Webhook | 説明 | | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `terminal.reader.action_succeeded` | 非同期アクションが成功したときに送信されます。`process_payment_intent`、`confirm_payment_intent`、`process_setup_intent`、`refund_payment` など、カードの提示が必要なアクションに対して送信されます。 | | `terminal.reader.action_failed` | 非同期アクションが失敗したときに送信されます。`process_payment_intent`、`process_setup_intent`、`refund_payment` など、カードの提示が必要なアクションに対して送信されます。`set_reader_display` と `cancel_action` アクションには Webhook は送信されません。システムで[これらのエラーを処理](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#handle-errors)する必要があります。 | | `terminal.reader.action_updated` | 非同期アクションが更新されたときに送信されます。`collect_payment_method` などのアクションに対して送信されます。 | # JavaScript > This is a JavaScript for when terminal-sdk-platform is js. View the full page at https://docs.stripe.com/terminal/payments/collect-card-payment?terminal-sdk-platform=js. > #### スマートリーダーの推奨事項 > > [BBPOS WisePOS E リーダー](https://docs.stripe.com/terminal/payments/setup-reader/bbpos-wisepos-e.md)、[Stripe Reader S700/S710](https://docs.stripe.com/terminal/readers/stripe-reader-s700-s710.md)、[Verifone リーダー](https://docs.stripe.com/terminal/payments/setup-reader/verifone.md)などのスマートリーダーでは、JavaScript SDK ではなく[サーバー主導の実装](https://docs.stripe.com/terminal/payments/setup-integration.md?terminal-sdk-platform=server-driven)を使用することをお勧めします。 > > JavaScript SDK では、POS とリーダーが、有効なローカル DNS と同じローカルネットワーク上にある必要があります。サーバー主導型の統合では、代わりに Stripe API を使用するため、複雑なネットワーク環境ではよりシンプルになります。ニーズに最適なプラットフォームの選択に役立つ[プラットフォーム比較](https://docs.stripe.com/terminal/payments/setup-reader.md#sdk)をご覧ください。 Payment Intents API を初めて使用する場合には、以下のリソースが役立ちます。 - [Payment Intents API](https://docs.stripe.com/payments/payment-intents.md) - [PaymentIntent (支払いインテント) オブジェクト](https://docs.stripe.com/api/payment_intents.md) - [その他の支払いシナリオ](https://docs.stripe.com/payments/more-payment-scenarios.md) Stripe Terminal で支払いを回収するには、アプリケーションに決済フローを記述する必要があります。Stripe Terminal SDK を使用して、1 つの支払いセッションを表すオブジェクトである [PaymentIntent (支払いインテント)](https://docs.stripe.com/api.md#payment_intents) を作成して更新します。 Terminal の組み込みは支払いプロセスにおける失敗に対応できるように設計されており、支払いプロセスを複数のステップに分割し、各ステップを安全に再試行できるようになっています。 1. [PaymentIntent を作成](https://docs.stripe.com/terminal/payments/collect-card-payment.md#create-payment)します。 1. [決済手段を収集する](https://docs.stripe.com/terminal/payments/collect-card-payment.md#collect-payment)支払いを[自動](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-capture_method)と[手動](https://docs.stripe.com/payments/place-a-hold-on-a-payment-method.md)のどちらでキャプチャーするかを定義できます。 1. [決済を処理](https://docs.stripe.com/terminal/payments/collect-card-payment.md#confirm-payment)します。顧客のカードの承認は、SDK が決済を処理するときに行われます。 1. (オプション) [支払いをキャプチャーする](https://docs.stripe.com/terminal/payments/collect-card-payment.md#capture-payment) > この統合形態は[オフラインカード決済](https://docs.stripe.com/terminal/features/operate-offline/collect-card-payments.md)をサポートしていません。 ## PaymentIntent を作成する [サーバー側] 支払いを回収する最初のステップは、支払いフローを開始することです。顧客がチェックアウトを開始するとき、アプリケーションは `PaymentIntent` オブジェクトを作成する必要があります。これは、Stripe での新しい支払いセッションを表します。 [テスト金額](https://docs.stripe.com/terminal/references/testing.md#physical-test-cards)を使用して、さまざまな結果を生成してみてください。`00` で終わる金額では、支払いが承認されます。 > #### 拒否されたカードの PaymentIntents を再作成しない > > クレジットカードが拒否された場合は、決済インテントを再作成しないでください。代わりに、同じ決済インテントを再利用して、[二重請求を回避](https://docs.stripe.com/terminal/payments/collect-card-payment.md#avoiding-double-charges)します。 次の例は、サーバで `PaymentIntent` を作成する方法を示しています。 #### curl ```bash curl https://api.stripe.com/v1/payment_intents \ -u <>: \ -d "amount"=1000 \ -d "currency"="usd" \ -d "payment_method_types[]"="card_present" \ -d "capture_method"="manual" ``` Terminal の支払いでは、`payment_method_types` パラメータに `card_present` が含まれている必要があります。 以下のように決済フローを制御できます。 - `card_present` 支払いの支払いフローを完全に制御するには、`capture_method` を `manual` に設定します。これにより、支払いを確定する前に照合ステップを追加できます。 - 1 ステップで支払いのオーソリとキャプチャーを行うには、`capture_method` を `automatic` に設定します。 カナダで Interac の支払いを受け入れるには、`payment_method_types` に `interac_present` も含める必要があります。詳細については、[カナダのドキュメント](https://docs.stripe.com/terminal/payments/regional.md?integration-country=CA)をご覧ください。 `PaymentIntent` には、個々の `PaymentIntent` に固有のキーである [client secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) が含まれています。client secret を使用するには、これをサーバーで `PaymentIntent` から取得し、[クライアント側に渡す](https://docs.stripe.com/payments/payment-intents.md#passing-to-client)必要があります。 #### Ruby ```ruby post '/create_payment_intent' do intent = # ... Create or retrieve the PaymentIntent {client_secret: intent.client_secret}.to_json end ``` [collectPaymentMethod](https://docs.stripe.com/terminal/references/api/js-sdk.md#collect-payment-method) を呼び出す際に、client secret をパラメーターとして使用します。 決済手段の収集に進むためにクライアント側アプリケーションで必要なものは、`client_secret` だけです。 ## 支払い方法を収集する [クライアント側] - [collectPaymentMethod (JavaScript)](https://docs.stripe.com/terminal/references/api/js-sdk.md#collect-payment-method) `PaymentIntent` を作成したら、次のステップは SDK で決済手段を収集することです。 決済手段を収集するには、アプリがリーダーに接続されている必要があります。アプリが `collectPaymentMethod` を呼び出した後、接続されたリーダーはカードの提示を待ちます。 ```javascript async () => { // clientSecret is the client_secret from the PaymentIntent you created in Step 1. const result = await terminal.collectPaymentMethod(clientSecret); if (result.error) { // Placeholder for handling result.error } else { // Placeholder for processing result.paymentIntent } } ``` この方法では、接続されたカードリーダーを使用して暗号化された決済手段のデータを収集し、その暗号化されたデータをローカルの `PaymentIntent` に関連付けます。 ### 支払い方法の詳細をオプションで調査する - [collectPaymentMethod config_override (JavaScript)](https://docs.stripe.com/terminal/references/api/js-sdk.md#collect-payment-method) 高度なユースケースでは、提示されたカードの支払い方法の詳細を調査し、オーソリ前に自社のビジネスロジックを実行できます。 `update_payment_intent` パラメーターを使用して、`PaymentMethod` をサーバー側の `PaymentIntent` に関連付けます。このデータは `collectPaymentMethod` レスポンスで返されます。 ```javascript async () => { // clientSecret is the client_secret from the PaymentIntent you created in Step 1. const result = await terminal.collectPaymentMethod(clientSecret, { config_override: { update_payment_intent: true } }); if (result.error) { // Placeholder for handling result.error } else { const pm = result.paymentIntent.payment_method const card = pm?.card_present ?? pm?.interac_present // Placeholder for business logic on card before processing result.paymentIntent } } ``` このメソッドは、収集された暗号化された決済手段データを `PaymentIntent` オブジェクトの更新に関連付けます。 [決済を処理](https://docs.stripe.com/terminal/payments/collect-card-payment.md#confirm-payment)するまでオーソリは必要ありません。この高度なユースケースは Verifone P400 ではサポートされていません。 決済手段を収集したら、30 秒以内に支払いを承認するか、収集をキャンセルする必要があります。 SDK が[オフラインで実行](https://docs.stripe.com/terminal/features/operate-offline/collect-card-payments.md)されている場合、`PaymentIntent` オブジェクトには `paymentMethod` フィールドがありません。 この時点で、カードブランド、口座情報、その他の役立つデータなどの属性にアクセスできます。 Stripe は `wallet.type` 属性で示すとおり、取引でモバイルウォレットが使用されたかどうかを検出するよう試みます。ただし、カード発行会社がモバイルウォレットのリーダーによる識別に対応していない場合、この属性は自動入力されないため、正確な検出は保証されません。[確定](https://docs.stripe.com/terminal/payments/collect-card-payment.md#confirm-payment)ステップでオーソリが行われた後に、Stripe はネットワークから最新の情報を取得し、`wallet.type` を確実に更新します。 ### 収集をキャンセルする #### プログラムによるキャンセル JavaScript SDK で [cancelCollectPaymentMethod](https://docs.stripe.com/terminal/references/api/js-sdk.md#cancel-collect-payment-method) を呼び出すと、決済手段の収集をキャンセルできます。 #### 顧客によるキャンセル - [enable_customer_cancellation (JavaScript)](https://docs.stripe.com/terminal/references/api/js-sdk.md#collect-payment-method) 取引の `enable_customer_cancellation` を true に設定すると、スマートリーダーのユーザーにキャンセルボタンが表示されます。 キャンセルボタンをタップすると、現在の取引がキャンセルされます。 ```javascript terminal.collectPaymentMethod( clientSecret, { config_override: {enable_customer_cancellation: true } } ) ``` ### イベントを処理する > JavaScript SDK は、ディスプレイが内蔵されている Verifone P400、BBPOS WisePOS E、Stripe Reader S700/S710 のみをサポートします。リーダーが決済手段の回収プロセスのイベントをユーザーに表示するため、アプリケーションが決済手段のイベントを表示する必要はありません。取引の決済手段を消去するには、レジ係がキャンセル (❌) キーを押します。 ## 支払いを確定する [クライアント側] - [processPayment (JavaScript)](https://docs.stripe.com/terminal/references/api/js-sdk.md#process-payment) 顧客から決済手段を収集したら、次のステップに進み、SDK で支払いを処理します。支払いを続行する準備ができたら、[ステップ 2](https://docs.stripe.com/terminal/payments/collect-card-payment.md#collect-payment) の更新後の `PaymentIntent` を使用して `processPayment` を呼び出します。 - 支払いの手動キャプチャーでは、`processPayment` コールが成功すると、`PaymentIntent` のステータスが `requires_capture` になります。 - 支払いの自動キャプチャーでは、`PaymentIntent` は `succeeded` 状態に移行します。 クライアント側で必ず Terminal SDK を使用して PaymentIntents を確定してください。サーバー側での確定では PIN プロンプトなどの重要なメッセージが無視されるため、取引の失敗につながる可能性があります。 ```javascript async () => { const result = await terminal.processPayment(paymentIntent); if (result.error) { // Placeholder for handling result.error } else if (result.paymentIntent) { // Placeholder for notifying your backend to capture result.paymentIntent.id } } ``` 2 日以内に PaymentIntent を手動でキャプチャーする必要があり、キャプチャーしなければオーソリは期限切れになり、売上は顧客にリリースされます。 ### 失敗に対処する - [Error codes (JavaScript)](https://docs.stripe.com/terminal/references/api/js-sdk.md#error-codes) 決済の処理に失敗すると、SDK は更新された `PaymentIntent` を含むエラーを返します。アプリケーションは `PaymentIntent` を調べて、エラーへの対処方法を決定する必要があります。 | PaymentIntent のステータス | 意味 | 解決策 | | -------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------ | | `requires_payment_method` | 支払い方法が拒否されました | 同じ `PaymentIntent` を使用して `collectPaymentMethod` を再度呼び出し、別の決済手段の収集を試みます。 | | `requires_confirmation` | 一時的な接続の問題 | 同じ `PaymentIntent` を使用して `processPayment` を再度呼び出し、リクエストを再試行します。 | | `PaymentIntent` が `nil` です | Stripe へのリクエストがタイムアウトし、`PaymentIntent` のステータスが不明です | 元の `PaymentIntent` の処理を再試行します。新しく作成しないでください。新しく作成すると、カード会員に複数の承認が発生する可能性があります。 | タイムアウトが複数回、連続して発生する場合、接続に問題がある可能性があります。アプリがインターネットと通信できることを確認してください。 ### 二重支払いの防止 `PaymentIntent` オブジェクトは、Stripe での資金移動を可能にします。1 つの取引を表すには、`PaymentIntent` を 1 つ使用します。 カードが (残高不足などのために) 拒否された後、同じ `PaymentIntent` を再利用して、顧客が別のカードで再試行できるようにします。 `PaymentIntent` を編集する場合は、`collectPaymentMethod` を呼び出してリーダー上の決済情報を更新する必要があります。 `PaymentIntent` は、Stripe で処理する前に `requires_payment_method` ステータスである必要があります。承認済み、キャプチャー済み、キャンセル済みの `PaymentIntent` はリーダーで処理できません。 ## 支払いをキャプチャーする [サーバー側] [ステップ 1](https://docs.stripe.com/terminal/payments/collect-card-payment.md#create-payment) の `PaymentIntent` の作成時に `capture_method` を `manual` として定義した場合、SDK はオーソリ済みでキャプチャーはされていない `PaymentIntent` をアプリケーションに返します。[オーソリとキャプチャー](https://docs.stripe.com/payments/place-a-hold-on-a-payment-method.md)の違いについて、詳細を確認してください。 アプリが SDK から確定済みの `PaymentIntent` を受信したら、その支払いをキャプチャーするようにアプリからバックエンドに対して通知するようにしてください。バックエンドにエンドポイントを作成し、`PaymentIntent` ID を受け付け、それをキャプチャーするように Stripe API にリクエストを送信します。 ```curl curl -X POST https://api.stripe.com/v1/payment_intents/{{PAYMENT_INTENT_ID}}/capture \ -u "<>:" ``` `capture` コールが成功すると、`PaymentIntent` のステータスは `succeeded` になります。 キャプチャーされたプラットフォーム手数料が連結アカウントに対して正確であることを確認するために、支払いを手動でキャプチャーする前にそれぞれの `PaymentIntent` を調べ、必要に応じてプラットフォーム手数料を修正します。 ### 支払いを照合する ビジネスの支払いアクティビティを監視するため、毎日の最後の作業としてサーバで PaymentIntent と内部注文システムを照合することをお勧めします。 `PaymentIntent` のステータスが `requires_capture` のままの場合には、以下の 2 つの可能性があります。 **顧客のカード明細上の不要なオーソリ** - 原因: ユーザーが取引の途中でアプリの決済フローを中止した - 解決策:キャプチャーされていない `PaymentIntent` が、サーバーにある完了済みの注文に関連付けられていない場合には、[キャンセル](https://docs.stripe.com/api/payment_intents/cancel.md)できます。キャンセルされた `PaymentIntent` を使用して支払いを実行することはできません。 **顧客からの売上回収が未完了** - 原因: 支払いをキャプチャーするようにバックエンドに通知する、アプリからのリクエストのエラー - 解決策:キャプチャーされていない `PaymentIntent` が、サーバにある完了済みの注文に関連付けられており、その注文について他の支払い (現金による支払いなど) を受けていない場合には、この PaymentIntent を[キャプチャー](https://docs.stripe.com/api/payment_intents/capture.md)できます。 ### チップを徴収する (アメリカのみ) アメリカでは、対象となるユーザーは[売上確定時に領収書でチップを受け取る](https://docs.stripe.com/terminal/features/collecting-tips/on-receipt.md)ことができます。 # iOS > This is a iOS for when terminal-sdk-platform is ios. View the full page at https://docs.stripe.com/terminal/payments/collect-card-payment?terminal-sdk-platform=ios. Payment Intents API を初めて使用する場合には、以下のリソースが役立ちます。 - [Payment Intents API](https://docs.stripe.com/payments/payment-intents.md) - [PaymentIntent (支払いインテント) オブジェクト](https://docs.stripe.com/api/payment_intents.md) - [その他の支払いシナリオ](https://docs.stripe.com/payments/more-payment-scenarios.md) Stripe Terminal で支払いを回収するには、アプリケーションに決済フローを記述する必要があります。Stripe Terminal SDK を使用して、1 つの支払いセッションを表すオブジェクトである [PaymentIntent (支払いインテント)](https://docs.stripe.com/api.md#payment_intents) を作成して更新します。 Terminal の組み込みは支払いプロセスにおける失敗に対応できるように設計されており、支払いプロセスを複数のステップに分割し、各ステップを安全に再試行できるようになっています。 1. [PaymentIntent を作成](https://docs.stripe.com/terminal/payments/collect-card-payment.md#create-payment)します。 1. [決済を処理](https://docs.stripe.com/terminal/payments/collect-card-payment.md#process-payment)します。顧客のカードの承認は、SDK が決済を処理するときに行われます。 1. (オプション) [支払いをキャプチャーする](https://docs.stripe.com/terminal/payments/collect-card-payment.md#capture-payment) ## PaymentIntent を作成する [クライアント側] [サーバー側] 支払いを回収する最初のステップは、支払いフローを開始することです。顧客がチェックアウトを開始するとき、アプリケーションは `PaymentIntent` オブジェクトを作成する必要があります。これは、Stripe での新しい支払いセッションを表します。 - [createPaymentIntent (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPTerminal.html#/c:objc\(cs\)SCPTerminal\(im\)createPaymentIntent:completion:) クライアント側またはサーバー側で `PaymentIntent` を作成できます。 [テスト金額](https://docs.stripe.com/terminal/references/testing.md#physical-test-cards)を使用して、さまざまな結果を生成してみてください。`00` で終わる金額では、支払いが承認されます。 > #### 拒否されたカードの PaymentIntents を再作成しない > > クレジットカードが拒否された場合は、決済インテントを再作成しないでください。代わりに、同じ決済インテントを再利用して、[二重請求を回避](https://docs.stripe.com/terminal/payments/collect-card-payment.md#avoiding-double-charges)します。 ### クライアント側 クライアントから `PaymentIntent` を作成します。 > アプリが Verifone P400 に接続されている場合は、iOS SDK から PaymentIntent を作成できません。代わりに、[サーバー側で PaymentIntent を作成](https://docs.stripe.com/terminal/payments/collect-card-payment.md#create-server-side)し、SDK の `Terminal.retrievePaymentIntent` メソッドを使用して、アプリ内に PaymentIntent を取得する必要があります。 #### Swift ```swift import UIKit import StripeTerminal class PaymentViewController: UIViewController { // ... // Action for a "Checkout" button func checkoutAction() throws { let params = try PaymentIntentParametersBuilder(amount: 1000, currency: "usd").build() Terminal.shared.createPaymentIntent(params) { createResult, createError in if let error = createError { print("createPaymentIntent failed: \(error)") } else if let paymentIntent = createResult { print("createPaymentIntent succeeded") // ... } } } // ... } ``` ### サーバー側 支払いの開始に必要な情報がアプリですぐに利用できない場合は、サーバで `PaymentIntent` を作成することができます。 次の例は、サーバで `PaymentIntent` を作成する方法を示しています。 #### curl ```bash curl https://api.stripe.com/v1/payment_intents \ -u <>: \ -d "amount"=1000 \ -d "currency"="usd" \ -d "payment_method_types[]"="card_present" \ -d "capture_method"="manual" ``` Terminal の支払いでは、`payment_method_types` パラメータに `card_present` が含まれている必要があります。 以下のように決済フローを制御できます。 - `card_present` 支払いの支払いフローを完全に制御するには、`capture_method` を `manual` に設定します。これにより、支払いを確定する前に照合ステップを追加できます。 - 1 ステップで支払いのオーソリとキャプチャーを行うには、`capture_method` を `automatic` に設定します。 オーストラリアで決済を受け付けるには、`capture_method` を`automatic`または `manual_preferred` に設定する必要があります。詳細については、Stripe の[オーストラリアのドキュメント](https://docs.stripe.com/terminal/payments/regional.md?integration-country=AU)をご覧ください。カナダで Interac 支払いを受け付けるには、`payment_method_types` に `interac_present` も含める必要があります。詳細については、Stripe の[カナダのドキュメント](https://docs.stripe.com/terminal/payments/regional.md?integration-country=CA)をご覧ください。 `PaymentIntent` には、個々の `PaymentIntent` に固有のキーである [client secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) が含まれています。client secret を使用するには、これをサーバーで `PaymentIntent` から取得し、[クライアント側に渡す](https://docs.stripe.com/payments/payment-intents.md#passing-to-client)必要があります。 #### Ruby ```ruby post '/create_payment_intent' do intent = # ... Create or retrieve the PaymentIntent {client_secret: intent.client_secret}.to_json end ``` - [retrievePaymentIntent (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPTerminal.html#/c:objc\(cs\)SCPTerminal\(im\)retrievePaymentIntent:completion:) `PaymentIntent` を取得するには、client secret を使用して `retrievePaymentIntent` を呼び出します。 `PaymentIntent` を取得したら、それを使用して `processPaymentIntent` を呼び出します。 #### Swift ```swift func checkoutButtonAction() { // ... Fetch the client secret from your backend Terminal.shared.retrievePaymentIntent(clientSecret: clientSecret) { retrieveResult, retrieveError in if let error = retrieveError { print("retrievePaymentIntent failed: \(error)") } else if let paymentIntent = retrieveResult { print("retrievePaymentIntent succeeded: \(paymentIntent)") // ... } } } ``` ## 支払いを処理する [クライアント側] 顧客が提示したカードで決済を即時に処理するか、決済の処理に進む前にカード詳細を調べるかを選択できます。大半のユースケースでは、API コール数が少なく抑えられ、統合がシンプルになるため、即時に処理することをお勧めします。ただし、カードの承認前に独自のビジネスロジックを挿入する場合は、収集と確定の 2 段階のフローを使用できます。 #### 即時に処理する PaymentIntent を作成したら、次に決済を処理します。リーダーは顧客に対してカードをタップまたは挿入するように求め、その後、決済が承認されます。 - [processPaymentIntent (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPTerminal.html#/c:objc\(cs\)SCPTerminal\(im\)processPaymentIntent:delegate:completion:) 決済の処理中に、カード会員がウォレットからカードを取得するまでに数秒かかったり、決済中にオペレーターに質問したりする可能性があります。 #### Swift ```swift // Action for a "Checkout" button func checkoutAction() throws { let params = try PaymentIntentParametersBuilder(amount: 1000, currency: "usd").build() Terminal.shared.createPaymentIntent(params) { createResult, createError in if let error = createError { print("createPaymentIntent failed: \(error)") } else if let paymentIntent = createResult { print("createPaymentIntent succeeded") self.processCancelable = Terminal.shared.processPaymentIntent(paymentIntent, collectConfig: nil, confirmConfig: nil) { processResult, processError in if let error = processError { print("processPaymentIntent failed: \(error)") } else if let processedPaymentIntent = processResult { print("processPaymentIntent succeeded") // Notify your backend to capture the PaymentIntent if let stripeId = processedPaymentIntent.stripeId { APIClient.shared.capturePaymentIntent(stripeId) { captureError in if let error = captureError { print("capturePaymentIntent failed: \(error)") } else { print("capturePaymentIntent succeeded") } } } else { print("Payment processed offline"); } } } } } } ``` ### 収集をキャンセルする #### プログラムによるキャンセル - [Cancelable (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPCancelable.html) iOS SDK から返される `Cancelable` オブジェクトを使用して、PaymentIntent の処理をキャンセルできます。 #### 顧客によるキャンセル - [setCustomerCancellation (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPCollectPaymentIntentConfigurationBuilder.html#/c:objc\(cs\)SCPCollectPaymentIntentConfigurationBuilder\(im\)setCustomerCancellation) - [CustomerCancellation (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Enums/SCPCustomerCancellation.html) スマートリーダーは、デフォルトで顧客にキャンセルボタンを表示します。これを無効にするには、`customerCancellation` を `.disableIfAvailable` に設定します。 キャンセルボタンをタップすると、現在の取引がキャンセルされます。 #### Swift ```swift let collectConfig = try CollectPaymentIntentConfigurationBuilder() .setCustomerCancellation(.disableIfAvailable) // turn OFF the cancel button, ON by default .build() Terminal.shared.collectPaymentMethod(paymentIntent: paymentIntent, collectConfig: collectConfig) { intentWithPaymentMethod, attachError in } ``` ### イベントを処理する - [ReaderDisplayDelegate (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Protocols/SCPReaderDisplayDelegate.html) 内蔵ディスプレイのない [Stripe M2](https://docs.stripe.com/terminal/readers/stripe-m2.md) などのリーダーを使用して決済手段を収集する場合、決済手段収集プロセスのイベントをアプリからユーザーに表示できるようにする必要があります。これらのイベントは、ユーザーが決済を正常に収集するのに役立ちます (カードを再試行する、別のカードを試す、別の読み取り方法を使用するなど)。 取引が開始されると、SDK は `ReaderInputOptions` 値をアプリのリーダー表示ハンドラに渡し、受け入れ可能な入力の種類 (`Swipe`、`Insert`、`Tap` など) を示します。アプリの決済 UI で、これらのオプションのいずれかを使用してカードを提示することを求めるプロンプトをユーザーに表示します。 取引中に、SDK がアプリに対して、アプリのリーダー表示ハンドラに `ReaderDisplayMessage` 値を渡すことで、ユーザーに追加のプロンプト (`Retry Card` など) を表示するように要求する場合があります。これらのメッセージが決済 UI でユーザーに表示されることを確認してください。 #### Swift ```swift // MARK: MobileReaderDelegate - only needed for Bluetooth readers, this is the delegate set during connectReader func reader(_ reader: Reader, didRequestReaderInput inputOptions: ReaderInputOptions = []) { readerMessageLabel.text = Terminal.stringFromReaderInputOptions(inputOptions) } func reader(_ reader: Reader, didRequestReaderDisplayMessage displayMessage: ReaderDisplayMessage) { readerMessageLabel.text = Terminal.stringFromReaderDisplayMessage(displayMessage) } ``` ### iPhone のタッチ決済で決済を収集する アプリケーション側で決済を収集する準備ができると、Stripe iOS SDK がその画面を引き継いで収集プロセスを処理します。[process payment](https://docs.stripe.com/terminal/payments/collect-card-payment.md#process-payment) メソッドを呼び出した後、アプリケーションは実行中のままになりますが、iPhone ではカード会員に全画面のプロンプトが表示され、カードまたは NFC ベースのモバイルウォレットを提示するように求められます。カードの読み取りエラーが発生した場合は、再試行を求めるプロンプトが表示されます。提示に成功すると、成功の表示が返され、アプリケーションに制御が返されます。 ![iPhone のタッチ決済](https://b.stripecdn.com/docs-statics-srv/assets/tap-on-mobile-ios-payment-collection.50a552f2d75b8a3b92a439810cd9361d.png) 支払いの回収 - 決済を手動でキャプチャーする場合、`processPaymentIntent` 呼び出しが成功すると、`PaymentIntent` のステータスが `requires_capture` になります。 - 支払いの自動キャプチャーでは、`PaymentIntent` は `succeeded` 状態に移行します。 2 日以内に PaymentIntent を手動でキャプチャーする必要があり、キャプチャーしなければオーソリは期限切れになり、売上は顧客にリリースされます。 ### 失敗に対処する - [ConfirmPaymentIntentError (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPConfirmPaymentIntentError.html#/c:objc\(cs\)SCPConfirmPaymentIntentError\(py\)paymentIntent) 決済の処理に失敗した場合、SDK は更新された `PaymentIntent` を含むエラーを返します (Stripe によって拒否された場合)。アプリケーションでは、`PaymentIntent` を調べてエラーの対処方法を判断する必要があります。 | PaymentIntent ステータス | 意味 | 解決策 | | -------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------ | | `requires_payment_method` | 支払い方法が拒否されました | 同じ `PaymentIntent` を使用して `processPaymentIntent` を再度呼び出し、別の決済手段の収集を試みます。 | | `requires_confirmation` | 一時的な接続の問題 | 同じ `PaymentIntent` を使用して `processPaymentIntent` を再度呼び出し、リクエストを再試行します。 | | `PaymentIntent` が `nil` です | Stripe へのリクエストがタイムアウトし、`PaymentIntent` のステータスが不明です | 元の `PaymentIntent` の処理を再試行します。新しく作成しないでください。新しく作成すると、カード会員に複数の承認が発生する可能性があります。 | タイムアウトが複数回、連続して発生する場合、接続に問題がある可能性があります。アプリがインターネットと通信できることを確認してください。 ### 二重請求を避ける `PaymentIntent` オブジェクトは、Stripe での資金移動を可能にします。1 つの取引を表すには、`PaymentIntent` を 1 つ使用します。 カードが (残高不足などのために) 拒否された後、同じ `PaymentIntent` を再利用して、顧客が別のカードで再試行できるようにします。 `PaymentIntent` を編集する場合、`processPaymentIntent` を呼び出してリーダーの決済情報を更新する必要があります。 `PaymentIntent` を Stripe で処理するには、ステータスが `requires_payment_method` である必要があります。承認済み、キャプチャー済み、キャンセル済みの `PaymentIntent` をリーダーで処理することはできません。 #### 収集、検査、確認 PaymentIntent を作成したら、次に決済を処理します。リーダーは顧客に対してカードをタップまたは挿入するように求め、その後 PaymentMethod を作成します。 ## PaymentMethod を収集する - [collectPaymentMethod (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPTerminal.html#/c:objc\(cs\)SCPTerminal\(im\)collectPaymentMethod:delegate:completion:) `PaymentIntent` を作成したら、次のステップは SDK で決済手段を収集することです。 決済手段を収集するには、アプリをリーダーに接続する必要があります。アプリが `collectPaymentMethod` を呼び出した後、接続されたリーダーはカードが提示されるのを待ちます。 #### Swift ```swift import UIKit import StripeTerminal class PaymentViewController: UIViewController, ReaderDisplayDelegate { // Label for displaying messages from the card reader let readerMessageLabel = UILabel(frame: .zero) var collectCancelable: Cancelable? = nil // ... // Action for a "Checkout" button func checkoutAction() throws { let params = try PaymentIntentParametersBuilder(amount: 1000, currency: "usd").build() Terminal.shared.createPaymentIntent(params) { createResult, createError in if let error = createError { print("createPaymentIntent failed: \(error)") } else if let paymentIntent = createResult { print("createPaymentIntent succeeded") self.collectCancelable = Terminal.shared.collectPaymentMethod(paymentIntent) { collectResult, collectError in if let error = collectError { print("collectPaymentMethod failed: \(error)") } else if let paymentIntent = collectResult { print("collectPaymentMethod succeeded") // ... Confirm the payment } } } } } } // MARK: MobileReaderDelegate - only needed for mobile readers, this is the delegate set during connectReader func reader(_ reader: Reader, didRequestReaderInput inputOptions: ReaderInputOptions = []) { readerMessageLabel.text = Terminal.stringFromReaderInputOptions(inputOptions) } func reader(_ reader: Reader, didRequestReaderDisplayMessage displayMessage: ReaderDisplayMessage) { readerMessageLabel.text = Terminal.stringFromReaderDisplayMessage(displayMessage) } // MARK: ReaderDisplayDelegate func terminal(_ terminal: Terminal, didRequestReaderInput inputOptions: ReaderInputOptions = []) { readerMessageLabel.text = Terminal.stringFromReaderInputOptions(inputOptions) } func terminal(_ terminal: Terminal, didRequestReaderDisplayMessage displayMessage: ReaderDisplayMessage) { readerMessageLabel.text = Terminal.stringFromReaderDisplayMessage(displayMessage) } ``` この方法では、接続されたカードリーダーを使用して暗号化された決済手段のデータを収集し、その暗号化されたデータをローカルの `PaymentIntent` に関連付けます。 ### 支払い方法の詳細をオプションで調査する - [CollectPaymentIntentConfiguration (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPCollectPaymentIntentConfiguration.html) - [CardPresentDetails (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPCardPresentDetails.html) 高度なユースケースでは、提示されたカードの支払い方法の詳細を調査し、オーソリ前に自社のビジネスロジックを実行できます。 Use the `setUpdatePaymentIntent` setter in `CollectPaymentIntentConfigurationBuilder` to attach a `PaymentMethod` to the server-side `PaymentIntent`. This data is returned in the `collectPaymentMethod` response. #### Swift ```swift class PaymentViewController: UIViewController, ReaderDisplayDelegate { // ... // Action for a "Checkout" button func checkoutAction() throws { let params = try PaymentIntentParametersBuilder(amount: 1000, currency: "usd").build() Terminal.shared.createPaymentIntent(params) { createResult, createError in if let error = createError { print("createPaymentIntent failed: \(error)") } else if let paymentIntent = createResult { print("createPaymentIntent succeeded") let collectConfig = try CollectPaymentIntentConfigurationBuilder().setUpdatePaymentIntent(true).build() self.collectCancelable = Terminal.shared.collectPaymentMethod(paymentIntent: paymentIntent, collectConfig: collectConfig) { collectResult, collectError in if let error = collectError { print("collectPaymentMethod failed: \(error)") } else if let paymentIntent = collectResult { print("collectPaymentMethod succeeded") if let paymentMethod = paymentIntent.paymentMethod, let card = paymentMethod.cardPresent ?? paymentMethod.interacPresent { // ... Perform business logic on card } // ... Confirm the payment } } } } } } ``` このメソッドは、収集済みの暗号化された決済手段データを `PaymentIntent` オブジェクトへの更新に関連付けます。支払いを確定するまで、オーソリは必要ありません。この高度なユースケースは Verifone P400 ではサポートされていません。 決済手段収集後、30 秒以内に決済を承認またはキャンセルする必要があります。 SDK が[オフラインで実行](https://docs.stripe.com/terminal/features/operate-offline/collect-card-payments.md)されている場合、`PaymentIntent` オブジェクトには `paymentMethod` フィールドがありません。 この時点で、カードブランド、口座情報、その他の役立つデータなどの属性にアクセスできます。 Stripe は `wallet.type` 属性で示すとおり、取引でモバイルウォレットが使用されたかどうかを検出するよう試みます。ただし、カード発行会社がモバイルウォレットのリーダーによる識別に対応していない場合、この属性は自動入力されないため、正確な検出は保証されません。承認後に[決済が処理](https://docs.stripe.com/terminal/payments/collect-card-payment.md#process-payment)されると、Stripe はネットワークから最新の情報を取得し、`wallet.type` を更新します。 ### 収集をキャンセルする #### プログラムによるキャンセル - [Cancelable (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPCancelable.html) iOS SDK から返される `Cancelable` オブジェクトを使用して、支払い方法の収集をキャンセルできます。 #### 顧客によるキャンセル - [setCustomerCancellation (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPCollectPaymentIntentConfigurationBuilder.html#/c:objc\(cs\)SCPCollectPaymentIntentConfigurationBuilder\(im\)setCustomerCancellation) - [CustomerCancellation (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Enums/SCPCustomerCancellation.html) スマートリーダーは、デフォルトで顧客にキャンセルボタンを表示します。これを無効にするには、`customerCancellation` を `.disableIfAvailable` に設定します。 キャンセルボタンをタップすると、現在の取引がキャンセルされます。 #### Swift ```swift let collectConfig = try CollectPaymentIntentConfigurationBuilder() .setCustomerCancellation(.disableIfAvailable) // turn OFF the cancel button, ON by default .build() Terminal.shared.collectPaymentMethod(paymentIntent: paymentIntent, collectConfig: collectConfig) { intentWithPaymentMethod, attachError in } ``` ### イベントを処理する - [ReaderDisplayDelegate (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Protocols/SCPReaderDisplayDelegate.html) 内蔵ディスプレイのない [Stripe M2](https://docs.stripe.com/terminal/readers/stripe-m2.md) などのリーダーを使用して決済手段を収集する場合、決済手段収集プロセスのイベントをアプリからユーザーに表示できるようにする必要があります。これらのイベントは、ユーザーが決済を正常に収集するのに役立ちます (カードを再試行する、別のカードを試す、別の読み取り方法を使用するなど)。 取引が開始されると、SDK は `ReaderInputOptions` 値をアプリのリーダー表示ハンドラに渡し、受け入れ可能な入力の種類 (`Swipe`、`Insert`、`Tap` など) を示します。アプリの決済 UI で、これらのオプションのいずれかを使用してカードを提示することを求めるプロンプトをユーザーに表示します。 取引中に、SDK がアプリに対して、アプリのリーダー表示ハンドラに `ReaderDisplayMessage` 値を渡すことで、ユーザーに追加のプロンプト (`Retry Card` など) を表示するように要求する場合があります。これらのメッセージが決済 UI でユーザーに表示されることを確認してください。 #### Swift ```swift // MARK: MobileReaderDelegate - only needed for Bluetooth readers, this is the delegate set during connectReader func reader(_ reader: Reader, didRequestReaderInput inputOptions: ReaderInputOptions = []) { readerMessageLabel.text = Terminal.stringFromReaderInputOptions(inputOptions) } func reader(_ reader: Reader, didRequestReaderDisplayMessage displayMessage: ReaderDisplayMessage) { readerMessageLabel.text = Terminal.stringFromReaderDisplayMessage(displayMessage) } ``` ### iPhone のタッチ決済で決済を収集する アプリケーション側で決済を収集する準備ができると、Stripe iOS SDK がその画面を引き継いで収集プロセスを処理します。[process payment](https://docs.stripe.com/terminal/payments/collect-card-payment.md#process-payment) メソッドを呼び出した後、アプリケーションは実行中のままになりますが、iPhone ではカード会員に全画面のプロンプトが表示され、カードまたは NFC ベースのモバイルウォレットを提示するように求められます。カードの読み取りエラーが発生した場合は、再試行を求めるプロンプトが表示されます。提示に成功すると、成功の表示が返され、アプリケーションに制御が返されます。 ![iPhone のタッチ決済](https://b.stripecdn.com/docs-statics-srv/assets/tap-on-mobile-ios-payment-collection.50a552f2d75b8a3b92a439810cd9361d.png) 支払いの回収 ## PaymentIntent を確定する - [confirmPaymentIntent (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPTerminal.html#/c:objc\(cs\)SCPTerminal\(im\)confirmPaymentIntent:completion:) 顧客から決済手段を収集できたら、次のステップでは SDK で決済を確定します。決済を続行する準備ができたら、[前のステップ](https://docs.stripe.com/terminal/payments/collect-card-payment.md#collect-inspect-payment-method)からの更新後の `PaymentIntent` を使用して `confirmPaymentIntent` を呼び出します。 - 決済の手動キャプチャーでは、`confirmPaymentIntent` 呼び出しが成功すると、`PaymentIntent` のステータスが `requires_capture` になります。 - 支払いの自動キャプチャーでは、`PaymentIntent` は `succeeded` 状態に移行します。 クライアント側では常に Terminal SDK を使用して PaymentIntents を確定します。サーバー側の確定により、PIN プロンプトなどの重要なやり取りがバイパスされ、取引が失敗する可能性があります。 #### Swift ```swift // Action for a "Checkout" button func checkoutAction() throws { let params = try PaymentIntentParametersBuilder(amount: 1000, currency: "usd").build() Terminal.shared.createPaymentIntent(params) { createResult, createError in if let error = createError { print("createPaymentIntent failed: \(error)") } else if let paymentIntent = createResult { print("createPaymentIntent succeeded") self.collectCancelable = Terminal.shared.collectPaymentMethod(paymentIntent) { collectResult, collectError in if let error = collectError { print("collectPaymentMethod failed: \(error)") } else if let collectPaymentMethodPaymentIntent = collectResult { print("collectPaymentMethod succeeded") // ... Confirm the payment self.confirmCancelable = Terminal.shared.confirmPaymentIntent(collectPaymentMethodPaymentIntent) { confirmResult, confirmError in if let error = confirmError { print("confirmPaymentIntent failed: \(error)") } else if let confirmedPaymentIntent = confirmResult { print("confirmPaymentIntent succeeded") // Notify your backend to capture the PaymentIntent if let stripeId = confirmedPaymentIntent.stripeId { APIClient.shared.capturePaymentIntent(stripeId) { captureError in if let error = captureError { print("capture failed: \(error)") } else { print("capture succeeded") } } } else { print("Payment collected offline"); } } } } } } } ``` 2 日以内に PaymentIntent を手動でキャプチャーする必要があり、キャプチャーしなければオーソリは期限切れになり、売上は顧客にリリースされます。 ### 失敗に対処する - [ConfirmPaymentIntentError (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPConfirmPaymentIntentError.html#/c:objc\(cs\)SCPConfirmPaymentIntentError\(py\)paymentIntent) 決済の確定に失敗した場合、SDK は更新された `PaymentIntent` を含むエラーを返します。アプリケーションでは、`PaymentIntent` を調べてエラーの対処方法を判断する必要があります。 | PaymentIntent のステータス | 意味 | 解決策 | | -------------------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | `requires_payment_method` | 支払い方法が拒否されました | 同じ `PaymentIntent` を使用して `collectPaymentMethod` を再度呼び出し、別の決済手段の収集を試みます。 | | `requires_confirmation` | 一時的な接続の問題 | 同じ `PaymentIntent` を使用して `confirmPaymentIntent` を再度呼び出し、リクエストを再試行します。 | | `PaymentIntent` が `nil` です | Stripe へのリクエストがタイムアウトし、`PaymentIntent` のステータスが不明です | 元の `PaymentIntent` の確定を再試行します。新しい PaymentIntent を作成しないでください。新しく作成すると、カード会員に複数の承認が発生する可能性があります。 | タイムアウトが複数回、連続して発生する場合、接続に問題がある可能性があります。アプリがインターネットと通信できることを確認してください。 ### 二重請求を避ける `PaymentIntent` オブジェクトは、Stripe での資金移動を可能にします。1 つの取引を表すには、`PaymentIntent` を 1 つ使用します。 カードが (残高不足などのために) 拒否された後、同じ `PaymentIntent` を再利用して、顧客が別のカードで再試行できるようにします。 `PaymentIntent` を編集する場合、`collectPaymentMethod` を呼び出してリーダーの決済情報を更新する必要があります。 `PaymentIntent` を Stripe で確定するには、ステータスが `requires_payment_method` である必要があります。承認済み、キャプチャー済み、キャンセル済みの `PaymentIntent` をリーダーで確定することはできません。 ## 支払いをキャプチャーする [サーバー側] [ステップ 1](https://docs.stripe.com/terminal/payments/collect-card-payment.md#create-payment) の `PaymentIntent` の作成時に `capture_method` を `manual` として定義した場合、SDK はオーソリ済みでキャプチャーはされていない `PaymentIntent` をアプリケーションに返します。[オーソリとキャプチャー](https://docs.stripe.com/payments/place-a-hold-on-a-payment-method.md)の違いについて、詳細を確認してください。 アプリが SDK から確定済みの `PaymentIntent` を受信したら、その支払いをキャプチャーするようにアプリからバックエンドに対して通知するようにしてください。バックエンドにエンドポイントを作成し、`PaymentIntent` ID を受け付け、それをキャプチャーするように Stripe API にリクエストを送信します。 ```curl curl -X POST https://api.stripe.com/v1/payment_intents/{{PAYMENT_INTENT_ID}}/capture \ -u "<>:" ``` `capture` コールが成功すると、`PaymentIntent` のステータスは `succeeded` になります。 キャプチャーされたプラットフォーム手数料が連結アカウントに対して正確であることを確認するために、支払いを手動でキャプチャーする前にそれぞれの `PaymentIntent` を調べ、必要に応じてプラットフォーム手数料を修正します。 ### 支払いを照合する ビジネスの支払いアクティビティを監視するため、毎日の最後の作業としてサーバで PaymentIntent と内部注文システムを照合することをお勧めします。 `PaymentIntent` のステータスが `requires_capture` のままの場合には、以下の 2 つの可能性があります。 **顧客のカード明細上の不要なオーソリ** - 原因: ユーザーが取引の途中でアプリの決済フローを中止した - 解決策:キャプチャーされていない `PaymentIntent` が、サーバーにある完了済みの注文に関連付けられていない場合には、[キャンセル](https://docs.stripe.com/api/payment_intents/cancel.md)できます。キャンセルされた `PaymentIntent` を使用して支払いを実行することはできません。 **顧客からの売上回収が未完了** - 原因: 支払いをキャプチャーするようにバックエンドに通知する、アプリからのリクエストのエラー - 解決策:キャプチャーされていない `PaymentIntent` が、サーバにある完了済みの注文に関連付けられており、その注文について他の支払い (現金による支払いなど) を受けていない場合には、この PaymentIntent を[キャプチャー](https://docs.stripe.com/api/payment_intents/capture.md)できます。 ### チップを徴収する (アメリカのみ) アメリカでは、対象となるユーザーは[売上確定時に領収書でチップを受け取る](https://docs.stripe.com/terminal/features/collecting-tips/on-receipt.md)ことができます。 # Android > This is a Android for when terminal-sdk-platform is android. View the full page at https://docs.stripe.com/terminal/payments/collect-card-payment?terminal-sdk-platform=android. Payment Intents API を初めて使用する場合には、以下のリソースが役立ちます。 - [Payment Intents API](https://docs.stripe.com/payments/payment-intents.md) - [PaymentIntent (支払いインテント) オブジェクト](https://docs.stripe.com/api/payment_intents.md) - [その他の支払いシナリオ](https://docs.stripe.com/payments/more-payment-scenarios.md) Stripe Terminal で支払いを回収するには、アプリケーションに決済フローを記述する必要があります。Stripe Terminal SDK を使用して、1 つの支払いセッションを表すオブジェクトである [PaymentIntent (支払いインテント)](https://docs.stripe.com/api.md#payment_intents) を作成して更新します。 Terminal の組み込みは支払いプロセスにおける失敗に対応できるように設計されており、支払いプロセスを複数のステップに分割し、各ステップを安全に再試行できるようになっています。 1. [PaymentIntent を作成](https://docs.stripe.com/terminal/payments/collect-card-payment.md#create-payment)します。 1. [決済を処理](https://docs.stripe.com/terminal/payments/collect-card-payment.md#process-payment)します。顧客のカードの承認は、SDK が決済を処理するときに行われます。 1. (オプション) [支払いをキャプチャーする](https://docs.stripe.com/terminal/payments/collect-card-payment.md#capture-payment) ## PaymentIntent を作成する [クライアント側] [サーバー側] 支払いを回収する最初のステップは、支払いフローを開始することです。顧客がチェックアウトを開始するとき、アプリケーションは `PaymentIntent` オブジェクトを作成する必要があります。これは、Stripe での新しい支払いセッションを表します。 - [createPaymentIntent (Android)](https://stripe.dev/stripe-terminal-android/core/com.stripe.stripeterminal/-terminal/create-payment-intent.html) クライアント側またはサーバー側で `PaymentIntent` を作成できます。 [テスト金額](https://docs.stripe.com/terminal/references/testing.md#physical-test-cards)を使用して、さまざまな結果を生成してみてください。`00` で終わる金額では、支払いが承認されます。 > #### 拒否されたカードの PaymentIntents を再作成しない > > クレジットカードが拒否された場合は、決済インテントを再作成しないでください。代わりに、同じ決済インテントを再利用して、[二重請求を回避](https://docs.stripe.com/terminal/payments/collect-card-payment.md#avoiding-double-charges)します。 ### クライアント側 クライアントから `PaymentIntent` を作成します。 > アプリが Verifone P400 に接続されている場合は、Android SDK から PaymentIntent を作成できません。代わりに、[サーバー側で PaymentIntent を作成](https://docs.stripe.com/terminal/payments/collect-card-payment.md#create-server-side)し、SDK の `Terminal.retrievePaymentIntent` メソッドを使用して、アプリ内に PaymentIntent を取得する必要があります。 #### Kotlin ```kotlin val params = PaymentIntentParameters.Builder() .setAmount(1000) .setCurrency("usd") .build() Terminal.getInstance().createPaymentIntent( params, object : PaymentIntentCallback { override fun onSuccess(paymentIntent: PaymentIntent) { // Placeholder for handling successful operation } override fun onFailure(e: TerminalException) { // Placeholder for handling exception } } ) ``` ### サーバー側 支払いの開始に必要な情報がアプリですぐに利用できない場合は、サーバで `PaymentIntent` を作成することができます。 次の例は、サーバで `PaymentIntent` を作成する方法を示しています。 #### curl ```bash curl https://api.stripe.com/v1/payment_intents \ -u <>: \ -d "amount"=1000 \ -d "currency"="usd" \ -d "payment_method_types[]"="card_present" \ -d "capture_method"="manual" ``` Terminal の支払いでは、`payment_method_types` パラメータに `card_present` が含まれている必要があります。 以下のように決済フローを制御できます。 - `card_present` 支払いの支払いフローを完全に制御するには、`capture_method` を `manual` に設定します。これにより、支払いを確定する前に照合ステップを追加できます。 - 1 ステップで支払いのオーソリとキャプチャーを行うには、`capture_method` を `automatic` に設定します。 オーストラリアで決済を受け付けるには、`capture_method` を`automatic`または `manual_preferred` に設定する必要があります。詳細については、Stripe の[オーストラリアのドキュメント](https://docs.stripe.com/terminal/payments/regional.md?integration-country=AU)をご覧ください。カナダで Interac 支払いを受け付けるには、`payment_method_types` に `interac_present` も含める必要があります。詳細については、Stripe の[カナダのドキュメント](https://docs.stripe.com/terminal/payments/regional.md?integration-country=CA)をご覧ください。 `PaymentIntent` には、個々の `PaymentIntent` に固有のキーである [client secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) が含まれています。client secret を使用するには、これをサーバーで `PaymentIntent` から取得し、[クライアント側に渡す](https://docs.stripe.com/payments/payment-intents.md#passing-to-client)必要があります。 #### Ruby ```ruby post '/create_payment_intent' do intent = # ... Create or retrieve the PaymentIntent {client_secret: intent.client_secret}.to_json end ``` - [retrievePaymentIntent (Android)](https://stripe.dev/stripe-terminal-android/core/com.stripe.stripeterminal/-terminal/retrieve-payment-intent.html) `PaymentIntent` を取得するには、client secret を使用して `retrievePaymentIntent` を呼び出します。 `PaymentIntent` を取得したら、それを使用して `processPaymentIntent` を呼び出します。 #### Kotlin ```kotlin Terminal.getInstance().retrievePaymentIntent( clientSecret, object : PaymentIntentCallback { override fun onSuccess(paymentIntent: PaymentIntent) { // Placeholder for handling successful operation } override fun onFailure(e: TerminalException) { // Placeholder for handling exception } } ) ``` ## 支払いを処理する [クライアント側] 顧客が提示したカードで決済を即時に処理するか、決済の処理に進む前にカード詳細を調べるかを選択できます。大半のユースケースでは、API コール数が少なく抑えられ、統合がシンプルになるため、即時に処理することをお勧めします。ただし、カードの承認前に独自のビジネスロジックを挿入する場合は、収集と確定の 2 段階のフローを使用できます。 #### 即時に処理する PaymentIntent を作成したら、次に決済を処理します。リーダーは顧客に対してカードをタップまたは挿入するように求め、その後、決済が承認されます。 - [processPaymentIntent (Android)](https://stripe.dev/stripe-terminal-android/core/com.stripe.stripeterminal/-terminal/process-payment-intent.html) 決済の処理中に、カード会員がウォレットからカードを取得するまでに数秒かかったり、決済中にオペレーターに質問したりする可能性があります。 #### Kotlin ```kotlin val cancelable = Terminal.getInstance().processPaymentIntent( paymentIntent = paymentIntent, collectConfig = CollectPaymentIntentConfiguration.Builder().build(), confirmConfig = ConfirmPaymentIntentConfiguration.Builder().build(), callback = object : PaymentIntentCallback { override fun onSuccess(paymentIntent: PaymentIntent) { println("processPaymentIntent succeeded") // Notify your backend to capture the PaymentIntent if (paymentIntent.id != null) { ApiClient.capturePaymentIntent(paymentIntent.id) { error -> if (error != null) { println("capturePaymentIntent failed: $error") } else { println("capturePaymentIntent succeeded") } } } else { println("Payment collected offline") } } override fun onFailure(e: TerminalException) { println("processPaymentIntent failed: $e") } } ) ``` ### 収集をキャンセルする #### プログラムによるキャンセル - [Cancelable (Android)](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.callable/-cancelable/index.html) Android SDK から返される `Cancelable` オブジェクトを使用して、PaymentIntent の処理をキャンセルできます。 #### 顧客によるキャンセル - [setCustomerCancellation (Android)](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.models/-collect-payment-intent-configuration/-builder/set-customer-cancellation.html) - [顧客キャンセル (Android)](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.models/-customer-cancellation/index.html) スマートリーダーは、デフォルトで顧客にキャンセルボタンを表示します。これを無効にするには、`customerCancellation` を `DISABLE_IF_AVAILABLE` に設定します。 キャンセルボタンをタップすると、現在の取引がキャンセルされます。 #### Kotlin ```kotlin Terminal.getInstance().collectPaymentMethod( paymentIntent, object : PaymentIntentCallback { override fun onSuccess(paymentIntent: PaymentIntent) { // Placeholder for handling successful operation } override fun onFailure(e: TerminalException) { // Placeholder for handling exception } },CollectPaymentIntentConfiguration.Builder() .setCustomerCancellation(CustomerCancellation.DISABLE_IF_AVAILABLE) // turn OFF the cancel button, ON by default .build(), ) ``` ### イベントを処理する - [MobileReaderListener (Android)](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.callable/-mobile-reader-listener/index.html) 内蔵ディスプレイのない [Stripe M2](https://docs.stripe.com/terminal/readers/stripe-m2.md) などのリーダーを使用して決済手段を収集する場合、決済手段収集プロセスのイベントをアプリからユーザーに表示できるようにする必要があります。これらのイベントは、ユーザーが決済を正常に収集するのに役立ちます (カードを再試行する、別のカードを試す、別の読み取り方法を使用するなど)。 取引が開始されると、SDK は `ReaderInputOptions` 値をアプリのリーダー表示ハンドラに渡し、受け入れ可能な入力の種類 (`Swipe`、`Insert`、`Tap` など) を示します。アプリの決済 UI で、これらのオプションのいずれかを使用してカードを提示することを求めるプロンプトをユーザーに表示します。 取引中に、SDK がアプリに対して、アプリのリーダー表示ハンドラに `ReaderDisplayMessage` 値を渡すことで、ユーザーに追加のプロンプト (`Retry Card` など) を表示するように要求する場合があります。これらのメッセージが決済 UI でユーザーに表示されることを確認してください。 #### Kotlin ```kotlin class ReaderActivity : AppCompatActivity(), MobileReaderListener { // ... override fun onRequestReaderInput(options: ReaderInputOptions) { Toast.makeText(activity, options.toString(), Toast.LENGTH_SHORT).show() } override fun onRequestReaderDisplayMessage(message: ReaderDisplayMessage) { Toast.makeText(activity, message.toString(), Toast.LENGTH_SHORT).show() } // ... } ``` ### Android のタッチ決済で決済を収集する アプリケーション側で決済を収集する準備ができると、Stripe Android SDK がその画面を引き継いで収集プロセスを処理します。[process payment](https://docs.stripe.com/terminal/payments/collect-card-payment.md#process-payment) メソッドを呼び出した後は、アプリケーションは実行中のままになります。Android デバイスではカード会員に全画面のプロンプトが表示され、カードまたは NFC ベースのモバイルウォレットを提示するように求められます。カードの読み取りエラーが発生した場合は、再試行を求めるプロンプトが表示されます。提示に成功すると、成功の表示が返され、アプリケーションに制御が返されます。 ![Android のタッチ決済](https://b.stripecdn.com/docs-statics-srv/assets/tap-to-pay-on-android-payment-collection.1297981f07df468768e4c8286b99281b.jpeg) 支払いの回収 - 決済を手動でキャプチャーする場合、`processPaymentIntent` 呼び出しが成功すると、`PaymentIntent` のステータスが `requires_capture` になります。 - 支払いの自動キャプチャーでは、`PaymentIntent` は `succeeded` 状態に移行します。 2 日以内に PaymentIntent を手動でキャプチャーする必要があり、キャプチャーしなければオーソリは期限切れになり、売上は顧客にリリースされます。 ### 失敗に対処する - [TerminalException (Android)](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.models/-terminal-exception/index.html) 決済の処理に失敗した場合、SDK は更新された `PaymentIntent` を含むエラーを返します (Stripe によって拒否された場合)。アプリケーションでは、`PaymentIntent` を調べてエラーの対処方法を判断する必要があります。 | PaymentIntent ステータス | 意味 | 解決策 | | -------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------ | | `requires_payment_method` | 支払い方法が拒否されました | 同じ `PaymentIntent` を使用して `processPaymentIntent` を再度呼び出し、別の決済手段の収集を試みます。 | | `requires_confirmation` | 一時的な接続の問題 | 同じ `PaymentIntent` を使用して `processPaymentIntent` を再度呼び出し、リクエストを再試行します。 | | `PaymentIntent` が `nil` です | Stripe へのリクエストがタイムアウトし、`PaymentIntent` のステータスが不明です | 元の `PaymentIntent` の処理を再試行します。新しく作成しないでください。新しく作成すると、カード会員に複数の承認が発生する可能性があります。 | タイムアウトが複数回、連続して発生する場合、接続に問題がある可能性があります。アプリがインターネットと通信できることを確認してください。 ### 二重請求を避ける `PaymentIntent` オブジェクトは、Stripe での資金移動を可能にします。1 つの取引を表すには、`PaymentIntent` を 1 つ使用します。 カードが (残高不足などのために) 拒否された後、同じ `PaymentIntent` を再利用して、顧客が別のカードで再試行できるようにします。 `PaymentIntent` を編集する場合、`processPaymentIntent` を呼び出してリーダーの決済情報を更新する必要があります。 `PaymentIntent` を Stripe で処理するには、ステータスが `requires_payment_method` である必要があります。承認済み、キャプチャー済み、キャンセル済みの `PaymentIntent` をリーダーで処理することはできません。 #### 収集、検査、確認 PaymentIntent を作成したら、次に決済を処理します。リーダーは顧客に対してカードをタップまたは挿入するように求め、その後 PaymentMethod を作成します。 ## PaymentMethod を収集する - [collectPaymentMethod (Android)](https://stripe.dev/stripe-terminal-android/core/com.stripe.stripeterminal/-terminal/collect-payment-method.html) `PaymentIntent` を作成したら、次のステップは SDK で決済手段を収集することです。 決済手段を収集するには、アプリをリーダーに接続する必要があります。アプリが `collectPaymentMethod` を呼び出した後、接続されたリーダーはカードが提示されるのを待ちます。 #### Kotlin ```kotlin val cancelable = Terminal.getInstance().collectPaymentMethod( paymentIntent, object : PaymentIntentCallback { override fun onSuccess(paymentIntent: PaymentIntent) { // Placeholder for handling successful operation } override fun onFailure(e: TerminalException) { // Placeholder for handling exception } } ) ``` この方法では、接続されたカードリーダーを使用して暗号化された決済手段のデータを収集し、その暗号化されたデータをローカルの `PaymentIntent` に関連付けます。 ### 支払い方法の詳細をオプションで調査する - [CollectPaymentIntentConfiguration (Android)](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.models/-collect-payment-intent-configuration/index.html) - [CardPresentDetails (Android)](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.models/-card-present-details/index.html) 高度なユースケースでは、提示されたカードの支払い方法の詳細を調査し、オーソリ前に自社のビジネスロジックを実行できます。 Use the `updatePaymentIntent` parameter in `CollectPaymentIntentConfiguration` to attach a `PaymentMethod` to the server-side `PaymentIntent`. This data is returned in the `collectPaymentMethod` response. #### Kotlin ```kotlin val collectConfig = CollectPaymentIntentConfiguration.Builder() .updatePaymentIntent(true) .build() val cancelable = Terminal.getInstance().collectPaymentMethod(paymentIntent, object : PaymentIntentCallback { override fun onSuccess(paymentIntent: PaymentIntent) { val pm = paymentIntent.paymentMethod val card = pm?.cardPresentDetails ?: pm?.interacPresentDetails // Placeholder for business logic on card before confirming paymentIntent } override fun onFailure(e: TerminalException) { // Placeholder for handling exception } } ) ``` このメソッドは、収集済みの暗号化された決済手段データを `PaymentIntent` オブジェクトへの更新に関連付けます。支払いを確定するまで、オーソリは必要ありません。この高度なユースケースは Verifone P400 ではサポートされていません。 決済手段収集後、30 秒以内に決済を承認またはキャンセルする必要があります。 SDK が[オフラインで実行](https://docs.stripe.com/terminal/features/operate-offline/collect-card-payments.md)されている場合、`PaymentIntent` オブジェクトには `paymentMethod` フィールドがありません。 この時点で、カードブランド、口座情報、その他の役立つデータなどの属性にアクセスできます。 Stripe は `wallet.type` 属性で示すとおり、取引でモバイルウォレットが使用されたかどうかを検出するよう試みます。ただし、カード発行会社がモバイルウォレットのリーダーによる識別に対応していない場合、この属性は自動入力されないため、正確な検出は保証されません。承認後に[決済が処理](https://docs.stripe.com/terminal/payments/collect-card-payment.md#process-payment)されると、Stripe はネットワークから最新の情報を取得し、`wallet.type` を更新します。 ### 収集をキャンセルする #### プログラムによるキャンセル - [Cancelable (Android)](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.callable/-cancelable/index.html) Android SDK から返される `Cancelable` オブジェクトを使用して、支払い方法の収集をキャンセルできます。 #### 顧客によるキャンセル - [setCustomerCancellation (Android)](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.models/-collect-payment-intent-configuration/-builder/set-customer-cancellation.html) - [顧客キャンセル (Android)](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.models/-customer-cancellation/index.html) スマートリーダーは、デフォルトで顧客にキャンセルボタンを表示します。これを無効にするには、`customerCancellation` を `DISABLE_IF_AVAILABLE` に設定します。 キャンセルボタンをタップすると、現在の取引がキャンセルされます。 #### Kotlin ```kotlin Terminal.getInstance().collectPaymentMethod( paymentIntent, object : PaymentIntentCallback { override fun onSuccess(paymentIntent: PaymentIntent) { // Placeholder for handling successful operation } override fun onFailure(e: TerminalException) { // Placeholder for handling exception } },CollectPaymentIntentConfiguration.Builder() .setCustomerCancellation(CustomerCancellation.DISABLE_IF_AVAILABLE) // turn OFF the cancel button, ON by default .build(), ) ``` ### イベントを処理する - [MobileReaderListener (Android)](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.callable/-mobile-reader-listener/index.html) 内蔵ディスプレイのない [Stripe M2](https://docs.stripe.com/terminal/readers/stripe-m2.md) などのリーダーを使用して決済手段を収集する場合、決済手段収集プロセスのイベントをアプリからユーザーに表示できるようにする必要があります。これらのイベントは、ユーザーが決済を正常に収集するのに役立ちます (カードを再試行する、別のカードを試す、別の読み取り方法を使用するなど)。 取引が開始されると、SDK は `ReaderInputOptions` 値をアプリのリーダー表示ハンドラに渡し、受け入れ可能な入力の種類 (`Swipe`、`Insert`、`Tap` など) を示します。アプリの決済 UI で、これらのオプションのいずれかを使用してカードを提示することを求めるプロンプトをユーザーに表示します。 取引中に、SDK がアプリに対して、アプリのリーダー表示ハンドラに `ReaderDisplayMessage` 値を渡すことで、ユーザーに追加のプロンプト (`Retry Card` など) を表示するように要求する場合があります。これらのメッセージが決済 UI でユーザーに表示されることを確認してください。 #### Kotlin ```kotlin class ReaderActivity : AppCompatActivity(), MobileReaderListener { // ... override fun onRequestReaderInput(options: ReaderInputOptions) { Toast.makeText(activity, options.toString(), Toast.LENGTH_SHORT).show() } override fun onRequestReaderDisplayMessage(message: ReaderDisplayMessage) { Toast.makeText(activity, message.toString(), Toast.LENGTH_SHORT).show() } // ... } ``` ### Android のタッチ決済で決済を収集する アプリケーション側で決済を収集する準備ができると、Stripe Android SDK がその画面を引き継いで収集プロセスを処理します。[process payment](https://docs.stripe.com/terminal/payments/collect-card-payment.md#process-payment) メソッドを呼び出した後は、アプリケーションは実行中のままになります。Android デバイスではカード会員に全画面のプロンプトが表示され、カードまたは NFC ベースのモバイルウォレットを提示するように求められます。カードの読み取りエラーが発生した場合は、再試行を求めるプロンプトが表示されます。提示に成功すると、成功の表示が返され、アプリケーションに制御が返されます。 ![Android のタッチ決済](https://b.stripecdn.com/docs-statics-srv/assets/tap-to-pay-on-android-payment-collection.1297981f07df468768e4c8286b99281b.jpeg) 支払いの回収 ## PaymentIntent を確定する - [confirmPaymentIntent (Android)](https://stripe.dev/stripe-terminal-android/core/com.stripe.stripeterminal/-terminal/confirm-payment-intent.html) 顧客から決済手段を収集できたら、次のステップでは SDK で決済を確定します。決済を続行する準備ができたら、[前のステップ](https://docs.stripe.com/terminal/payments/collect-card-payment.md#collect-inspect-payment-method)からの更新後の `PaymentIntent` を使用して `confirmPaymentIntent` を呼び出します。 - 決済の手動キャプチャーでは、`confirmPaymentIntent` 呼び出しが成功すると、`PaymentIntent` のステータスが `requires_capture` になります。 - 支払いの自動キャプチャーでは、`PaymentIntent` は `succeeded` 状態に移行します。 クライアント側では常に Terminal SDK を使用して PaymentIntents を確定します。サーバー側の確定により、PIN プロンプトなどの重要なやり取りがバイパスされ、取引が失敗する可能性があります。 #### Kotlin ```kotlin val cancelable = Terminal.getInstance().confirmPaymentIntent( paymentIntent, object : PaymentIntentCallback { override fun onSuccess(paymentIntent: PaymentIntent) { // Placeholder handling successful operation } override fun onFailure(e: TerminalException) { // Placeholder for handling exception } } ) ``` 2 日以内に PaymentIntent を手動でキャプチャーする必要があり、キャプチャーしなければオーソリは期限切れになり、売上は顧客にリリースされます。 ### 失敗に対処する - [TerminalException (Android)](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.models/-terminal-exception/index.html) 決済の確定に失敗した場合、SDK は更新された `PaymentIntent` を含むエラーを返します。アプリケーションでは、`PaymentIntent` を調べてエラーの対処方法を判断する必要があります。 | PaymentIntent のステータス | 意味 | 解決策 | | -------------------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | `requires_payment_method` | 支払い方法が拒否されました | 同じ `PaymentIntent` を使用して `collectPaymentMethod` を再度呼び出し、別の決済手段の収集を試みます。 | | `requires_confirmation` | 一時的な接続の問題 | 同じ `PaymentIntent` を使用して `confirmPaymentIntent` を再度呼び出し、リクエストを再試行します。 | | `PaymentIntent` が `nil` です | Stripe へのリクエストがタイムアウトし、`PaymentIntent` のステータスが不明です | 元の `PaymentIntent` の確定を再試行します。新しい PaymentIntent を作成しないでください。新しく作成すると、カード会員に複数の承認が発生する可能性があります。 | タイムアウトが複数回、連続して発生する場合、接続に問題がある可能性があります。アプリがインターネットと通信できることを確認してください。 ### 二重請求を避ける `PaymentIntent` オブジェクトは、Stripe での資金移動を可能にします。1 つの取引を表すには、`PaymentIntent` を 1 つ使用します。 カードが (残高不足などのために) 拒否された後、同じ `PaymentIntent` を再利用して、顧客が別のカードで再試行できるようにします。 `PaymentIntent` を編集する場合、`collectPaymentMethod` を呼び出してリーダーの決済情報を更新する必要があります。 `PaymentIntent` を Stripe で確定するには、ステータスが `requires_payment_method` である必要があります。承認済み、キャプチャー済み、キャンセル済みの `PaymentIntent` をリーダーで確定することはできません。 ## 支払いをキャプチャーする [サーバー側] [ステップ 1](https://docs.stripe.com/terminal/payments/collect-card-payment.md#create-payment) の `PaymentIntent` の作成時に `capture_method` を `manual` として定義した場合、SDK はオーソリ済みでキャプチャーはされていない `PaymentIntent` をアプリケーションに返します。[オーソリとキャプチャー](https://docs.stripe.com/payments/place-a-hold-on-a-payment-method.md)の違いについて、詳細を確認してください。 アプリが SDK から確定済みの `PaymentIntent` を受信したら、その支払いをキャプチャーするようにアプリからバックエンドに対して通知するようにしてください。バックエンドにエンドポイントを作成し、`PaymentIntent` ID を受け付け、それをキャプチャーするように Stripe API にリクエストを送信します。 ```curl curl -X POST https://api.stripe.com/v1/payment_intents/{{PAYMENT_INTENT_ID}}/capture \ -u "<>:" ``` `capture` コールが成功すると、`PaymentIntent` のステータスは `succeeded` になります。 キャプチャーされたプラットフォーム手数料が連結アカウントに対して正確であることを確認するために、支払いを手動でキャプチャーする前にそれぞれの `PaymentIntent` を調べ、必要に応じてプラットフォーム手数料を修正します。 ### 支払いを照合する ビジネスの支払いアクティビティを監視するため、毎日の最後の作業としてサーバで PaymentIntent と内部注文システムを照合することをお勧めします。 `PaymentIntent` のステータスが `requires_capture` のままの場合には、以下の 2 つの可能性があります。 **顧客のカード明細上の不要なオーソリ** - 原因: ユーザーが取引の途中でアプリの決済フローを中止した - 解決策:キャプチャーされていない `PaymentIntent` が、サーバーにある完了済みの注文に関連付けられていない場合には、[キャンセル](https://docs.stripe.com/api/payment_intents/cancel.md)できます。キャンセルされた `PaymentIntent` を使用して支払いを実行することはできません。 **顧客からの売上回収が未完了** - 原因: 支払いをキャプチャーするようにバックエンドに通知する、アプリからのリクエストのエラー - 解決策:キャプチャーされていない `PaymentIntent` が、サーバにある完了済みの注文に関連付けられており、その注文について他の支払い (現金による支払いなど) を受けていない場合には、この PaymentIntent を[キャプチャー](https://docs.stripe.com/api/payment_intents/capture.md)できます。 ### チップを徴収する (アメリカのみ) アメリカでは、対象となるユーザーは[売上確定時に領収書でチップを受け取る](https://docs.stripe.com/terminal/features/collecting-tips/on-receipt.md)ことができます。 # React Native > This is a React Native for when terminal-sdk-platform is react-native. View the full page at https://docs.stripe.com/terminal/payments/collect-card-payment?terminal-sdk-platform=react-native. Payment Intents API を初めて使用する場合には、以下のリソースが役立ちます。 - [Payment Intents API](https://docs.stripe.com/payments/payment-intents.md) - [PaymentIntent (支払いインテント) オブジェクト](https://docs.stripe.com/api/payment_intents.md) - [その他の支払いシナリオ](https://docs.stripe.com/payments/more-payment-scenarios.md) Stripe Terminal で支払いを回収するには、アプリケーションに決済フローを記述する必要があります。Stripe Terminal SDK を使用して、1 つの支払いセッションを表すオブジェクトである [PaymentIntent (支払いインテント)](https://docs.stripe.com/api.md#payment_intents) を作成して更新します。 Terminal の組み込みは支払いプロセスにおける失敗に対応できるように設計されており、支払いプロセスを複数のステップに分割し、各ステップを安全に再試行できるようになっています。 1. [PaymentIntent を作成](https://docs.stripe.com/terminal/payments/collect-card-payment.md#create-payment)します。 1. [決済を処理](https://docs.stripe.com/terminal/payments/collect-card-payment.md#process-payment)します。顧客のカードの承認は、SDK が決済を処理するときに行われます。 1. (オプション) [支払いをキャプチャーする](https://docs.stripe.com/terminal/payments/collect-card-payment.md#capture-payment) ## PaymentIntent を作成する [クライアント側] [サーバー側] 支払いを回収する最初のステップは、支払いフローを開始することです。顧客がチェックアウトを開始するとき、アプリケーションは `PaymentIntent` オブジェクトを作成する必要があります。これは、Stripe での新しい支払いセッションを表します。 - [createPaymentIntent (React Native)](https://stripe.dev/stripe-terminal-react-native/api-reference/interfaces/StripeTerminalSdkType.html#createPaymentIntent) クライアント側またはサーバー側で `PaymentIntent` を作成できます。 [テスト金額](https://docs.stripe.com/terminal/references/testing.md#physical-test-cards)を使用して、さまざまな結果を生成してみてください。`00` で終わる金額では、支払いが承認されます。 > #### 拒否されたカードの PaymentIntents を再作成しない > > クレジットカードが拒否された場合は、決済インテントを再作成しないでください。代わりに、同じ決済インテントを再利用して、[二重請求を回避](https://docs.stripe.com/terminal/payments/collect-card-payment.md#avoiding-double-charges)します。 ### クライアント側 クライアントから `PaymentIntent` を作成します。 > アプリが Verifone P400 に接続されている場合は、React Native SDK から PaymentIntent を作成できません。代わりに、[サーバー側で PaymentIntent を作成](https://docs.stripe.com/terminal/payments/collect-card-payment.md#create-server-side)し、SDK の `retrievePaymentIntent` メソッドを使用して、アプリ内に PaymentIntent を取得する必要があります。 ```js const {error, paymentIntent} = await createPaymentIntent({ amount: 1000, currency: "usd", }); ``` ### サーバー側 支払いの開始に必要な情報がアプリですぐに利用できない場合は、サーバで `PaymentIntent` を作成することができます。 次の例は、サーバで `PaymentIntent` を作成する方法を示しています。 #### curl ```bash curl https://api.stripe.com/v1/payment_intents \ -u <>: \ -d "amount"=1000 \ -d "currency"="usd" \ -d "payment_method_types[]"="card_present" \ -d "capture_method"="manual" ``` Terminal の支払いでは、`payment_method_types` パラメータに `card_present` が含まれている必要があります。 以下のように決済フローを制御できます。 - `card_present` 支払いの支払いフローを完全に制御するには、`capture_method` を `manual` に設定します。これにより、支払いを確定する前に照合ステップを追加できます。 - 1 ステップで支払いのオーソリとキャプチャーを行うには、`capture_method` を `automatic` に設定します。 オーストラリアで決済を受け付けるには、`capture_method` を`automatic`または `manual_preferred` に設定する必要があります。詳細については、Stripe の[オーストラリアのドキュメント](https://docs.stripe.com/terminal/payments/regional.md?integration-country=AU)をご覧ください。カナダで Interac 支払いを受け付けるには、`payment_method_types` に `interac_present` も含める必要があります。詳細については、Stripe の[カナダのドキュメント](https://docs.stripe.com/terminal/payments/regional.md?integration-country=CA)をご覧ください。 `PaymentIntent` には、個々の `PaymentIntent` に固有のキーである [client secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) が含まれています。client secret を使用するには、これをサーバーで `PaymentIntent` から取得し、[クライアント側に渡す](https://docs.stripe.com/payments/payment-intents.md#passing-to-client)必要があります。 #### Ruby ```ruby post '/create_payment_intent' do intent = # ... Create or retrieve the PaymentIntent {client_secret: intent.client_secret}.to_json end ``` - [retrievePaymentIntent (React Native)](https://stripe.dev/stripe-terminal-react-native/api-reference/interfaces/StripeTerminalSdkType.html#retrievePaymentIntent) `PaymentIntent` を取得するには、client secret を使用して `retrievePaymentIntent` を呼び出します。 `PaymentIntent` を取得したら、それを使用して `processPaymentIntent` を呼び出します。 ```js const { paymentIntent, error } = await retrievePaymentIntent(clientSecret); if (error) { // Placeholder for handling exception return; } // Placeholder for collecting payment method ``` ## 支払いを処理する [クライアント側] 顧客が提示したカードで決済を即時に処理するか、決済の処理に進む前にカード詳細を調べるかを選択できます。大半のユースケースでは、API コール数が少なく抑えられ、統合がシンプルになるため、即時に処理することをお勧めします。ただし、カードの承認前に独自のビジネスロジックを挿入する場合は、収集と確定の 2 段階のフローを使用できます。 #### 即時に処理する PaymentIntent を作成したら、次に決済を処理します。リーダーは顧客に対してカードをタップまたは挿入するように求め、その後、決済が承認されます。 - [processPaymentIntent (React Native)](https://stripe.dev/stripe-terminal-react-native/api-reference/interfaces/StripeTerminalSdkType.html#processpaymentintent) 決済の処理中に、カード会員がウォレットからカードを取得するまでに数秒かかったり、決済中にオペレーターに質問したりする可能性があります。 ```js const { paymentIntent, error } = await processPaymentIntent({ paymentIntent: paymentIntent, }); if (error) { // Placeholder for handling exception return; } // Notify your backend to capture the PaymentIntent ``` ### 収集をキャンセルする #### プログラムによるキャンセル - [cancelProcessPaymentIntent (React Native)](https://stripe.dev/stripe-terminal-react-native/api-reference/interfaces/StripeTerminalSdkType.html#cancelprocesspaymentintent) You can cancel processing a PaymentIntent by calling `cancelProcessPaymentIntent` in the React Native SDK. #### 顧客によるキャンセル - [customerCancellation (React Native)](https://stripe.dev/stripe-terminal-react-native/api-reference/types/CustomerCancellation.html) Smart readers show customers a cancel button by default. You can disable this by setting `customerCancellation` to `'disableIfAvailable'`. キャンセルボタンをタップすると、現在の取引がキャンセルされます。 ```js const { paymentIntent, error } = await collectPaymentMethod({ paymentIntent: paymentIntent,customerCancellation: 'disableIfAvailable' }); if (error) { // Placeholder for handling exception } // Placeholder for processing PaymentIntent ``` ### イベントを処理する - [UserCallbacks (React Native)](https://stripe.dev/stripe-terminal-react-native/api-reference/index.html#UserCallbacks) 内蔵ディスプレイのない [Stripe M2](https://docs.stripe.com/terminal/readers/stripe-m2.md) などのリーダーを使用して決済手段を収集する場合、決済手段収集プロセスのイベントをアプリからユーザーに表示できるようにする必要があります。これらのイベントは、ユーザーが決済を正常に収集するのに役立ちます (カードを再試行する、別のカードを試す、別の読み取り方法を使用するなど)。 取引が開始されると、SDK は `ReaderInputOptions` 値をアプリのリーダー表示ハンドラに渡し、受け入れ可能な入力の種類 (`Swipe`、`Insert`、`Tap` など) を示します。アプリの決済 UI で、これらのオプションのいずれかを使用してカードを提示することを求めるプロンプトをユーザーに表示します。 取引中に、SDK がアプリに対して、アプリのリーダー表示ハンドラに `ReaderDisplayMessage` 値を渡すことで、ユーザーに追加のプロンプト (`Retry Card` など) を表示するように要求する場合があります。これらのメッセージが決済 UI でユーザーに表示されることを確認してください。 ```js useStripeTerminal({ onDidRequestReaderInput: (options) => { // Placeholder for updating your app's checkout UI Alert.alert(options.join('/')); }, onDidRequestReaderDisplayMessage: (message) => { Alert.alert(message); }, }); ``` - 決済を手動でキャプチャーする場合、`processPaymentIntent` 呼び出しが成功すると、`PaymentIntent` のステータスが `requires_capture` になります。 - 支払いの自動キャプチャーでは、`PaymentIntent` は `succeeded` 状態に移行します。 2 日以内に PaymentIntent を手動でキャプチャーする必要があり、キャプチャーしなければオーソリは期限切れになり、売上は顧客にリリースされます。 ### 失敗に対処する - [StripeError (React Native)](https://stripe.dev/stripe-terminal-react-native/api-reference/interfaces/StripeError.html) 決済の処理に失敗した場合、SDK は更新された `PaymentIntent` を含むエラーを返します (Stripe によって拒否された場合)。アプリケーションでは、`PaymentIntent` を調べてエラーの対処方法を判断する必要があります。 | PaymentIntent ステータス | 意味 | 解決策 | | -------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------ | | `requires_payment_method` | 支払い方法が拒否されました | 同じ `PaymentIntent` を使用して `processPaymentIntent` を再度呼び出し、別の決済手段の収集を試みます。 | | `requires_confirmation` | 一時的な接続の問題 | 同じ `PaymentIntent` を使用して `processPaymentIntent` を再度呼び出し、リクエストを再試行します。 | | `PaymentIntent` が `nil` です | Stripe へのリクエストがタイムアウトし、`PaymentIntent` のステータスが不明です | 元の `PaymentIntent` の処理を再試行します。新しく作成しないでください。新しく作成すると、カード会員に複数の承認が発生する可能性があります。 | タイムアウトが複数回、連続して発生する場合、接続に問題がある可能性があります。アプリがインターネットと通信できることを確認してください。 ### 二重請求を避ける `PaymentIntent` オブジェクトは、Stripe での資金移動を可能にします。1 つの取引を表すには、`PaymentIntent` を 1 つ使用します。 カードが (残高不足などのために) 拒否された後、同じ `PaymentIntent` を再利用して、顧客が別のカードで再試行できるようにします。 `PaymentIntent` を編集する場合、`processPaymentIntent` を呼び出してリーダーの決済情報を更新する必要があります。 `PaymentIntent` を Stripe で処理するには、ステータスが `requires_payment_method` である必要があります。承認済み、キャプチャー済み、キャンセル済みの `PaymentIntent` をリーダーで処理することはできません。 #### 収集、検査、確認 PaymentIntent を作成したら、次に決済を処理します。リーダーは顧客に対してカードをタップまたは挿入するように求め、その後 PaymentMethod を作成します。 ## PaymentMethod を収集する - [collectPaymentMethod (React Native)](https://stripe.dev/stripe-terminal-react-native/api-reference/interfaces/StripeTerminalSdkType.html#collectpaymentmethod) `PaymentIntent` を作成したら、次のステップは SDK で決済手段を収集することです。 決済手段を収集するには、アプリをリーダーに接続する必要があります。アプリが `collectPaymentMethod` を呼び出した後、接続されたリーダーはカードが提示されるのを待ちます。 ```js const { paymentIntent, error } = await collectPaymentMethod({ paymentIntent: paymentIntent }); if (error) { // Placeholder for handling exception } // Placeholder for processing PaymentIntent ``` この方法では、接続されたカードリーダーを使用して暗号化された決済手段のデータを収集し、その暗号化されたデータをローカルの `PaymentIntent` に関連付けます。 ### 支払い方法の詳細をオプションで調査する - [CollectPaymentMethodParams (React Native)](https://stripe.dev/stripe-terminal-react-native/api-reference/types/CollectPaymentMethodParams.html) - [CardPresentDetails (React Native)](https://stripe.dev/stripe-terminal-react-native/api-reference/types/CardPresentDetails.html) 高度なユースケースでは、提示されたカードの支払い方法の詳細を調査し、オーソリ前に自社のビジネスロジックを実行できます。 Use the `updatePaymentIntent` parameter to attach a `PaymentMethod` to the server-side `PaymentIntent`. This data is returned in the `collectPaymentMethod` response. ```js const { paymentIntent, error } = await collectPaymentMethod({ paymentIntent: paymentIntent, updatePaymentIntent: true, }); if (error) { // Placeholder for handling exception } // Placeholder for processing PaymentIntent ``` このメソッドは、収集済みの暗号化された決済手段データを `PaymentIntent` オブジェクトへの更新に関連付けます。支払いを確定するまで、オーソリは必要ありません。この高度なユースケースは Verifone P400 ではサポートされていません。 決済手段収集後、30 秒以内に決済を承認またはキャンセルする必要があります。 SDK が[オフラインで実行](https://docs.stripe.com/terminal/features/operate-offline/collect-card-payments.md)されている場合、`PaymentIntent` オブジェクトには `paymentMethod` フィールドがありません。 この時点で、カードブランド、口座情報、その他の役立つデータなどの属性にアクセスできます。 Stripe は `wallet.type` 属性で示すとおり、取引でモバイルウォレットが使用されたかどうかを検出するよう試みます。ただし、カード発行会社がモバイルウォレットのリーダーによる識別に対応していない場合、この属性は自動入力されないため、正確な検出は保証されません。承認後に[決済が処理](https://docs.stripe.com/terminal/payments/collect-card-payment.md#process-payment)されると、Stripe はネットワークから最新の情報を取得し、`wallet.type` を更新します。 ### 収集をキャンセルする #### プログラムによるキャンセル - [cancelCollectPaymentMethod (React Native)](https://stripe.dev/stripe-terminal-react-native/api-reference/interfaces/StripeTerminalSdkType.html#cancelcollectpaymentmethod) You can cancel payment method collection by calling [cancelCollectPaymentMethod](https://stripe.dev/stripe-terminal-react-native/api-reference/interfaces/StripeTerminalSdkType.html#cancelcollectpaymentmethod) in the React Native SDK. #### 顧客によるキャンセル - [customerCancellation (React Native)](https://stripe.dev/stripe-terminal-react-native/api-reference/types/CustomerCancellation.html) Smart readers show customers a cancel button by default. You can disable this by setting `customerCancellation` to `'disableIfAvailable'`. キャンセルボタンをタップすると、現在の取引がキャンセルされます。 ```js const { paymentIntent, error } = await collectPaymentMethod({ paymentIntent: paymentIntent,customerCancellation: 'disableIfAvailable' }); if (error) { // Placeholder for handling exception } // Placeholder for processing PaymentIntent ``` ### イベントを処理する - [UserCallbacks (React Native)](https://stripe.dev/stripe-terminal-react-native/api-reference/index.html#UserCallbacks) 内蔵ディスプレイのない [Stripe M2](https://docs.stripe.com/terminal/readers/stripe-m2.md) などのリーダーを使用して決済手段を収集する場合、決済手段収集プロセスのイベントをアプリからユーザーに表示できるようにする必要があります。これらのイベントは、ユーザーが決済を正常に収集するのに役立ちます (カードを再試行する、別のカードを試す、別の読み取り方法を使用するなど)。 取引が開始されると、SDK は `ReaderInputOptions` 値をアプリのリーダー表示ハンドラに渡し、受け入れ可能な入力の種類 (`Swipe`、`Insert`、`Tap` など) を示します。アプリの決済 UI で、これらのオプションのいずれかを使用してカードを提示することを求めるプロンプトをユーザーに表示します。 取引中に、SDK がアプリに対して、アプリのリーダー表示ハンドラに `ReaderDisplayMessage` 値を渡すことで、ユーザーに追加のプロンプト (`Retry Card` など) を表示するように要求する場合があります。これらのメッセージが決済 UI でユーザーに表示されることを確認してください。 ```js useStripeTerminal({ onDidRequestReaderInput: (options) => { // Placeholder for updating your app's checkout UI Alert.alert(options.join('/')); }, onDidRequestReaderDisplayMessage: (message) => { Alert.alert(message); }, }); ``` ## PaymentIntent を確定する - [confirmPaymentIntent (React Native)](https://stripe.dev/stripe-terminal-react-native/api-reference/interfaces/StripeTerminalSdkType.html#confirmpaymentintent) 顧客から決済手段を収集できたら、次のステップでは SDK で決済を確定します。決済を続行する準備ができたら、[前のステップ](https://docs.stripe.com/terminal/payments/collect-card-payment.md#collect-inspect-payment-method)からの更新後の `PaymentIntent` を使用して `confirmPaymentIntent` を呼び出します。 - 決済の手動キャプチャーでは、`confirmPaymentIntent` 呼び出しが成功すると、`PaymentIntent` のステータスが `requires_capture` になります。 - 支払いの自動キャプチャーでは、`PaymentIntent` は `succeeded` 状態に移行します。 クライアント側では常に Terminal SDK を使用して PaymentIntents を確定します。サーバー側の確定により、PIN プロンプトなどの重要なやり取りがバイパスされ、取引が失敗する可能性があります。 ```js const { paymentIntent, error } = await confirmPaymentIntent({ paymentIntent: paymentIntent }); if (error) { // Placeholder for handling exception return; } // Placeholder for notifying your backend to capture paymentIntent.id ``` 2 日以内に PaymentIntent を手動でキャプチャーする必要があり、キャプチャーしなければオーソリは期限切れになり、売上は顧客にリリースされます。 ### 失敗に対処する - [StripeError (React Native)](https://stripe.dev/stripe-terminal-react-native/api-reference/interfaces/StripeError.html) 決済の確定に失敗した場合、SDK は更新された `PaymentIntent` を含むエラーを返します。アプリケーションでは、`PaymentIntent` を調べてエラーの対処方法を判断する必要があります。 | PaymentIntent のステータス | 意味 | 解決策 | | -------------------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | `requires_payment_method` | 支払い方法が拒否されました | 同じ `PaymentIntent` を使用して `collectPaymentMethod` を再度呼び出し、別の決済手段の収集を試みます。 | | `requires_confirmation` | 一時的な接続の問題 | 同じ `PaymentIntent` を使用して `confirmPaymentIntent` を再度呼び出し、リクエストを再試行します。 | | `PaymentIntent` が `nil` です | Stripe へのリクエストがタイムアウトし、`PaymentIntent` のステータスが不明です | 元の `PaymentIntent` の確定を再試行します。新しい PaymentIntent を作成しないでください。新しく作成すると、カード会員に複数の承認が発生する可能性があります。 | タイムアウトが複数回、連続して発生する場合、接続に問題がある可能性があります。アプリがインターネットと通信できることを確認してください。 ### 二重請求を避ける `PaymentIntent` オブジェクトは、Stripe での資金移動を可能にします。1 つの取引を表すには、`PaymentIntent` を 1 つ使用します。 カードが (残高不足などのために) 拒否された後、同じ `PaymentIntent` を再利用して、顧客が別のカードで再試行できるようにします。 `PaymentIntent` を編集する場合、`collectPaymentMethod` を呼び出してリーダーの決済情報を更新する必要があります。 `PaymentIntent` を Stripe で確定するには、ステータスが `requires_payment_method` である必要があります。承認済み、キャプチャー済み、キャンセル済みの `PaymentIntent` をリーダーで確定することはできません。 ## 支払いをキャプチャーする [サーバー側] [ステップ 1](https://docs.stripe.com/terminal/payments/collect-card-payment.md#create-payment) の `PaymentIntent` の作成時に `capture_method` を `manual` として定義した場合、SDK はオーソリ済みでキャプチャーはされていない `PaymentIntent` をアプリケーションに返します。[オーソリとキャプチャー](https://docs.stripe.com/payments/place-a-hold-on-a-payment-method.md)の違いについて、詳細を確認してください。 アプリが SDK から確定済みの `PaymentIntent` を受信したら、その支払いをキャプチャーするようにアプリからバックエンドに対して通知するようにしてください。バックエンドにエンドポイントを作成し、`PaymentIntent` ID を受け付け、それをキャプチャーするように Stripe API にリクエストを送信します。 ```curl curl -X POST https://api.stripe.com/v1/payment_intents/{{PAYMENT_INTENT_ID}}/capture \ -u "<>:" ``` `capture` コールが成功すると、`PaymentIntent` のステータスは `succeeded` になります。 キャプチャーされたプラットフォーム手数料が連結アカウントに対して正確であることを確認するために、支払いを手動でキャプチャーする前にそれぞれの `PaymentIntent` を調べ、必要に応じてプラットフォーム手数料を修正します。 ### 支払いを照合する ビジネスの支払いアクティビティを監視するため、毎日の最後の作業としてサーバで PaymentIntent と内部注文システムを照合することをお勧めします。 `PaymentIntent` のステータスが `requires_capture` のままの場合には、以下の 2 つの可能性があります。 **顧客のカード明細上の不要なオーソリ** - 原因: ユーザーが取引の途中でアプリの決済フローを中止した - 解決策:キャプチャーされていない `PaymentIntent` が、サーバーにある完了済みの注文に関連付けられていない場合には、[キャンセル](https://docs.stripe.com/api/payment_intents/cancel.md)できます。キャンセルされた `PaymentIntent` を使用して支払いを実行することはできません。 **顧客からの売上回収が未完了** - 原因: 支払いをキャプチャーするようにバックエンドに通知する、アプリからのリクエストのエラー - 解決策:キャプチャーされていない `PaymentIntent` が、サーバにある完了済みの注文に関連付けられており、その注文について他の支払い (現金による支払いなど) を受けていない場合には、この PaymentIntent を[キャプチャー](https://docs.stripe.com/api/payment_intents/capture.md)できます。 ### チップを徴収する (アメリカのみ) アメリカでは、対象となるユーザーは[売上確定時に領収書でチップを受け取る](https://docs.stripe.com/terminal/features/collecting-tips/on-receipt.md)ことができます。