Webhook なしでカード支払いを受け付ける
注意
Stripe は、Card Element ではなく、新しい Payment 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 を再度確定するサーバ側
このコードは、前のステップでの処理と同様に、支払いに追加の認証が必要なときにのみ実行されます。どの支払いでもこの追加ステップが必要になる場合があるため、コード自体はオプションではありません。
上記で設定したものと同じエンドポイントを使用し、PaymentIntent を再度確定することにより、支払いを完了して注文のフルフィルメントを実行します。この確定は支払い試行から 1 時間以内に実行してください。実行されない場合は、支払いが失敗して取引が requires_payment_method
に戻されます。
次のアクションを処理するクライアント側
顧客による操作が必要な状況を処理するコードを記述します。支払いは通常、ステップ 4 のサーバーでの確定後に成功します。それに対して、3D セキュアによる認証など、PaymentIntent で顧客による追加アクションが必要になったときに、このコードが機能します。
stripe.handleCardAction を使用して、顧客のアクションを処理する UI をトリガーします。認証が成功した場合、PaymentIntent のステータスは requires_confirmation
になります。支払いを完了するには、サーバーで 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.handleCardAction
の完了には数秒かかる場合があります。この間、フォームが再送信されないように無効化し、スピナーのような待機中のインジケータを表示します。エラーが発生した場合は、エラーを顧客に知らせ、フォームを再度有効化し、待機中のインジケータを非表示にします。支払いを完了するために、顧客が認証などの追加ステップを実行する必要がある場合は、Stripe.js がそのプロセスをステップごとに顧客に提示します。
PaymentIntent を再度確定するサーバ側
このコードは、前のステップでの処理と同様に、支払いに追加の認証が必要なときにのみ実行されます。どの支払いでもこの追加ステップが必要になる場合があるため、コード自体はオプションではありません。
上記で設定したものと同じエンドポイントを使用し、PaymentIntent を再度確定することにより、支払いを完了して注文のフルフィルメントを実行します。この確定は支払い試行から 1 時間以内に実行してください。実行されない場合は、支払いが失敗して取引が requires_payment_method
に戻されます。
組み込みをテストする
この組み込みの準備ができていることを確認するために、テスト環境で使用できるテストカードがいくつかあります。任意のセキュリティコードおよび有効期限を指定して、これらのカードを使用します。
番号 | 説明 |
---|---|
支払いが成功し、すぐに処理されます。 | |
認証が必要です。Stripe は、顧客に認証を求めるモーダルをトリガーします。 | |
常に支払い拒否コード insufficient_funds で失敗します。 |
テストカードの一覧については、テストに関するガイドを参照してください。