• Resolved IT Hertz

    (@it-hertz)


    I need to generate a new order using selections from a Contact Form 7 dropdown. I’m experimenting with Product Dropdown Field For Contact Form 7 plugin, but in this use case, a stock CF7 dropdown could maybe work.
    The user may then go directly to checkout when they login, after being manually approved at some future time (I’m using Ultimate Member for account handling).

    I made a custom shortcode that provides a button for the user to click when they login, which takes them directly to checkout. The subadmin must manually create the order on the back end – this needs to be automated for the front end CF7 form.

    I’m using Database for Contact Form 7 plugin, so I could do this either way – direct from the CF7 form to WC or use the database as middleman (pull data from user registration and send that to WC). I think it might be simpler to just take dropdown values and plug them into WC order hook(s).

    I am not using a shop nor cart, as there are only 4 virtual “products”, and to prevent user error resulting in incorrect orders.

    I browsed the WC hooks, and there’s a ton of them, but I didn’t see anything that seemed like it would build the order from scratch as if the subadmin had done it on the back end. Maybe I overlooked it/them?

    I am aware of premium addons for WC-CF7 integration, but my client is a poor dance school and they aren’t going to pay for this – I am their pro bono webmaster, so everything has to be done for free.
    The “products” are dance classes, and, since there can be up to 5 dancers per family on a given form, I will need to potentially combine dropdown selections together for the grand total of the order.

    Help?

Viewing 6 replies - 1 through 6 (of 6 total)
  • con

    (@conschneider)

    Engineer

    Hi there,

    I did some research for you. Here are some links:

    https://stackoverflow.com/questions/40610928/contact-form-7-woocommerce-save-form-data-in-orders

    The first one is a similar approach.
    The second one looked like it might be just what you need.

    Kind regards,

    Thread Starter IT Hertz

    (@it-hertz)

    Apologies for not having elaborated on critical requirements. Maybe the following will help.

    I had already experimented with the 2nd method, but it won’t work because my client needs to prevent checkout until the user’s registration has been approved. Approval is done manually by a subadmin, and could take days. The URL method as-is takes the user directly to checkout upon submit.

    I wonder whether I could save that URL to a temporary post/page and assign that link to my “Proceed to Checkout” button for when the user logs in after being approved. That may be easier than saving the product selections to db then retrieving and compiling an order that way. I could probably do it via cookies, but I have to consider the possibility that the user is in the habit of clearing cookies.

    But, I need this part of the CF7 form to be saved as an order, just as if a subadmin had created the order themselves on the back end, so that the subadmin can have full control over it (view all details, edit, delete) prior to checkout.

    The subadmin may need to edit the order prior to checkout – e.g., user selects incorrect class for their child’s age group. In that event, since editing and deletion is unavailable, the user would have to contact the subadmin and request revision or cancellation (unless the problem is obvious and the admin can edit w/o user input).

    I realize that orders can be edited by admin after checkout, and that works fine as long as the user hasn’t paid yet, so that a revised invoice can be emailed. What if the user goes ahead and pays and then discovers they need to change something? The option then would be refund, but my client wishes to prevent all refund scenarios.

    I guess it’s nigh on impossible to prevent all human error scenarios, but I’m trying to anyway. 🙂

    The first method you linked looked promising, but I’m getting the same result as the last commenter: the form hangs on submit and no order is created.

    Thread Starter IT Hertz

    (@it-hertz)

    I thought of a different way to possibly pull this off.

    I have my CF7 form automagically register new users with the role “Pending” assigned to them on submit.

    Perhaps I can use CF7’s wpcf7_before_send_mail hook to capture dropdown data and save the selections (product IDs) to the update_user_meta array, and simply get_user_meta to build the URL string when the user logs in and goes to the checkout page.

    This would keep it entirely as a PHP function, avoiding any JS, which would require passing variables from JS to PHP (e.g., via cookie).

    As I have restricted the checkout page to approved users, this would take care of the checkout only after approval requirement.

    Of course, even if I get that to work, it does nothing to resolve the issue of admins not being able to modify the order prior to checkout.

    Hi @it-hertz

    Of course, even if I get that to work, it does nothing to resolve the issue of admins not being able to modify the order prior to checkout.

    I understand that the suggested solution above still has some improvements to be done in order to meet your needs.

    I do not have an exact example of how this can be achieved.

    I’ll keep this thread open for a little longer to see if anyone else can chime in to share any other hints.

    We have our developer resources portal that can help you get going, so I would recommend you to check it further from here: https://developer.woocommerce.com/

    You can also visit the WooCommerce Community Forum, the WooCommerce FB group, or the #developers channel of our Community Slack. We’re lucky to have a great community of open-source developers for WooCommerce, and many of our developers hang out there, too.

    Another option is to check our customizations page to hire an expert that can create a custom solution for you: https://woocommerce.com/experts/

    Thanks!

    Thread Starter IT Hertz

    (@it-hertz)

    I coded this for a CF7 combination dance school class enrollment & website account registration form. This snippet obviously goes inside a larger function.

    Doing it this way avoids using global variables, and besides, I couldn’t get $id = $product->get_id(); to work anyway (nor did wc_get_product_id_by_sku, nor any of the MANY variations and schemes I tried. The ONLY thing that works in my case is to associate known product IDs with CF7 dropdown options. I presume it’s due to this being in a function (CF7 wpcf7_before_send_mail) that doesn’t hook into WC. <shrugh>
    Thus, this snippet doesn’t get product IDs. But, for those who know the product IDs (anyone with WC backend capabilities), it works just fine.

    Minor loop nesting is involved. I had considered looping the $_POST values, but it would require about the same number of lines. If you have a lot of dropdowns, looping may be preferable.

    This does not take multi-select into account, since this school only allows the student to enroll in a single class per season.

    // Create WC order from CF7 dropdowns
    
    $class_pick = array( // 5 student enrollment slots available per form
       $_POST['Dancer_1_Class'], // use $_POST instead of $posted_data to get raw dropdown data
       $_POST['Dancer_2_Class'],
       $_POST['Dancer_3_Class'],
       $_POST['Dancer_4_Class'],
       $_POST['Dancer_5_Class']
    );
    $classes = array( // 4 classes available to each dancer, 1 choice per dancer
       'Class 1: $100' => 1001, // associate product id (value) with dropdown option (key)
       'Class 2: $200' => 1002,
       'Class 3: $300' => 1003,
       'Class 4: $400' => 1004
    );
    $order = wc_create_order();
    foreach ( $class_pick as $selection ) {  // match class with dropdown selection
       foreach ( $classes as $class => $id ) { // get product id from $classes array
          if ( $selection == $class ) {
             $order->add_product( wc_get_product( $id ), 1 );
          }
       }
    }
    $order->set_address( $address, 'billing' ); // insert billing array data which also dumps into customer account meta (not shown)
    $order->calculate_totals();
    $order->update_status("Completed", 'New User Created', true);

    Some readers may be wondering why I didn’t nest a third loop to account for repeats (more than 1 student enrolling in the same class). Not doing so will make it easier for my subadmins to look at the order and know which line belongs with which dancer – e.g., if dancer 2 and dancer 4 are both enrolling in class 3, the order would show x2 for product 1003, but would not specify which of the 5 dancers that product belongs to, only that it wasn’t dancer 1. The subadmins will have these specifics via CF7 email and separate database to look at, but I may as well make it less confusing for them while they’re in the WC orders.

    Plugin Support Kaushik S. a11n

    (@kaushiksomaiya)

    Hi there @it-hertz

    That’s a good way too.

    If the flow is “Users adding products to cart” -> “Users going to CF7 form”, you can also try the following approach:

    1. Create an ajax endpoint in WordPress: https://codex.wordpress.org/AJAX_in_Plugins
    2. Use DOM Events in CF7 and pass data via Ajax call: https://contactform7.com/dom-events/
    3. Pull the WC Cart object in the Ajax PHP handler part and get line items: https://www.businessbloomer.com/woocommerce-get-cart-info-total-items-etc-from-cart-object/

    I hope that helps!

Viewing 6 replies - 1 through 6 (of 6 total)

The topic ‘Create order from Contact Form 7 dropdowns?’ is closed to new replies.