😀
Firebase Hosting でホスティングしているアプリにStripeを統合する
Firebase Hosting でアプリをホスティングしている場合、Stripe を統合するには、Firebase Functions(サーバーサイドロジック)とフロントエンド(Reactアプリ)を組み合わせて構築する。
手順
Firebaseのセッティング
- Firebase CLI をインストール(未インストールの場合)
npm install -g firebase-tools
- Firebaseプロジェクトにログイン
firebase login
- Firebaseプロジェクトを初期化
firebase init
初期化の際の質問事項は必要に応じて選択。
StripeのバックエンドをFirebase Functionsに構築
Firebase Functions を使用するように設定していると、開発しているアプリケーションの中にfunctionsという名前のディレクトリが作成されており、ここにFirebase側で実行させたい処理を追加していくことになる。
- Stripeライブラリをインストール
Firebase Functionsのディレクトリ(通常 functions/)に移動し、Stripe SDKをインストールする。
cd functions
npm install stripe
npm install firebase-functions firebase-admin
- PyamentIntentエンドポイントを作成
functions/index.jsまたはindex.tsに以下を追加。
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const stripe = require("stripe")("sk_test_YourSecretKey"); // あなたのStripeシークレットキー
admin.initializeApp();
// PaymentIntent を作成するエンドポイント
exports.createPaymentIntent = functions.https.onRequest(async (req, res) => {
try {
const amount = req.body.amount; // クライアントから送信された支払額(例: 1000 = 10.00 USD)
const currency = req.body.currency || "usd"; // デフォルトはUSD
const paymentIntent = await stripe.paymentIntents.create({
amount,
currency,
automatic_payment_methods: { enabled: true }, // 支払い方法を自動管理
});
res.status(200).send({
clientSecret: paymentIntent.client_secret,
});
} catch (error) {
console.error(error);
res.status(500).send({ error: error.message });
}
});
- デプロイ
Firebase Functionsをデプロイ
firebase deploy --only functions
デプロイ後、createPaymentIntent 関数のURLが表示されるので、これをメモしておくことを忘れずに。(例: https://<region>-<project-id>.cloudfunctions.net/createPaymentIntent)。
Reactアプリのフロントエンドを構築
- Stripeのライブラリをインストール
npm install @stripe/react-stripe-js @stripe/stripe-js
- Stripe.jsの統合
- フロントエンドで PaymentIntent を取得し、Stripe Elements を利用。
// src/CheckoutForm.tsx
import React, { useState } from "react";
import { useStripe, useElements, PaymentElement } from "@stripe/react-stripe-js";
const CheckoutForm: React.FC = () => {
const stripe = useStripe();
const elements = useElements();
const [isProcessing, setIsProcessing] = useState(false);
const [errorMessage, setErrorMessage] = useState("");
const handleSubmit = async (event: React.FormEvent) => {
event.preventDefault();
if (!stripe || !elements) return;
setIsProcessing(true);
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: window.location.origin + "/success", // 支払い成功後のリダイレクトURL
},
});
if (error) {
setErrorMessage(error.message || "支払いエラーが発生しました");
}
setIsProcessing(false);
};
return (
<form onSubmit={handleSubmit}>
<PaymentElement />
<button disabled={!stripe || isProcessing} type="submit">
{isProcessing ? "処理中..." : "支払う"}
</button>
{errorMessage && <p>{errorMessage}</p>}
</form>
);
};
export default CheckoutForm;
- App に組み込む
CheckoutForm を Stripe.js にラップしてレンダリング。
// src/App.tsx
import React, { useEffect, useState } from "react";
import { loadStripe } from "@stripe/stripe-js";
import { Elements } from "@stripe/react-stripe-js";
import CheckoutForm from "./CheckoutForm";
const stripePromise = loadStripe("pk_test_YourPublishableKey"); // あなたの公開可能キー
const App: React.FC = () => {
const [clientSecret, setClientSecret] = useState("");
useEffect(() => {
// Firebase Functions のエンドポイントから PaymentIntent を取得
fetch("https://<your-cloud-function-url>/createPaymentIntent", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ amount: 1000 }), // 金額を指定(例: $10.00)
})
.then((res) => res.json())
.then((data) => setClientSecret(data.clientSecret));
}, []);
const options = {
clientSecret,
};
return (
<div>
<h1>Stripe Checkout</h1>
{clientSecret && (
<Elements stripe={stripePromise} options={options}>
<CheckoutForm />
</Elements>
)}
</div>
);
};
export default App;
- Reactアプリをデプロイ
ビルドしてデプロイ
npm run build
firebase deploy --only hosting
以上。
Discussion