Stripe and Squid Webhooks
Squidの @webhook デコレーターを使用して、Stripe のイベントに応答します
Webhooks は、イベントが発生したときにアプリまたはサービスから送信される HTTP リクエストです。リクエストのペイロードには、イベントに関する有用な情報が含まれており、それを独自のコード内でアクションを取るために使用できます。通常、製品のダッシュボードを通して HTTP エンドポイントをサービスに提供します。各製品にはそれぞれ webhook を持つ独自のイベントがありますが、以下は一般的なシナリオの一覧です:
- 新規ユーザーの作成
- ユーザーのプロファイルの更新
- データベースまたはストレージの変更
- アナリティクスイベント
このチュートリアルでは、Stripe の顧客の請求書ステータスが「paid」に変更されたときに実行される webhook を作成します。
何を構築するか
- Stripe の webhook に応答して、組み込みのデータベースにデータを追加する Squid バックエンド。
学べること
- Stripe のイベントにフックする Squid Service の作成方法
- データベースにセキュリティを追加する Squid Service の作成方法
必要なもの
- Squid CLI
- Squid アカウント
- Stripe アカウント
- Stripe CLI
- 任意: Auth0 アカウント(React を使用して設定された single-page application)
Environment setup
- 次のコマンドを使用して Squid CLI をインストールします:
npm install -g @squidcloud/cli
- notes-app のコードサンプルをダウンロードします:
squid init-sample stripe-webhooks --template stripe-webhooks
- 好みの IDE でプロジェクトを開きます。
starter プロジェクトには frontend と backend の二つのフォルダがあることに注意してください。ここで記述するコードはバックエンドのみなので、現時点ではフロントエンドに変更を加える必要はありません。最後のセクションでは、リアルタイムにドキュメント更新を確認できるようフロントエンドの構成オプションも用意されています。
Set up the Squid backend
There are two subfolders that make up the stripe-webhooks project: frontend and backend. The backend folder contains the Squid backend for the app.
Navigate to the Squid Console and create a new application named
stripe-webhooks.
- In the Squid Console, navigate to the application overview page and scroll to the Backend project section. Click Create .env file and copy the command.

- In the terminal, change to the backend directory:
cd backend
- Create the
.envfile using the command you copied from the console. The command has the following format:
squid init-env --appId YOUR_APP_ID --apiKey YOUR_API_KEY --environmentId dev --squidDeveloperId YOUR_SQUID_DEVELOPER_KEY --region us-east-1.aws
- Install the required dependencies:
npm install
The backend is now set up and ready to use with a frontend!
Create the webhook service
このセクションで作成する webhook Squid Service は、新しい請求書をそのステータスとともに追加するか、既存の請求書を「paid」というステータスで更新するために設計されています。各フィールドのキーは Stripe の請求書IDで、値は「paid」または「unpaid」となります。
ドキュメントIDはユーザーの認証IDです。セキュリティルールはユーザーが自分自身の請求書のみを閲覧できるように構成されています。イメージとしては以下のような構造になっています:
userPayments:
squidUserId123: {
kaglautA235980A: 'paid'
Edg26GH697dk104: 'unpaid'
...
squidUserId456: {
SFHGhg995gja0435: 'unpaid'
...
backend/src/service/に移動し、stripe-webhook-service.tsファイルを開きます。StripeWebhookServiceクラス内に、次の関数を追加します:
async addInvoiceToDatabase(stripeUserId: string, invoiceId: string, paid: boolean): Promise<string | any> {
const paidStatus = paid ? 'paid' : 'unpaid';
try {
// Find user in database
const userDocs = await this.squid.collection('userPayments').query().eq('stripeUserId', stripeUserId).snapshot();
if (userDocs.length === 0) {
console.log('new user found, adding to database');
const newInvoices = { [invoiceId]: paidStatus };
await this.squid
.collection('userPayments')
.doc('squidUserId123')
.insert({ stripeUserId: stripeUserId, invoices: newInvoices });
return 'new user, database update complete';
}
const newInvoices = { ...userDocs[0].data.invoices, [invoiceId]: paidStatus };
await userDocs[0].update({ invoices: newInvoices });
return 'database update complete';
} catch (error) {
console.error(error);
return error.message;
}
}
このヘルパー関数は、Stripe の顧客ID、Stripe の請求書ID、そして請求書の「paid」ステータスの3つのパラメータを受け取ります。userPayments というコレクションに対して、指定された Stripe 顧客IDに属するドキュメントをクエリし、その請求書を更新して新しい請求書を追加します。
ドキュメントが見つからなかった場合、squidUserId123 というキーで新しいドキュメントを追加します。これは、各 Stripe の顧客には関連付けられた Squid ユーザーIDが存在するはずであり、そのユーザーIDがキーとして使用されるドキュメントが存在するという前提に基づいたデモ用の実装です。実際のアプリでは、このシナリオはエラーとしてログを記録するなど、別の方法で対処することになるでしょう。
addInvoiceToDatabase関数の後に、次のコードを追加します:
@webhook('handleStripePayment')
async handleStripePayment(request: WebhookRequest): Promise<WebhookResponse | any> {
const stripeUserId = request.body.data.object.customer;
const invoiceId = request.body.data.object.id;
const response = await this.addInvoiceToDatabase(stripeUserId, invoiceId, true);
return this.createWebhookResponse(response);
}
この関数は @webhook デコレーターを使用しており、Squid webhook としてマークされています。文字列 handleStripePayment はエンドポイントURLに使用されるので、エンドポイントの目的が明確になるような値を選択してください。
customer および id プロパティは、Stripe から送信されるリクエストのボディ内に含まれています。利用可能なプロパティの詳細については、Stripe documentation on webhooks を参照してください。
これらの属性は addInvoiceToDatabase 関数に渡され、その後、Squid の createWebhookResponse 関数を使用して Stripe にレスポンスが送信されます。
backendフォルダ内で、以下のコマンドを実行してローカルで Squid バックエンドを起動します:
squid start
ターミナルのログには webhook 用の URL が含まれます。ログは次のようになります:
| Available webhooks:
| Webhook URL for handleStripePayment: https://YOUR_APP_ID-dev-YOUR_SQUID_DEVELOPER_ID.us-east-1.aws.squid.cloud/webhooks/SQUID_WEBHOOK_NAME
この URL は後で必要になるので、必ず控えておいてください。
Add a Stripe customer
このセクションを行うには、Stripe アカウント が必要です。
- テストモードで、Stripe ダッシュボードの [Customers] セクションに移動します (https://dashboard.stripe.com/test/customers)。
- Add customer をクリックし、顧客の名前を John Doe など、好みの名前に設定します。
- Add customer をクリックして、新規顧客を保存します。
Add the webhook to Stripe
- Stripe ダッシュボードで Developers をクリックします。
- Developers ページで Wehooks タブをクリックします。
- Add endpoint をクリックします。
- ターミナルログから取得したエンドポイント URL を貼り付けます。念のため、Endpoint URL は以下の形式になっています:
https://YOUR_APP_ID-dev-YOUR_SQUID_DEVELOPER_ID.us-east-1.aws.squid.cloud/webhooks/handleStripePayment
ここで使用している URL 形式は dev 環境向けです。prod 環境の場合のエンドポイント形式は、https://YOUR_APP_IDYOUR_SQUID_DEVELOPER_ID.APP_REGION.squid.cloud/webhooks/SQUID_WEBHOOK_NAME となります。
-
Select events をクリックし、invoice.paid を選択します。検索バーを使用すると便利です。
-
Add endpoint をクリックします。
Test the webhook
-
新しいターミナルウィンドウを開きます。既に2つのターミナルウィンドウが開いているはずです。まだの場合は、Stripe CLI をインストールしてください。
-
Stripe の顧客IDを保存するために環境変数を追加します。Stripe の顧客IDは、Stripe ダッシュボードの Customers セクションの対象顧客の details 内に表示されます。
export customer=YOUR_STRIPE_CUSTOMER_ID
- 以下の Stripe コマンドを使用して、顧客に対して新しい paid 請求書を作成します:
stripe trigger invoice.paid --override invoiceitem:customer=$customer --override invoice:customer=$customer --override payment_method:customer=$customer
このチュートリアルの目的上、これらのフラグの意味について深く理解する必要はありません。Stripe CLI の詳細については、Stripe のリファレンスドキュメント をご確認ください。
このコマンドは、先ほど設定した一時的な環境変数を使用しています。別のターミナルウィンドウで実行する場合は、改めて customer 変数を設定する必要があります。
-
Stripe ダッシュボードで、webhooks タブから自分のエンドポイントを選択します。そこで、発生したイベント、Squid のレスポンス、およびリクエストボディを確認できます。
-
Stripe ダッシュボードの Customers タブを選択し、対象顧客のプロファイルの Invoices セクションまでスクロールします。paid 請求書が追加されていることに気づくはずです。
また、顧客一覧に新たな名前の付いていない顧客が表示されます。Stripe CLI を使って invoice.paid イベントをテストすると新規ユーザーが作成されますが、これはライブイベントでは発生しません。
You did it!
おめでとうございます!Stripe でトリガーされるイベントに応答する Squid Service webhook を作成しました。このセクションでの目標が達成されたのでここで終了しても良いですが、さらに追加することも可能です。
Bonus section: Add a frontend app
バックエンドの更新されたドキュメントデータを確認するため、クエリを追加してドキュメントを取得し、その結果をログ出力することも可能です。しかし、実際のアプリでデータをどのように利用するかを反映するためには、フロントエンドで更新内容を表示するのが最適です。
以下のボーナスステップでは、Stripe のイベントに応じたデータベースのリアルタイム更新を確認できるフロントエンドの構成方法を説明します。
Auth0 アカウント(React を使用して設定された single-page application)が必要です。
Add the Auth0 integration
- まだ Auth0 アプリを作成していない場合は、Auth0 アカウント をセットアップし、React を使用して設定された single-page application を作成します。
コールバック URL とログアウト URL の追加時には、http://localhost:5173を使用してください。 dev環境の Squid Console で、Integrations タブを選択します。- Available integrations タブをクリックして、すべてのインテグレーションを表示します。
- Auth0 インテグレーションまでスクロールし、Add integration をクリックします。
- Integration ID に auth0 と入力します。
- Auth0 アプリの client ID と domain を入力します。これらは Auth0 コンソールで確認できます。
- Add integration をクリックします。
Add Squid to the frontend
The following steps add configuration parameters to connect the application to Squid.
- Open a new terminal window and navigate to the project's frontend. You should now have two open terminal windows: one for the app's backend and one for the frontend.
cd frontend
- Install the required dependencies:
npm install
- Run the following command to create a
.env.localfile with the Squid environment configuration needed to initialize Squid:
npm run setup-env
frontend/src/main.tsxに移動します。Auth0Providerコンポーネントがあり、設定が必要であることに注目してください:
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<Auth0Provider
domain="AUTH0_DOMAIN"
clientId="AUTH0_CLIENT_ID"
authorizationParams={{
redirect_uri: window.location.origin,
audience: 'auth0-api-id',
}}
>
<SquidContextProvider
options={{
appId: import.meta.env.VITE_SQUID_APP_ID,
region: import.meta.env.VITE_SQUID_REGION,
environmentId: import.meta.env.VITE_SQUID_ENVIRONMENT_ID,
squidDeveloperId: import.meta.env.VITE_SQUID_DEVELOPER_ID,
}}
>
<App />
</SquidContextProvider>
</Auth0Provider>
);
-
Auth0Providerコンポーネント内のプレースホルダーを、Auth0 アプリの domain と client ID に置き換えます。 -
frontend/src/App.tsxファイルを開きます。stripeUserId変数のプレースホルダーを、作成した Stripe の顧客の顧客IDに置き換えます。Stripe ダッシュボードでこのIDを確認できます。
...
function App() {
const stripeUserId = '[YOUR_STRIPE_CUSTOMER_ID]'
...
frontendフォルダ内で、以下のコマンドを実行します:
npm run dev
-
フロントエンドアプリを表示するには、ターミナルに表示された PORT 番号の localhost:PORT に移動します。通常、アドレスは
http://localhost:5173となります。 -
Log in ボタンを使用してログインします。
-
Add mock data をクリックして、架空の請求書を生成します。
-
Stripe コマンドを実行しているターミナルウィンドウで、顧客に対して別の paid 請求書を作成します。可能であれば、別の画面で実行するか、ターミナルウィンドウのサイズを縮小して、Webアプリも同時に確認できるようにしてください。
stripe trigger invoice.paid --override invoiceitem:customer=$customer --override invoice:customer=$customer --override payment_method:customer=$customer
- Webアプリ上で、新しい paid 請求書が表示されていることを確認します。素晴らしいですね!
Congratulations! 🦑
お疲れ様でした!Stripe でトリガーされたイベントに応答する webhook を Squid Service で作成し、さらにリアルタイムで変更内容を確認できるフロントエンドも構成できました。
Next steps
Squid でエンドポイントを作成したので、次のことに挑戦してみてください:
- Squid で複数のエンドポイントを追加し、他の Stripe イベントに接続する。
- 他の製品で webhook を使用する場合に、Squid のエンドポイントを接続する。
- Squid Backend SDK に用意されているその他の機能については、Check out the docs をご確認ください。