WooCommerce Subscriptions插件:初始订阅到期/重新订阅时替换产品为Premium Pass的最佳实现方案咨询
Great question! Let's walk through the most robust approach to meet your subscription replacement needs with WooCommerce Subscriptions—leveraging the platform's built-in subscription switching functionality alongside targeted hooks to automate the process, plus a one-click checkout button for a smooth user experience.
The best path here combines automated product replacement for renewals/resubscriptions (using WooCommerce hooks) and a one-click subscription switch button to let users manually trigger the upgrade. This approach leverages WooCommerce Subscriptions' native features, ensuring subscription history is preserved while enforcing your business logic.
First, we’ll use hooks to automatically swap Silver/Gold Passes with Premium Pass when:
- An initial subscription triggers auto-renewal
- A user resubscribes after canceling their Silver/Gold Pass
Prerequisites
Replace the placeholder product IDs in the code below with your actual:
$original_product_ids: Silver Pass + Gold Pass IDs$premium_pass_id: Premium Pass ID
Hook 1: Replace Product on Auto-Renewal
This hook triggers when a renewal order is created, updating both the renewal order and the parent subscription to use Premium Pass for future renewals:
add_action( 'woocommerce_subscription_renewal_order_created', 'replace_subscription_product_on_renewal', 10, 2 ); function replace_subscription_product_on_renewal( $renewal_order, $subscription ) { // Update these IDs to match your products $premium_pass_id = 123; $premium_product = wc_get_product( $premium_pass_id ); if ( ! $premium_product ) return; // Clear original line items from the renewal order $renewal_order->remove_all_items(); // Add Premium Pass to the renewal order $renewal_order->add_product( $premium_product, 1 ); // Update the parent subscription to use Premium Pass for all future renewals $subscription->set_product_id( $premium_pass_id ); $subscription->save(); }
Hook 2: Replace Product on Resubscription
This hook intercepts checkout when a user tries to resubscribe to Silver/Gold Pass (after canceling) and swaps it with Premium Pass:
add_action( 'woocommerce_checkout_create_order_line_item', 'replace_subscription_product_on_resubscribe', 10, 4 ); function replace_subscription_product_on_resubscribe( $item, $cart_item_key, $values, $order ) { // Only target subscription products if ( ! $values['data']->is_type( 'subscription' ) ) return; // Update these IDs to match your products $original_product_ids = array( 456, 789 ); // Silver + Gold Pass IDs $premium_pass_id = 123; // Premium Pass ID $user_id = get_current_user_id(); if ( ! $user_id ) return; // Check if the user has an existing/canceled subscription to Silver/Gold Pass $has_prev_subscription = wcs_user_has_subscription( $user_id, $original_product_ids, 'any' ); // Swap the product if user is resubscribing to Silver/Gold if ( in_array( $values['data']->get_id(), $original_product_ids ) && $has_prev_subscription ) { $premium_product = wc_get_product( $premium_pass_id ); if ( $premium_product ) { $item->remove(); // Remove original product from order $order->add_product( $premium_product, 1 ); // Add Premium Pass } } }
To let users manually trigger the switch (and skip the cart), we’ll add a button to their "My Account > Subscriptions" page that directly adds Premium Pass to the cart and redirects to checkout.
Add Button to Subscription List
add_filter( 'woocommerce_my_account_my_subscriptions_actions', 'add_one_click_premium_switch_button', 10, 2 ); function add_one_click_premium_switch_button( $actions, $subscription ) { // Update these IDs to match your products $original_product_ids = array( 456, 789 ); // Silver + Gold Pass IDs $premium_pass_id = 123; // Premium Pass ID // Only show button for Silver/Gold subscriptions if ( in_array( $subscription->get_product_id(), $original_product_ids ) ) { // Generate secure checkout URL with switch parameters $switch_url = wp_nonce_url( add_query_arg( array( 'action' => 'switch_to_premium', 'subscription_id' => $subscription->get_id(), 'product_id' => $premium_pass_id ), wc_get_checkout_url() ), 'switch_subscription_nonce' ); $actions['switch_to_premium'] = array( 'url' => $switch_url, 'name' => __( 'Switch to Premium Pass', 'your-text-domain' ), 'icon' => 'arrow-right', ); } return $actions; }
Handle Button Click & Redirect to Checkout
add_action( 'template_redirect', 'handle_one_click_premium_switch' ); function handle_one_click_premium_switch() { // Validate request parameters and security nonce if ( ! isset( $_GET['action'] ) || $_GET['action'] !== 'switch_to_premium' ) return; if ( ! isset( $_GET['subscription_id'], $_GET['product_id'] ) ) return; if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'switch_subscription_nonce' ) ) die( 'Invalid request' ); $subscription_id = absint( $_GET['subscription_id'] ); $premium_pass_id = absint( $_GET['product_id'] ); $subscription = wcs_get_subscription( $subscription_id ); $premium_product = wc_get_product( $premium_pass_id ); if ( ! $subscription || ! $premium_product ) return; // Clear cart and add Premium Pass WC()->cart->empty_cart(); WC()->cart->add_to_cart( $premium_pass_id ); // Optional: Cancel the original subscription immediately (remove if you want it to expire naturally) // $subscription->update_status( 'cancelled' ); // Redirect to checkout wp_safe_redirect( wc_get_checkout_url() ); exit; }
- Test in a Staging Environment: Always test these changes in a staging site first to avoid disrupting live orders.
- Email Templates: Since we’re replacing the product in orders/subscriptions, all default WooCommerce emails will automatically show "Premium Pass" (no extra template edits needed unless you’re using custom templates).
- Subscription History: Using
set_product_id()on the subscription ensures future renewals use Premium Pass, preserving the user’s subscription timeline. - User Permissions: The code only shows the switch button to the subscription owner and validates requests with nonces to prevent unauthorized actions.
内容的提问来源于stack exchange,提问作者DashaLuna




