支払いを回収する
注
For BBPOS WisePOS E and Stripe Reader S700, we recommend this integration, which uses the Stripe API instead of a Terminal SDK to collect payments.
Stripe Terminal で支払いを回収するには、アプリケーションに支払いフローを記述する必要があります。Stripe Terminal SDK を使用して、1 つの支払いセッションを表すオブジェクトである PaymentIntent (支払いインテント) を作成して更新します。
中心となる概念は、SDK ベースの導入と似ていますが、サーバー主導型の導入では使用されるステップが少し異なります。
ステップ 1 では、支払いを自動と手動のどちらでキャプチャーするかを定義できます。顧客のカードのオーソリは、リーダーが支払いを処理するときにステップ 2 で行われます。
PaymentIntent を作成する
支払い回収の最初のステップは、決済フローを開始することです。顧客が購入を開始したときに、バックエンドで PaymentIntent (支払いインテント) オブジェクトを作成する必要があります。これは、Stripe で新しい決済セッションが開始されることを表します。サーバー主導型の実装では、サーバー側で PaymentIntent を作成します。
テスト環境で、テスト用金額を使用してさまざまなエラーシナリオをシミュレーションできます。本番環境では、PaymentIntent の金額は支払いに使用されるリーダーに表示されます。
Terminal の支払いでは、payment_method_types
パラメーターに card_present
が含まれている必要があります。
注
カナダで Interac の決済を受け付けるには、payment_method_types
に interac_present
も含める必要があります。詳細については、カナダ向けのドキュメントをご覧ください。
以下のように決済フローを制御できます。
card_present
決済の決済フローを完全に管理するには、capture_method
をmanual
に設定します。これにより、決済を確定する前に照合ステップを追加できます。- 1 ステップで支払いのオーソリとキャプチャーを行うには、
capture_method
をautomatic
に設定します。
支払いを処理する
You can process a payment immediately with the card presented by a customer, or instead inspect card details before proceeding to process the payment. For most use cases, we recommend processing immediately, as it is a simpler integration with less API calls and webhook events. However, if you would like to insert your own business logic before the card is authorized, you can use the two step collect and confirm flow.
シミュレーションされたリーダーを使用する場合、present_payment_method エンドポイントを使用して、リーダーでのカード保有者のタップやカードの挿入をシミュレーションします。さまざまな成功と失敗のシナリオをシミュレーションするには、テストカードを使用します。
支払いをキャプチャーする
ステップ 1 の PaymentIntent の作成時に capture_method
を manual
として定義した場合、SDK はオーソリ済みでキャプチャーされていない PaymentIntent をアプリケーションに返します。オーソリとキャプチャーの違いについて、詳細を確認してください。アプリケーションが確定済みの PaymentIntent を受信したら、アプリケーションからバックエンドに PaymentIntent をキャプチャーするように通知されることを確認します。このようにするには、バックエンドにエンドポイントを作成し、そこで PaymentIntent ID を受け取り、それをキャプチャーするように Stripe API にリクエストを送信します。
capture の呼び出しが成功すると、PaymentIntent のステータスが succeeded
になります。
リーダーの状態を確認する
リーダーがアクションを完了したことを確認するには、新しいリーダーのアクションを開始するか支払いのキャプチャーに進む前にアプリケーションでリーダーの状態を確認する必要があります。ほとんどの場合、この確認によって支払いの成功 (承認) を確認し、取引を完了するための操作画面をオペレーターに表示できるようになります。支払い拒否などのエラーの処理が必要になる場合もあります。
以下のいずれかを使用して、リーダーのステータスを確認します。
Webhook をリッスンする 推奨
回復力を最大限に高めるために、アプリケーションで Stripe からの Webhook をリッスンし、リーダーのステータスに関するリアルタイムの通知を受け取ることをお勧めします。Stripe は以下の 3 つの Webhook でリーダーのアクションのステータスをアプリケーションに通知します。
Status | 説明 |
---|---|
terminal.reader.action_succeeded | Sent when a reader action succeeds, such as when a payment is authorized successfully. |
terminal.reader.action_failed | Sent when a reader action fails, such as when a card is declined due to insufficient funds. |
terminal.reader.action_updated Beta | Sent when a reader action is updated, such as when a payment method is collected (only triggered for the collect_payment_method action). |
これらの Webhook をリッスンするには、Webhook エンドポイントを作成します。これらのイベントは優先度が高く、重要な決済パスに含まれるため、専用の Webhook エンドポイントを設定することをお勧めします。
To retrieve terminal.reader.action_updated
events, webhook endpoints must have the terminal_collect_confirm_beta
beta header set. Create webhooks to have the same API version and beta header as your collect_payment_method
and confirm_payment_intent
calls.
Stripe API をポーリングする
Webhook の配信に問題が発生した場合に備え、必要に応じてオペレーターが呼び出せる POS インターフェイスに check status
のボタンを追加して、Stripe API をポーリングできます。
PaymentIntent を使用する
処理を求めてリーダーに渡した PaymentIntent を取得できます。PaymentIntent 作成時の初期ステータスは requires_payment_method
です。決済手段が正常に収集されると、ステータスは requires_confirmation
に更新されます。支払いが正常に処理されると、ステータスは requires_capture
に更新されます。
Reader オブジェクトを使用する
リーダーが受信した最新の操作とそのステータスを示す action 属性を含む、Reader (リーダー) オブジェクトを使用できます。アプリケーションはリーダーを取得して、リーダーの操作のステータスが変更されていないかを確認できます。
Reader オブジェクトは、支払い処理ステップへのレスポンスとしても返されます。支払いを処理する際の、action
タイプは process_payment_intent
です。
支払いが成功すると、action.status
は succeeded
に更新されます。これにより取引の完了に進めることになります。その他の action.status
には、failed
や in_progress
があります。
エラーを処理する
以下のエラーは、アプリケーションが処理する必要がある一般的なタイプです。
二重支払いの防止
PaymentIntent オブジェクトは、Stripe での資金移動を可能にします。単一の PaymentIntent を使用して 1 つの取引を表します。
カードが (残高不足などのために) 拒否された後、同じ PaymentIntent を再利用して、顧客が別のカードで再試行できるようにします。
PaymentIntent を編集する場合、process_payment_intent を呼び出してリーダーの支払い情報を更新する必要があります。
Stripe で PaymentIntent を処理できるようにするには、ステータスが requires_payment_method
である必要があります。オーソリ済み、キャプチャー済み、キャンセル済みの PaymentIntent をリーダーによって処理することはできず、intent_invalid_state
エラーが返されます。
{ "error": { "code": "intent_invalid_state", "doc_url": "https://stripe.com/docs/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 属性と action.failure_message 属性を確認して、支払いが拒否された理由を確認します。
{ "id": "tmr_xxx", "object": "terminal.reader", "action": { "failure_code": "card_declined", "failure_message": "Your card has insufficient funds.", "process_payment_intent": { "payment_intent": "pi_xxx" }, "status": "failed", "type": "process_payment_intent" }, ... }
カードが拒否された場合には、顧客に別の決済手段を使用するように促します。同じ PaymentIntent を使用して、process_payment_intent エンドポイントに別のリクエストを送信します。新しい PaymentIntent を作成する場合には、二重の支払いを避けるため、失敗した PaymentIntent をキャンセルする必要があります。
注
カードの読み取りエラー (チップの読み取りエラーなど) が発生すると、顧客に再試行を促すメッセージがリーダーに自動的に表示されます。このとき、アプリケーションに通知は送られません。再試行が複数回失敗した場合、process_payment_intent リクエストをもう一度行うことで、別の決済手段を使用するように求めることができます。
支払いのタイムアウト
インターネット接続の信頼性が低いリーダーは、カードのオーソリ時のネットワーキングリクエストのタイムアウトが原因で支払いの処理が失敗する場合があります。リーダーでは、処理画面が数秒間にわたって表示された後、失敗の画面が表示され、failure_code
が connection_error
の terminal.reader.action_failed
Webhook を受信します。
{ "id": "tmr_xxx", "object": "terminal.reader", "action": { "failure_code": "connection_error", "failure_message": "Could not connect to Stripe.", "process_payment_intent": { "payment_intent": "pi_xxx" }, "status": "failed", "type": "process_payment_intent" }, ... }
支払い確認リクエストが Stripe のバックエンドシステムで処理されていても、リーダーが Stripe からレスポンスを受信する前に切断されていることがあります。この失敗コードが設定された Webhook を受信した場合、PaymentIntent の status
を取得して、支払いが正常にオーソリされたかどうかを確認します。
決済のキャンセル
Programmatic cancellation
処理中の支払いのキャンセルが必要になることがあります。たとえば、実装がリーダーですでに支払いの回収を開始した後で、顧客が購入アイテムを追加する場合などです。その場合は、cancel_action エンドポイントを使用してリーダーをリセットします。
注
支払いのオーソリの途中で支払いをキャンセルすることはできません。顧客がすでにリーダーで支払うカードを提示している場合、処理が完了するまで待機する必要があります。通常、オーソリは数秒で完了します。オーソリ中に cancel_action を呼び出すと、terminal_reader_busy
エラーが発生します。
Customer-initiated cancellation
Users can set the value of enable_customer_cancellation
on these endpoints:
When set to true, smart reader users see a cancel button.
Payment collection with cancellation enabled
Tapping the cancel button cancels the active transaction. Stripe sends a terminal.reader.action_failed
webhook with a failure_code of customer_canceled
.
{ "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": "pi_xxx", "process_config": { "enable_customer_cancellation": true } }, "status": "failed", "type": "process_payment_intent" } }
リーダーがビジー状態
リーダーが一度に処理できるリクエストは 1 つのみです。同じリーダーで 2 つの API リクエストを同時に行うと、いずれか一方が terminal_reader_busy
エラーで失敗します。
{ "error": { "code": "terminal_reader_busy", "doc_url": "https://stripe.com/docs/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-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
エラーコードを受信します。
{ "error": { "code": "terminal_reader_timeout", "doc_url": "https://stripe.com/docs/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-payment?terminal-sdk-platform=server-driven#handle-errors for details on how to handle this error.", "type": "invalid_request_error" } }
この場合は、API リクエストを再試行することをお勧めします。
注
稀に、terminal_reader_timeout
エラーコードが偽陰性になります。このシナリオでは、上記のように terminal_reader_timeout
エラーを API から受け取りますが、リーダーは実際にはコマンドを正常に受信しています。偽陰性が起こるのは、Stripe がメッセージをリーダーに送信しても、一時的なネットワーキング障害が原因でリーダーから確認を受信していない場合です。
リーダーがオフライン状態
設置場所でのインターネット接続が失われ、リーダーと Stripe の間の通信が切断されることがあります。このようなケースでは、リーダーは、POS アプリケーションとバックエンドインフラから開始されたイベントに応答しません。
リーダーが API リクエストへの応答に一貫して失敗する場合は、電源が入っていない (電源コードが外れている、バッテリーが切れているなど) か、インターネットに正しく接続されていない可能性があります。
Stripe でリーダーからの信号の受信が 2 分間にわたり途切れている場合、そのリーダーはオフラインと見なされます。オフライン状態のリーダーで API メソッドを呼び出そうとすると、terminal_reader_offline
エラーコードが返されます。
{ "error": { "code": "terminal_reader_offline", "doc_url": "https://stripe.com/docs/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://stripe.com/docs/terminal/payments/collect-payment?terminal-sdk-platform=server-driven#handle-errors for details on how to handle this error.", "type": "invalid_request_error" } }
接続上の問題をデバッグするガイドに従い、リーダーがインターネットに正しく接続されていることを確認します。
Webhook の欠落
リーダーが支払いの途中で切断された場合は、API でアクションのステータスを更新することはできません。このシナリオでは、リーダーは、カードが提示された後にエラー画面を表示します。ただし、API の Reader オブジェクトは、デバイスの失敗を反映する更新は行われず、リーダーのアクションの Webhook も受け取りません。この状況では、リーダーはアクションのステータス in_progress
のままになる場合があり、レジ係は 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 は送信されません。実装でこれらのエラーを処理する必要があります。 |
terminal.reader.action_updated | 非同期アクションが更新されたときに送信されます。collect_payment_method などのアクションに対して送信されます。 |