Webhook なしでカード支払いを受け付ける
サーバでカード決済を確定して、カードの認証リクエストを処理する方法をご紹介します。
注意
Stripe は、Card Element ではなく、新しい Payment Element の使用をお勧めしています。これにより、1 つの Element で複数の決済手段を受け付けることができます。Card Element と Payment Element を使用する状況についてご紹介します。
より幅広いサポートと将来の保証のために、非同期的な支払いを目的とした標準的な実装を使用してください。
この組み込みは、Webhook を使用したりオフラインイベントを処理したりせずに、クライアントから返される応答を待って、サーバーで支払いを確定します。この組み込みはシンプルに見えるかもしれませんが、ビジネスの成長に合わせて拡張するのが難しく、以下のような制限があります。
- カードのみをサポート: ACH や現地で一般的な決済手段に個別に対応するには、追加のコードを記述する必要があります。
- 二重請求のリスク: 顧客が支払おうとするたびに新たな PaymentIntent を同期的に作成することにより、顧客に対して誤って二重請求が行われるリスクがあります。必ずベストプラクティスに従ってください。
- クライアントへの追加トリップ: 3D セキュアを備えたカード、または強力な顧客認証 (SCA) などの規制の対象となるカードでは、クライアント側での追加の手順が必要になります。
この実装の使用を選択した場合は、上記の制限にご注意ください。制限を設けたくない場合は、標準的な実装を使用します。
カード詳細を収集するクライアント側
Stripe.js と Stripe Elements を使用して、クライアント側でカード情報を収集します。Elements は、カード番号、郵便番号、有効期限を収集して検証するための事前構築された UI コンポーネントのセットです。
Stripe Element には、HTTPS 接続を介して支払い情報を Stripe に安全に送信する iframe が含まれています。組み込みを機能させるには、決済ページのアドレスの先頭を http:// ではなく https:// にする必要があります。
HTTPS を使用せずに実装をテストできます。本番環境で決済を受け付ける準備が整ったら、HTTPS を有効化します。
サーバへ PaymentMethod を送信するクライアント側
PaymentMethod が正常に作成されたら、その ID をサーバーに送信します。
const stripePaymentMethodHandler = async (result) => { if (result.error) { // Show error in payment form } else { // Otherwise send paymentMethod.id to your server (see Step 4) const res = await fetch('/pay', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ payment_method_id: result.paymentMethod.id, }), }) const paymentResponse = await res.json(); // Handle server response (see Step 4) handleServerResponse(paymentResponse); } }
PaymentIntent を作成するサーバ側
リクエストを受信するためにサーバにエンドポイントを設定します。このエンドポイントは、後で でも、追加の認証ステップが必要なカードの処理に使用されます。
クライアント側で作成した PaymentMethod) の ID を使って新しい PaymentIntent を作成します。PaymentIntent の作成時に confirm プロパティを true に設定するか、作成後に confirm を呼び出すことにより、PaymentIntent を確定できます。カード支払いでは、オーソリとキャプチャーの分離もサポートされています。
支払いで3D セキュア認証などの追加アクションが必要な場合、PaymentIntent のステータスは requires_
に設定されます。支払いが失敗すると、ステータスは requires_
に戻され、ユーザにエラーを表示する必要があります。支払いで追加認証が求められない場合は、支払いが作成され、PaymentIntent のステータスは succeeded
に設定されます。
注
2019-02-11 以前の API のバージョンでは、requires_
の代わりに requires_
、requires_
の代わりに requires_
が表示されます。
後で再利用するためにカードを保存する場合は、PaymentMethod を格納するため Customer を作成して、PaymentIntent の作成時に以下の追加パラメータを渡します。
- 顧客。Customer の ID に設定します。
- setup_future_usage。
off_
に設定し、顧客が存在しない場合のオフセッションの支払いにこの PaymentMethod を再利用する予定であることを Stripe に伝えます。このプロパティを設定すると、PaymentIntent が確定され、ユーザによる必要な操作がすべて完了した後で、顧客に PaymentMethod が保存されます。詳細については、支払い後のカードの保存に関するコード例を参照してください。session
次のアクションを処理するクライアント側
顧客による操作が必要な状況を処理するためのコードを記述します。通常、ステップ 4 のサーバーでの確定後に支払いは成功しますが、3D セキュアによる認証など、PaymentIntent で顧客による追加の対応が必要になったときに、このコードが機能します。
stripe.handleCardAction を使用して、顧客のアクションを処理するための UI を起動させます。認証が成功した場合、PaymentIntent’ のステータスは requires_
になります。サーバーで PaymentIntent を再度確定して支払いを完了します。
テスト中は、認証が必要なテストカード番号 ( など) を使用して、このフローを必ず実施するようにします。認証を必要としないカード ( など) を使用すると、フローのこの部分がスキップされ、ステップ 4 で完了します。
const handleServerResponse = async (response) => { if (response.error) { // Show error from server on payment form } else if (response.requires_action) { // Use Stripe.js to handle the required card action const { error: errorAction, paymentIntent } = await stripe.handleCardAction(response.payment_intent_client_secret); if (errorAction) { // Show error from Stripe.js in payment form } else { // The card action has been handled // The PaymentIntent can be confirmed again on the server const serverResponse = await fetch('/pay', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ payment_intent_id: paymentIntent.id }) }); handleServerResponse(await serverResponse.json()); } } else { // Show success message } }
注
stripe.
の完了には数秒かかる場合があります。この間、フォームが再送信されないように無効化し、スピナーのような待機中のインジケータを表示します。エラーが発生した場合は、エラーを顧客に知らせ、フォームを再度有効化し、待機中のインジケータを非表示にします。支払いを完了するために、顧客が認証などの追加ステップを実行する必要がある場合は、Stripe.js がそのプロセスをステップごとに顧客に提示します。
PaymentIntent を再度確定するサーバ側
このコードは、直前のステップでの処理と同様に、支払いに追加の認証が必要な場合にのみ実行されます。どの支払いでもこの追加ステップが必要になる場合があるため、コード自体はオプションではありません。
上記で設定したものと同じエンドポイントを使用し、PaymentIntent を再度確定することにより、支払いを完了して注文のフルフィルメントを実行します。この確定は支払い試行から 1 時間以内に実行してください。実行されない場合は、支払いが失敗して取引が requires_
に戻されます。
組み込みをテストする
この実装の準備ができていることを確認するために、サンドボックスで使用できるテストカードがいくつかあります。任意のセキュリティコードおよび将来の有効期限を指定して使用します。
番号 | 説明 |
---|---|
支払いが成功し、すぐに処理されます。 | |
認証が必要です。Stripe は、顧客に認証を求めるモーダルをトリガーします。 | |
常に支払い拒否コード insufficient_ で失敗します。 |
テストカードの一覧については、テストに関するガイドを参照してください。