: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
/* global Stripe, wpforms, wpforms_stripe, WPForms, WPFormsUtils */
* @param window.wpformsStripePaymentElementAppearance
* @param wpforms_stripe.data.element_appearance
* @param wpforms_stripe.data.element_locale
* @param wpforms_stripe.i18n.element_load_error
* @param wpforms_stripe.i18n.empty_details
* @param wpforms_stripe.publishable_key
// noinspection ES6ConvertVarToLetConst
* WPForms Stripe Payment Element function.
// eslint-disable-next-line no-var
var WPFormsStripePaymentElement = window.WPFormsStripePaymentElement || ( function( document, window, $ ) {
* Original Submit Handler.
let originalSubmitHandler;
// noinspection JSUnusedLocalSymbols
* Public functions and properties.
* @property {Function} confirmPayment Payment confirmation.
* Object to store form data.
app.stripe = Stripe( // eslint-disable-line new-cap
wpforms_stripe.publishable_key,
locale: wpforms_stripe.data.element_locale,
betas: [ 'elements_enable_deferred_intent_beta_1' ],
$( document ).on( 'wpformsReady', function() {
app.initializeFormsDefaultObject();
$( '.wpforms-stripe form' )
.each( app.setupStripeForm )
.on( 'wpformsConvFormsFieldActivationAfter', app.convFormsFieldActivationAfter ); // Initialize in Conversational Form on field activation.
.on( 'wpformsBeforePageChange', app.pageChange )
.on( 'wpformsAmountTotalCalculated', app.updateElementsTotalAmount )
.on( 'wpformsProcessConditionalsField', function( e, formID, fieldID, pass, action ) {
app.processConditionalsField( formID, fieldID, pass, action );
* Initialize forms default object.
initializeFormsDefaultObject() {
$( '.wpforms-stripe form' ).each( function() {
const formId = $( this ).data( 'formid' );
* Setup and configure a Stripe form.
$stripeDiv = $form.find( '.wpforms-field-stripe-credit-card' );
if ( ! $stripeDiv.find( '.wpforms-field-row' ).length ) {
const validator = $form.data( 'validator' );
// Store the original submitHandler.
originalSubmitHandler = validator.settings.submitHandler;
// Replace the default submit handler.
validator.settings.submitHandler = app.submitHandler;
$form.on( 'wpformsAjaxSubmitActionRequired', app.confirmPaymentActionCallback );
if ( $stripeDiv.hasClass( 'wpforms-conditional-field' ) ) {
app.setupPaymentElement( $form );
* Handle confirm payment server response.
* @param {Object} e Event object.
* @param {Object} json Json returned from a server.
* @param {boolean} json.data.action_required Whether action is required.
* @param {string} json.data.payment_intent_client_secret Payment intent client secret.
* @param {boolean} json.success Success.
async confirmPaymentActionCallback( e, json ) {
if ( ! json.success || ! json.data.action_required ) {
const redirectUrl = new URL( window.location.href ),
formId = $form.data( 'formid' );
await app.stripe.confirmPayment(
clientSecret: json.data.payment_intent_client_secret, // eslint-disable-line camelcase
return_url: redirectUrl.toString(), // eslint-disable-line camelcase
payment_method: app.forms[ formId ].paymentMethodId, // eslint-disable-line camelcase
).then( function( result ) {
app.handleConfirmPayment( $form, result );
* Callback for Stripe 'confirmPayment' method.
* @param {jQuery} $form Form element.
* @param {Object} result Data returned by 'handleCardPayment'.
* @param {Object} result.error Error.
* @param {Object} result.paymentIntent Payment intent.
handleConfirmPayment( $form, result ) {
app.displayStripeError( $form, result.error.message );
const formId = $form.data( 'formid' );
if ( result.paymentIntent && result.paymentIntent.status === 'succeeded' ) {
$form.find( '.wpforms-stripe-payment-method-id' ).remove();
$form.find( '.wpforms-stripe-payment-intent-id' ).remove();
$form.append( '<input type="hidden" class="wpforms-stripe-payment-intent-id" name="wpforms[payment_intent_id]" value="' + result.paymentIntent.id + '">' );
$form.append( '<input type="hidden" class="wpforms-stripe-payment-link-email" name="wpforms[payment_link_email]" value="' + app.forms[ formId ].linkEmail + '">' );
wpforms.formSubmitAjax( $form );
app.formAjaxUnblock( $form );
* Setup, mount and configure Stripe Payment Element.
* @param {jQuery} $form Form element.
setupPaymentElement( $form ) {
const formId = $form.data( 'formid' );
if ( $.isEmptyObject( app.forms ) ) {
app.initializeFormsDefaultObject();
if ( app.forms[ formId ].paymentElement ) {
app.forms[ formId ].elements = app.stripe.elements(
currency: wpforms.getCurrency().code.toLowerCase(),
// eslint-disable-next-line
// See min amount for different currencies https://stripe.com/docs/currencies#minimum-and-maximum-charge-amounts.
locale: wpforms_stripe.data.element_locale,
appearance: app.getElementAppearanceOptions( $form ),
app.initializePaymentElement( $form );
app.linkEmailMappedFieldTriggers( $form );
// Update the total amount in case of fixed price.
wpforms.amountTotalCalc( $form );
// Update styles in Modern Markup mode.
app.updatePaymentElementStylesModern( $form );
* Handle Process Conditionals for Stripe field.
* @param {string} formID Form ID.
* @param {string} fieldID Field ID.
* @param {boolean} pass Pass logic.
* @param {string} action Action to execute.
processConditionalsField( formID, fieldID, pass, action ) { // eslint-disable-line complexity
const $form = $( '#wpforms-form-' + formID ),
$stripeDiv = $form.find( '.wpforms-field-stripe-credit-card' ),
isHidden = ( pass && action === 'hide' ) || ( ! pass && action !== 'hide' );
$stripeDiv.data( 'field-id' ).toString() !== fieldID ||
app.forms[ formID ].paymentElement ||
app.setupPaymentElement( $form );
* Get Element appearance options.
* @param {jQuery} $form Form element.
* @return {Object} Appearance options.
getElementAppearanceOptions( $form ) { // eslint-disable-line complexity, max-lines-per-function
const customAppearanceOptions = app.getCustomAppearanceOptions();
if ( ! $.isEmptyObject( customAppearanceOptions ) ) {
return customAppearanceOptions;
const $hiddenInput = $form.find( '.wpforms-stripe-credit-card-hidden-input' ),
$fieldRow = $form.find( '.wpforms-field-stripe-credit-card .wpforms-field-row' );
const labelHide = ! $fieldRow.hasClass( 'wpforms-sublabel-hide' );
borderColor: app.getCssPropertyValue( $hiddenInput, '--field-border' ) || app.getCssPropertyValue( $hiddenInput, 'border-color' ),
borderRadius: app.getCssPropertyValue( $hiddenInput, 'border-radius' ),
fontSize: app.getCssPropertyValue( $hiddenInput, 'font-size' ),
colorPrimary: app.getCssPropertyValue( $hiddenInput, '--primary-color' ) || app.getCssPropertyValue( $hiddenInput, 'color' ),
colorText: app.getCssPropertyValue( $hiddenInput, '--secondary-color' ) || app.getCssPropertyValue( $hiddenInput, 'color' ),
colorTextPlaceholder: app.getCssPropertyValue( $hiddenInput, '--secondary-color-50' ) || WPFormsUtils.cssColorsUtils.getColorWithOpacity( app.getCssPropertyValue( $hiddenInput, 'color' ), '0.5' ),
colorBackground: app.getCssPropertyValue( $hiddenInput, '--background-color' ) || app.getCssPropertyValue( $hiddenInput, 'background-color' ),
fontFamily: app.getCssPropertyValue( $hiddenInput, 'font-family' ),
focusColor: app.getCssPropertyValue( $hiddenInput, '--accent-color' ) || app.getCssPropertyValue( $hiddenInput, 'color' ),
if ( window.WPForms && WPForms.FrontendModern ) {
inputStyle.colorPrimary = WPForms.FrontendModern.getSolidColor( inputStyle.colorPrimary );
labels: $fieldRow.data( 'sublabel-position' ),
colorPrimary: inputStyle.colorPrimary,
colorBackground: inputStyle.colorBackground,
colorText: inputStyle.colorText,
colorDanger: inputStyle.errorColor,
fontFamily: inputStyle.fontFamily,
borderRadius: inputStyle.borderRadius,
colorTextPlaceholder: inputStyle.colorTextPlaceholder,
colorIcon: inputStyle.colorText,
color: inputStyle.colorText,
borderRadius: inputStyle.borderRadius,
boxShadow: '0 0 0 1px ' + inputStyle.borderColor,
fontSize: inputStyle.fontSize,
lineHeight: parseInt( inputStyle.fontSize, 10 ) + 5 + 'px', // match the font and line height to prevent overflow
color: inputStyle.colorText,
backgroundColor: inputStyle.colorBackground,
'.Input:focus, .Input:hover': {
boxShadow: '0 0 0 2px ' + inputStyle.focusColor,
fontFamily: inputStyle.fontFamily,
lineHeight: labelHide ? '1.3' : '0',
opacity: Number( labelHide ),
color: inputStyle.colorPrimary,
'.CheckboxInput, .CodeInput, .PickerItem': {
border: '1px solid ' + inputStyle.borderColor,
border: '1px solid ' + inputStyle.borderColor,
borderRadius: inputStyle.borderRadius,
color: inputStyle.colorText,
color: inputStyle.colorText,
color: inputStyle.colorText,
'.Action, .MenuAction': {
backgroundColor: 'transparent',
'.Action:hover, .MenuAction:hover': {
backgroundColor: 'transparent',
'.Error, .RedirectText': {
color: inputStyle.errorColor,
fill: inputStyle.colorText,
* Get custom appearance options.
* @return {Object} Element appearance options.
getCustomAppearanceOptions() {
if ( typeof window.wpformsStripePaymentElementAppearance === 'object' ) {
return window.wpformsStripePaymentElementAppearance;
if ( ! $.isEmptyObject( wpforms_stripe.data.element_appearance ) ) {
return wpforms_stripe.data.element_appearance;
* Get CSS property value.
* In case of exception, return empty string.
* @param {jQuery} $element Element.
* @param {string} property Property.
* @return {string} Property value.
getCssPropertyValue( $element, property ) {
return $element.css( property );
* Initialize Payment Element.
* @param {jQuery} $form Form element.
* @param {string} email Email address.
initializePaymentElement( $form, email = '' ) {
const $fieldRow = $form.find( '.wpforms-field-stripe-credit-card .wpforms-field-row' );
const formId = $form.data( 'formid' );
if ( app.forms[ formId ].paymentElement ) {
app.forms[ formId ].paymentElement.destroy();
app.forms[ formId ].paymentElement = app.forms[ formId ].elements.create( 'payment', { defaultValues : { billingDetails: { email } } } );
app.mountPaymentElement( $form );
// eslint-disable-next-line complexity
app.forms[ formId ].paymentElement.on( 'change', function( event ) {
app.forms[ formId ].paymentType = event.value.type;
// Destroy a link element as it's not required for Google and Apple Pay.
if ( ! $fieldRow.data( 'link-email' ) ) {
if ( event.value.type === 'google_pay' || event.value.type === 'apple_pay' ) {
app.forms[ formId ].linkElement.destroy();
app.forms[ formId ].linkDestroyed = true;
} else if ( app.forms[ formId ].linkDestroyed ) {
app.initializeLinkAuthenticationElement( $form );
app.forms[ formId ].linkDestroyed = false;
$fieldRow.data( 'type', event.value.type );
$fieldRow.data( 'completed', false );
$fieldRow.find( 'label.wpforms-error' ).toggle( event.value.type === 'card' );
app.forms[ formId ].elementsModified = true;
$fieldRow.data( 'completed', true );
app.hideStripeFieldError( $form );
$fieldRow.data( 'completed', false );
app.forms[ formId ].paymentElement.on( 'loaderror', function( event ) {