7

I currently have a one-page checkout that works great for anonymous users. After payment is complete, an account is created with the 'Create a new account for an anonymous order' checkout rule.

Now I need to add a subscription product to the site, and plan to use Commerce License and Commerce License Billing to sell a role. To handle recurring payments, I plan to use Commerce Card on File.

This introduces a problem because Card on File requires an authenticated user in order to save cards. See https://www.drupal.org/node/1553468

How can I create a user account before checkout finishes so that Card on File can properly save cards?

Ideally, there would be a custom checkout page that forces account registration as a first step in checkout, but only for users purchasing subscription products.

I don't allow visitors to register on the site at the moment (except via Commerce Checkout), and I'd rather not change that.

1

I suggest the following steps :

  • create a custom checkout pane (see checkout_pane_example.module ) and embed the user register form in that pane:

    /**
     * Implements hook_commerce_checkout_pane_info().
     */
    function vts_register_commerce_checkout_pane_info() {
      $panes['register'] = array(
        'title' => t('Create an account'),
        'base' => 'vts_register_pane',
        'name' => t('NAME'),
        'page' => 'checkout',
        'weight' => -5,
      );
      return $panes;
    }
    /*
     * Add user_register_form to register pane
     */
    function vts_register_pane_checkout_form($form, &$form_state, $checkout_pane, $order) { 
      $pane_form = drupal_get_form('user_register_form');
      return $pane_form;
    }
    /*
     * Alter checkout form register pane
     */
    function vts_register_form_commerce_checkout_form_checkout_alter(&$form, &$form_state, $form_id) {
      unset($form['register']['actions']); 
    }
    /**
     * checkout form submission callback.
     */
    function vts_register_pane_checkout_form_submit($form, &$form_state, $checkout_pane, $order) {
      $new_user = array(
        //dsm to find the correct $form_state['input'] for username here, because I have an altered user register form...
        'name' => $form_state['input']['field_name_first']['und'][0]['value'].'_'.$form_state['input']['field_name_last']['und'][0]['value'],
        'pass' => user_password(),
        'mail' => $form_state['input']['mail'],
        'init' => $form_state['values']['mail'],
        'status' => 1,
        'roles' => array(DRUPAL_AUTHENTICATED_RID => TRUE),
      );
      if($GLOBALS['user']->uid == '0') {
        $user = user_save('', $new_user);
        //ASSIGN the current order to created user
        $order->uid = $user->uid;
        commerce_order_save($order);
        $GLOBALS['user'] = $user;
      }
      //check that you got a new user and the order was assigned to him
      dsm($user, 'user');
      dsm($order, 'order');
    }
    /**
     * Validation callback.
     */
    function vts_register_pane_checkout_form_validate($form, &$form_state, $checkout_pane, $order) {
      //validation stuff
      return TRUE;
    }
    /**
     * Ouputs Review checkout pane.
     */
    function vts_register_pane_review($form, $form_state, $checkout_pane, $order) {
      // add some info to review pane
      return;
    }
    
  • Go to admin/commerce/config/checkout and set it as disabled

  • Install Commerce Rules Extra, it adds the features you need :

Rules conditions : Total product of type quantity comparison

Rules actions : Change pane properties : Change visibility, page, weight of a pane

  • Create a rule :
    • Event: Process checkout pane.
    • Conditions : user is anonymous ; subscription product quantity > 0.
    • Action : Change pane properties : enabled: true; move to checkout.
  • Great, I will try this. Do you have any suggestions for how to auto-approve the new account and log the user in before going to the next step? – Dave Bruns Sep 21 '14 at 17:32
  • @DaveBruns I edited the answer, this was a bit more tricky – Kojo Sep 22 '14 at 18:37
  • thanks I appreciate you looking into this and providing more detail. Will this code redirect back to checkout after account creation? I also found something similar in drupal.org/project/commerce_extra, (see Commerce Extra Login Page sub-module) but the redirect is not working for me. – Dave Bruns Sep 22 '14 at 18:47
  • The idea is Not to leave the checkout process. Register and log in immediately when going to review pane.Tested a couple of times only the above code. You may have to tune it a little bit, but this fully answers your question I believe. Let me know – Kojo Sep 22 '14 at 18:48
  • Yes, of course. A little too much module testing, sorry. I've got your code in a module, but the submit function fails because $form_state is empty for some reason. – Dave Bruns Sep 22 '14 at 21:46
0

In addition to Kojo’s excellent solution, I might add that I believe the correct username input field for normal Drupal install is located in:

'name' => $form_state['input']['name']

The module still redirects to the new user profile page, but I will be investigating the cause further today.

0

There's a setting also a setting in drupalcommerce for drupal 8.

/admin/commerce/config/checkout-flows/manage/default

Now there you will see

Login or continue as guest

Click on gear icon, click and then uncheck Allow guest checkout.

That's all you need to do.

  • This answers the title of the question, but not the question itself. – joshmiller Jul 6 '17 at 19:18
0

here is how i achieve to create the user_register_form commerce checkout pane :

/**
 * Implements hook_commerce_checkout_pane_info().
 */
function edw_commerce_dc_commerce_checkout_pane_info() {
  $panes['register'] = [
    'title' => t('Create an account'),
    'base' => 'edw_commerce_dc_register_pane',
    'name' => t('Authentication'),
    'file' => 'edw_commerce_dc.pane.inc',
    'page' => 'checkout',
    'weight' => -5,
  ];
  return $panes;
}

/*
 * Alter checkout form register pane
 */
function edw_commerce_dc_form_commerce_checkout_form_checkout_alter(&$form, &$form_state, $form_id) {
  unset($form['register']['actions']);
  if(isset($form['register'])){
    $form_id = 'user_register_form';
    $hooks = array('form');
    $hooks[] = 'form_' . $form_id;
    drupal_alter($hooks, $form['register'], $form_state, $form_id);
  }
}

    /*
 * Add user_register_form to register pane
 */
function edw_commerce_dc_register_pane_checkout_form($form, &$form_state, $checkout_pane, $order) {
  if (user_is_anonymous()) {
    $pane_form = drupal_retrieve_form('user_register_form', $form_state);
    $pane_form['#tree'] = FALSE;
    return $pane_form;
  }
}

/**
 * checkout form submission callback.
 */
function edw_commerce_dc_register_pane_checkout_form_submit($form, &$form_state, $checkout_pane, $order) {
  if (isset($form['register'])) {
    foreach ($form["register"]["#submit"] as $callback) {
      $callback($form['register'], $form_state);
    }
  }
}

/**
 * checkout form submission callback.
 */
function edw_commerce_dc_register_pane_checkout_form_validate($form, &$form_state, $checkout_pane, $order) {
  if (isset($form['register'])) {
    foreach ($form["register"]["#validate"] as $callback) {
      $callback($form['register'], $form_state);
    }
    if (!form_get_errors()) {
      return TRUE;
    }
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.