チェックアウトページのエラーを修正して売上と顧客ロイヤルティを高める方法
公開: 2022-05-25現代の急速に進化するデジタルの世界では、顧客は企業が提供するオンラインの機会に依存しており、すべてが完璧であると期待しています。 一度カスタマージャーニーでエラーを経験したことがあるこれらのクライアントは、悪いサービスを覚えており、代替の製品/サービスを探すことを好みます。 そのため、困難を防ぎ、業績を常に監視することが非常に重要です。
このケースでは、OWOX BIチームが、売上と顧客ロイヤルティを高めるためにチェックアウトページでエラーを修正するのに苦労した家電および家電製品の小売業者に提供するソリューションについて説明します。
目次
- チャレンジ
- ゴール
- 解決
- ステップ1.エラーに関するデータを収集する
- ステップ2.データを処理する
- ステップ3.取得したデータを使用する
- 結果
チャレンジ
1日あたり約70万人が小売店のウェブサイトにアクセスして、商品のレビューを読んだり、購入したいものを探したりしています。 ただし、ユーザーはチェックアウトページでWebサイトのエラーが発生し、オンラインで注文を完了できなくなり、会社の収益が減少する場合があります。
ゴール
アナリストとテスターは、顧客の苦情を注意深く調査して、典型的なエラーシナリオを定義しました。 スペシャリストが再現できたエラーが修正されました。 残りの重大なバグには、セットアップの監視が必要でした。 以前は、同社はそのようなデータの収集に使用せず、バグの正確な数とそれらがコンバージョン率にどのように影響するかを評価することができませんでした。 また、ユーザーが注文できるように、各バグが特定のユーザーとどのように関連しているかを知る必要がありました。
アナリストは、Webサイトの重大なバグの監視を設定し、顧客がチェックアウトページで正常に注文できるように最善を尽くすことを選択しました。 これにより、売り上げが増加し、顧客のWebサイトのエクスペリエンスが向上します。 課題は、現在Webサイトで何かを注文しようとしている顧客を失うことがないようにするためにリアルタイムの監視が必要だったことです。
解決
目標を達成するために、次の計画が作成されました。
- 追加のコードをウェブサイトに配置して、エラーに関するデータを収集し、GoogleBigQueryに送信します。
- 得られたデータを処理し、会社のニーズに応じた構造でテーブルにエクスポートします。
- ユーザーとエラーに関するデータをコールセンターに送信して、顧客に連絡して注文を支援するように整理します。
会社のデータフローは次のようになります。

ステップ1.エラーに関するデータを収集する
同社はGoogleTagManagerを使用して、ユーザーがオンラインで行っていることを追跡しています。 ただし、ウェブサイトのすべての論理エラーを標準のGoogleTagManagerの方法で追跡できるわけではありません。 これが、カスタムスクリプトが特別に作成され、必要なWebサイトページでGoogleタグマネージャーを介して実装された理由です。 スクリプトは、詳細なエラーデータをDataLayerに追加します。
次に、Google Tag Managerタグを使用して、エラーデータがOWOXBIパイプラインを介してGoogleBigQueryに送信されます。 これにより、GoogleBigQueryのウェブサイトからほぼリアルタイムで生のサンプリングされていないデータを取得できます。
アナリストはAPIを使用して、ユーザーに関するデータをCRMからGoogle BigQueryに送信し、クラウドデータウェアハウスで必要なすべてのデータを取得します。
- エラー時間。
- エラータイプ。
- ユーザーID。
- ユーザーのメールアドレス。
- ユーザー都市。
- カート内の現在の製品ステータス。
ステップ2.データを処理する
OWOX BI Pipelineを使用して、さまざまなパラメータを持つデータテーブルが取得されました。 OWOX BIアナリストは、テーブルからデータをプルするSQLクエリを作成し、明確な構造でデータを返します。各行が1つの間違いに等しい行のセットです。
以下はSQLクエリの例です。
Select date, hour,minute, email, description, City, productIds, productnames, productprice, cartquantity, cartamount, From ( SELECT usererrors.date as date, usererrors.hour as hour, usererrors.minute as minute, usererrors.userEmail as email, usererrors.action as action, usererrors.error as error, case when action = 'disabled' and error = 'buttonCreateOrder' then 'Unable to checkout in cart' when action = 'notAdded' and error = 'productToCart' then 'Unable to add product to cart' when action = 'open' and error = 'emptyCart' then 'Product can not be viewed in cart' when action = 'open' and error = 'HoldingPageCheckout' then 'Maintenance work in progress (after checkout)' when action = 'absent' and error = ƋdiscountCart' then Ƌ% discount unavailable online (in cart)' when action = 'absent' and error = ƋdiscountCheckout' then Ƌ% discount unavailable online (at the checkout page)' when action = 'disabled' and error = 'buttonSubmit' then 'Button "Place Order" not working at the checkout page' else 'Other' end as description, Dimensions.city as City, Dimensions.productids as productIds, Dimensions.productnames as productnames, customMetrics.productprice as productprice, customMetrics.cartquantity as cartquantity, customMetrics.cartamount as cartamount, FROM (SELECT date, hour,minute, hitId, userEmail, eventInfo.eventAction as action, eventInfo.eventLabel as error, hour(CURRENT_TIMESTAMP())+2-hour as currenthour from TABLE_DATE_RANGE([mvideo-ru:Streaming.streaming_], DATE_ADD(CURRENT_TIMESTAMP(), 0 ,'DAY'), DATE_ADD(CURRENT_TIMESTAMP(), 0 , 'DAY') ) where eventInfo.eventCategory = 'Errors' and userEmail is not null group by 1,2,3,4,5,6,7,8) as usererrors left join (SELECT hitId, MAX(IF(customDimensions.index=4, customDimensions.value, NULL)) WITHIN hitId AS city, MAX(IF(customDimensions.index=21, customDimensions.value, NULL)) WITHIN hitId AS productids, Max(IF(customDimensions.index=22, customDimensions.value, NULL)) WITHIN hitId AS productnames from TABLE_DATE_RANGE([mvideo-ru:Streaming.streaming_], DATE_ADD(CURRENT_TIMESTAMP(), 0 ,'DAY'), DATE_ADD(CURRENT_TIMESTAMP(), 0 , 'DAY') )) as Dimensions ON Dimensions.hitId=usererrors.hitId left join (SELECT hitId, MAX(IF(customMetrics.index=1, customMetrics.value, NULL)) WITHIN hitId AS productprice, MAX(IF(customMetrics.index=4, customMetrics.value, NULL)) WITHIN hitId AS cartamount, Max(IF(customMetrics.index=5, customMetrics.value, NULL)) WITHIN hitId AS cartquantity FROM TABLE_DATE_RANGE([mvideo-ru:Streaming.streaming_], DATE_ADD(CURRENT_TIMESTAMP(), 0 ,'DAY'), DATE_ADD(CURRENT_TIMESTAMP(), 0 , 'DAY') )) as customMetrics ON customMetrics.hitId=usererrors.hitId where usererrors.currenthour=0 ) ORDER BY date asc, hour asc, minute asc, email asc
Select date, hour,minute, email, description, City, productIds, productnames, productprice, cartquantity, cartamount, From ( SELECT usererrors.date as date, usererrors.hour as hour, usererrors.minute as minute, usererrors.userEmail as email, usererrors.action as action, usererrors.error as error, case when action = 'disabled' and error = 'buttonCreateOrder' then 'Unable to checkout in cart' when action = 'notAdded' and error = 'productToCart' then 'Unable to add product to cart' when action = 'open' and error = 'emptyCart' then 'Product can not be viewed in cart' when action = 'open' and error = 'HoldingPageCheckout' then 'Maintenance work in progress (after checkout)' when action = 'absent' and error = ƋdiscountCart' then Ƌ% discount unavailable online (in cart)' when action = 'absent' and error = ƋdiscountCheckout' then Ƌ% discount unavailable online (at the checkout page)' when action = 'disabled' and error = 'buttonSubmit' then 'Button "Place Order" not working at the checkout page' else 'Other' end as description, Dimensions.city as City, Dimensions.productids as productIds, Dimensions.productnames as productnames, customMetrics.productprice as productprice, customMetrics.cartquantity as cartquantity, customMetrics.cartamount as cartamount, FROM (SELECT date, hour,minute, hitId, userEmail, eventInfo.eventAction as action, eventInfo.eventLabel as error, hour(CURRENT_TIMESTAMP())+2-hour as currenthour from TABLE_DATE_RANGE([mvideo-ru:Streaming.streaming_], DATE_ADD(CURRENT_TIMESTAMP(), 0 ,'DAY'), DATE_ADD(CURRENT_TIMESTAMP(), 0 , 'DAY') ) where eventInfo.eventCategory = 'Errors' and userEmail is not null group by 1,2,3,4,5,6,7,8) as usererrors left join (SELECT hitId, MAX(IF(customDimensions.index=4, customDimensions.value, NULL)) WITHIN hitId AS city, MAX(IF(customDimensions.index=21, customDimensions.value, NULL)) WITHIN hitId AS productids, Max(IF(customDimensions.index=22, customDimensions.value, NULL)) WITHIN hitId AS productnames from TABLE_DATE_RANGE([mvideo-ru:Streaming.streaming_], DATE_ADD(CURRENT_TIMESTAMP(), 0 ,'DAY'), DATE_ADD(CURRENT_TIMESTAMP(), 0 , 'DAY') )) as Dimensions ON Dimensions.hitId=usererrors.hitId left join (SELECT hitId, MAX(IF(customMetrics.index=1, customMetrics.value, NULL)) WITHIN hitId AS productprice, MAX(IF(customMetrics.index=4, customMetrics.value, NULL)) WITHIN hitId AS cartamount, Max(IF(customMetrics.index=5, customMetrics.value, NULL)) WITHIN hitId AS cartquantity FROM TABLE_DATE_RANGE([mvideo-ru:Streaming.streaming_], DATE_ADD(CURRENT_TIMESTAMP(), 0 ,'DAY'), DATE_ADD(CURRENT_TIMESTAMP(), 0 , 'DAY') )) as customMetrics ON customMetrics.hitId=usererrors.hitId where usererrors.currenthour=0 ) ORDER BY date asc, hour asc, minute asc, email asc
クエリの結果、アナリストは次の情報を含むテーブルを取得しました。

- 日にち;
- 時間;
- 分;
- ユーザーのメールアドレス。
- エラーの説明;
- ユーザー都市;
- カート内の製品のID。
- カート内の製品の名前。
- カート内の製品の価格。
- カート内の製品の総数。
- カート内の商品の合計価格。
次に、OWOX BI BigQuery Reportsアドオンを使用して、Googleスプレッドシートへのデータのインポートを設定しました。このアドオンは、テーブル内の情報を1時間ごとに自動的に更新します。 これは、レポートに過去1時間のエラーに関する最新のデータが常に含まれていることを意味します。
このようなレポートの例を以下に示します。

ステップ3.取得したデータを使用する
担当ユーザーは、エラーに関するレポートを1時間ごとに自動的に受信します(勤務時間に応じて午前9時から午後6時まで)。 次に、修正すべき重大な問題がある場合に備えて会社の開発者に送信し、ユーザーに電話して電話で注文を完了するのを支援するカスタマーサクセスマネージャーに送信します。
結果
- 構造化されたレポートは、ユーザーが購入できないWebサイトのエラーを監視するために作成されました。
- 同社の開発者は、Webサイトにフィードバックフォームを追加しました。 ログインしなかったユーザーにエラーが表示されるたびに自動的に表示されるため、問題を報告して連絡先の詳細を残すことができます。 これにより、会社はエラーやバグに迅速に対応できるだけでなく、ログインしなかったユーザーの連絡先など、顧客ベースを拡大することができます。
- 会社のコールセンターは、製品をカートに追加してチェックアウトするときに問題に直面しているユーザーに関するデータをすばやく取得できます。 コールセンターのオペレーターは、カートの中身を知り、購入を完了するのに役立ちます。
- ウェブサイトのエラーが原因で電話を受けたユーザーの約3%が、電話での注文を正常に完了しました。 これにより、エラーが無視された場合に失われていたであろう追加の$1,600が会社に与えられます。