Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
15568bf
Integrate Stripe Connect proxy server for secure OAuth flow
superdav42 Dec 15, 2025
bd87731
Optimize Stripe OAuth performance and remove application fees
superdav42 Dec 15, 2025
c431f91
Remove platform_client_id - now handled by proxy server
superdav42 Dec 15, 2025
44f23c3
fix stripe
superdav42 Dec 31, 2025
b0155af
Merge branch 'main' of github.com:Multisite-Ultimate/ultimate-multisi…
superdav42 Jan 2, 2026
f980d7c
Hide redundant billing address fields when Stripe gateway is selected
superdav42 Jan 2, 2026
4f14632
Merge branch 'main' into stripe-claude
superdav42 Feb 8, 2026
18efb0b
Add Stripe checkout and subscription renewal E2E tests
superdav42 Feb 9, 2026
2e044f4
fix: use env var check instead of secrets context in workflow if cond…
superdav42 Feb 9, 2026
30e8f1c
fix: override wp-env plugins in CI to exclude missing domain-seller a…
superdav42 Feb 9, 2026
c5937c4
fix: rewrite wp-env.json in CI to strip addons and mappings
superdav42 Feb 9, 2026
568a608
Fix invoice PDF download failing with expired nonce
superdav42 Feb 9, 2026
01b2fae
Fix Stripe checkout test mock missing latest_charge field
superdav42 Feb 9, 2026
76b6b62
change the validation rules
superdav42 Feb 9, 2026
966176e
add attachement pdf in test emails
superdav42 Feb 10, 2026
7454593
Only check for memory errors
superdav42 Feb 10, 2026
4a125da
Merge branch 'main' into stripe-claude
superdav42 Feb 12, 2026
e58d57c
Actually get stripe to work
superdav42 Feb 13, 2026
52f9f17
fix test
superdav42 Feb 13, 2026
0a6982a
Fix duplicate Country/ZIP fields on Stripe checkout
superdav42 Feb 13, 2026
caf0854
Update tests/e2e/cypress/fixtures/process-stripe-renewal.php
superdav42 Feb 13, 2026
1ec49d7
Update inc/managers/class-gateway-manager.php
superdav42 Feb 13, 2026
827e78e
Move payment status CSS from inline to checkout.css
superdav42 Feb 13, 2026
2da2f14
Merge branch 'main' into stripe-claude
superdav42 Feb 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
583 changes: 312 additions & 271 deletions assets/js/gateways/stripe.js

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion inc/admin-pages/class-wizard-admin-page.php
Original file line number Diff line number Diff line change
Expand Up @@ -205,13 +205,22 @@ public function output() {
'labels' => $this->get_labels(),
'sections' => $this->get_sections(),
'current_section' => $this->get_current_section(),
'classes' => 'wu-w-full wu-mx-auto sm:wu-w-11/12 xl:wu-w-8/12 wu-mt-8 sm:wu-max-w-screen-lg',
'classes' => $this->get_classes(),
'clickable_navigation' => $this->clickable_navigation,
'form_id' => $this->form_id,
]
);
}

/**
* Return the classes used in the main wrapper.
*
* @return string
*/
protected function get_classes() {
return 'wu-w-full wu-mx-auto sm:wu-w-11/12 xl:wu-w-8/12 wu-mt-8 sm:wu-max-w-screen-lg';
}

/**
* Returns the first section of the signup process
*
Expand Down
110 changes: 110 additions & 0 deletions inc/checkout/class-checkout-pages.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ public function init(): void {

add_shortcode('wu_confirmation', [$this, 'render_confirmation_page']);

/*
* Enqueue payment status polling script on thank you page.
*/
add_action('wp_enqueue_scripts', [$this, 'maybe_enqueue_payment_status_poll']);

add_filter('lostpassword_redirect', [$this, 'filter_lost_password_redirect']);

if (is_main_site()) {
Expand Down Expand Up @@ -204,6 +209,8 @@ public function get_error_message($error_code, $username = '') {
'password_reset_mismatch' => __('<strong>Error:</strong> The passwords do not match.'), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
'invalidkey' => __('<strong>Error:</strong> Your password reset link appears to be invalid. Please request a new link below.'), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
'expiredkey' => __('<strong>Error:</strong> Your password reset link has expired. Please request a new link below.'), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
'invalid_key' => __('<strong>Error:</strong> Your password reset link appears to be invalid. Please request a new link below.'), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
'expired_key' => __('<strong>Error:</strong> Your password reset link has expired. Please request a new link below.'), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
];

/**
Expand Down Expand Up @@ -665,4 +672,107 @@ public function render_confirmation_page($atts, $content = null) { // phpcs:igno
]
);
}

/**
* Maybe enqueue payment status polling script on thank you page.
*
* This script polls the server to check if a pending payment has been completed,
* providing a fallback mechanism when webhooks are delayed or not working.
*
* @since 2.x.x
* @return void
*/
public function maybe_enqueue_payment_status_poll(): void {

// Only on thank you page (payment hash and status=done in URL)
$payment_hash = wu_request('payment');
$status = wu_request('status');

if (empty($payment_hash) || 'done' !== $status || 'none' === $payment_hash) {
return;
}

$payment = wu_get_payment_by_hash($payment_hash);

if (! $payment) {
return;
}

// Only poll for pending Stripe payments
$gateway_id = $payment->get_gateway();

if (empty($gateway_id)) {
$membership = $payment->get_membership();
$gateway_id = $membership ? $membership->get_gateway() : '';
}

// Only poll for Stripe payments that are still pending
$is_stripe_payment = in_array($gateway_id, ['stripe', 'stripe-checkout'], true);
$is_pending = $payment->get_status() === \WP_Ultimo\Database\Payments\Payment_Status::PENDING;

if (! $is_stripe_payment) {
return;
}

wp_register_script(
'wu-payment-status-poll',
wu_get_asset('payment-status-poll.js', 'js'),
['jquery'],
wu_get_version(),
true
);

wp_localize_script(
'wu-payment-status-poll',
'wu_payment_poll',
[
'payment_hash' => $payment_hash,
'ajax_url' => admin_url('admin-ajax.php'),
Comment on lines +786 to +787
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

rg -n "payment.status|payment_status|wu_payment.*poll|wu_check_payment" --type=php -C3

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 33946


🏁 Script executed:

# Also search for add_action calls with ajax
rg -n "add_action.*wp_ajax" --type=php -C2

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 10159


🏁 Script executed:

# Let's look at the specific file to understand context
head -750 inc/checkout/class-checkout-pages.php | tail -50

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 1826


🏁 Script executed:

# Find Gateway Manager class and its init/constructor
rg -n "class.*Gateway.*Manager|function init|function __construct" inc/managers/class-gateway-manager.php -A5 | head -50

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 334


🏁 Script executed:

# Check if there's any is_main_site or multisite-specific handling in the hook registration
rg -n "is_main_site|is_multisite|switch_to_blog|restore_current_blog" inc/managers/class-gateway-manager.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 136


🏁 Script executed:

# Look for where Gateway Manager is instantiated
rg -n "new.*Gateway.*Manager|Gateway_Manager" inc/ -l | head -10

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 227


🏁 Script executed:

# Check the actual handler implementation to see if it accesses data from the current site
sed -n '596,650p' inc/managers/class-gateway-manager.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 1671


🏁 Script executed:

# Find the wu_get_payment_by_hash function
rg -n "function wu_get_payment_by_hash|def wu_get_payment_by_hash" --type=php -A10

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 637


🏁 Script executed:

# Check if payments are stored globally (main site) or per-site
rg -n "payments.*table|register_table.*payment" inc/ --type=php | head -20

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 388


🏁 Script executed:

# Look for any switch_to_blog or site context handling in payment queries
rg -n "switch_to_blog|restore_current_blog|blog_id|get_current_blog_id" inc/managers/class-gateway-manager.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 63


🏁 Script executed:

# Check where the AJAX hook is registered and if there's any site filtering
sed -n '100,150p' inc/managers/class-gateway-manager.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 1594


🏁 Script executed:

# Check where Gateway Manager singleton is instantiated
rg -n "Gateway_Manager::get_instance|gateway_manager\|new Gateway_Manager" inc/ --type=php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 873


🏁 Script executed:

# Check the Singleton trait to understand how it works
rg -n "trait Singleton|get_instance|instance" inc/traits/class-singleton.php -A5

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 151


🏁 Script executed:

# Check if wp_ajax hooks are global or site-specific in WordPress multisite
# by looking at how the payment status polling script is enqueued
sed -n '694,760p' inc/checkout/class-checkout-pages.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 2272


🏁 Script executed:

# Look for any documentation or comments about multisite handling
rg -n "multisite|is_multisite|subsite|sub-site" inc/managers/class-gateway-manager.php -i

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 2116


🏁 Script executed:

# Check how WP Ultimo loads and initializes managers
rg -n "plugins_loaded|on_load" inc/class-wp-ultimo.php -B2 -A5 | head -40

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 337


🏁 Script executed:

# Verify if Gateway Manager's on_load method is called and if it's site-aware
sed -n '66,180p' inc/managers/class-gateway-manager.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 3148


🏁 Script executed:

# Check the payment-status-poll.js to see how it handles the AJAX call
find . -name "payment-status-poll.js" -type f 2>/dev/null

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 63


🏁 Script executed:

# Look for assets directory
fd -t f "payment-status-poll" --type f

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 63


🏁 Script executed:

# Check the Gateway Manager's verify_and_complete_payment to see if there's site context handling
rg -n "verify_and_complete_payment" inc/gateways/ --type=php -A15 | head -60

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 1304


🏁 Script executed:

# Check if payments table is truly global by looking at the table registration
sed -n '1,60p' inc/database/payments/class-payments-table.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 1025


🏁 Script executed:

# Look for any blog_id or site-specific columns in the payments table
rg -n "blog_id|site_id|get_site_id" inc/database/payments/ --type=php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 63


🏁 Script executed:

# Check the base manager to understand how the Gateway Manager extends it
rg -n "class Base_Manager|is_main_site|current_site" inc/managers/class-base-manager.php -B2 -A10 | head -50

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 274


🏁 Script executed:

# Check if wp_ajax hooks are truly site-specific or global in WordPress multisite
# by searching for any site-specific AJAX handling patterns in the codebase
rg -n "wp_ajax.*switch_to_blog|wp_ajax.*restore_current_blog" inc/ --type=php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 63


🏁 Script executed:

# Verify the Payment::get_by_hash method to confirm it accesses the global table
rg -n "get_by_hash|class Payment" inc/models/class-payment.php -A20 | head -60

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 566


🏁 Script executed:

# Check if there are any tests that verify multisite AJAX functionality
find . -name "*test*" -o -name "*spec*" -type f | xargs grep -l "multisite\|ajax\|admin_url" 2>/dev/null | head -5

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 300


🏁 Script executed:

# Look at how admin_url is documented and whether there's any multisite-specific handling
rg -n "admin_url.*admin-ajax" inc/ --type=php -B3 -A3

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 4440


Use the main site's admin-ajax.php for consistency with multisite handling patterns.

The AJAX handler is registered globally and the payments table is global, so requests technically work from subsite admin-ajax.php URLs. However, the codebase already uses get_admin_url(wu_get_main_site_id(), 'admin-ajax.php') for similar AJAX operations in email and invoice template customization. Align this to use the main site's admin-ajax.php URL for consistency and to avoid potential future issues with site context.

🤖 Prompt for AI Agents
In `@inc/checkout/class-checkout-pages.php` around lines 738 - 739, In
class-checkout-pages.php update the 'ajax_url' value (the array key 'ajax_url'
in the payment data returned by the class) to use the main site admin-ajax
endpoint instead of admin_url('admin-ajax.php'); replace the current
admin_url('admin-ajax.php') usage with get_admin_url(wu_get_main_site_id(),
'admin-ajax.php') so AJAX requests point to the main site's admin-ajax.php
consistent with other code paths.

'poll_interval' => 3000, // 3 seconds
'max_attempts' => 20, // 60 seconds total
'should_poll' => $is_pending,
'status_selector' => '.wu-payment-status',
'success_redirect' => '',
'messages' => [
'completed' => __('Payment confirmed! Refreshing page...', 'ultimate-multisite'),
'pending' => __('Verifying your payment with Stripe...', 'ultimate-multisite'),
'timeout' => __('Payment verification is taking longer than expected. Your payment may still be processing. Please refresh the page or contact support if you believe payment was made.', 'ultimate-multisite'),
'error' => __('Error checking payment status. Retrying...', 'ultimate-multisite'),
'checking' => __('Checking payment status...', 'ultimate-multisite'),
],
]
);

wp_enqueue_script('wu-payment-status-poll');

// Add inline CSS for the status messages
wp_add_inline_style(
'wu-checkout',
'
.wu-payment-status {
padding: 12px 16px;
border-radius: 6px;
margin-bottom: 16px;
font-weight: 500;
}
.wu-payment-status-pending,
.wu-payment-status-checking {
background-color: #fef3cd;
color: #856404;
border: 1px solid #ffc107;
}
.wu-payment-status-completed {
background-color: #d4edda;
color: #155724;
border: 1px solid #28a745;
}
.wu-payment-status-timeout,
.wu-payment-status-error {
background-color: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
'
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for wu-checkout registration and enqueuing in the codebase
rg -n "wu-checkout" --type=php | head -40

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 4819


🏁 Script executed:

#!/bin/bash
# Get context around lines 757-785 in the checkout-pages file
wc -l inc/checkout/class-checkout-pages.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 122


🏁 Script executed:

#!/bin/bash
# Read the section around lines 757-785 to understand context
sed -n '740,790p' inc/checkout/class-checkout-pages.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 1592


🏁 Script executed:

#!/bin/bash
# Get broader context to find the function/method name
sed -n '720,760p' inc/checkout/class-checkout-pages.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 1509


🏁 Script executed:

#!/bin/bash
# Check the class structure and method definitions
rg -n "function|public|protected|private" inc/checkout/class-checkout-pages.php | grep -B5 -A5 "75[0-9]"

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 63


🏁 Script executed:

#!/bin/bash
# Look at where class-checkout-pages is instantiated and used
rg -n "class-checkout-pages\|checkout-pages" --type=php | head -20

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 63


🏁 Script executed:

#!/bin/bash
# Look for function definitions around line 700-750
sed -n '700,730p' inc/checkout/class-checkout-pages.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 920


🏁 Script executed:

#!/bin/bash
# Get all function/method definitions in the file with line numbers
rg -n "^\s*(public|private|protected)?\s*function" inc/checkout/class-checkout-pages.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 1445


🏁 Script executed:

#!/bin/bash
# Find where maybe_enqueue_payment_status_poll is called/hooked
rg -n "maybe_enqueue_payment_status_poll" --type=php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 306


🏁 Script executed:

#!/bin/bash
# Check the init method and hooks in class-checkout-pages
sed -n '30,95p' inc/checkout/class-checkout-pages.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 2280


🏁 Script executed:

#!/bin/bash
# Check when/where wu-checkout is enqueued in class-checkout.php
sed -n '2620,2650p' inc/checkout/class-checkout.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 1042


🏁 Script executed:

#!/bin/bash
# Find where register_scripts from class-checkout is called
rg -n "register_scripts" inc/checkout/class-checkout.php | head -5

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 199


🏁 Script executed:

#!/bin/bash
# Search for hooks/actions that call register_scripts on checkout
rg -n "register_scripts\|class-checkout" inc/checkout/class-checkout.php | grep -i "add_action\|add_filter" | head -10

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 63


🏁 Script executed:

#!/bin/bash
# Check the Checkout class initialization to see when register_scripts is called
sed -n '1,150p' inc/checkout/class-checkout.php | grep -A5 -B5 "register_scripts"

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 63


🏁 Script executed:

#!/bin/bash
# Find where wu_checkout_scripts action is fired
rg -n "wu_checkout_scripts" --type=php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 830


🏁 Script executed:

#!/bin/bash
# Check the initialization of Checkout class
sed -n '150,250p' inc/checkout/class-checkout.php | head -60

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 1516


🏁 Script executed:

#!/bin/bash
# Check what's enqueued on thank-you pages - search for enqueue in render_confirmation_page and related methods
sed -n '674,700p' inc/checkout/class-checkout-pages.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 988


🏁 Script executed:

#!/bin/bash
# Check if wu_checkout_scripts is fired on thank-you page
rg -n "render_confirmation_page\|do_action.*wu_checkout_scripts" inc/checkout/class-checkout-pages.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 63


🏁 Script executed:

#!/bin/bash
# Get full context of render_confirmation_page method
sed -n '674,695p' inc/checkout/class-checkout-pages.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 760


🏁 Script executed:

#!/bin/bash
# Check the confirmation template to see if it enqueues wu-checkout
find . -path "./views/*" -name "*confirmation*" -type f

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 114


🏁 Script executed:

#!/bin/bash
# Look for confirmation template
find . -name "confirmation.php" -type f

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 114


🏁 Script executed:

#!/bin/bash
# Check where wu_checkout_scripts is fired on the thank-you/confirmation page
rg -n "do_action.*wu_checkout_scripts" views/ --type=php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 153


🏁 Script executed:

#!/bin/bash
# Read the confirmation template to see what it does
cat views/checkout/confirmation.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 1703


🏁 Script executed:

#!/bin/bash
# Check if confirmation page calls any actions related to scripts
rg -n "do_action\|wp_enqueue" views/checkout/confirmation.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 63


🏁 Script executed:

#!/bin/bash
# Check if 'wu-checkout' is ever enqueued on pages outside of checkout form context
rg -n "wp_enqueue.*wu-checkout" --type=php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 701


🏁 Script executed:

#!/bin/bash
# Verify: does the thank-you page trigger wp_enqueue_scripts while wu_checkout_scripts fires?
# Check the page flow - look for how pages are rendered
sed -n '1,50p' inc/checkout/class-checkout-pages.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 1337


🏁 Script executed:

#!/bin/bash
# Double-check by looking at the full maybe_enqueue_payment_status_poll function
sed -n '694,786p' inc/checkout/class-checkout-pages.php

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 2828


Inline styles depend on wu-checkout handle being enqueued, which is not present on thank-you pages.

wp_add_inline_style('wu-checkout', ...) will silently fail on the thank-you page because the wu-checkout stylesheet is only enqueued during checkout form rendering (via the wu_checkout_scripts action in class-checkout.php), not during confirmation page display. The status message styles won't render.

Attach the inline CSS to the wu-payment-status-poll script you're already enqueuing instead:

wp_add_inline_script('wu-payment-status-poll', 'your_css_here', 'before');

Or register and enqueue a minimal styles dependency:

wp_register_style('wu-payment-status', false);
wp_enqueue_style('wu-payment-status');
wp_add_inline_style('wu-payment-status', '...');
🤖 Prompt for AI Agents
In `@inc/checkout/class-checkout-pages.php` around lines 757 - 785, The inline CSS
is being added with wp_add_inline_style using the 'wu-checkout' handle which
isn't enqueued on thank-you pages, so move the CSS to a handle that is present:
either attach it to the existing 'wu-payment-status-poll' script using
wp_add_inline_script('wu-payment-status-poll', ...) with the CSS string (and
'before' position), or register and enqueue a minimal style handle (e.g.,
wp_register_style('wu-payment-status', false);
wp_enqueue_style('wu-payment-status'); ) and then call
wp_add_inline_style('wu-payment-status', ...) so the .wu-payment-status styles
are output on the confirmation page; update the code in class-checkout-pages.php
where wp_add_inline_style('wu-checkout', ...) is currently used.

}
}
19 changes: 19 additions & 0 deletions inc/checkout/signup-fields/class-signup-field-billing-address.php
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,25 @@ public function to_fields_array($attributes) {

foreach ($fields as &$field) {
$field['wrapper_classes'] = trim(wu_get_isset($field, 'wrapper_classes', '') . ' ' . $attributes['element_classes']);

/*
* When zip_and_country is enabled (showing only ZIP + country),
* hide the billing address fields when any Stripe gateway is selected.
* Both Stripe Payment Element and Stripe Checkout collect Country and ZIP,
* making these fields redundant.
*
* Using :style binding instead of v-show for better Vue compatibility
* with server-rendered in-DOM templates.
*/
if ($zip_only) {
// Ensure wrapper_html_attr array exists
if ( ! isset($field['wrapper_html_attr'])) {
$field['wrapper_html_attr'] = [];
}

// Use :style binding to hide element when any Stripe gateway is selected
$field['wrapper_html_attr'][':style'] = "{ display: gateway && gateway.startsWith('stripe') ? 'none' : '' }";
}
}

uasort($fields, 'wu_sort_by_order');
Expand Down
Loading
Loading