Blog
Stripeの商品データをAlgoliaにインデックスする方法
Algolia Advent Calendar 2021 19日目の記事です。
Stripeには、ベータ版ですが「Search API」があります。これを使うことで、商品データの検索などを行うことができます。
ですが、複数のデータを使った検索やレコメンデーションなどを求め始めると、Algoliaを使った方が効率的なケースが多いでしょう。
ということで、今回は簡単にですが、Stripeに登録または更新した商品データをAlgoliaにインデックスする方法を紹介します。
データの流れ
商品更新からインデックスまでは、以下のようなフローで行います。
- Stripeで商品データを更新する
- Stripe WebhookがAPIを呼び出す
- Expressで実装したAPIが、Algoliaにインデックスする
Stripe Webhook用 APIを用意する
まずはStripeのWebhookイベントを受け付けるAPIを用意します。
いろいろ方法はありますが、今回は手軽にStripe CLIを利用します。
サンプルアプリをセットアップ
Stripe CLIでサンプルアプリをローカルにDLします。accept-a-paymentなど、Webhookの実装があるものを選ぶようにしましょう。
% stripe samples create accept-a-payment
⣾ Downloading accept-a-payment ✔ Finished downloading
✔ Selected integration: prebuilt-checkout-page
✔ Selected client: react-cra
✔ Selected server: node
⣾ Copying files over… accept-a-payment ✔ Files copied
⣷ Configuring your code… accept-a-payment ✔ Project configured
サーバー側のプロジェクトをセットアップ、起動させましょう。
% cd accept-a-payment/server
% npm install
% npm start
$ node server.js
body-parser deprecated undefined extended: provide extended option server.js:20:17
Node server listening on port 4242!
Stripe CLIで、ローカルのAPIにWebhookイベントをforwardする
Stripe CLIのlistenコマンドで、Stripe WebhookのイベントをローカルAPIで受けれるようにしましょう。
% stripe listen --forward-to localhost:4242/webhook
⡿ Getting ready… > Ready! You are using Stripe API Version [2020-08-27]. Your webhook signing secret is whsec_xxxx
Webhookの実装を変更する
最後に商品データの作成と更新を受け付けるように、Webhookの実装を変更します。
app.post('/webhook', async (req, res) => {
let event;
// Check if webhook signing is configured.
if (process.env.STRIPE_WEBHOOK_SECRET) {
// Retrieve the event by verifying the signature using the raw body and secret.
let signature = req.headers['stripe-signature'];
try {
event = stripe.webhooks.constructEvent(
req.rawBody,
signature,
process.env.STRIPE_WEBHOOK_SECRET
);
} catch (err) {
console.log(`⚠️ Webhook signature verification failed.`);
return res.sendStatus(400);
}
} else {
// Webhook signing is recommended, but if the secret is not configured in `.env`,
// retrieve the event data directly from the request body.
event = req.body;
}
if (!/product/.test(event.type)) {
res.sendStatus(200);
return
}
if (['product.updated','product.created'].includes(event.type)) {
const product = event.data.object
const param = {
objectID: product.id,
description: product.description,
name: product.name,
}
if (product.metadata) {
Object.entries(product.metadata).forEach(([key, value]) => {
param[key] = value
})
}
// Algolia Index処理
}
res.sendStatus(200);
});
APIにAlgoliaのクライアントライブラリを追加
Algoliaへのインデックス処理を実行するライブラリを追加します。
% npm i -S algoliasearch
Algoliaに商品データをインデックスする
先ほど変更したコードをさらに編集します。// Algolia Index処理部分を以下のように変更しましょう。
const algoliaApplicationId = 'XXXX'
const algoliaAdminApiKey = 'XXXX'
const client = algoliasearch(algoliaApplicationId, algoliaAdminApiKey);
const index = client.initIndex("IndexName");
await index.saveObject(param)
この状態で、npm startを再実行し、サーバーを再起動させましょう。
Stripeの商品を追加または更新する
あとはStripe DashboardまたはCLI、APIでデータを更新して実際に動かしてみましょう。Stripe CLIの場合は、以下のような形になります。
% stripe products create --name test --description "example product from cli"
{
"id": "prod_Knw0BhTC5MOcdI",
"object": "product",
"active": true,
"attributes": [
],
"created": 1639900154,
"description": "example product from cli",
"images": [
],
"livemode": false,
"metadata": {
},
"name": "test",
"package_dimensions": null,
"shippable": null,
"statement_descriptor": null,
"tax_code": null,
"type": "service",
"unit_label": null,
"updated": 1639900154,
"url": null
}
AlogliaのIndexを確認する
Algolia側のDashboardで、データの追加や更新が確認できていればOKです。

Tips1: データ更新時のキーについて
algoliasearchライブラリのsaveObjectでは、objectIDが更新時のキーになります。
自動生成させてもよいのですが、Stripeの商品IDがユニークなので、そのままobjectIDに指定して作成も更新も同じ処理でできるようにしています。
Tips2: 価格について
Stripeは、商品データに価格情報を持ちません。商品のIDを利用して、stripe.prices.listを実行し、価格データを取得する必要があります。
AlgoliaにIndexする場合、ケースによってはprice側でIndexをそれぞれ作成し、productが持つデータをそこにマージする形が良いケースもあるかもしれません。
この辺りは、もう少しまとめたものを来年にでも公開できればと思います。
Tools to Support Stripe Development
We provide helpful tools to extend the Stripe Dashboard and streamline development and testing.
View All ToolsRelated Articles
Support This Project
If you find this content helpful, consider supporting the project through GitHub Sponsors. Your support helps maintain and improve these tools.
