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>