DEV Community

seller-mind
seller-mind

Posted on

Rethinking Post-Purchase Tracking to Eliminate WISMO Support Tickets

When I first started helping a friend manage their Shopify store, I thought the hard part was getting the initial sales. I was wrong. The real nightmare began after the checkout.

Within a week of launching, my inbox was flooded with the same question: "Where is my order?"

We were dealing with a massive wave of WISMO (Where Is My Order) tickets. The default Shopify order status page was practically a dead end, just showing a basic "fulfilled" status and a raw tracking number. Customers would click the tracking number, get redirected to a confusing, unbranded carrier website, lose trust, and immediately email us for an update.

I was spending hours every week copy-pasting tracking links and reassuring anxious customers. It was exhausting and completely unscalable.

So I decided to build something.

The Cost of Ignoring the Post-Purchase Experience

The post-purchase experience is often an afterthought in e-commerce, but ignoring it has a very real cost.

WISMO tickets aren't just annoying; they drain your resources. If we look at the math, handling a single support ticket takes an average of 5 to 10 minutes. If your store processes a few hundred orders a week, even a small WISMO rate means dozens of hours lost to repetitive support tasks.

Beyond the time cost, there is the brand damage. When a customer has to leave your store to check their tracking on a third-party carrier site, the emotional connection is broken. They are no longer in your branded environment. They are looking at a generic, sometimes broken, logistics page. If there is a slight delay, they assume the worst and blame you, not the carrier.

The problem wasn't that our shipping was slow; the problem was that our communication was invisible.

Technical Approach: Best Practices for Tracking

To fix this, I realized we needed a fully branded tracking experience that kept the customer on our domain. Here are the concrete best practices I followed when architecting this solution, which eventually became the foundation for my own tool.

1. Keep the tracking experience on-domain

Never redirect your customers to a carrier’s website. Your tracking page should live on your own domain, wrapped in your store's header and footer. This maintains the brand illusion and keeps the customer in a familiar environment. When they see your logo and your brand colors while checking their shipping status, their anxiety drops significantly.

2. Use Shopify App Embed blocks for installation

In the past, adding a tracking widget meant asking merchants to edit their theme.liquid file or deal with complex theme app extensions. This is a massive friction point. The modern approach is to use Shopify App Embed blocks. This allows the widget to be toggled on and off directly from the Shopify theme editor without touching a single line of code.

Here is an example of how the App Embed block renders the widget on the order status page:

{% comment %}
  Renders shipment tracking widget on order status pages
{% endcomment %}

<div id="parcelglance-widget" 
     data-order-id="{{ order.id }}"
     data-order-number="{{ order.name }}"
     data-store-name="{{ shop.name }}"
     style="min-height: 200px;">
</div>

<script>
(function() {
  const script = document.createElement('script');
  script.src = 'https://cdn.parcelglance.com/widget.js';
  script.async = true;
  script.onload = function() {
    Parcelglance.init({
      orderId: document.getElementById('parcelglance-widget').dataset.orderId,
      orderNumber: document.getElementById('parcelglance-widget').dataset.orderNumber,
      storeName: document.getElementById('parcelglance-widget').dataset.storeName,
      container: 'parcelglance-widget',
    });
  };
  document.head.appendChild(script);
})();
</script>
Enter fullscreen mode Exit fullscreen mode

By passing the Liquid variables directly into data attributes, the JavaScript widget can initialize securely without needing to parse the URL or make extra GraphQL calls just to get the current order context.

3. Secure your webhook handlers

To get real-time tracking status from major carriers, you need to listen to Shopify's fulfillment webhooks. However, you must verify these requests to prevent malicious actors from spoofing order data.

Always validate the x-shopify-hmac-sha256 header against your webhook secret. Here is a quick Node.js example of how to verify the payload:

const crypto = require('crypto');

function verifyShopifyWebhook(rawBody, hmacHeader, secret) {
  const hash = crypto
    .createHmac('sha256', secret)
    .update(rawBody, 'utf8')
    .digest('base64');
  return hash === hmacHeader;
}
Enter fullscreen mode Exit fullscreen mode

If the hash doesn't match, reject the request immediately. This ensures that the tracking data you are storing and displaying to your customers is authentic and untampered.

4. Make the widget visually customizable

A tracking widget shouldn't look like a generic plugin. It needs to match the store's theme. Provide options to customize the primary colors, fonts, and layout. If the tracking page looks like it was natively built by the store owner, customers will trust the information presented on it.

Practical Results and Lessons Learned

Implementing these practices made a significant difference for the store I was helping.

What worked exceptionally well was the shift to App Embed blocks. Merchants loved that they could install the tracking page in two clicks via the theme editor. It removed the fear of "breaking the theme" that many store owners have when installing new apps.

What surprised me was the psychological impact of the on-domain experience. For example, before the redesign, a 5-day shipping delay would trigger a panic email. After moving the tracking on-domain with clear, branded visual progress bars, customers would just check the page themselves. The visual progress made the wait feel active rather than stagnant.

If I could change one thing from my initial build, it would be how I handled carrier API polling. At first, I queried the carrier APIs every time a customer loaded the page. This was slow and hit rate limits. I quickly pivoted to relying purely on Shopify webhooks to update the database, and then just serving that cached data to the frontend. It made the widget load instantly.

Wrapping Up

Building this from scratch taught me a lot about the post-purchase experience, and I realized many other Shopify developers and store owners were facing the exact same WISMO headaches.

That’s why I packaged these concepts into Parcelglance. It’s a Shopify app that adds a fully branded, real-time tracking page to your store, designed specifically to keep customers informed and reduce those endless support tickets.

You can check out the free Shipment Tracking Widget and see how it works for your own store at parcelglance.com.


Full disclosure: I'm the developer of Parcelglance. I built this because I needed it myself.

Top comments (0)