This is the documentation for LemonStand V1, which has been discontinued. You can learn more and upgrade your store here.

LemonStand Version 1 Has Been Discontinued

This documentation is for LemonStand Version 1. LemonStand is now offered as a cloud-based eCommerce platform.
You can try the new LemonStand and learn about upgrading here.

How to Simplify the Checkout Process

The approach described below allows to remove the Payment Method step from the checkout sequence and combine the Pay and Order Review pages, so the payment method selector and payment form are displayed right on the Order Review page. The described approach is compatible with the AJAX-driven single-page checkout implementation.

In this article we suppose that you used the demo store template, which is included to the LemonStand installer. If you built your store from scratch, partial and page names may not match names we refer below.

Step 1. Removing unnecessary steps from the checkout sequence

To remove the Payment Method and Pay steps from the checkout progress indicator, find the shop:checkout_progress partial and comment out the Payment Method and Pay lines in the $steps array. Also you can change the Order Review step name to Review and Pay:

$steps = array(
  'billing_info' => 'Billing Information',
  'shipping_info' => 'Shipping Information',
  'shipping_method' => 'Shipping Method',
//'payment_method' => 'Payment Method',
  'review' => 'Review and Pay',
//'pay' => 'Pay',
);

Step 2. Creating a default payment method

LemonStand requires a payment method to be assigned to an order before it can be saved to the database. In this step we will create a default payment method which we will be assigning to all new orders. Customers will be able to choose another payment method on the Review and Pay page.

Go to the Shop/Payment Methods page and click a payment method you would like to make default. Enter the default word to the LemonStand API Code field and save the payment method.

Step 3. Forcing LemonStand to create an order after the Shipping Method step

LemonStand requires an order to be saved to the database before the visitor can pay it. This means that we need LemonStand to create the order after the Shipping Method step and before redirecting to the Review and Pay page. We can achieve it with a custom AJAX handler. Find the Checkout page in the page list (a page which uses the shop:checkout action). Go to AJAX page and paste the following code to the text field:

function place_order_and_pay($controller, $page, $params)
{
  Shop_CheckoutData::set_payment_method(Shop_PaymentMethod::find_by_api_code('default')->id);
 
  // Call the default action handler
  $controller->action();

  // Pretend that we are on the Review checkout step
  // to force LemonStand to place the order
  $_POST['checkout_step'] = 'review';
  $controller->action();
}

Save the page and go to the partials list (CMS/Partials). Find the shop:checkout_shipping_method partial and click it. Inside the partial code, find the Next button declaration. The default onclick event handler on this button triggers the on_action server handler. Replace the on_action handler name with the place_order_and_pay (this is a name of the AJAX handler we just created on the Checkout page):

<input 
  type="button" 
  onclick="return $(this).getForm().sendRequest('place_order_and_pay', 
    {update:{'checkout_page': 'checkout_partial'}})" 
  value="Place order and pay"/>

Step 4. Updating the Pay page

The secret of this approach is making the Pay page looking like the Order Review page. To achieve it, you need to display all order details which you usually display on the Order Review page. On the Pay page you have access to the Shop_Order object (the $order variable). You can use it for loading and displaying the order items, order totals, tax information, etc. You can learn details on these pages: Creating the Order Details page and Shop_Order class.

On the CMS/Pages page find the Pay page. The default Pay page implementation contains some order details information, and the payment form. We are going to leave the order details information (you can extend it), make the payment form updatable and add a payment method selector.

Making the payment form updatable

We want the payment form to refresh each time when a customer selects a payment method in the list. To do that, we need to move the payment form code to a partial. Find the following code on the Pay page:

<? if ($order->payment_method->has_payment_form()): ?>
  <div class="payment_form">
    <? $payment_method->render_payment_form($this) ?>
  </div>
<? else: ?>
  <? if ($message = $payment_method->pay_offline_message()): ?>
    <p><?= h($message) ?></p>    
  <? else: ?>
    <p>Payment method "<?= h($payment_method->name) ?>" has no payment form. Please pay and notify us.</p>    
  <? endif ?>
  <p class="no_print"><a href="/"><img src="<?= root_url('/resources/images/btn_continue_shopping.gif') ?>" alt="Continue shopping"/></a></p>
<? endif ?>

Cut it to the clipboard (remove from the Pay page). Go to the CMS/Partials page and create a new partial. Name it payment_form. Paste the code from the clipboard and save the partial.

Return to the Pay page. In the place where was the payment form, render the payment form partial with the following code:

<div id="payment_form">
  <? $this->render_partial('payment_form') ?>
</div>

Adding the payment method selector

The last step is adding the payment method selector. The selector will contain a list of applicable payment methods as radio buttons. You can use the following code for creating the list:

<?= open_form() ?>
  <? $payment_methods = Shop_PaymentMethod::list_applicable(
     $order->billing_country_id,
     $order->total) ?>

  <? foreach ($payment_methods as $payment_method): ?>
    <input 
      <?= radio_state($payment_method->id == $order->payment_method_id) ?> 
      type="radio" 
      value="<?= $payment_method->id ?>" 
      name="payment_method" 
      id="<?= 'payment_method'.$payment_method->id ?>"
      onclick="$(this).getForm().sendRequest('shop:on_updatePaymentMethod', {
         update: {'payment_form': 'payment_form'}})"/>

    <label for="<?= 'payment_method'.$payment_method->id ?>"><?= h($payment_method->name) ?></label><br/>
  <? endforeach ?>
</form>

Please note that the onclick handler of the radio buttons triggers the shop:on_updatePaymentMethod AJAX server handler. This handler is defined in the Shop module. It assigns a new payment method to the order.

After modifying the Pay page you can style it to match other checkout steps.

Next: Displaying a List of Active Product Catalog Price Rules
Previous: Implementing a Ship to Same Billing Address Feature
Return to Tips and Tricks