import Listener from "./listener";
/**
* Listens for payment failure errors and sends them to the dataLayer.
* Uses a `PaymentErrorHandler` object to determine the error type,
* payment form element, and error element.
* @class
* @param {PaymentErrorHandler} errorHandler - An object that contains the errorType, paymentForm, and errorElement
* @extends Listener
*/
export class PaymentErrorListener extends Listener {
eventName = "payment_failure";
constructor(errorHandler) {
super();
this.handler = errorHandler;
this.eventName = errorHandler.errorType || this.eventName;
}
listen() {
this.handleError();
this.watchForErrors(this.handler.paymentForm);
}
/**
* Trigger the event if an error is displayed
*/
handleError() {
const error = this.handler.errorElement;
if (error) this.trigger(error);
}
/**
* Watch for errors in the payment form
* This is necessary because errors may be displayed after the page loads
* @param {HTMLElement | null | undefined} form - The payment form element
* @return {void}
*/
watchForErrors(form) {
if (!form) return;
const observer = new MutationObserver(() => this.handleError());
observer.observe(form, { subtree: true, childList: true });
}
createPayload(errorElement) {
return {
error_message: errorElement.innerText.trim()
};
}
}
/**
* Handles form validation errors on ReCharge checkout
* @type {PaymentErrorHandler}
*/
export const clientExceptionRechargeHandler = {
errorType: "client_exception_error",
get paymentForm() {
return document.getElementById('payment');
},
get errorElement() {
return document.querySelector('#payment div.field-with-errors span.error-message');
}
};
/**
* Handles payment failure errors on ReCharge checkout
* @type {PaymentErrorHandler}
*/
export const paymentFailureRechargeHandler = {
get errorElement() {
const form = document.getElementById('payment');
const el = form.querySelector('div.field-with-errors span.error-message, div.paypal-error-message');
return (el && el.style.display !== 'none') ? el : null;
}
};
/**
* Handles payment failure errors on Shopify checkout
* @type {PaymentErrorHandler}
*/
export const paymentFailureShopifyHandler = {
get errorElement() {
return document.querySelector('[data-payment-method] .notice--error:not(.hidden) .notice__text');
}
};
/**
* @typedef {Object} PaymentErrorHandler
* @property {string | undefined} errorType - The event name to trigger
* @property {HTMLElement | null | undefined} paymentForm - The payment form element
* @property {HTMLElement | null | undefined} errorElement - The element that contains the error message
*/