購入完了ファネルを分析する
Analytics 4 で、Stripe Checkout の購入完了ファネルを分析します。
Google Analytics 4 (GA4) を使用して、顧客が Stripe Checkout の購入ファネルを進む状況を追跡します。始める前に、GA4 のアカウントを設定して、GA4 プロパティーを追加します。
サイトを設定する
購入ボタンのある商品ページを作成します。
product.html<html> <head> <title>Buy cool new product</title> </head> <body> <script> window.addEventListener("load", function () { document .getElementById("submit") .addEventListener("click", function (event) { event.preventDefault(); fetch("/create-checkout-session", { method: "POST", }) .then((response) => response.json()) .then((checkoutSession) => { window.location.href = checkoutSession.url; }); }); }); </script> <form> <button id="submit">Checkout</button> </form> </body> </html>
Checkout セッションを作成してページを提供するサーバー側エンドポイントを作成します。
index.js// This example sets up endpoints using the Express framework. const express = require("express"); require("dotenv").config(); const app = express(); // Set your secret key. Remember to switch to your live key in production! // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')(
); const request = require("request"); app.post( "/create-checkout-session", express.urlencoded({ extended: false }), async (req, res) => { const session = await stripe.checkout.sessions.create({ payment_method_types: ["card"], line_items: [ { price_data: { currency: "usd", product_data: { name: "T-shirt", }, unit_amount: 2000, }, quantity: 1, }, ], mode: "payment", success_url: req.get("origin") + "/success", cancel_url: req.get("origin") + "/cancel", }); res.json({ url: session.url }); } ); app.get("/product", function (req, res) { res.sendFile(__dirname + "/product.html"); }); app.get("/success", function (req, res) { res.sendFile(__dirname + "/success.html"); }); app.get("/cancel", function (req, res) { res.sendFile(__dirname + "/cancel.html"); }); app.listen(4242, () => console.log(`Listening on port ${4242}!`));'sk_test_BQokikJOvBiI2HlWgH4olfQ2'成功ページを作成します。
success.html<html> <head> <title>Thanks for your order!</title> </head> <body> <h1>Thanks for your order!</h1> <p> We appreciate your business! If you have any questions, please email <a href="mailto:orders@example.com">orders@example.com</a>. </p> </body> </html>
キャンセル後のページを作成します。
canceled.html<html> <head> <title>Order Canceled!</title> </head> <body> <p> <a href="/product">Start another order</a>. </p> </body> </html>
インストルメンテーションの説明
次の例では、顧客が次の状況であると想定しています。
- 商品ページを閲覧した。
- 購入ボタンをクリックし、Stripe Checkout にリダイレクトされた。
- 支払いを完了し、成功ページにリダイレクトされた。
簡単な要約
方法 | 商品を閲覧 | 購入ボタンをクリック | 購入を完了 |
---|---|---|---|
クライアント側 | product ページに Google Analytics のタグを追加する | Stripe Checkout にリダイレクトする前にイベントを記録する | success ページに Google Analytics のタグを追加する |
サーバー側 | 該当なし | Stripe Checkout にリダイレクトする前にイベントを記録する | checkout. Webhook を受信したときにイベントを記録する |
クライアント ID が保存されているサーバー側 | 該当なし | 該当なし | checkout. Webhook を受信したときにイベントを記録し、クライアント側イベントに関連付ける |
インストルメンテーションを追加する
参照元除外リストに
checkout.
を追加します。stripe. com 商品ページ、成功ページ、キャンセルページに Google アナリティクスのタグを追加します。タグによって、ページの読み込み時に自動的にイベントが発生します。
product.html<html> <head> <!-- START GOOGLE ANALYTICS --> <script async src="https://www.googletagmanager.com/gtag/js?id=<GOOGLE_ANALYTICS_CLIENT_ID>" ></script> <script> window.dataLayer = window.dataLayer || []; function gtag() { window.dataLayer.push(arguments); } gtag("js", new Date()); gtag("config", "<GOOGLE_ANALYTICS_CLIENT_ID>"); </script> <!-- END GOOGLE ANALYTICS --> <title>Buy cool new product</title> </head> <body> <script> window.addEventListener("load", function () { document .getElementById("submit") .addEventListener("click", function (event) { event.preventDefault(); fetch("/create-checkout-session", { method: "POST", }) .then((response) => response.json()) .then((checkoutSession) => { window.location.href = checkoutSession.url; }); }); }); </script> <form> <button id="submit">Checkout</button> </form> </body> </html>
success.html<html> <head> <!-- START GOOGLE ANALYTICS --> <script async src="https://www.googletagmanager.com/gtag/js?id=<GOOGLE_ANALYTICS_CLIENT_ID>" ></script> <script> window.dataLayer = window.dataLayer || []; function gtag() { window.dataLayer.push(arguments); } gtag("js", new Date()); gtag("config", "<GOOGLE_ANALYTICS_CLIENT_ID>"); </script> <!-- END GOOGLE ANALYTICS --> <title>Thanks for your order!</title> </head> <body> <h1>Thanks for your order!</h1> <p> We appreciate your business! If you have any questions, please email <a href="mailto:orders@example.com">orders@example.com</a>. </p> </body> </html>
canceled.html<html> <head> <!-- START GOOGLE ANALYTICS --> <script async src="https://www.googletagmanager.com/gtag/js?id=<GOOGLE_ANALYTICS_CLIENT_ID>" ></script> <script> window.dataLayer = window.dataLayer || []; function gtag() { window.dataLayer.push(arguments); } gtag("js", new Date()); gtag("config", "<GOOGLE_ANALYTICS_CLIENT_ID>"); </script> <!-- END GOOGLE ANALYTICS --> <title>Order Canceled!</title> </head> <body> <p> <a href="/product">Start another order</a>. </p> </body> </html>
Stripe Checkout にリダイレクトする直前にイベントを発生させます。
product.html<html> <head> <!-- START GOOGLE ANALYTICS --> <script async src="https://www.googletagmanager.com/gtag/js?id=<GOOGLE_ANALYTICS_CLIENT_ID>" ></script> <script> window.dataLayer = window.dataLayer || []; function gtag() { window.dataLayer.push(arguments); } gtag("js", new Date()); gtag("config", "<GOOGLE_ANALYTICS_CLIENT_ID>"); </script> <!-- END GOOGLE ANALYTICS --> <title>Buy cool new product</title> </head> <body> <script> window.addEventListener("load", function () { document .getElementById("submit") .addEventListener("click", function (event) { event.preventDefault(); fetch("/create-checkout-session", { method: "POST", }) .then((response) => response.json()) .then((checkoutSession) => { window.location.href = checkoutSession.url; gtag("event", "begin_checkout", { event_callback: function () { window.location.href = checkoutSession.url; }, }); }); }); }); </script> <form> <button id="submit">Checkout</button> </form> </body> </html>
購入完了ファネルのメトリクスを分析する
適切なインストルメンテーションを追加すると、購入完了ファネルで定義された各ステップに対応するメトリクスを確認できます。
- 商品ページの閲覧数: 商品ページを閲覧したページ訪問者の数。
- begin_checkout イベント数: 購入ボタンをクリックして Stripe Checkout にリダイレクトされたページ訪問者の数。
- 成功ページの閲覧数: 購入を完了し、成功ページにリダイレクトされたページ訪問者の数。
これらの数値を使用して、訪問者が購入完了ファネルのどこで離脱しているのか確認できます。
オプションサーバー側のイベント記録
この例では、購入の完了を追跡するために、ユーザーが成功ページに到達するシナリオを想定しています。これはおおむねほとんどのユースケースに適していますが、次のような状況では包括的な解決策にならない可能性があります。
- 成功ページが指定されていない決済フロー。
- 成功ページへのリダイレクトが失敗した場合でも、購入完了メトリクスをログに記録することが重要な場合。
- 成功 URL に有用な情報 (配送の進捗状況や確認番号など) が記載されているために、顧客がこの URL を頻繁に更新している状況。
イベントハンドラー
成功ページを使用せずに購入の完了メトリクスを記録するには、イベントハンドラーを設定して checkout.
イベントを取得するたびにメトリクスを記録します。
次の強調表示されたコードを追加した後は、成功ページの閲覧数の代わりに、purchase
メトリクスを使用して、購入を完了した訪問者数を分析できます。
// This example sets up endpoints using the Express framework. const express = require("express"); require("dotenv").config(); const app = express(); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')(
); const request = require("request"); app.post( "/create-checkout-session", express.urlencoded({ extended: false }), async (req, res) => { const session = await stripe.checkout.sessions.create({ payment_method_types: ["card"], line_items: [ { price_data: { currency: "usd", product_data: { name: "T-shirt", }, unit_amount: 2000, }, quantity: 1, }, ], mode: "payment", success_url: req.get("origin") + "/success", cancel_url: req.get("origin") + "/cancel", }); res.json({ url: session.url }); } ); app.get("/product", function (req, res) { res.sendFile(__dirname + "/product.html"); }); app.get("/success", function (req, res) { res.sendFile(__dirname + "/success.html"); }); app.get("/cancel", function (req, res) { res.sendFile(__dirname + "/cancel.html"); }); app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => { const payload = req.body; const sig = req.headers["stripe-signature"]; let event; try { event = stripe.webhooks.constructEvent( payload, sig, process.env.STRIPE_WEBHOOK_SECRET ); } catch (err) { return res.status(400).send(`Webhook Error: ${err.message}`); } if (event.type === "checkout.session.completed") { // Record metrics using the Google Analytics Measurement Protocol // See https://developers.google.com/analytics/devguides/collection/protocol/ga4 const MEASUREMENT_ID = <GOOGLE_ANALYTICS_MEASUREMENT_ID>; // GA4 Measurement ID const API_SECRET = <GOOGLE_ANALYTICS_API_SECRET>; // GA4 Measurement Protocol API secret fetch("https://www.google-analytics.com/mp/collect?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}", { method: "POST", body: JSON.stringify({ client_id: 'XXXXXXXXXX.YYYYYYYYYY', // Client ID events: [{ name: "purchase", params: {}, }] }) }); } res.status(200); }); app.listen(4242, () => console.log(`Listening on port ${4242}!`));'sk_test_BQokikJOvBiI2HlWgH4olfQ2'
オプションクライアント側とサーバー側のイベントを関連付ける
サーバー側のイベント記録では、匿名のクライアント ID に対するサーバー側のメトリクスを記録しました。この ID はページ閲覧数のメトリクスとは異なるため、Google Analytics にはページ閲覧数と購入メトリクスを関連付ける手段がありません。クライアント側とサーバー側のメトリクスの関連付けを維持するには、次のようにします。
訪問者に固有の ID (Google アナリティクスのクライアント ID など) を選択し、サーバーに送信します。
product.html<html> <head> <!-- START GOOGLE ANALYTICS --> <script async src="https://www.googletagmanager.com/gtag/js?id=<GOOGLE_ANALYTICS_CLIENT_ID>" ></script> <script> window.dataLayer = window.dataLayer || []; function gtag() { window.dataLayer.push(arguments); } gtag("js", new Date()); gtag("config", "<GOOGLE_ANALYTICS_CLIENT_ID>"); </script> <!-- END GOOGLE ANALYTICS --> <title>Buy cool new product</title> </head> <body> <script> window.addEventListener("load", function () { document .getElementById("submit") .addEventListener("click", function (event) { event.preventDefault(); fetch("/create-checkout-session", { method: "POST", }) .then((response) => response.json()) .then((checkoutSession) => { gtag("event", "begin_checkout", { event_callback: function () { window.location.href = checkoutSession.url; }, }); // Get the analytics client id (https://developers.google.com/tag-platform/gtagjs/reference) // and send it to the server so it can be linked with the checkout session gtag("get", "<GOOGLE_ANALYTICS_CLIENT_ID>", "client_id", (clientID) => { fetch("/create-checkout-session", { method: "POST", body: new URLSearchParams({ analyticsClientId: clientID }), }) .then((response) => response.json()) .then((checkoutSession) => { gtag("event", "begin_checkout", { event_callback: function () { gtag("event", "begin_checkout", { event_callback: function () { window.location.href = checkoutSession.url; }, }); }, }); }); }); }); }); </script> <form> <button id="submit">Checkout</button> </form> </body> </html>
リクエストから ID を読み取ります。
Checkout セッションのメタデータに ID を格納します。
ID を取得し、イベントを記録するリクエストとともに送信します。
index.js// This example sets up endpoints using the Express framework. const express = require("express"); require("dotenv").config(); const app = express(); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')(
); const request = require("request"); app.post( "/create-checkout-session", express.urlencoded({ extended: false }), async (req, res) => { const session = await stripe.checkout.sessions.create({ payment_method_types: ["card"], line_items: [ { price_data: { currency: "usd", product_data: { name: "T-shirt", }, unit_amount: 2000, }, quantity: 1, }, ], mode: "payment", success_url: req.get("origin") + "/success", cancel_url: req.get("origin") + "/cancel", metadata: { analyticsClientId: req.body.analyticsClientId, }, }); res.json({ url: session.url }); } ); app.get("/product", function (req, res) { res.sendFile(__dirname + "/product.html"); }); app.get("/success", function (req, res) { res.sendFile(__dirname + "/success.html"); }); app.get("/cancel", function (req, res) { res.sendFile(__dirname + "/cancel.html"); }); app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => { const payload = req.body; const sig = req.headers["stripe-signature"]; let event; try { event = stripe.webhooks.constructEvent( payload, sig, process.env.STRIPE_WEBHOOK_SECRET ); } catch (err) { return res.status(400).send(`Webhook Error: ${err.message}`); } if (event.type === "checkout.session.completed") { // Record metrics using the Google Analytics Measurement Protocol // See https://developers.google.com/analytics/devguides/collection/protocol/ga4 const params = new URLSearchParams({ v: "1", // Version tid: <GOOGLE_ANALYTICS_CLIENT_ID>, // Tracking ID / Property ID. cid: "555", // Anonymous Client ID cid: event.data.object.metadata.analyticsClientId, // Client ID t: "event", // Event hit type ec: "ecommerce", // Event Category ea: "purchase", // Event Action }); request(`https://www.google-analytics.com/batch?${params.toString()}`, { method: "POST", }); } res.status(200); }); app.listen(4242, () => console.log(`Listening on port ${4242}!`));'sk_test_BQokikJOvBiI2HlWgH4olfQ2'
オプションサーバー側のリダイレクト
この例では、Stripe へのリダイレクトがクライアント側で発生すると想定しています。サーバー側から Stripe にリダイレクトする必要がある場合は、Stripe Checkout へのリダイレクトの直前に、サーバーで 'begin_
メトリクスを記録します。
// This example sets up endpoints using the Express framework. const express = require("express"); require("dotenv").config(); const app = express(); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')(
); const request = require("request"); app.post( "/create-checkout-session", express.urlencoded({ extended: false }), async (req, res) => { const session = await stripe.checkout.sessions.create({ payment_method_types: ["card"], line_items: [ { price_data: { currency: "usd", product_data: { name: "T-shirt", }, unit_amount: 2000, }, quantity: 1, }, ], mode: "payment", success_url: req.get("origin") + "/success", cancel_url: req.get("origin") + "/cancel", }); res.json({ url: session.url }); // Record metrics using the Google Analytics Measurement Protocol // See https://developers.google.com/analytics/devguides/collection/protocol/ga4 const MEASUREMENT_ID = <GOOGLE_ANALYTICS_MEASUREMENT_ID>; // GA4 Measurement ID const API_SECRET = <GOOGLE_ANALYTICS_API_SECRET>; // GA4 Measurement Protocol API secret fetch("https://www.google-analytics.com/mp/collect?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}", { method: "POST", body: JSON.stringify({ client_id: 'XXXXXXXXXX.YYYYYYYYYY', // Client ID events: [{ name: "begin_checkout", params: {}, }] }) }); res.redirect(303, session.url); } ); app.get("/product", function (req, res) { res.sendFile(__dirname + "/product.html"); }); app.get("/success", function (req, res) { res.sendFile(__dirname + "/success.html"); }); app.get("/cancel", function (req, res) { res.sendFile(__dirname + "/cancel.html"); }); app.listen(4242, () => console.log(`Listening on port ${4242}!`));'sk_test_BQokikJOvBiI2HlWgH4olfQ2'
<html> <head> <!-- START GOOGLE ANALYTICS --> <script async src="https://www.googletagmanager.com/gtag/js?id=<GOOGLE_ANALYTICS_CLIENT_ID>" ></script> <script> window.dataLayer = window.dataLayer || []; function gtag() { window.dataLayer.push(arguments); } gtag("js", new Date()); gtag("config", "<GOOGLE_ANALYTICS_CLIENT_ID>"); </script> <!-- END GOOGLE ANALYTICS --> <title>Buy cool new product</title> </head> <body> <script> window.addEventListener("load", function () { document .getElementById("submit") .addEventListener("click", function (event) { event.preventDefault(); fetch("/create-checkout-session", { method: "POST", }) .then((response) => response.json()) .then((checkoutSession) => { gtag("event", "begin_checkout", { event_callback: function () { window.location.href = checkoutSession.url; }, }); }); }); }); </script> <form> <button id="submit">Checkout</button> <form action="/create-checkout-session" method="POST"> <button type="submit">Checkout</button> </form> </body> </html>