如何在WooCommerce中正确优先入队自定义Stripe JS代码至订单确认页(替代模板直接修改)
Fixing WooCommerce Stripe JS Element Disappearance via Custom Plugin
Great call moving away from modifying core WooCommerce templates—template edits break on plugin updates and are hard to maintain. Let's walk through how to properly enqueue your Stripe script and get those elements working reliably from your custom plugin.
Key Issues with Your Current Setup
- Your script isn't restricted to the checkout page (loads everywhere, wasting resources)
- You aren't explicitly defining dependencies between Stripe.js and your custom script
- You're missing the DOM containers (
#card-numberand#card-errors) that your JS needs to mount elements to (since you removed them from the template) - Hardcoding your Stripe publishable key in JS isn't secure or maintainable
Step 1: Update Your Script Enqueue Code
Modify your plugin's PHP to load scripts only on the checkout page, set proper dependencies, and pass your Stripe key safely to the frontend:
add_action('wp_enqueue_scripts', [self::class, 'enqueue'], 100); public static function enqueue() { // Only load scripts on the WooCommerce checkout page if (!is_checkout()) { return; } // Enqueue Stripe.js v3 (load first, no dependencies) wp_enqueue_script( 'woocommerce-pay-later-stripe', 'https://js.stripe.com/v3/', [], '3.0', true // Load in footer for better performance ); // Enqueue your custom script, DEPENDING on Stripe.js and jQuery wp_enqueue_script( 'woocommerce-pay-later-main', plugins_url('/assets/main.js', __DIR__), ['jquery', 'woocommerce-pay-later-stripe'], // Critical: ensures Stripe loads first '1.0.0', // Use your plugin's version number here true ); // Pass your Stripe publishable key to the frontend (safe alternative to hardcoding) wp_localize_script( 'woocommerce-pay-later-main', 'PayLaterStripeSettings', [ 'publishableKey' => 'pk_test_51IB3etJxogSn2Fj0hqBSBcCkGH76cUowa9iWK7Xm7gj3O2jdt8FfcIXrHoZGIk4ySL1MyYYp1IxN582FOsjgI1DD00Hr7nvVF1' ] ); }
Step 2: Add Stripe DOM Containers via WooCommerce Hooks
Since you removed the containers from the template, add them dynamically using a WooCommerce action hook:
// Insert Stripe card element containers above the checkout submit button add_action('woocommerce_review_order_before_submit', [self::class, 'add_stripe_card_containers']); public static function add_stripe_card_containers() { echo '<div id="card-number" class="woocommerce-form-row woocommerce-form-row--wide" style="margin-bottom: 1rem;"></div>'; echo '<div id="card-errors" role="alert" style="color: #fa755a; margin-bottom: 1rem;"></div>'; }
Step 3: Refine Your Custom JS (main.js)
Update your script to use the localized Stripe key, handle WooCommerce form submission properly, and add error resilience:
(function ($) { "use strict"; $(document).ready(function () { // Guard clause: make sure Stripe and our settings are loaded if (typeof Stripe === 'undefined' || typeof PayLaterStripeSettings === 'undefined') { console.error('Stripe.js or plugin settings failed to load'); return; } // Initialize Stripe with our localized publishable key const stripe = Stripe(PayLaterStripeSettings.publishableKey); const elements = stripe.elements(); // Custom styling for Stripe elements const style = { base: { color: '#32325d', fontFamily: '"Helvetica Neue", Helvetica, sans-serif', fontSmoothing: 'antialiased', fontSize: '16px', '::placeholder': { color: '#aab7c4' } }, invalid: { color: '#fa755a', iconColor: '#fa755a' } }; // Create and mount the card element const card = elements.create('card', { style: style }); card.mount('#card-number'); // Handle real-time validation errors card.on('change', function (event) { const displayError = document.getElementById('card-errors'); displayError.textContent = event.error ? event.error.message : ''; }); // Intercept WooCommerce checkout form submission const checkoutForm = $('form.checkout'); checkoutForm.on('submit', function (event) { // Disable submit button to prevent duplicate submissions const submitBtn = checkoutForm.find('button[type="submit"]'); submitBtn.prop('disabled', true); // Create Stripe token from card data stripe.createToken(card).then(function (result) { if (result.error) { // Show error and re-enable button document.getElementById('card-errors').textContent = result.error.message; submitBtn.prop('disabled', false); } else { // Insert token as hidden field and submit form $('<input>').attr({ type: 'hidden', name: 'stripeToken', value: result.token.id }).appendTo(checkoutForm); checkoutForm.unbind('submit').submit(); } }); // Prevent default form submission until token is created event.preventDefault(); }); }); })(jQuery);
Critical Notes for Success
- Priority: The
100priority inwp_enqueue_scriptsensures your scripts load after WooCommerce's default scripts, avoiding conflicts. - Server-Side Handling: You'll need to add server-side code to process the
stripeTokenwhen the form is submitted (verify the token with Stripe and create a charge). - Conflict Prevention: If you're using WooCommerce's official Stripe plugin, add a condition to only load your scripts when your payment method is selected.
内容的提问来源于stack exchange,提问作者Mohsin
相关产品推荐
相关产品推荐

