WooCommerce创建两类不同结账表单及直连支付方案问询
Hey there! Let's break down your two WooCommerce needs into actionable solutions—first separating checkout forms for regular users vs advertisers, then skipping checkout for specific products to jump straight to payment. Here's how to make it happen:
The key here is targeting user roles. First, we'll create a dedicated "Advertiser" role, then tweak checkout fields based on who's checking out.
Step 1: Create the "Advertiser" User Role
You can do this with code or a plugin:
Code Method
Add this to your child theme's functions.php file (always back up your site first!):
add_action('init', 'create_advertiser_role'); function create_advertiser_role() { add_role( 'advertiser', 'Advertiser', array( 'read' => true, // Let them read content 'edit_posts' => false, // Restrict post editing 'delete_posts' => false, ) ); }
No-Code Method
Use the User Role Editor plugin—install it, go to Users > User Role Editor, and create a new role named "Advertiser" with the permissions you need.
Step 2: Customize Checkout Fields by Role
Now we'll show/hide fields based on whether the user is an advertiser or regular customer.
Code Method
Add this to your child theme's functions.php:
add_filter('woocommerce_checkout_fields', 'custom_checkout_fields_by_role'); function custom_checkout_fields_by_role($fields) { // Check if current user has the Advertiser role if (current_user_can('advertiser')) { // Add a custom required field for advertisers $fields['billing']['billing_advertiser_id'] = array( 'label' => __('Advertiser ID', 'woocommerce'), 'placeholder' => _x('Enter your unique advertiser ID', 'placeholder', 'woocommerce'), 'required' => true, 'class' => array('form-row-wide'), 'clear' => true ); // Remove fields advertisers don't need unset($fields['billing']['billing_company']); unset($fields['shipping']['shipping_company']); } else { // Optional: Remove fields regular users don't need unset($fields['billing']['billing_vat']); } return $fields; }
You can also add role-specific messages with this snippet:
add_action('woocommerce_before_checkout_form', 'checkout_role_message'); function checkout_role_message() { if (current_user_can('advertiser')) { echo '<p class="advertiser-note" style="color: #2ecc71;">*Please enter your advertiser ID to complete your order.</p>'; } }
No-Code Method
Use these plugins together:
- Checkout Field Editor for WooCommerce: Build your custom fields.
- Conditional Fields for WooCommerce: Set rules like "Show Advertiser ID field only when user role is Advertiser".
For this, we'll either redirect after adding the product to cart, or replace the "Add to Cart" button with a direct payment link.
Option 1: Redirect to Payment After Adding Target Product
This creates a pending order automatically and sends the user straight to payment. Add this to functions.php:
add_action('template_redirect', 'direct_payment_for_specific_product'); function direct_payment_for_specific_product() { $target_product_id = 123; // Replace with your product's ID $cart = WC()->cart; // Only run on cart page, and if user isn't already on checkout if (is_cart() && !is_checkout() && !empty($cart->get_cart())) { $product_in_cart = false; // Check if target product is in the cart foreach ($cart->get_cart() as $item) { if ($item['product_id'] === $target_product_id) { $product_in_cart = true; break; } } if ($product_in_cart) { // Create a new order $order = wc_create_order(); // Add the product to the order $order->add_product(wc_get_product($target_product_id), 1); // Use customer's saved billing/shipping details $order->set_address($cart->get_billing_address(), 'billing'); $order->set_address($cart->get_shipping_address(), 'shipping'); // Calculate totals and save order $order->calculate_totals(); $order->update_status('pending', 'Direct payment initiated'); // Empty cart (optional, if you want to avoid duplicate orders) $cart->empty_cart(); // Redirect to the payment page for this order wp_redirect(wc_get_endpoint_url('order-pay', $order->get_id(), wc_get_checkout_url())); exit; } } }
Option 2: Replace "Add to Cart" with "Buy Now" Button
This lets users click directly to payment without going through cart/checkout. Add these snippets to functions.php:
For Shop/Category Pages
add_filter('woocommerce_loop_add_to_cart_link', 'direct_buy_button_archive', 10, 2); function direct_buy_button_archive($link, $product) { $target_product_id = 123; if ($product->get_id() === $target_product_id) { $link = '<a href="' . esc_url(add_query_arg('product_id', $product->get_id(), wc_get_endpoint_url('order-pay', '', wc_get_checkout_url()))) . '" class="button alt">' . __('Buy Now', 'woocommerce') . '</a>'; } return $link; }
For Single Product Page
// Remove default Add to Cart button remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30); // Add custom Buy Now button add_action('woocommerce_single_product_summary', 'direct_buy_button_single', 30); function direct_buy_button_single() { global $product; $target_product_id = 123; if ($product->get_id() === $target_product_id) { echo '<a href="' . esc_url(add_query_arg('product_id', $product->get_id(), wc_get_endpoint_url('order-pay', '', wc_get_checkout_url()))) . '" class="single_add_to_cart_button button alt">' . __('Buy Now', 'woocommerce') . '</a>'; } else { // Show default button for other products woocommerce_template_single_add_to_cart(); } }
Final Step: Auto-Add Product to Order on Payment Page
Add this to make sure the product is added to the order when the user lands on the payment page:
add_action('woocommerce_before_order_pay', 'add_product_to_direct_order'); function add_product_to_direct_order($order_id) { $order = wc_get_order($order_id); // Only run if order is empty and product ID is in URL if ($order->get_total() == 0 && isset($_GET['product_id'])) { $product_id = intval($_GET['product_id']); $order->add_product(wc_get_product($product_id), 1); $order->calculate_totals(); $order->save(); } }
内容的提问来源于stack exchange,提问作者Sandeep

