diff --git a/assets/js/stripe-payment-request.js b/assets/js/stripe-payment-request.js
new file mode 100644
index 0000000..3b4fc54
--- /dev/null
+++ b/assets/js/stripe-payment-request.js
@@ -0,0 +1,825 @@
+/* global wc_stripe_payment_request_params, Stripe */
+jQuery( function( $ ) {
+	'use strict';
+
+	var stripe = Stripe( wc_stripe_payment_request_params.stripe.key, {
+		locale: wc_stripe_payment_request_params.stripe.locale
+	} ),
+		paymentRequestType;
+
+	/**
+	 * Object to handle Stripe payment forms.
+	 */
+	var wc_stripe_payment_request = {
+		/**
+		 * Get WC AJAX endpoint URL.
+		 *
+		 * @param  {String} endpoint Endpoint.
+		 * @return {String}
+		 */
+		getAjaxURL: function( endpoint ) {
+			return wc_stripe_payment_request_params.ajax_url
+				.toString()
+				.replace( '%%endpoint%%', 'wc_stripe_' + endpoint );
+		},
+
+		getCartDetails: function() {
+			var data = {
+				security: wc_stripe_payment_request_params.nonce.payment
+			};
+
+			$.ajax( {
+				type:    'POST',
+				data:    data,
+				url:     wc_stripe_payment_request.getAjaxURL( 'get_cart_details' ),
+				success: function( response ) {
+					wc_stripe_payment_request.startPaymentRequest( response );
+				}
+			} );
+		},
+
+		getAttributes: function() {
+			var select = $( '.variations_form' ).find( '.variations select' ),
+				data   = {},
+				count  = 0,
+				chosen = 0;
+
+			select.each( function() {
+				var attribute_name = $( this ).data( 'attribute_name' ) || $( this ).attr( 'name' );
+				var value          = $( this ).val() || '';
+
+				if ( value.length > 0 ) {
+					chosen ++;
+				}
+
+				count ++;
+				data[ attribute_name ] = value;
+			});
+
+			return {
+				'count'      : count,
+				'chosenCount': chosen,
+				'data'       : data
+			};
+		},
+
+		processSource: function( source, paymentRequestType ) {
+			var data = wc_stripe_payment_request.getOrderData( source, paymentRequestType );
+
+			return $.ajax( {
+				type:    'POST',
+				data:    data,
+				dataType: 'json',
+				url:     wc_stripe_payment_request.getAjaxURL( 'create_order' )
+			} );
+		},
+
+		/**
+		 * Get order data.
+		 *
+		 * @since 3.1.0
+		 * @version 4.0.0
+		 * @param {PaymentResponse} source Payment Response instance.
+		 *
+		 * @return {Object}
+		 */
+		getOrderData: function( evt, paymentRequestType ) {
+			var source   = evt.source;
+			var email    = source.owner.email;
+			var phone    = source.owner.phone;
+			var billing  = source.owner.address;
+			var name     = source.owner.name;
+			var shipping = evt.shippingAddress;
+			var data     = {
+				_wpnonce:                  wc_stripe_payment_request_params.nonce.checkout,
+				billing_first_name:        null !== name ? name.split( ' ' ).slice( 0, 1 ).join( ' ' ) : '',
+				billing_last_name:         null !== name ? name.split( ' ' ).slice( 1 ).join( ' ' ) : '',
+				billing_company:           '',
+				billing_email:             null !== email   ? email : evt.payerEmail,
+				billing_phone:             null !== phone   ? phone : evt.payerPhone && evt.payerPhone.replace( '/[() -]/g', '' ),
+				billing_country:           null !== billing ? billing.country : '',
+				billing_address_1:         null !== billing ? billing.line1 : '',
+				billing_address_2:         null !== billing ? billing.line2 : '',
+				billing_city:              null !== billing ? billing.city : '',
+				billing_state:             null !== billing ? billing.state : '',
+				billing_postcode:          null !== billing ? billing.postal_code : '',
+				shipping_first_name:       '',
+				shipping_last_name:        '',
+				shipping_company:          '',
+				shipping_country:          '',
+				shipping_address_1:        '',
+				shipping_address_2:        '',
+				shipping_city:             '',
+				shipping_state:            '',
+				shipping_postcode:         '',
+				shipping_method:           [ null === evt.shippingOption ? null : evt.shippingOption.id ],
+				order_comments:            '',
+				payment_method:            'stripe',
+				ship_to_different_address: 1,
+				terms:                     1,
+				stripe_source:             source.id,
+				payment_request_type:      paymentRequestType
+			};
+
+			if ( shipping ) {
+				data.shipping_first_name = shipping.recipient.split( ' ' ).slice( 0, 1 ).join( ' ' );
+				data.shipping_last_name  = shipping.recipient.split( ' ' ).slice( 1 ).join( ' ' );
+				data.shipping_company    = shipping.organization;
+				data.shipping_country    = shipping.country;
+				data.shipping_address_1  = typeof shipping.addressLine[0] === 'undefined' ? '' : shipping.addressLine[0];
+				data.shipping_address_2  = typeof shipping.addressLine[1] === 'undefined' ? '' : shipping.addressLine[1];
+				data.shipping_city       = shipping.city;
+				data.shipping_state      = shipping.region;
+				data.shipping_postcode   = shipping.postalCode;
+			}
+
+			return data;
+		},
+
+		/**
+		 * Generate error message HTML.
+		 *
+		 * @since 3.1.0
+		 * @version 4.0.0
+		 * @param  {String} message Error message.
+		 * @return {Object}
+		 */
+		getErrorMessageHTML: function( message ) {
+			return $( '<div class="woocommerce-error" />' ).text( message );
+		},
+
+		/**
+		 * Display error messages.
+		 *
+		 * @since 4.8.0
+		 * @param {Object} message DOM object with error message to display.
+		 */
+		displayErrorMessage: function( message ) {
+			$( '.woocommerce-error' ).remove();
+
+			if ( wc_stripe_payment_request_params.is_product_page ) {
+				var element = $( '.product' ).first();
+				element.before( message );
+
+				$( 'html, body' ).animate({
+					scrollTop: element.prev( '.woocommerce-error' ).offset().top
+				}, 600 );
+			} else {
+				var $form = $( '.shop_table.cart' ).closest( 'form' );
+				$form.before( message );
+				$( 'html, body' ).animate({
+					scrollTop: $form.prev( '.woocommerce-error' ).offset().top
+				}, 600 );
+			}
+		},
+
+		/**
+		 * Abort payment and display error messages.
+		 *
+		 * @since 3.1.0
+		 * @version 4.8.0
+		 * @param {PaymentResponse} payment Payment response instance.
+		 * @param {Object}          message DOM object with error message to display.
+		 */
+		abortPayment: function( payment, message ) {
+			payment.complete( 'fail' );
+			wc_stripe_payment_request.displayErrorMessage( message );
+		},
+
+		/**
+		 * Complete payment.
+		 *
+		 * @since 3.1.0
+		 * @version 4.0.0
+		 * @param {PaymentResponse} payment Payment response instance.
+		 * @param {String}          url     Order thank you page URL.
+		 */
+		completePayment: function( payment, url ) {
+			wc_stripe_payment_request.block();
+
+			payment.complete( 'success' );
+
+			// Success, then redirect to the Thank You page.
+			window.location = url;
+		},
+
+		block: function() {
+			$.blockUI( {
+				message: null,
+				overlayCSS: {
+					background: '#fff',
+					opacity: 0.6
+				}
+			} );
+		},
+
+		/**
+		 * Update shipping options.
+		 *
+		 * @param {Object}         details Payment details.
+		 * @param {PaymentAddress} address Shipping address.
+		 */
+		updateShippingOptions: function( details, address ) {
+			var data = {
+				security:  wc_stripe_payment_request_params.nonce.shipping,
+				country:   address.country,
+				state:     address.region,
+				postcode:  address.postalCode,
+				city:      address.city,
+				address:   typeof address.addressLine[0] === 'undefined' ? '' : address.addressLine[0],
+				address_2: typeof address.addressLine[1] === 'undefined' ? '' : address.addressLine[1],
+				payment_request_type: paymentRequestType,
+				is_product_page: wc_stripe_payment_request_params.is_product_page,
+			};
+
+			return $.ajax( {
+				type:    'POST',
+				data:    data,
+				url:     wc_stripe_payment_request.getAjaxURL( 'get_shipping_options' )
+			} );
+		},
+
+		/**
+		 * Updates the shipping price and the total based on the shipping option.
+		 *
+		 * @param {Object}   details        The line items and shipping options.
+		 * @param {String}   shippingOption User's preferred shipping option to use for shipping price calculations.
+		 */
+		updateShippingDetails: function( details, shippingOption ) {
+			var data = {
+				security: wc_stripe_payment_request_params.nonce.update_shipping,
+				shipping_method: [ shippingOption.id ],
+				payment_request_type: paymentRequestType,
+				is_product_page: wc_stripe_payment_request_params.is_product_page,
+			};
+
+			return $.ajax( {
+				type: 'POST',
+				data: data,
+				url:  wc_stripe_payment_request.getAjaxURL( 'update_shipping_method' )
+			} );
+		},
+
+		/**
+		 * Adds the item to the cart and return cart details.
+		 *
+		 */
+		addToCart: function() {
+			var product_id = $( '.single_add_to_cart_button' ).val();
+
+			// Check if product is a variable product.
+			if ( $( '.single_variation_wrap' ).length ) {
+				product_id = $( '.single_variation_wrap' ).find( 'input[name="product_id"]' ).val();
+			}
+
+			var data = {
+				security: wc_stripe_payment_request_params.nonce.add_to_cart,
+				product_id: product_id,
+				qty: $( '.quantity .qty' ).val(),
+				attributes: $( '.variations_form' ).length ? wc_stripe_payment_request.getAttributes().data : []
+			};
+
+			// add addons data to the POST body
+			var formData = $( 'form.cart' ).serializeArray();
+			$.each( formData, function( i, field ) {
+				if ( /^addon-/.test( field.name ) ) {
+					if ( /\[\]$/.test( field.name ) ) {
+						var fieldName = field.name.substring( 0, field.name.length - 2);
+						if ( data[ fieldName ] ) {
+							data[ fieldName ].push( field.value );
+						} else {
+							data[ fieldName ] = [ field.value ];
+						}
+					} else {
+						data[ field.name ] = field.value;
+					}
+				}
+			} );
+
+			return $.ajax( {
+				type: 'POST',
+				data: data,
+				url:  wc_stripe_payment_request.getAjaxURL( 'add_to_cart' )
+			} );
+		},
+
+		clearCart: function() {
+			var data = {
+					'security': wc_stripe_payment_request_params.nonce.clear_cart
+				};
+
+			return $.ajax( {
+				type:    'POST',
+				data:    data,
+				url:     wc_stripe_payment_request.getAjaxURL( 'clear_cart' ),
+				success: function( response ) {}
+			} );
+		},
+
+		getRequestOptionsFromLocal: function() {
+			return {
+				total: wc_stripe_payment_request_params.product.total,
+				currency: wc_stripe_payment_request_params.checkout.currency_code,
+				country: wc_stripe_payment_request_params.checkout.country_code,
+				requestPayerName: true,
+				requestPayerEmail: true,
+				requestPayerPhone: wc_stripe_payment_request_params.checkout.needs_payer_phone,
+				requestShipping: wc_stripe_payment_request_params.product.requestShipping,
+				displayItems: wc_stripe_payment_request_params.product.displayItems
+			};
+		},
+
+		/**
+		 * Starts the payment request
+		 *
+		 * @since 4.0.0
+		 * @version 4.8.0
+		 */
+		startPaymentRequest: function( cart ) {
+			var paymentDetails,
+				options;
+
+			if ( wc_stripe_payment_request_params.is_product_page ) {
+				options = wc_stripe_payment_request.getRequestOptionsFromLocal();
+
+				paymentDetails = options;
+			} else {
+				options = {
+					total: cart.order_data.total,
+					currency: cart.order_data.currency,
+					country: cart.order_data.country_code,
+					requestPayerName: true,
+					requestPayerEmail: true,
+					requestPayerPhone: wc_stripe_payment_request_params.checkout.needs_payer_phone,
+					requestShipping: cart.shipping_required ? true : false,
+					displayItems: cart.order_data.displayItems
+				};
+
+				paymentDetails = cart.order_data;
+			}
+
+			// Puerto Rico (PR) is the only US territory/possession that's supported by Stripe.
+			// Since it's considered a US state by Stripe, we need to do some special mapping.
+			if ( 'PR' === options.country ) {
+				options.country = 'US';
+			}
+
+			// Handle errors thrown by Stripe, so we don't break the product page
+			try {
+				var paymentRequest = stripe.paymentRequest( options );
+
+				var elements = stripe.elements( { locale: wc_stripe_payment_request_params.button.locale } );
+				var prButton = wc_stripe_payment_request.createPaymentRequestButton( elements, paymentRequest );
+
+				// Check the availability of the Payment Request API first.
+				paymentRequest.canMakePayment().then( function( result ) {
+					if ( ! result ) {
+						return;
+					}
+					if ( result.applePay ) {
+						paymentRequestType = 'apple_pay';
+					} else if ( result.googlePay ) {
+						paymentRequestType = 'google_pay';
+					} else {
+						paymentRequestType = 'payment_request_api';
+					}
+
+					wc_stripe_payment_request.attachPaymentRequestButtonEventListeners( prButton, paymentRequest );
+					wc_stripe_payment_request.showPaymentRequestButton( prButton );
+				} );
+
+				// Possible statuses success, fail, invalid_payer_name, invalid_payer_email, invalid_payer_phone, invalid_shipping_address.
+				paymentRequest.on( 'shippingaddresschange', function( evt ) {
+					$.when( wc_stripe_payment_request.updateShippingOptions( paymentDetails, evt.shippingAddress ) ).then( function( response ) {
+						evt.updateWith( { status: response.result, shippingOptions: response.shipping_options, total: response.total, displayItems: response.displayItems } );
+					} );
+				} );
+
+				paymentRequest.on( 'shippingoptionchange', function( evt ) {
+					$.when( wc_stripe_payment_request.updateShippingDetails( paymentDetails, evt.shippingOption ) ).then( function( response ) {
+						if ( 'success' === response.result ) {
+							evt.updateWith( { status: 'success', total: response.total, displayItems: response.displayItems } );
+						}
+
+						if ( 'fail' === response.result ) {
+							evt.updateWith( { status: 'fail' } );
+						}
+					} );
+				} );
+
+				paymentRequest.on( 'source', function( evt ) {
+					// Check if we allow prepaid cards.
+					if ( 'no' === wc_stripe_payment_request_params.stripe.allow_prepaid_card && 'prepaid' === evt.source.card.funding ) {
+						wc_stripe_payment_request.abortPayment( evt, wc_stripe_payment_request.getErrorMessageHTML( wc_stripe_payment_request_params.i18n.no_prepaid_card ) );
+					} else {
+						$.when( wc_stripe_payment_request.processSource( evt, paymentRequestType ) ).then( function( response ) {
+							if ( 'success' === response.result ) {
+								wc_stripe_payment_request.completePayment( evt, response.redirect );
+							} else {
+								wc_stripe_payment_request.abortPayment( evt, response.messages );
+							}
+						} );
+					}
+				} );
+			} catch( e ) {
+				// Leave for troubleshooting
+				console.error( e );
+			}
+		},
+
+		getSelectedProductData: function() {
+			var product_id = $( '.single_add_to_cart_button' ).val();
+
+			// Check if product is a variable product.
+			if ( $( '.single_variation_wrap' ).length ) {
+				product_id = $( '.single_variation_wrap' ).find( 'input[name="product_id"]' ).val();
+			}
+
+			var addons = $( '#product-addons-total' ).data('price_data') || [];
+			var addon_value = addons.reduce( function ( sum, addon ) { return sum + addon.cost; }, 0 );
+
+			var data = {
+				security: wc_stripe_payment_request_params.nonce.get_selected_product_data,
+				product_id: product_id,
+				qty: $( '.quantity .qty' ).val(),
+				attributes: $( '.variations_form' ).length ? wc_stripe_payment_request.getAttributes().data : [],
+				addon_value: addon_value,
+			};
+
+			return $.ajax( {
+				type: 'POST',
+				data: data,
+				url:  wc_stripe_payment_request.getAjaxURL( 'get_selected_product_data' )
+			} );
+		},
+
+		/**
+		 * Creates a wrapper around a function that ensures a function can not
+		 * called in rappid succesion. The function can only be executed once and then agin after
+		 * the wait time has expired.  Even if the wrapper is called multiple times, the wrapped
+		 * function only excecutes once and then blocks until the wait time expires.
+		 *
+		 * @param {int} wait       Milliseconds wait for the next time a function can be executed.
+		 * @param {function} func       The function to be wrapped.
+		 * @param {bool} immediate Overriding the wait time, will force the function to fire everytime.
+		 *
+		 * @return {function} A wrapped function with execution limited by the wait time.
+		 */
+		debounce: function( wait, func, immediate ) {
+			var timeout;
+			return function() {
+				var context = this, args = arguments;
+				var later = function() {
+					timeout = null;
+					if (!immediate) func.apply(context, args);
+				};
+				var callNow = immediate && !timeout;
+				clearTimeout(timeout);
+				timeout = setTimeout(later, wait);
+				if (callNow) func.apply(context, args);
+			};
+		},
+
+		/**
+		 * Creates stripe paymentRequest element or connects to custom button
+		 *
+		 * @param {object} elements       Stripe elements instance.
+		 * @param {object} paymentRequest Stripe paymentRequest object.
+		 *
+		 * @return {object} Stripe paymentRequest element or custom button jQuery element.
+		 */
+		createPaymentRequestButton: function( elements, paymentRequest ) {
+			var button;
+			if ( wc_stripe_payment_request_params.button.is_custom ) {
+				button = $( wc_stripe_payment_request_params.button.css_selector );
+				if ( button.length ) {
+					// We fallback to default paymentRequest button if no custom button is found in the UI.
+					// Add flag to be sure that created button is custom button rather than fallback element.
+					button.data( 'isCustom', true );
+					return button;
+				}
+			}
+
+			if ( wc_stripe_payment_request_params.button.is_branded ) {
+				if ( wc_stripe_payment_request.shouldUseGooglePayBrand() ) {
+					button = wc_stripe_payment_request.createGooglePayButton();
+					// Add flag to be sure that created button is branded rather than fallback element.
+					button.data( 'isBranded', true );
+					return button;
+				} else {
+					// Not implemented branded buttons default to Stripe's button
+					// Apple Pay buttons can also fall back to Stripe's button, as it's already branded
+					// Set button type to default or buy, depending on branded type, to avoid issues with Stripe
+					wc_stripe_payment_request_params.button.type = 'long' === wc_stripe_payment_request_params.button.branded_type ? 'buy' : 'default';
+				}
+			}
+
+			return elements.create( 'paymentRequestButton', {
+				paymentRequest: paymentRequest,
+				style: {
+					paymentRequestButton: {
+						type: wc_stripe_payment_request_params.button.type,
+						theme: wc_stripe_payment_request_params.button.theme,
+						height: wc_stripe_payment_request_params.button.height + 'px',
+					},
+				},
+			} );
+		},
+
+		/**
+		 * Checks if button is custom payment request button.
+		 *
+		 * @param {object} prButton Stripe paymentRequest element or custom jQuery element.
+		 *
+		 * @return {boolean} True when prButton is custom button jQuery element.
+		 */
+		isCustomPaymentRequestButton: function ( prButton ) {
+			return prButton && 'function' === typeof prButton.data && prButton.data( 'isCustom' );
+		},
+
+		isBrandedPaymentRequestButton: function ( prButton ) {
+			return prButton && 'function' === typeof prButton.data && prButton.data( 'isBranded' );
+		},
+
+		shouldUseGooglePayBrand: function () {
+			var ua = window.navigator.userAgent.toLowerCase();
+			var isChrome = /chrome/.test( ua ) && ! /edge|edg|opr|brave\//.test( ua ) && 'Google Inc.' === window.navigator.vendor;
+			// newer versions of Brave do not have the userAgent string
+			var isBrave = isChrome && window.navigator.brave;
+			return isChrome && ! isBrave;
+		},
+
+		createGooglePayButton: function () {
+			var allowedThemes = [ 'dark', 'light', 'light-outline' ];
+			var allowedTypes = [ 'short', 'long' ];
+
+			var theme  = wc_stripe_payment_request_params.button.theme;
+			var type   = wc_stripe_payment_request_params.button.branded_type;
+			var locale = wc_stripe_payment_request_params.button.locale;
+			var height = wc_stripe_payment_request_params.button.height;
+			theme = allowedThemes.includes( theme ) ? theme : 'light';
+			var gpaySvgTheme = 'dark' === theme ? 'dark' : 'light';
+			type = allowedTypes.includes( type ) ? type : 'long';
+
+			var button = $( '<button type="button" id="wc-stripe-branded-button" aria-label="Google Pay" class="gpay-button"></button>' );
+			button.css( 'height', height + 'px' );
+			button.addClass( theme + ' ' + type );
+			if ( 'long' === type ) {
+				var url = 'https://www.gstatic.com/instantbuy/svg/' + gpaySvgTheme + '/' + locale + '.svg';
+				var fallbackUrl = 'https://www.gstatic.com/instantbuy/svg/' + gpaySvgTheme + '/en.svg';
+				// Check if locale GPay button exists, default to en if not
+				setBackgroundImageWithFallback( button, url, fallbackUrl );
+			}
+
+			return button;
+		},
+
+		attachPaymentRequestButtonEventListeners: function( prButton, paymentRequest ) {
+			// First, mark the body so we know a payment request button was used.
+			// This way error handling can any display errors in the most appropriate place.
+			prButton.on( 'click', function ( evt ) {
+				$( 'body' ).addClass( 'woocommerce-stripe-prb-clicked' );
+			});
+
+			// Then, attach specific handling for selected pages and button types
+			if ( wc_stripe_payment_request_params.is_product_page ) {
+				wc_stripe_payment_request.attachProductPageEventListeners( prButton, paymentRequest );
+			} else {
+				wc_stripe_payment_request.attachCartPageEventListeners( prButton, paymentRequest );
+			}
+		},
+
+		attachProductPageEventListeners: function( prButton, paymentRequest ) {
+			var paymentRequestError = [];
+			var addToCartButton = $( '.single_add_to_cart_button' );
+
+			prButton.on( 'click', function ( evt ) {
+				// If login is required for checkout, display redirect confirmation dialog.
+				if ( wc_stripe_payment_request_params.login_confirmation ) {
+					evt.preventDefault();
+					displayLoginConfirmation( paymentRequestType );
+					return;
+				}
+
+				// First check if product can be added to cart.
+				if ( addToCartButton.is( '.disabled' ) ) {
+					evt.preventDefault(); // Prevent showing payment request modal.
+					if ( addToCartButton.is( '.wc-variation-is-unavailable' ) ) {
+						window.alert( wc_add_to_cart_variation_params.i18n_unavailable_text );
+					} else if ( addToCartButton.is( '.wc-variation-selection-needed' ) ) {
+						window.alert( wc_add_to_cart_variation_params.i18n_make_a_selection_text );
+					}
+					return;
+				}
+
+				if ( 0 < paymentRequestError.length ) {
+					evt.preventDefault();
+					window.alert( paymentRequestError );
+					return;
+				}
+
+				wc_stripe_payment_request.addToCart();
+
+				if ( wc_stripe_payment_request.isCustomPaymentRequestButton( prButton ) || wc_stripe_payment_request.isBrandedPaymentRequestButton( prButton ) ) {
+					evt.preventDefault();
+					paymentRequest.show();
+				}
+			});
+
+			$( document.body ).on( 'wc_stripe_unblock_payment_request_button wc_stripe_enable_payment_request_button', function () {
+				wc_stripe_payment_request.unblockPaymentRequestButton();
+			} );
+
+			$( document.body ).on( 'wc_stripe_block_payment_request_button', function () {
+				wc_stripe_payment_request.blockPaymentRequestButton( 'wc_request_button_is_blocked' );
+			} );
+
+			$( document.body ).on( 'wc_stripe_disable_payment_request_button', function () {
+				wc_stripe_payment_request.blockPaymentRequestButton( 'wc_request_button_is_disabled' );
+			} );
+
+			$( document.body ).on( 'woocommerce_variation_has_changed', function () {
+				$( document.body ).trigger( 'wc_stripe_block_payment_request_button' );
+
+				$.when( wc_stripe_payment_request.getSelectedProductData() ).then( function ( response ) {
+					$.when(
+						paymentRequest.update( {
+							total: response.total,
+							displayItems: response.displayItems,
+						} )
+					).then( function () {
+						$( document.body ).trigger( 'wc_stripe_unblock_payment_request_button' );
+					} );
+				});
+			} );
+
+			// Block the payment request button as soon as an "input" event is fired, to avoid sync issues
+			// when the customer clicks on the button before the debounced event is processed.
+			$( '.quantity' ).on( 'input', '.qty', function() {
+				$( document.body ).trigger( 'wc_stripe_block_payment_request_button' );
+			} );
+
+			$( '.quantity' ).on( 'input', '.qty', wc_stripe_payment_request.debounce( 250, function() {
+				$( document.body ).trigger( 'wc_stripe_block_payment_request_button' );
+				paymentRequestError = [];
+
+				$.when( wc_stripe_payment_request.getSelectedProductData() ).then( function ( response ) {
+					if ( response.error ) {
+						paymentRequestError = [ response.error ];
+						$( document.body ).trigger( 'wc_stripe_unblock_payment_request_button' );
+					} else {
+						$.when(
+							paymentRequest.update( {
+								total: response.total,
+								displayItems: response.displayItems,
+							} )
+						).then( function () {
+							$( document.body ).trigger( 'wc_stripe_unblock_payment_request_button' );
+						});
+					}
+				} );
+			}));
+
+			if ( $('.variations_form').length ) {
+				$( '.variations_form' ).on( 'found_variation.wc-variation-form', function ( evt, variation ) {
+					if ( variation.is_in_stock ) {
+						wc_stripe_payment_request.unhidePaymentRequestButton();
+					} else {
+						wc_stripe_payment_request.hidePaymentRequestButton();
+					}
+				} );
+			}
+		},
+
+		attachCartPageEventListeners: function ( prButton, paymentRequest ) {
+			prButton.on( 'click', function ( evt ) {
+				// If login is required for checkout, display redirect confirmation dialog.
+				if ( wc_stripe_payment_request_params.login_confirmation ) {
+					evt.preventDefault();
+					displayLoginConfirmation( paymentRequestType );
+					return;
+				}
+
+				if (
+					wc_stripe_payment_request.isCustomPaymentRequestButton(
+						prButton
+					) ||
+					wc_stripe_payment_request.isBrandedPaymentRequestButton(
+						prButton
+					)
+				) {
+					evt.preventDefault();
+					paymentRequest.show();
+				}
+			} );
+		},
+
+		showPaymentRequestButton: function( prButton ) {
+			if ( wc_stripe_payment_request.isCustomPaymentRequestButton( prButton ) ) {
+				prButton.addClass( 'is-active' );
+				$( '#wc-stripe-payment-request-wrapper, #wc-stripe-payment-request-button-separator' ).show();
+			} else if ( wc_stripe_payment_request.isBrandedPaymentRequestButton( prButton ) ) {
+				$( '#wc-stripe-payment-request-wrapper, #wc-stripe-payment-request-button-separator' ).show();
+				$( '#wc-stripe-payment-request-button' ).html( prButton );
+			} else if ( $( '#wc-stripe-payment-request-button' ).length ) {
+				$( '#wc-stripe-payment-request-wrapper, #wc-stripe-payment-request-button-separator' ).show();
+				prButton.mount( '#wc-stripe-payment-request-button' );
+			}
+		},
+
+		hidePaymentRequestButton: function () {
+			$( '#wc-stripe-payment-request-wrapper, #wc-stripe-payment-request-button-separator' ).hide();
+		},
+
+		unhidePaymentRequestButton: function () {
+			const stripe_wrapper = $( '#wc-stripe-payment-request-wrapper' );
+			const stripe_separator = $( '#wc-stripe-payment-request-button-separator' );
+			// If either element is hidden, ensure both show.
+			if ( stripe_wrapper.is(':hidden') || stripe_separator.is(':hidden') ) {
+				stripe_wrapper.show();
+				stripe_separator.show();
+			}
+		},
+
+		blockPaymentRequestButton: function( cssClassname ) {
+			// check if element isn't already blocked before calling block() to avoid blinking overlay issues
+			// blockUI.isBlocked is either undefined or 0 when element is not blocked
+			if ( $( '#wc-stripe-payment-request-button' ).data( 'blockUI.isBlocked' ) ) {
+				return;
+			}
+
+			$( '#wc-stripe-payment-request-button' )
+				.addClass( cssClassname )
+				.block( { message: null } );
+		},
+
+		unblockPaymentRequestButton: function() {
+			$( '#wc-stripe-payment-request-button' )
+				.removeClass( ['wc_request_button_is_blocked', 'wc_request_button_is_disabled'] )
+				.unblock();
+		},
+
+		/**
+		 * Initialize event handlers and UI state
+		 *
+		 * @since 4.0.0
+		 * @version 4.0.0
+		 */
+		init: function() {
+			if ( wc_stripe_payment_request_params.is_product_page ) {
+				wc_stripe_payment_request.startPaymentRequest( '' );
+			} else {
+				wc_stripe_payment_request.getCartDetails();
+			}
+
+		},
+	};
+
+	wc_stripe_payment_request.init();
+
+	// We need to refresh payment request data when total is updated.
+	$( document.body ).on( 'updated_cart_totals', function() {
+		wc_stripe_payment_request.init();
+	} );
+
+	// We need to refresh payment request data when total is updated.
+	$( document.body ).on( 'updated_checkout', function() {
+		wc_stripe_payment_request.init();
+	} );
+
+	function setBackgroundImageWithFallback( element, background, fallback ) {
+		element.css( 'background-image', 'url(' + background + ')' );
+		// Need to use an img element to avoid CORS issues
+		var testImg = document.createElement("img");
+		testImg.onerror = function () {
+			element.css( 'background-image', 'url(' + fallback + ')' );
+		}
+		testImg.src = background;
+	}
+
+	// TODO: Replace this by `client/blocks/payment-request/login-confirmation.js`
+	// when we start using webpack to build this file.
+	function displayLoginConfirmation( paymentRequestType ) {
+		if ( ! wc_stripe_payment_request_params.login_confirmation ) {
+			return;
+		}
+
+		var message = wc_stripe_payment_request_params.login_confirmation.message;
+
+		// Replace dialog text with specific payment request type "Apple Pay" or "Google Pay".
+		if ( 'payment_request_api' !== paymentRequestType ) {
+			message = message.replace(
+				/\*\*.*?\*\*/,
+				'apple_pay' === paymentRequestType ? 'Apple Pay' : 'Google Pay'
+			);
+		}
+
+		// Remove asterisks from string.
+		message = message.replace( /\*\*/g, '' );
+
+		if ( confirm( message ) ) {
+			// Redirect to my account page.
+			window.location.href = wc_stripe_payment_request_params.login_confirmation.redirect_url;
+		}
+	}
+} );
