HEX
Server: Apache
System: Linux efa57bbe-abb1-400d-2985-3b056fbc2701.secureserver.net 6.1.147-1.el9.elrepo.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Jul 24 12:33:32 EDT 2025 x86_64
User: root (0)
PHP: 8.0.30.4
Disabled: NONE
Upload Files
File: //var/www/wp-content/mu-plugins/vendor/godaddy/mwc-core/assets/js/payments/frontend/poynt.js
/**
 * Poynt Collect payment form handler.
 *
 * @since 1.0.0
 */
jQuery( ( $ ) => {

	'use strict';

	/**
	 * Payment form handler.
	 *
	 * Interacts with the Poynt Collect API to process a checkout payment form.
	 *
	 * @link https://docs.poynt.com/app-integration/poynt-collect/#poynt-collect
	 *
	 * @since 1.0.0
	 */
	window.MWCPaymentsPoyntPaymentFormHandler = class MWCPaymentsPoyntPaymentFormHandler {

		/**
		 * Instantiates the payment form handler.
		 *
		 * Loads the payment handler and intercepts form submissions to inject the token returned by Poynt Collect API.
		 *
		 * @since 1.0.0
		 *
		 * @param {Object} args form handler arguments
		 */
		constructor( args ) {

			this.appId            = args.appId;
			this.businessId       = args.businessId;
			this.customerAddress  = args.customerAddress;
			this.shippingAddress  = args.shippingAddress;
			this.isLoggingEnabled = args.isLoggingEnabled;
			this.options          = args.options;
			this.formInitialized  = false;

			// bail if no Poynt wrappers exist on the page
			if (! $('#mwc-payments-poynt-hosted-form').length) {
				return;
			}

			if ( $( 'form.checkout' ).length ) {
				this.form = $( 'form.checkout' );
				this.handleCheckout();
			} else if ( $( 'form#order_review' ).length ) {
				this.form = $( 'form#order_review' );
				this.handlePayPage();
			} else if ( $( 'form#add_payment_method' ).length ) {
				this.form = $( 'form#add_payment_method' );
				this.handleMyAccount();
			} else {
				this.debugLog('No payment form available');
				return;
			}

			// clear the payment nonce on errors
			$( document.body ).on( 'checkout_error', () => {
				this.clearNonce();
			} );
		}

		/**
		 * Gets the nonce field.
		 *
		 * Returns a jQuery object with the hidden input that holds a nonce value.
		 *
		 * @since 1.0.0
		 *
		 * @returns {Object} jQuery object
		 */
		getNonceField() {
			return $( '#mwc-payments-poynt-payment-nonce' );
		}

		/**
		 * Clears the payment nonce.
		 *
		 * Resets the nonce value in the hidden input.
		 *
		 * @since 1.0.0
		 */
		clearNonce() {
			this.getNonceField().val( '' );
		}

		/**
		 * Creates a nonce using Poynt Collect.
		 *
		 * Saves the nonce to a hidden input and resubmits the form.
		 *
		 * @link https://docs.poynt.com/app-integration/poynt-collect/#creating-a-nonce
		 *
		 * @since 1.0.0
		 */
		createNonce() {

			let nonceData = {
				businessId: this.businessId
			};

			if ( this.customerAddress.firstName )  {
				nonceData.firstName = this.customerAddress.firstName;
			}

			if ( this.customerAddress.lastName )  {
				nonceData.lastName = this.customerAddress.lastName;
			}

			if ( this.customerAddress.line1 )  {
				nonceData.line1 = this.customerAddress.line1;
			}

			if ( this.customerAddress.line2 ) {
				nonceData.line2 = this.customerAddress.line2;
			}

			if ( this.customerAddress.city ) {
				nonceData.city = this.customerAddress.city;
			}

			if ( this.customerAddress.state ) {
				nonceData.territory = this.customerAddress.state;
			}

			if ( this.customerAddress.country ) {
				nonceData.countryCode = this.customerAddress.country;
			}

			if ( this.customerAddress.postcode )  {
				nonceData.zip = this.customerAddress.postcode;
			}

			if ( this.customerAddress.phone ) {
				nonceData.phone = this.customerAddress.phone;
			}

			if ( this.customerAddress.email ) {
				nonceData.emailAddress = this.customerAddress.email;
			}

			if ( this.shippingAddress.line1 ) {
				nonceData.shippingLine1 = this.shippingAddress.line1;
			}

			if ( this.shippingAddress.line2 ) {
				nonceData.shippingLine2 = this.shippingAddress.line2;
			}

			if ( this.shippingAddress.city ) {
				nonceData.shippingCity = this.shippingAddress.city;
			}

			if ( this.shippingAddress.state ) {
				nonceData.shippingTerritory = this.shippingAddress.state;
			}

			if ( this.shippingAddress.postcode ) {
				nonceData.shippingZip = this.shippingAddress.postcode;
			}

			this.debugLog( nonceData );

			/**
			 * @link https://docs.poynt.com/app-integration/poynt-collect/#collect-getnonce
			 */
			this.collect.getNonce( nonceData );
		}

		handleCheckout() {
			$( document.body ).on( 'updated_checkout', () => this.setFields() );

			$( document.body ).on( 'updated_checkout', () => this.handleSavedPaymentMethods() );

			this.form.on( 'checkout_place_order_poynt', () => this.validatePaymentData() );
		}

		/**
		 * Determines whether a nonce exists.
		 *
		 * Checks the hidden input for a value.
		 *
		 * @since 1.0.0
		 *
		 * @returns {boolean} whether a nonce exists
		 */
		hasNonce() {
			return this.getNonceField().val().length > 0;
		}

		handleMyAccount() {

			this.setFields();

			this.form.submit( () => {

				if ( $( '#add_payment_method input[name=payment_method]:checked' ).val() === 'poynt' ) {
					return this.validatePaymentData();
				}
			} );
		}

		/**
		 * Handles the error event data.
		 *
		 * Logs errors to console and maybe renders them in a user-facing notice.
		 *
		 * @link https://docs.poynt.com/app-integration/poynt-collect/getting-started/event-listeners.html#error
		 *
		 * We render their provided message if the error is:
		 * - a result of the form submit (inline field errors are not handled by our JS)
		 * - of type "invalid_details" or "missing_fields". These are the only two known types right now,
		 *   but we check for them anyway in case more are added later that we might not want displayed
		 *
		 * Note: the event will have a different shape than what's documented above if it comes after form validation, directly from their
		 * server-side API. They just pass the raw error in that case, so there is no event.data.error object. For that
		 * we just render the generic error message.
		 *
		 * @param {Object} event after a form error
		 */
		handleError( event ) {

			// always console log the event
			this.debugLog( event );

			// only handle error events
			if ('error' !== event?.type) {
				return;
			}

			// default to a generic error message
			let errorMessage = poyntPaymentFormI18n.errorMessages.genericError;

			// special handling for errors from the form vs. the API
			if (event.data?.error) {

				// if this is not a submit event (such as a field change), don't render anything
				if ('submit' !== event.data.error?.source) {
					return;
				}

				// use the provided error message if available and is fixable by C2
				if (event.data.error.message && ['invalid_details', 'missing_fields'].includes(event.data.error.type)) {
					errorMessage = event.data.error.message;
				}
			}

			// render the error at the top of the page
			this.renderErrors( [ errorMessage ] );
		}

		handlePayPage() {

			this.setFields();

			this.handleSavedPaymentMethods();

			this.form.submit( () => {

				if ( $( '#order_review input[name=payment_method]:checked' ).val() === 'poynt' ) {
					return this.validatePaymentData();
				}
			} );
		}

		/**
		 * Handles a payment form ready event.
		 *
		 * Unblocks the payment form after initialization.
		 *
		 * @since 1.0.0
		 *
		 * @param {Object} event after the form is ready
		 */
		handlePaymentFormReady( event ) {

			if ( ! event.type || 'ready' !== event.type ) {
				this.debugLog( event );
			} else {
				this.debugLog( 'Payment form ready' );
			}

			this.form.unblock();
		}

		/**
		 * Handles a nonce ready event.
		 *
		 * Sets the nonce to hidden field and submits the form.
		 *
		 * @since 1.0.0
		 *
		 * @param {Object} payload containing the nonce
		 */
		handleNonceReady( payload ) {

			if ( payload.data && payload.data.nonce ) {
				this.getNonceField().val( payload.data.nonce );
				this.debugLog( 'Nonce set' );
			} else {
				this.clearNonce();
				this.debugLog( 'Nonce value is empty' );
			}

			this.form.submit();
		}

		handleSavedPaymentMethods() {

			let $newMethodForm = $('.mwc-payments-poynt-new-payment-method-form');

			$('input.mwc-payments-poynt-payment-method').change( () => {

				if ( $( "input.mwc-payments-poynt-payment-method:checked" ).val() ) {
					$newMethodForm.slideUp( 200 );
				} else {
					$newMethodForm.slideDown( 200 );
				}

			} ).change();

			$( 'input#createaccount' ).change(function () {

				let $parentRow = $('input.mwc-payments-tokenize-payment-method').closest( 'p.form-row' );

				if ( $( this ).is( ':checked' ) ) {
					$parentRow.slideDown();
					$parentRow.next().show();
				} else {
					$parentRow.hide();
					$parentRow.next().hide();
				}
			});

			if (! $( 'input#createaccount' ).is( ':checked' ) ) {
				$( 'input#createaccount' ).change();
			}
		}

		/**
		 * Initializes the form.
		 *
		 * Adds listeners for the ready and error events.
		 *
		 * @link https://docs.poynt.com/app-integration/poynt-collect/#collect-mount
		 *
		 * @since 1.0.0
		 */
		initForm() {

			// run only once
			if ( this.initializingForm ) {
				return;
			}

			this.initializingForm = true;

			this.collect = new TokenizeJs( this.businessId, this.appId );

			/**
			 * Initialize the Payment Form with Poynt Collect API.
			 */
			this.collect.mount( 'mwc-payments-poynt-hosted-form', document, this.options );

			// triggers when a nonce is ready
			this.collect.on( 'nonce', payload => {
				this.handleNonceReady( payload );
			} );

			// triggers when the payment form is ready
			this.collect.on( 'ready', event => {

				this.initializingForm = false;
				this.formInitialized  = true;

				this.handlePaymentFormReady( event );
			} );

			// triggers when there is a payment form error
			this.collect.on( 'error', error => {
				this.handleError( error );
			} );
		}

		/**
		 * Sets up the payment fields.
		 *
		 * Calls parent method and initializes the payment form.
		 *
		 * @since 1.0.0
		 */
		setFields() {

			this.fields = $('.payment_method_poynt');

			if ( this.formInitialized ) {
				this.collect.unmount( 'mwc-payments-poynt-hosted-form', document );
				this.formInitialized = false;
			}

			if ( this.businessId && this.appId && ! this.initializingForm ) {
				this.initForm();
			}
		}

		validatePaymentData() {

			if ( this.form.is( '.processing' ) ) {
				return false;
			}

			if ( this.fields.find( 'input.mwc-payments-poynt-payment-method:checked' ).val() || this.hasNonce() ) {
				return true;
			}

			// override the loaded address data if available via form fields
			if ( $( '#billing_first_name' ).val() ) {
				this.customerAddress.firstName = $( '#billing_first_name' ).val();
			}

			if ( $( '#billing_last_name' ).val() ) {
				this.customerAddress.lastName = $( '#billing_last_name' ).val();
			}

			if ( $( '#billing_phone' ).val() ) {
				this.customerAddress.phone = $( '#billing_phone' ).val();
			}

			if ( $( '#billing_email' ).val() ) {
				this.customerAddress.email = $( '#billing_email' ).val();
			}

			if ( $( '#billing_address_1' ).val() ) {
				this.customerAddress.line1 = $( '#billing_address_1' ).val();
			}

			if ( $( '#billing_address_2' ).val() ) {
				this.customerAddress.line2 = $( '#billing_address_2' ).val();
			}

			if ( $( '#billing_city' ).val() ) {
				this.customerAddress.city = $( '#billing_city' ).val();
			}

			if ( $( '#billing_state' ).val() ) {
				this.customerAddress.state = $( '#billing_state' ).val();
			}

			if ( $( '#billing_country' ).val() ) {
				this.customerAddress.country = $( '#billing_country' ).val();
			}

			if ( $( '#billing_postcode' ).val() ) {
				this.customerAddress.postcode = $( '#billing_postcode' ).val();
			}

			let shipToDifferentAddress = $( '#ship-to-different-address-checkbox' ).is( ':checked' );

			let shippingLine1    = this.shippingAddress.needsShipping ? (shipToDifferentAddress ? $( '#shipping_address_1' ).val() : this.customerAddress.line1) : '';
			let shippingLine2    = this.shippingAddress.needsShipping ? (shipToDifferentAddress ? $( '#shipping_address_2' ).val() : this.customerAddress.line2) : '';
			let shippingCity     = this.shippingAddress.needsShipping ? (shipToDifferentAddress ? $( '#shipping_city' ).val() : this.customerAddress.city) : '';
			let shippingState    = this.shippingAddress.needsShipping ? (shipToDifferentAddress ? $( '#shipping_state' ).val() : this.customerAddress.state) : '';
			let shippingPostcode = this.shippingAddress.needsShipping ? (shipToDifferentAddress ? $( '#shipping_postcode' ).val() : this.customerAddress.postcode) : '';

			if ( shippingLine1 && shippingLine1.length > 0 ) {
				this.shippingAddress.line1 = shippingLine1;
			}
			if ( shippingLine2 && shippingLine2.length > 0 ) {
				this.shippingAddress.line2 = shippingLine2;
			}
			if ( shippingCity && shippingCity.length > 0 ) {
				this.shippingAddress.city = shippingCity;
			}
			if ( shippingState && shippingState.length > 0 ) {
				this.shippingAddress.state = shippingState;
			}
			if ( shippingPostcode && shippingPostcode.length > 0 ) {
				this.shippingAddress.postcode = shippingPostcode;
			}

			// block the UI
			this.form.block( { message: null, overlayCSS: { background: '#fff', opacity: 0.6 } } );

			// create the nonce
			this.createNonce();

			// always return false to resubmit the form
			return false;
		}

		/**
		 * Logs an item to console if logging is enabled.
		 *
		 * @since 1.0.0
		 *
		 * @param {String|Object} logData
		 */
		debugLog( logData ) {
			if ( this.isLoggingEnabled ) {
				console.log( logData );
			}
		}

		renderErrors(errors) {
			$( '.woocommerce-error, .woocommerce-message' ).remove();

			this.form.prepend( '<ul class="woocommerce-error"><li>' + errors.join( '</li><li>' ) + '</li></ul>' );

			this.form.removeClass( 'processing' ).unblock();
			this.form.find( '.input-text, select' ).blur();

			$( 'html, body' ).animate( { scrollTop: this.form.offset().top - 100 }, 1000 );
		}

	}

	// dispatch loaded event
	$( document.body ).trigger( 'mwc_payments_poynt_payment_form_handler_loaded' );

} );