Webhook なしでカード支払いを受け付ける
サーバでカード決済を確定して、カードの認証リクエストを処理する方法をご紹介します。
注意
Stripe recommends using the newer Payment Element instead of the Card Element. It allows you to accept multiple payment methods with a single Element. Learn more about when to use the Card Element and Payment Element.
For a wider range of support and future proofing, use the standard integration for asynchronous payments.
この組み込みは、Webhook を使用したりオフラインイベントを処理したりせずに、クライアントから返される応答を待って、サーバーで支払いを確定します。この組み込みはシンプルに見えるかもしれませんが、ビジネスの成長に合わせて拡張するのが難しく、以下のような制限があります。
- カードのみをサポート: ACH や現地で一般的な支払い方法に個別に対応するには、追加のコードを記述する必要があります。
- Double-charge risk—By synchronously creating a new PaymentIntent each time your customer attempts to pay, you risk accidentally double-charging your customer. Be sure to follow best practices.
- クライアントへの追加トリップ: 3D セキュアを備えたカード、または強力な顧客認証 (SCA) などの規制の対象となるカードでは、クライアント側での追加の手順が必要になります。
Keep these limitations in mind if you decide to use this integration. Otherwise, use the standard integration.
カード詳細を収集するクライアント側
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 を作成するサーバ側
リクエストを受信するためにサーバにエンドポイントを設定します。このエンドポイントは、後で でも、追加の認証ステップが必要なカードの処理に使用されます。
Create a new PaymentIntent with the ID of the PaymentMethod created on your client. You can confirm the PaymentIntent by setting the confirm property to true when the PaymentIntent is created or by calling confirm after creation. Separate authorization and capture is also supported for card payments.
支払いで 3D セキュアの認証など、追加のアクションが求められる場合、PaymentIntent のステータスは requires_
に設定されます。支払いが失敗すると、ステータスは requires_
に戻され、ユーザにエラーを表示する必要があります。支払いで追加認証が求められない場合は、支払いが作成され、PaymentIntent のステータスは succeeded
に設定されます。
注
2019-02-11 以前の API のバージョンでは、requires_
の代わりに requires_
、requires_
の代わりに requires_
が表示されます。
If you want to save the card to reuse later, create a Customer to store the PaymentMethod and pass the following additional parameters when creating the PaymentIntent:
- customer. Set to the ID of the Customer.
- setup_future_usage. Set to
off_
to tell Stripe that you plan to reuse this PaymentMethod for off-session payments when your customer is not present. Setting this property saves the PaymentMethod to the Customer after the PaymentIntent is confirmed and any required actions from the user are complete. See the code sample on saving cards after a payment for more details.session
次のアクションを処理するクライアント側
顧客による操作が必要な状況を処理するコードを記述します。支払いは通常、ステップ 4 のサーバーでの確定後に成功します。それに対して、3D セキュアによる認証など、PaymentIntent で顧客による追加アクションが必要になったときに、このコードが機能します。
Use stripe.handleCardAction to trigger the UI for handling customer action. If authentication succeeds, the PaymentIntent has a status of requires_
. Confirm the PaymentIntent again on your server to finish the payment.
While testing, use a test card number that requires authentication (for example, ) to force this flow. Using a card that doesn’t require authentication (for example, ) skips this part of the flow and completes at step 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_ で失敗します。 |
テストカードの一覧については、テストに関するガイドを参照してください。