StripeとTwilioでSMS認証機能搭載の高速チェックアウトシステムを実装する方法

April 17, 2020
執筆者
Thor 雷神 Schaeff
寄稿者
Twilio の寄稿者によって表明された意見は彼ら自身のものです
レビュー担当者

Build fast checkout with SMS verification using Stripe and Twilio

この記事はTwilioデベロッパーエバンジェリストのKelley Robinsonが2020年4月に公開した記事(英語)の日本語版です。スクリーンショットや執筆者の所属、タイトルは公開時点のものです。

StripeとTwilioが協力し、サンプルアプリケーションを構築しました。このサンプルアプリケーションでは、顧客から支払い情報を安全に収集して保存する機能やTwilio Verifyを用いてリピート顧客に対して既に登録されているカード情報を用いた請求を行う前に認証コードを送信する機能が実装されています。

デモとリソース

YouTubeチャンネル「Stripe Developers」では、サンプルアプリケーションの設定方法を説明したこのチュートリアルの動画版を視聴できます。

YouTube - Checkout Remember Me with Twilio Verify

ローカルマシンでのサンプル実行

サンプルアプリケーションには、JavaScript(Node.js)形式とPython(Flask)形式の2つのバックエンド実装が用意されています。今回のチュートリアルでは、Node.jsバックエンドの設定方法について説明します。Python Flaskサーバーの実行手順についてはこちらを参照してください。

Stripe CLIを使用したサンプルの作成

Stripe CLIを使用し、Stripeサンプルを非常に簡単に設定できます。こちらの手順に従い、CLIをインストールします。

次に、Stripeアカウントにログインします。アカウントはこちらから作成できます。ログイン後、以下を実行します。https://www.youtube.com/watch?v=gjh5gOalYcM

stripe login

手順に従い、自身のアカウントでCLIを認証します。

以下のコマンドを実行し、サンプルを作成し、バックエンドの選択画面でnodeを選択します。

stripe samples create checkout-remember-me-with-twilio-verify

Stripe CLI

次に、新たに作成したサンプルフォルダに移動し、依存関係をインストールします。

cd checkout-remember-me-with-twilio-verify/server
npm install

注記: .envファイルの値はSTRIPE_PUBLISHABLE_KEYを除き、外部に情報を共有しないでください。.envファイルをコミットしないように十分に注意してください。

Stripe CLIがテストAPIキーを含んだ.envファイルを自動的に設定します。この.envファイルを開き、以下のTwilio識別子を追加します。

変数説明
ACCOUNT_SIDTwilioコンソール内を検索
AUTH_TOKENTwilioコンソール内を検索
VERIFY_SERVICE_SIDVerifyサービスを作成し、Verify SIDを取得

Twilioアカウントはこちらのリンクから作成できます。(このリンクを使用するとアカウントのアップグレード時に10米国ドル相当分のクレジットが追加で付与されます。)

Verifyサービスについては新しいサービスをTwilioコンソールで作成します。

Verify Service

Verify SIDは[General Settings]で確認できます。

Verify Service SID

必要な環境変数がすべて設定できたため、次にローカルサーバーを起動します。

npm start

これで、http://localhost:4242/でアプリケーションが起動しました。 🎉

ソースコードの確認

国際電話番号入力フィールドの設定

国選択機能を提供し、クライアント側で電話番号の形式の設定と検証を行うために、オープンソースライブラリintl-tel-inputを使用します。

// client/script.js
 
// Format phone number input field
const phoneInputField = document.querySelector('#phone');
const phoneInput = window.intlTelInput(phoneInputField, {
  separateDialCode: true,
  utilsScript: 'build/js/utils.js',
});
// Validate input
phoneInput.isValidNumber();
// Format input
phoneInput.getNumber();

クライアント側で入力を検証することでサーバーへのリクエスト件数を最小限に抑え、ユーザーにフィードバックをスピーディに提供できます。その結果、ユーザーエクスペリエンスを向上できます。

サーバー側で電話番号を検索

クライアント側での検証は非常に重要ですが、それだけでは十分とは言えません。そのため、Lookup APIを実行しサーバー上でも電話番号を確認します。

// server/server.js
 
try {
  // Validate the phone number input
  const number = await client.lookups.phoneNumbers(phone).fetch();
  number.phoneNumber; // Is valid number
} catch (error) {
  // Not a valid number
}

顧客の支払情報の収集と保存

顧客の支払情報を安全に収集するために、セットアップモードでStripe Checkoutを使用します。

// server/server.js
 
// Create a new customer object
const customer = await stripe.customers.create({
  phone: number.phoneNumber,
  email,
});
 
// Create a CheckoutSession to set up our payment methods recurring usage
const checkoutSession = await stripe.checkout.sessions.create({
  payment_method_types: ['card'],
  mode: 'setup',
  customer: customer.id,
  success_url: `${req.headers.origin}?session_id={CHECKOUT_SESSION_ID}`,
  cancel_url: `${req.headers.origin}/`,
});

生成されるチェックアウトセッションIDを使用し、Stripeがホストする支払いフォームに顧客をリダイレクトします。

// client/script.js

// Recirect to Checkout
await stripe.redirectToCheckout({ sessionId: checkoutSession.id });

入力されたクレジットカード情報をStripe Checkoutで検証し、有効な場合は顧客オブジェクトにそれをアタッチします。その後、顧客をアプリケーションにリダイレクトし、保存された顧客のクレジットカード情報を利用します。

認証コードの送信

保存されている支払い情報に対して請求を行うには、顧客が認証されており、顧客のクレジットカードへの請求が許可されていることを確認する必要があります。こちらの例では、Twilio Verifyを使用し顧客の電話番号に認証コードを送信することで本人認証を行っています。

次のような手間のかかる作業はすべてTwilio Verifyで自動的に処理されます。

  • 世界的に認知されているショートコードまたは英数字の送信者IDからの送信
  • 配信到達性を上げるために世界中のキャリアが許可リストに登録しているメッセージテンプレートの使用
  • ランダムな認証コードの生成とその有効期限の管理

このスニペットは認証コードを生成し、顧客へと送信します。

// server/server.js
 
// Start Twilio verify
const verification = await client.verify
  .services(process.env.VERIFY_SERVICE_SID)
  .verifications.create({ to: customer.phone, channel: 'sms' });

認証コードの確認

次に、顧客がアプリケーションに入力したコードを取得し、Twilio側で確認します。

// server/server.js
 
try {
  // Check Twilio verify code
  const verificationCheck = await client.verify
    .services(process.env.VERIFY_SERVICE_SID)
    .verificationChecks.create({ to: customer.phone, code });
 
  // Check the status
  if (verificationCheck.status === 'approved') {
    // Verification code is valid
  }
} catch (error) {
  // Incorrect code
}

顧客への請求

認証が完了したため、保存されているクレジットカード情報に対して請求をお子います。

// server/server.js
 
// Charge the stored method
const paymentIntent = await stripe.paymentIntents.create({
  amount,
  currency,
  customer: customerId,
  payment_method: paymentMethods.data[0].id,
  off_session: false, // Customer is on-session during checkout
  confirm: true, // Confirm and charge payment immediately
});

Stripe Webhookイベントのリッスン

Stripe CLIでは、ローカルで実行しているサーバーにWebhookイベントを転送してWebhookをテストできます。例として別のターミナルウィンドウで以下のコマンドを実行します。

stripe listen --forward-to localhost:4242/webhook

CLIが実行されているターミナルにイベントが表示され、ローカルサーバーの/webhookのルートにWebhookイベントが転送されます。

ご不明な点は、

今回のチュートリアルが皆さんのお役に立てば幸いです ❤️ フィードバックやご質問がある場合は、Twitterで投稿者までご連絡ください。