Jake Vanderwerf
2026-05-11 ac444cba221832c012c0435fdc8339fe9f37febb
1
(()=>{class e extends window.jvbCheckout{constructor(e={}){super({...window.squareConfig,...e}),this.payments=null,this.card=null}async init(){if(window.Square)try{this.payments=window.Square.payments(this.config.application_id,this.config.location_id),await this.initializePaymentMethods(),this.isInitialized=!0,document.dispatchEvent(new CustomEvent("checkoutReady",{detail:{checkout:this,provider:"square"}}))}catch(e){console.error("Failed to initialize Square payments:",e),this.handleError(e)}else console.error("Square Web Payments SDK not loaded")}async initializePaymentMethods(){if(document.getElementById("payment-container"))try{this.card=await this.payments.card({style:this.getCardStyle()}),await this.card.attach("#payment-container"),this.card.addEventListener("cardBrandChanged",e=>{console.log("Card brand:",e.detail.cardBrand)})}catch(e){throw console.error("Failed to initialize card:",e),e}}getCardStyle(){return{input:{fontSize:"16px",fontFamily:"inherit",color:"#333",backgroundColor:"#fff"},".input-container":{borderColor:"#ccc",borderRadius:"4px"},".input-container.is-focus":{borderColor:"#006AFF",borderWidth:"2px",outline:"2px solid #006AFF",outlineOffset:"2px"},".input-container.is-error":{borderColor:"#d63638"}}}async processPayment(e){try{let t=null;if(this.selectedCardId)t=this.selectedCardId;else{const i=await this.card.tokenize({verificationDetails:{amount:String(e.total),currencyCode:this.config.currency||"CAD",intent:"CHARGE",customerInitiated:!0,billingContact:{givenName:e.customer.name.split(" ")[0],familyName:e.customer.name.split(" ").slice(1).join(" "),email:e.customer.email,phone:e.customer.phone}}});if("OK"!==i.status){const e=i.errors?.map(e=>e.message).join(", ")||"Unknown error";throw new Error(`Card tokenization failed: ${e}`)}t=i.token,i.details?.userChallenged&&console.log("3D Secure verification completed")}return await this.submitToServer(t,e,!!this.selectedCardId)}catch(e){throw console.error("Payment processing failed:",e),e}}async submitToServer(e,t,i=!1){if(!this.isOpen)throw new Error("Store is currently closed");const a=await fetch(this.config.api_url+"process-payment",{method:"POST",headers:{"Content-Type":"application/json","X-WP-Nonce":this.config.nonce},body:JSON.stringify({source_id:e,is_saved_card:i,cart_id:this.getCartId(),amount:t.total,items:t.items,customer:{email:this.isLoggedIn?this.userEmail:t.customer.email,name:t.customer.name,phone:t.customer.phone},note:t.note,pickup_time:t.pickup_time})}),r=await a.json();if(!a.ok)throw new Error(r.message||"Payment processing failed");return this.clearCart(),r}extractOrderData(e){const t=super.extractOrderData(e);return t.items=t.items.map(e=>({catalog_object_id:e.catalog_id,quantity:e.quantity,price:e.price,note:e.note})),t}async loadSavedCards(){try{const e=await fetch(this.config.api_url+"saved-cards",{method:"GET",headers:{"X-WP-Nonce":this.config.nonce}}),t=await e.json();t.success&&t.cards&&(this.savedCards=t.cards,this.renderSavedCards())}catch(e){console.error("Failed to load saved cards:",e)}}}document.addEventListener("DOMContentLoaded",()=>{document.querySelector('#checkout[data-provider="square"]')&&(window.squareCheckout=new e)})})();