カード支払いを回収する
Stripe Terminal を使用したカード支払いの回収ができるように、アプリケーションとバックエンドを準備します。
BBPOS WisePOS E と Stripe Reader S700 では、Terminal SDK ではなく Stripe API を使用して支払いを回収するため、サーバー側の導入をお勧めします。
Stripe Terminal で支払いを回収するには、アプリケーションに決済フローを記述する必要があります。Stripe Terminal SDK を使用して、1 つの支払いセッションを表すオブジェクトである PaymentIntent (支払いインテント) を作成して更新します。
中心となる概念は、SDK ベースの導入と似ていますが、サーバー主導型の導入では使用されるステップが少し異なります。
- Create a PaymentIntent. You can define whether to automatically or manually capture your payments.
- Process the payment. Authorization on the customer’s card takes place when the reader processes the payment.
- (Optional) Capture the PaymentIntent.
注
This integration shape does not support offline card payments.
PaymentIntent を作成する
支払い回収の最初のステップは、決済フローを開始することです。顧客が購入を開始したときに、バックエンドで PaymentIntent (支払いインテント) オブジェクトを作成する必要があります。これは、Stripe で新しい決済セッションが開始されることを表します。サーバー主導型の実装では、サーバー側で PaymentIntent を作成します。
テスト環境で、テスト用金額を使用してさまざまなエラーシナリオをシミュレーションできます。本番環境では、PaymentIntent の金額は支払いに使用されるリーダーに表示されます。
Terminal の支払いでは、payment_
パラメーターに card_
が含まれている必要があります。
カナダで Interac 決済を受け付けるには、payment_
に interac_
を含める必要もあります。カナダの地域的な考慮事項をご覧ください。
以下のように決済フローを制御できます。
card_
決済の決済フローを完全に管理するには、present capture_
をmethod manual
に設定します。これにより、決済を確定する前に照合ステップを追加できます。- 1 ステップで支払いのオーソリとキャプチャーを行うには、
capture_
をmethod automatic
に設定します。
支払いを処理する
顧客が提示したカードで支払いを即時に処理するか、支払いの処理に進む前にカード情報を調べるかを選択できます。大半のユースケースでは、API コール数と Webhook イベント数が少なく抑えられ、システムがシンプルになるため、即時に処理することをお勧めします。ただし、カードの承認前に自社用のビジネスロジックを挿入する場合は、収集と確定の 2 段階のフローを使用できます。
シミュレーションされたリーダーを使用する場合、present_payment_method エンドポイントを使用して、リーダーでのカード保有者のタップやカードの挿入をシミュレーションします。さまざまな成功と失敗のシナリオをシミュレーションするには、テストカードを使用します。
支払いをキャプチャーする
ステップ 1 の PaymentIntent の作成時に capture_
を manual
として定義した場合、SDK はオーソリ済みでキャプチャーされていない PaymentIntent をアプリケーションに返します。オーソリとキャプチャーの違いについて、詳細を確認してください。アプリケーションが確定済みの PaymentIntent を受信したら、アプリケーションからバックエンドに PaymentIntent をキャプチャーするように通知されることを確認します。このようにするには、バックエンドにエンドポイントを作成し、そこで PaymentIntent ID を受け取り、それをキャプチャーするように Stripe API にリクエストを送信します。
capture の呼び出しが成功すると、PaymentIntent のステータスが succeeded
になります。
警告
2 日以内に PaymentIntents
を手動でキャプチャーする必要があり、キャプチャーしなければオーソリは期限切れになり、売上は顧客にリリースされます。
リーダーの状態を確認する
リーダーがアクションを完了したことを確認するには、新しいリーダーのアクションを開始したり支払いのキャプチャーに進む前に、アプリケーションでリーダーの状態を確認する必要があります。ほとんどの場合、この確認によって支払いの成功 (承認) を確認し、取引を完了するための操作画面をオペレーターに表示できるようになります。支払い拒否などのエラーの処理が必要になる場合もあります。
以下のいずれかを使用して、リーダーのステータスを確認します。
Webhook をリッスンする 推奨
回復力を最大限に高めるために、アプリケーションで Stripe からの Webhook をリッスンし、リーダーのステータスに関するリアルタイムの通知を受け取ることをお勧めします。Stripe は以下の 3 つの Webhook でリーダーのアクションのステータスをアプリケーションに通知します。
ステータス | 説明 |
---|---|
terminal. | 支払いが正常にオーソリされた場合など、リーダーのアクションが成功したときに送信されます。 |
terminal. | 残高不足によりカードが拒否された場合など、リーダーのアクションが失敗したときに送信されます。 |
terminal. ベータ | 支払い方法が収集されたときなど、リーダーのアクションが更新されたときに送信されます (collect_ アクションでのみトリガーされます)。 |
これらの Webhook をリッスンするには、Webhook エンドポイントを作成します。これらのイベントは優先度が高く、重要な決済パスに含まれるため、専用の Webhook エンドポイントを設定することをお勧めします。
terminal.
イベントを取得するには、Webhook エンドポイントに terminal_
ベータヘッダーが設定されている必要があります。collect_
コールおよび confirm_
コールと同じ API バージョンとベータヘッダーが指定された Webhook を作成します。
Stripe API をポーリングする
Webhook の配信に問題が発生した場合に備え、必要に応じてオペレーターが呼び出せる POS インターフェイスに check status
のボタンを追加して、Stripe API をポーリングできます。
PaymentIntent を使用する
処理を求めてリーダーに渡した PaymentIntent を取得できます。PaymentIntent 作成時の初期ステータスは requires_
です。支払い方法が正常に収集されると、ステータスは requires_
に更新されます。支払いが正常に処理されると、ステータスは requires_
に更新されます。
Reader オブジェクトを使用する
リーダーが受信した最新の操作とそのステータスを示す action 属性を含む、Reader (リーダー) オブジェクトを使用できます。アプリケーションはリーダーを取得して、リーダーの操作のステータスが変更されていないかを確認できます。
Reader オブジェクトは、支払い処理ステップへのレスポンスとしても返されます。支払いを処理する際の、action
タイプは process_
です。
支払いが成功すると、action.
は succeeded
に更新されます。これにより取引の完了に進めることになります。その他の action.
には、failed
や in_
があります。
エラーを処理する
以下のエラーは、アプリケーションが処理する必要がある一般的なタイプです。
二重支払いの防止
PaymentIntent オブジェクトは、Stripe での資金移動を可能にします。単一の PaymentIntent を使用して 1 つの取引を表します。
カードが (残高不足などのために) 拒否された後、同じ PaymentIntent を再利用して、顧客が別のカードで再試行できるようにします。
PaymentIntent を編集する場合、process_payment_intent を呼び出してリーダーの支払い情報を更新する必要があります。
Stripe で PaymentIntent を処理できるようにするには、ステータスが requires_
である必要があります。オーソリ済み、キャプチャー済み、キャンセル済みの PaymentIntent をリーダーによって処理することはできず、intent_
エラーが返されます。
{ "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.
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_
が connection_
の terminal.
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
を取得して、支払いが正常にオーソリされたかどうかを確認します。
タイムアウトを最小限に抑えるには、ネットワークが Stripe のネットワーク要件を満たしていることを確認してください。
決済のキャンセル
プログラムによるキャンセル
処理中の支払いのキャンセルが必要になることがあります。たとえば、実装でリーダーの支払いの回収をすでに開始した後、顧客が購入アイテムを追加する場合などです。その場合は、cancel_action エンドポイントを使用してリーダーをリセットします。
注
支払いのオーソリの途中で支払いをキャンセルすることはできません。顧客がすでにリーダーで支払うカードを提示している場合、処理が完了するまで待機する必要があります。通常、オーソリは数秒で完了します。オーソリ中に cancel_action を呼び出すと、terminal_
エラーが発生します。
顧客によるキャンセル
ユーザーは、以下のエンドポイントに enable_
の値を設定できます。
true に設定すると、スマートリーダーのユーザーにはキャンセルボタンが表示されます。
キャンセルが有効になった支払いの回収
キャンセルボタンをタップすると、アクティブな取引がキャンセルされます。Stripe は failure_code を customer_
として terminal.
Webhook を送信します。
{ "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_
エラーで失敗します。
{ "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_
エラーコードを受信します。
{ "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 のネットワーク要件を満たしていることを確認してください。
稀に、terminal_
エラーコードが偽陰性になります。このシナリオでは、上記のように terminal_
エラーを API から受け取りますが、リーダーは実際にはコマンドを正常に受信しています。偽陰性が起こるのは、Stripe がメッセージをリーダーに送信しても、一時的なネットワーキング障害が原因でリーダーから確認を受信していない場合です。
リーダーがオフライン状態
設置場所でのインターネット接続が失われ、リーダーと Stripe の間の通信が切断されることがあります。このようなケースでは、リーダーは、POS アプリケーションとバックエンドインフラから開始されたイベントに応答しません。
リーダーが API リクエストへの応答に一貫して失敗する場合は、電源が入っていない (電源コードが外れている、バッテリーが切れているなど) か、インターネットに正しく接続されていない可能性があります。
Stripe でリーダーからの信号の受信が 2 分間にわたり途切れている場合、そのリーダーはオフラインと見なされます。オフライン状態のリーダーで API メソッドを呼び出そうとすると、terminal_
エラーコードが返されます。
{ "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://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" } }
ネットワーク要件を参照して、リーダーがインターネットに正しく接続されていることを確認します。
Webhook の欠落
リーダーが支払いの途中で連結が解除された場合は、API でアクションのステータスを更新することはできません。このシナリオでは、リーダーは、カードが提示された後にエラー画面を表示します。ただし、API の Reader オブジェクトは、デバイスの失敗を反映する更新は行われず、リーダーのアクションの Webhook も受け取りません。この状況では、リーダーはアクションのステータス in_
のままになる場合があり、レジ係は cancel_action エンドポイントを呼び出してリーダーのステータスをリセットする必要があります。
Webhook の遅延
稀なケースではありますが、Stripe で障害が発生している場合、リーダーのアクションの Webhook が遅延することがあります。Reader または PaymentIntent オブジェクトのステータスをクエリすると、最新のステータスを確認することができます。
Webhook イベント
Webhook | 説明 |
---|---|
terminal. | 非同期アクションが成功したときに送信されます。process_ 、confirm_ 、process_ 、refund_ など、カードの提示が必要なアクションに対して送信されます。 |
terminal. | 非同期アクションが失敗したときに送信されます。process_ 、process_ 、refund_ など、カードの提示が必要なアクションに対して送信されます。set_ と cancel_ アクションには Webhook は送信されません。システムでこれらのエラーを処理する必要があります。 |
terminal. | 非同期アクションが更新されたときに送信されます。collect_ などのアクションに対して送信されます。 |