make a popup message appear when a customer uses a specific discount code

make a popup message appear when a customer uses a specific discount code

alaskasalmon
Visitor
2 0 0

Is it possible to make a customized pop up message or label appear when a customer uses a specific discount code. 

 

I am trying to tie a discount code to a donation pledge (each time someone uses a certain discount code, we commit to making a donation to a specific org.)

 

I would like a message to appear that states "thanks for supporting X organization" when a certain discount code is applied.

 

Thank you !

Replies 5 (5)

StevenT_A7
Explorer
81 6 8

Hi 

Yes It's possible and you can do it by adding some code and editing the theme in website. 

Let me know if you want more details .

Steven Taylor
302-260-8345
alaskasalmon
Visitor
2 0 0
I am interested in learning more

StevenT_A7
Explorer
81 6 8

Hi Alaska Salmon, 

If you tried the code given by abel and solution rectified then that's great if not , let me know . 

Steven Taylor
302-260-8345

Abel_Lesle
Shopify Partner
282 5 22

Hi @alaskasalmon , I'm assuming you're not on Shopify plus and need to show this when the discount code is applied on cart.

 

Here's a script that you can include on your theme.liquid before the </head> tag, 

<script>
class DiscountNotifier {
  constructor(options = {}) {
    // Now accepts an array of discount codes with their messages
    this.discountConfigs = options.discountConfigs || [
      {
        code: 'TEST10',
        organizationName: 'X organization',
        message: 'Thanks for supporting X organization with your discount!'
      },
      {
        code: 'CHARITY20',
        organizationName: 'Charity Foundation',
        message: '20% of your purchase goes to Charity Foundation!'
      }
    ];
    this.storagePrefix = 'discountPopupShown_';
    this.init();
  }

  async init() {
    this.cartWatcher = new CartWatcher();
    this.cartWatcher.init();
    window.addEventListener("cart_changed", this.handleCartChange.bind(this));
    
    // Check on initial load
    this.checkForDiscounts();
  }

  async handleCartChange() {
    await this.checkForDiscounts();
  }

  async checkForDiscounts() {
    const cart = await this.cartWatcher.fetchCart();
    
    // Check all configured discounts
    this.discountConfigs.forEach(config => {
      const hasDiscount = this.hasSpecificDiscount(cart, config.code);
      const wasPopupShown = sessionStorage.getItem(`${this.storagePrefix}${config.code}`) === 'true';
      
      if (hasDiscount && !wasPopupShown) {
        this.showThankYouPopup(config);
        sessionStorage.setItem(`${this.storagePrefix}${config.code}`, 'true');
      } else if (!hasDiscount) {
        sessionStorage.removeItem(`${this.storagePrefix}${config.code}`);
      }
    });
  }

  hasSpecificDiscount(cart, discountCode) {
    // Check both cart-level and item-level discounts
    const cartLevelMatch = cart.cart_level_discount_applications?.some(
      discount => discount.title === discountCode
    );
    
    const itemLevelMatch = cart.items?.some(item => 
      item.discounts?.some(discount => discount.title === discountCode)
    );
    
    return cartLevelMatch || itemLevelMatch;
  }

  showThankYouPopup(config) {
    // Create overlay
    const overlay = document.createElement('div');
    overlay.style.position = 'fixed';
    overlay.style.top = '0';
    overlay.style.left = '0';
    overlay.style.width = '100%';
    overlay.style.height = '100%';
    overlay.style.backgroundColor = 'rgba(0,0,0,0.5)';
    overlay.style.zIndex = '9998';
    overlay.style.display = 'flex';
    overlay.style.justifyContent = 'center';
    overlay.style.alignItems = 'center';
    overlay.style.animation = 'fadeIn 0.3s ease-in-out';
    
    // Create popup element
    const popup = document.createElement('div');
    popup.style.position = 'relative';
    popup.style.padding = '30px';
    popup.style.backgroundColor = '#ffffff';
    popup.style.borderRadius = '8px';
    popup.style.boxShadow = '0 4px 20px rgba(0,0,0,0.15)';
    popup.style.zIndex = '9999';
    popup.style.maxWidth = '450px';
    popup.style.width = '90%';
    popup.style.textAlign = 'center';
    popup.style.animation = 'fadeInScale 0.3s ease-in-out';
    
    // Add message
    popup.innerHTML = `
      <h3 style="margin-top: 0; color: #333; font-size: 1.5em;">Thank You!</h3>
      <p style="margin-bottom: 25px; color: #555; font-size: 1.1em; line-height: 1.5;">
        ${config.message || `Thanks for supporting ${config.organizationName}!`}
      </p>
      <button style="padding: 10px 25px; background: #4285f4; color: white; 
        border: none; border-radius: 4px; cursor: pointer; font-size: 1em;
        transition: background 0.2s;">OK</button>
    `;
    
    // Add close button event
    const closeBtn = popup.querySelector('button');
    const closePopup = () => {
      popup.style.animation = 'fadeOutScale 0.3s ease-in-out';
      overlay.style.animation = 'fadeOut 0.3s ease-in-out';
      setTimeout(() => {
        popup.remove();
        overlay.remove();
      }, 300);
    };
    
    closeBtn.addEventListener('click', closePopup);
    
    // Close when clicking outside
    overlay.addEventListener('click', (e) => {
      if (e.target === overlay) {
        closePopup();
      }
    });
    
    // Add styles for animation
    const style = document.createElement('style');
    style.textContent = `
      @keyframes fadeIn {
        from { opacity: 0; }
        to { opacity: 1; }
      }
      @keyframes fadeOut {
        from { opacity: 1; }
        to { opacity: 0; }
      }
      @keyframes fadeInScale {
        from { opacity: 0; transform: scale(0.95); }
        to { opacity: 1; transform: scale(1); }
      }
      @keyframes fadeOutScale {
        from { opacity: 1; transform: scale(1); }
        to { opacity: 0; transform: scale(0.95); }
      }
    `;
    document.head.appendChild(style);
    
    // Add to document
    overlay.appendChild(popup);
    document.body.appendChild(overlay);
    
    // Auto-close after 7 seconds
    setTimeout(() => {
      if (popup.parentNode) {
        closePopup();
      }
    }, 7000);
  }
}

// CartWatcher class remains the same as before
class CartWatcher {
  init() {
    this.emitCartChanges().then(() => {
      this.observeCartChanges();
    });
  }

  async fetchCart() {
    const response = await fetch('/cart.js');
    return response.json();
  }

  storeCart(cart) {
    localStorage.setItem('cart', JSON.stringify(cart));
  }

  storedCart() {
    return JSON.parse(localStorage.getItem('cart')) || { items: [] };
  }

  findCartChanges(oldCart, newCart) {
    const onlyInLeft = (l, r) => l.filter(li => !r.some(ri => li.key == ri.key));
    let result = {
      added: onlyInLeft(newCart.items, oldCart.items),
      removed: onlyInLeft(oldCart.items, newCart.items),
    };

    oldCart.items.forEach(oi => {
      const ni = newCart.items.find(i => i.key == oi.key && i.quantity != oi.quantity);
      if (!ni) return;
      let quantity = ni.quantity - oi.quantity;
      let item = { ...ni };
      item.quantity = Math.abs(quantity);
      quantity > 0
        ? result.added.push(item)
        : result.removed.push(item)
    });

    return result;
  }

  async emitCartChanges() {
    const newCart = await this.fetchCart();
    const oldCart = this.storedCart();
    const changes = this.findCartChanges(oldCart, newCart);

    const event = new CustomEvent("cart_changed", { detail: changes });
    window.dispatchEvent(event);

    this.storeCart(newCart);
  }

  observeCartChanges() {
    const cartObserver = new PerformanceObserver((list) => {
      list.getEntries().forEach((entry) => {
        const isValidRequestType = ['xmlhttprequest', 'fetch'].includes(entry.initiatorType);
        const isCartChangeRequest = /\/cart\//.test(entry.name);
        if (isValidRequestType && isCartChangeRequest) {
          this.emitCartChanges();
        }
      });
    });
    cartObserver.observe({ entryTypes: ["resource"] });
  }
}

// Initialize the notifier with multiple discount configurations
document.addEventListener('DOMContentLoaded', () => {
  new DiscountNotifier({
    discountConfigs: [
      {
        code: 'TEST10',
        organizationName: 'X organization',
        message: 'Thank you for using the TEST10 code! 10% of your purchase supports X organization.'
      },
      {
        code: 'CHARITY20',
        organizationName: 'Charity Foundation',
        message: 'Thank you for your generosity! 20% of your purchase will be donated to Charity Foundation.'
      },
      {
        code: 'EARTH5',
        organizationName: 'Earth Alliance',
        message: 'Thank you for supporting environmental causes! Your EARTH5 discount helps plant 5 trees.'
      }
    ]
  });
});
</script>

 

You can customise this array near the end to ensure that the script check for the exact discount code you've configured and show a message based on the same.

discountConfigs: [
      {
        code: 'TEST10',
        organizationName: 'X organization',
        message: 'Thank you for using the TEST10 code! 10% of your purchase supports X organization.'
      },
      {
        code: 'CHARITY20',
        organizationName: 'Charity Foundation',
        message: 'Thank you for your generosity! 20% of your purchase will be donated to Charity Foundation.'
      },
      {
        code: 'EARTH5',
        organizationName: 'Earth Alliance',
        message: 'Thank you for supporting environmental causes! Your EARTH5 discount helps plant 5 trees.'
      }
    ]

 

Note that this is not a theme specific implementation, meaning that it should work with any theme and any Shopify store.

 

If you found this helpful - please mark my answer as a solution so others can also find value from this.

 

Thank you,

Founder
Dollarlabs: Ultimate Discounts (5★) – If you can think of a discount, you can build it
Dollarback: Cashback & Loyalty (5★) – Simple cashback. Powerful loyalty.

tobebuilds
Shopify Partner
583 42 159

Hello Alaskasalmon,

 

Typically, customers enter discount codes in the checkout - an area where only Shopify Plus customers can change the UI/UX.

 

If you are on Shopify Plus, then you can consider developing a custom app using the Checkout UI Extensions API:

 

You might be able to build this with Checkout Blocks, an app owned by Shopify.

 

Best,

Tobe

Founder, Regios Discounts app (4.8 stars, 91 reviews, Built for Shopify)
- Custom discounts made simple
- "Just about any discount you'll ever need"
- Built by an ex-Google software engineer
- Often imitated, never duplicated