Firebaseでオンライン決済をするには?

Firebaseでオンライン決済をするには?

記事
IT・テクノロジー

Firebaseでオンライン決済をするには?

Stripeを利用したオンライン決済にもFirebaseを活用できます
Webサイトでオンライン決済ができると、Webサイトで商品の販売ができます。 オンラインコンテンツの販売などをするサイトも簡単に構築できます。
オンライン決済を自分で全て作ろうと思うと大変です。 しかし、外部のオンライン決済サービスを利用して、Firebaseと組み合わせるとオンライン決済も意外に簡単に実現できます。
この記事ではStripeというオンライン決済のサービスを利用して自分のWebサイトに組み込む方法について解説しています。

Stripeとは?

オンライン決済を提供するアメリカのサービスです。日本でもサービスを提供しています。他のサービスもありますが、比較的簡単に実装できるStripeを活用した例をこの記事では紹介します。
Stripeのサイトに行って開発者というメニューを選択すると英語の情報が主体ですが、Stripeを利用したオンライン決済の実装の仕方が解説されています。今回紹介するのが構築済みチェックアウトという仕組みです。
これは、Stripeが決済の為の画面(UI:User Interface)を予め構築しているサービスです。これを利用してご自分のWebページからこの画面を呼び出して決済するという方法です。クレジットカードの入力などの決済の手続きは全てこの画面で行うことができるので、あなたのWebページでは決済情報を扱う必要がありません。

Stripeの決済の流れ

Stripeでオンライン決済を行う場合の流れです。決済の手続きそのものはStripeが代行して行ってくれるので、Webページ側でやる事は、オンライン決済の為のセッションの要求と、決済画面の呼び出しだけです。
1.Stripeの決済のセッションを要求
2.Stripeに決済のためのセッションIDを送って、決済画面を要求
3.Stripeが予め用意した決済画面で決済情報を入力
4.Stripeがオンライン決済を実行
5.結果により指定したWebページにリダイレクト
決済が完了すると、結果によって予め指定したURLにリダイレクトされます。

Firebaseとの関係は?

ここまでの話だと、オンライン決済とFirebaseの関係がよくわかりませんよね? Stripeを用いたオンライン決済では、Firebaseは以下の部分で利用できます!
* オンライン決済のためのセッションを要求するサーバー側のサービス
* オンライン決済を行うWebサイト(Web)ページのホスティング

サーバー側(バックエンド)サービスが必要な理由

Stripeを利用したオンライン決済では、サーバー側(バックエンド)のサービスが必要になります。これは、安全なオンライン決済を行うためです。
もちろん、サーバー側(バックエンド)なしでも、オンライン決済を行う方法はあります。しかし、オンライン決済で起こり得る課題を考えるとサーバー側(バックエンド)のサービスを導入した方がより、安全で確実な決済が行えるからです。
具体的な例を挙げると、例えば販売価格をブラウザーから直接送る場合、最悪の場合は、実際とは違う販売価格を送って決済するという可能性はゼロではありません。利用者が使っているWebブラウザーでフロントエンドのコードは実行されているので、偽のデータを送る可能性を完全に排除するのは難しくなります。
サーバー側(バックエンド)のサービスを導入すると、フロントエンドのWebブラウザーからは、商品コードだけをサーバーに送れば、サーバー側で商品の価格などを取得して、Stripeのオンライン決済の為のセッションんを作る事ができます。
実際の商品情報ではなく、セッションの情報をStripeに送って決済をした方がより安全です。Stripe側では、オンライン決済のセッションを作成する際にサーバ側(バックエンド)のサービスから商品情報や価格情報を受け取った上で、セッションを作成します。
したがって、WebブラウザーがStripeのサーバーにオンライン決済の画面をリクエストする方法の場合は、商品や価格情報は一切送る必要がありません。こうする事で、本来の決済情報と違う情報で決済を実行するリスクを低くする事ができます。

Firebaseでサーバー側のバックエンドサービスを実装!

この実装例では、Firebaseのfunctionsを使って、サーバー側のバックエンドサービスを実装します。フロントエンドからの決済のリクエストを受け取って、その情報を基に、Stripeにオンライン決済のためのセッションをリクエストします。
フロントエンドのブラウザーがサーバー側のバックエンドに送る情報は:
* オンライン決済の為のセッションのリクエスト
* 購入する商品の商品コード(商品ID)
だけです。
サーバー側のバックエンドでは、受け取った商品コード(商品ID)を基に、データベース(FirebaseのCloud Firestore)から商品データを見つけて、他の商品情報や、価格情報、決済通貨などを取得します。
これらの情報から、Stripeが要求する情報と共にStripeにオンライン決済のセッションを要求します。Stripeのこの応答にセッションの情報を添付して送ってきます。サーバー側のバックエンドサービスは受けとったセッション情報をフロントエンドのブラウザーに返します。
処理はこれだけです。サーバー側のバックエンドのサービスというと難しそうですが簡単です。
基本的に使用するモジュールは、「express」と「stripe」です。 Firebaseのデータベースにサーバ側からアクセスするのに「firebase-admin」も利用しています。
Stripeとのやり取りは以下のようなコードになります。 ExpressでURLのルーティング処理をして、セッションのリクエストの場合は、この関数を呼び出すようにします。 なお、この関数を呼び出す前にStripeの秘密鍵(secret key)を使って、Stripeのオブジェクトを作成(初期化)しておく必要があります。
ブラウザーから送られてくる「商品コード(商品ID)productId」使って商品情報をFirebaseから取得します
function getSession(productId:string):string|undefined {
    //
    // サーバー側で商品情報を商品コード(商品ID)から取得
    //
    getProductInfo(productId).then((serverProduct) => {
        // 商品・価格情報
        const price_data = {
            currency: CONSTANT.DEFAULT_CURRENCY,
            product_data: {
                name: serverProduct.name,
            },
            unit_amount: serverProduct.unitAmount * 100,
        };
        // ストライプにオンライン決済のセッションを要求
        stripe.checkout.sessions.create({
            payment_method_types: ["card"],
            line_items: [{
                price_data: price_data,
                quantity: 1,
            }],
            mode: "payment",
            // 決済が成功した場合のリダイレクト先URL
            success_url:SUCCESS_URL,
            // 決済がキャンセルされた場合のリダイレクト先URL
            cancel_url: CANCEL_URL,
        })
        .then((session) => {
            // セッションの取得成功
            // セッションID(session.id)を返す
            return session.id
        })
        .catch((err) => {
            // セッションの取得失敗(エラー
            // 「undefined」を返す
            return undefined;
        })
    }).catch((err) => {
        // 商品情報の取得でエラーの場合
        // 「undefined」を返す
        return undefined;
    });
}

フロントエンドのUIはReactやVueを利用する!

フロントエンドの開発は、ReactやVueを利用して開発すると効率的です。
やることは、商品の一覧などを表示して、利用者が選択した商品を基に決済の処理を開始するという物です。

フロントエンドは基本的にユーザーインターフェース

フロントエンドでやる事は、
販売する商品の選択
*オンライン決済のセッションをリクエスト
*オンライン決済のセッションのIDを使ってStripeに決済画面を要求
*Stripeの画面で決済
*決済後リダイレクト

という一連の処理です。
商品の購入のボタンが押された場合の処理の例です。
async itemSelectionEvent(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) {
    const id: string = e.currentTarget.id;
    const product = this.state.products.find((item) => {
      return item.id === id;
    });
    if (product) {
      // "stripe"の初期化(公開鍵:public key)を使う
      const stripe = await stripePromise;
      // サーバーにStripeの決済セッションを要求
      axios
        .post(CONSTANT.API_STRIPE_PAY, { // 決済のAPIのURL
          // 送る情報は商品コード(商品ID)のみ
          productId: product.id
        })
        .then(async (response: AxiosResponse) => {
          if (stripe && response.data.id) {
            // Stripeの決済画面の要求
            const result = await stripe.redirectToCheckout({
              sessionId: response.data.id,
            });
            if (result.error) {
              console.log(result.error.message);
            }
          } else {
            // Error エラー処理
            // stripe が正しく初期化されていない場合
            // セッションIDが undefined か nullの場合
          }
        })
        .catch((error) => {
          // Error エラー処理
          // セッションリクエスト時のエラー
        })
    } else {
      // 選択された商品が見つからない場合 (基本的にはないはず)
    }
  }
決済の処理は、Stripeが行ってくれて、利用者が支払ったお金はStripeのアカウントに入ります。

まとめ

Firebaseを利用すれば、外部サービスであるStripeなどを利用したオンライン決済の仕組みは簡単に作れます。Firebaseのfunctionsを利用してバックエンドを実装します。バックエンドサーバーのフレームワークとしてよく利用されているexpressを利用すれば、シンプルなプログラムで簡単に実現できます。
決済のユーザーインターフェースも、メインの支払いの画面はStripeが用意してくれているので、フロントエンドでやる事は限定的です。
一番大切なのは、商品の紹介などの部分で、利用者が購入を決めるまでの部分の方が販売に影響します!
なお、Firebseのfunctionsの機能をインターネット上で利用する為には、Firebaseの利用プランをBlaze(従量性の有料プラン)にする必要があります。開発用に、テスト用のサーバーをPCで動かす場合は無料プランでも問題ありません。(firebase serveで利用する場合)
ブログだとソースコードが見づらいですが、ダイレクトメッセージでお問合せを頂ければコードの提供も相談に応じています。
サービス数40万件のスキルマーケット、あなたにぴったりのサービスを探す ココナラコンテンツマーケット ノウハウ記事・テンプレート・デザイン素材はこちら