Adding custom check balance form
By default, "Check Gift Card Balance" form is hosted via app proxy and available at your-store.com/tools/check-balance.
If you'd like to have full control over this form and/or host it on your pages, you can use the form widget below:
snippets/checky-widget.liquid:
{% comment %} Configure language and widget settings here (or replace with theme settings / metafields) {% endcomment %} {% assign lang = 'en' %} {% assign is_show_customer_name = false %} {% assign is_customer_name_required = false %} {% comment %} Define translation dictionary using Liquid {% endcomment %} {% case lang %} {% when 'it' %} {% assign check_gift_card_balance = 'Controlla il saldo della carta regalo' %} {% assign enter_name_or_email = 'Inserisci il tuo nome completo o l’e-mail:' %} {% assign enter_gc_last4 = 'Inserisci le ultime 4 cifre della carta regalo:' %} {% assign check = 'Controlla' %} {% assign checking = 'Verifica in corso...' %} {% assign no_gc_found = 'Nessuna carta regalo trovata' %} {% assign balance = 'Saldo' %} {% assign deactivated_on = 'Disattivata il' %} {% assign initial_amount = 'Importo iniziale' %} {% assign created = 'Creata il' %} {% assign expires = 'Scade il' %} {% assign please_enter_gc = 'Inserisci le ultime 4 cifre della carta regalo' %} {% assign please_enter_name = 'Inserisci il tuo nome o l’e-mail' %} {% assign enabled = 'Attiva' %} {% assign disabled = 'Disattivata' %} {% assign never = 'Mai' %} {% when 'es' %} {% assign check_gift_card_balance = 'Consultar saldo de la tarjeta de regalo' %} {% assign enter_name_or_email = 'Ingresa tu nombre completo o correo electrónico:' %} {% assign enter_gc_last4 = 'Ingresa los últimos 4 dígitos de la tarjeta de regalo:' %} {% assign check = 'Consultar' %} {% assign checking = 'Consultando...' %} {% assign no_gc_found = 'No se encontró ninguna tarjeta de regalo' %} {% assign balance = 'Saldo' %} {% assign deactivated_on = 'Desactivada el' %} {% assign initial_amount = 'Monto inicial' %} {% assign created = 'Creada' %} {% assign expires = 'Expira' %} {% assign please_enter_gc = 'Por favor, ingresa los últimos 4 dígitos de la tarjeta de regalo' %} {% assign please_enter_name = 'Por favor, ingresa tu nombre o correo electrónico' %} {% assign enabled = 'Activada' %} {% assign disabled = 'Desactivada' %} {% assign never = 'Nunca' %} {% else %} {% assign check_gift_card_balance = 'Check Gift Card Balance' %} {% assign enter_name_or_email = 'Enter your full name or email:' %} {% assign enter_gc_last4 = 'Enter Gift Card last 4 digits:' %} {% assign check = 'Check' %} {% assign checking = 'Checking..' %} {% assign no_gc_found = 'No Gift Card found' %} {% assign balance = 'Balance' %} {% assign deactivated_on = 'Deactivated on' %} {% assign initial_amount = 'Initial Amount' %} {% assign created = 'Created' %} {% assign expires = 'Expires' %} {% assign please_enter_gc = 'Please enter Gift Card last 4 digits' %} {% assign please_enter_name = 'Please enter your name or email' %} {% assign enabled = 'Enabled' %} {% assign disabled = 'Disabled' %} {% assign never = 'Never' %} {% endcase %} <style> .checky-widget-wrapper{ display:flex;flex-direction:column;align-items:center;padding:40px 0px; } .checky-widget-container{ max-width:600px;width:600px;padding:20px;border:2px solid #000;border-radius:20px; } .checky-widget-title{font-size:22px;font-weight:bold;margin-bottom:15px;} .checky-widget-input-container{ border:2px solid #000;border-radius:10px;display:flex;flex-direction:row;padding:3px; } .checky-input{ border:none;border-radius:0;height:40px;line-height:40px;font-size:18px;flex-grow:1;outline:none;box-shadow:none; } .checky-widget-input-container-secondary{margin-bottom:10px;} .checky-btn{ background:#000;color:#fff;width:120px;border-radius:5px;padding:5px 0;text-align:center;cursor:pointer; } .checky-widget-error-container{display:none;color:#c70a24;margin-top:5px;} .checky-widget-results-container{display:flex;flex-direction:column;align-items:center;} .checky-widget-no-gc{display:none;font-size:18px;color:#6b7280;font-weight:bold;text-align:center;margin-top:20px;} .checky-widget-gc-data{display:none;flex-direction:column;gap:20px;align-items:center;margin-top:40px} .checky-gc-row{display:flex;flex-direction:row;gap:20px;} .checky-gc-row-label{color:#6b7280;width:250px;text-align:right;} .checky-gc-row-value{font-weight:bold;width:250px;} .checky-gc-header{display:flex;flex-direction:row;align-items:center;gap:10px;} .checky-gc-code{font-size:16px;font-weight:bold;font-family:monospace;} .checky-gc-status{border-radius:10px;padding:3px 10px;font-size:12px;font-weight:bold} .checky-gc-status-enabled{background:#86efac;} .checky-gc-status-disabled{background:#fdba74;} .checky-gc-balance{font-size:20px;text-align:center;font-weight:bold;} .checky-gc-deactivated{display:none;background:#fdba74;font-size:12px;padding:3px 10px;border-radius:10px;font-weight:bold;text-align:center;} </style> <div class="checky-widget-wrapper"> <div class="checky-widget-container"> <div class="checky-widget-title">{{ check_gift_card_balance }}</div> {% if is_show_customer_name %} <div class="checky-widget-input-label">{{ enter_name_or_email }}</div> <div class="checky-widget-input-container checky-widget-input-container-secondary"> <input class="checky-input checky-input-customer" type="text" placeholder="John Doe"/> </div> {% endif %} <div class="checky-widget-input-label">{{ enter_gc_last4 }}</div> <div class="checky-widget-input-container"> <input class="checky-input checky-input-gc_code" type="text" placeholder="XXXX" maxlength="4"/> <button class="checky-btn" type="button">{{ check }}</button> </div> <div class="checky-widget-error-container"></div> <div class="checky-widget-results-container"> <div class="checky-widget-no-gc">{{ no_gc_found }}</div> <div class="checky-widget-gc-data"> <div class="checky-gc-header"> <div class="checky-gc-code"></div> <div class="checky-gc-status"></div> </div> <div class="checky-gc-balance">{{ balance }}: <span class="checky-gc-balance-value"></span></div> <div class="checky-gc-deactivated">{{ deactivated_on }} <span class="checky-gc-deactivated-value"></span></div> <div class="checky-gc-row"> <div class="checky-gc-row-label">{{ initial_amount }}</div> <div class="checky-gc-row-value checky-gc-initial-amount"></div> </div> <div class="checky-gc-row"> <div class="checky-gc-row-label">{{ created }}</div> <div class="checky-gc-row-value checky-gc-created"></div> </div> <div class="checky-gc-row"> <div class="checky-gc-row-label">{{ expires }}</div> <div class="checky-gc-row-value checky-gc-expires"></div> </div> </div> </div> </div> </div> <script> const CheckyWidget = { apiURL : "https://checky-api.punchy.dev/balance", shop: "{{ shop.permanent_domain }}", giftCard: null, errorMsg: null, formatDate: function(date) { const utcDate = new Date(date); return utcDate.toLocaleString(); }, toggleErrorMessage: function(errMsg = null){ this.errorMsg = errMsg; const elErrorMsg = document.querySelector('.checky-widget-error-container'); if(this.errorMsg){ elErrorMsg.innerHTML = this.errorMsg; elErrorMsg.style.display="block"; }else{ elErrorMsg.style.display="none"; } }, showGCDetails: function(){ const elResults = document.querySelector('.checky-widget-gc-data'); const elNotFound = document.querySelector('.checky-widget-no-gc'); if(this.giftCard?.maskedCode){ var elMaskedCode = document.querySelector('.checky-gc-code'); var elStatus = document.querySelector('.checky-gc-status'); var elBalance = document.querySelector('.checky-gc-balance-value'); var elDeactivated = document.querySelector('.checky-gc-deactivated'); var elDeactivatedVal = document.querySelector('.checky-gc-deactivated-value'); var elInitialAmount = document.querySelector('.checky-gc-initial-amount'); var elCreated = document.querySelector('.checky-gc-created'); var elExpires = document.querySelector('.checky-gc-expires'); elDeactivated.style.display="none"; elStatus.classList.remove("checky-gc-status-enabled","checky-gc-status-disabled"); elMaskedCode.innerHTML = this.giftCard?.maskedCode || ""; elStatus.innerHTML = this.giftCard?.enabled == true ? "{{ enabled }}" : "{{ disabled }}"; if(this.giftCard?.enabled == true){ elStatus.classList.add("checky-gc-status-enabled"); }else{ elStatus.classList.add("checky-gc-status-disabled"); } elBalance.innerHTML = this.giftCard?.balance || ""; elDeactivatedVal.innerHTML = this.giftCard?.deactivatedAt ? this.formatDate(this.giftCard?.deactivatedAt) : ""; if(this.giftCard?.deactivatedAt){ elDeactivated.style.display="block"; } elInitialAmount.innerHTML = this.giftCard?.initialValue || ""; elCreated.innerHTML = this.giftCard?.createdAt ? this.formatDate(this.giftCard?.createdAt) : ""; elExpires.innerHTML = this.giftCard?.expiresOn ? this.formatDate(this.giftCard?.expiresOn) : "{{ never }}"; elNotFound.style.display="none"; elResults.style.display="flex"; } else { elResults.style.display="none"; elNotFound.style.display="block"; } }, init: function(){ const self = this; document.querySelectorAll('.checky-btn').forEach((button) => { button.addEventListener('click', async function(){ if(button.disabled) return; button.disabled = true; button.textContent = "{{ checking }}"; await self.checkBalance(); button.textContent = "{{ check }}"; button.disabled = false; }); }); }, checkBalance: async function(){ this.toggleErrorMessage(); const gc_code = document.querySelector('.checky-input-gc_code').value; if(!gc_code || gc_code.length < 4){ this.toggleErrorMessage("{{ please_enter_gc }}"); return; } const requestData = { gc_code: gc_code, shop: this.shop }; {% if is_show_customer_name %} const customer = document.querySelector('.checky-input-customer').value; {% if is_customer_name_required %} if(!customer || customer.length < 1){ this.toggleErrorMessage("{{ please_enter_name }}"); return; } {% endif %} requestData.customer = customer; {% endif %} const response = await fetch(this.apiURL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestData), }); const content = await response.json(); this.giftCard = content?.giftCard; this.showGCDetails(); return true; } } document.addEventListener('DOMContentLoaded', () => { CheckyWidget.init(); }); </script>