如何通過修復結帳頁面上的錯誤來提高銷售額和客戶忠誠度
已發表: 2022-05-25在現代、快速發展的數字世界中,客戶依賴企業提供的在線機會,並期望一切都完美無缺。 一旦在客戶旅程中遇到任何錯誤,這些客戶會記住糟糕的服務,並更願意尋找替代產品/服務。 這就是為什麼防止任何困難並不斷監控業務績效如此重要的原因。
在這種情況下,我們描述了 OWOX BI 團隊為一家消費電子和家電零售商提供的解決方案,該零售商在解決結賬頁面錯誤以提高銷售額和客戶忠誠度方面遇到了挑戰。
目錄
- 挑戰
- 目標
- 解決方案
- 步驟 1. 收集有關錯誤的數據
- 步驟 2. 處理數據
- Step 3. 使用獲取的數據
- 結果
挑戰
每天約有 700,000 人訪問該零售商的網站,閱讀產品評論或四處瀏覽以找到他們想要購買的商品。 但是,用戶有時可能會在結帳頁面遇到網站錯誤,導致他們無法在線完成訂單,從而降低了公司的收入。
目標
分析師和測試人員仔細研究了客戶的投訴,以定義典型的錯誤場景。 專家設法重現的錯誤已得到修復。 其餘的關鍵錯誤需要設置監控。 此前,該公司不使用收集此類數據,仍然無法評估錯誤的確切數量以及它們如何影響轉化率。 公司還需要知道每個 bug 是如何與特定用戶相關聯的,以幫助用戶下訂單。
分析師選擇在網站設置關鍵漏洞監控,盡最大努力幫助客戶在結賬頁面成功下單。 這將增加銷售額並改善客戶網站體驗。 具有挑戰性的因素是需要實時監控,以免失去任何當前試圖在網站上訂購商品的客戶。
解決方案
為實現這一目標,制定了以下計劃:
- 將附加代碼放在網站上以收集有關錯誤的數據並將其發送到 Google BigQuery。
- 對獲取的數據進行處理,並根據公司需要將其導出到具有結構的表中。
- 組織將有關用戶和錯誤的數據發送到呼叫中心,呼叫中心將聯繫客戶以幫助他們下訂單。
以下是公司數據流的樣子:

步驟 1. 收集有關錯誤的數據
該公司使用谷歌標籤管理器來跟踪用戶的在線行為。 但是,並非網站上的所有邏輯錯誤都可以通過標準的 Google Tag Manager 方式進行跟踪。 這就是為什麼自定義腳本是專門編寫的,並通過谷歌標籤管理器在必要的網站頁面上實現。 這些腳本將詳細的錯誤數據添加到DataLayer 。
接下來,在 Google Tag Manager 標籤的幫助下,錯誤數據通過 OWOX BI Pipeline 進入 Google BigQuery。 這允許從 Google BigQuery 中的網站近乎實時地獲取原始未採樣數據。
分析師使用 API 將有關用戶的數據從 CRM 發送到 Google BigQuery,從而在雲數據倉庫中獲取他們需要的所有數據:
- 錯誤時間。
- 錯誤類型。
- 用戶身份。
- 用戶電子郵件地址。
- 用戶城市。
- 購物車中的當前產品狀態。
步驟 2. 處理數據
使用OWOX BI Pipeline,獲得了具有廣泛參數的數據表。 OWOX BI 分析師創建了一個 SQL 查詢來從表中提取數據,並以明確的結構返回它:一組行,每行代表一個錯誤。
下面是 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 表格,該插件每小時自動更新表中的信息。 這意味著報告始終包含有關前一小時錯誤的最新數據。
您可以在下面找到此類報告的示例:

Step 3. 使用獲取的數據
負責用戶每小時(上午 9 點到下午 6 點,根據工作時間)自動收到錯誤報告。 接下來,他們會將其發送給公司的開發人員,以防有關鍵問題需要解決,並發送給客戶成功經理,他們會打電話給用戶並幫助他們通過電話完成訂單。
結果
- 創建結構化報告是為了監控阻止用戶購買的網站錯誤。
- 該公司的開發人員在網站上添加了一個反饋表。 每次未登錄的用戶看到錯誤時,它都會自動出現,從而允許他們報告問題並留下他們的聯繫方式。 這有助於公司對任何錯誤或錯誤做出快速反應,並擴大客戶群,包括未登錄用戶的聯繫人。
- 該公司的呼叫中心可以在將產品添加到購物車和結賬時快速獲取有關面臨問題的用戶的數據。 呼叫中心操作員了解購物車內的物品並幫助完成購買。
- 由於網站錯誤而接到電話的用戶中,約有 3% 的用戶成功完成了電話下單。 如果忽略錯誤,這會給公司額外損失 1,600 美元。