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.

4 Answers 4

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.
12
  • 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, 2014 at 17:32
  • @DaveBruns I edited the answer, this was a bit more tricky
    – Kojo
    Sep 22, 2014 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, 2014 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, 2014 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, 2014 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.

1
  • This answers the title of the question, but not the question itself.
    – joshmiller
    Jul 6, 2017 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 and acknowledge that you have read and understand our privacy policy and code of conduct.

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