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.

Implementing a One-Step Checkout

Let's imagine that we are building an online store for a local shop based in California, USA. They want to sell goods only to local customers, so there is no need to force customers to select the country and state during the checkout. Also, the shop accepts only one payment method - credit cards, and always shipping is always free. It is possible to build the checkout implementation which will involve only one, for entering the customer billing name and address. The whole checkout process will contain only two steps:

  1. Billing information page. On this page customers will enter the billing name and address.
  2. Order review page. On this page customers will check the order content and click the Place Order and Pay button.

We require that the credit card payment method already exists and has the credit_card LemonStand API Code. Also, we suppose that the free shipping option exists and has the free_shipping LemonStand API Code. You can create a free shipping option basing on the Table Rate shipping method by specifying the * character in the country and state columns and 0 on the Price column.

For better understanding of the one-click checkout implementation we recommend you to check how the Checkout page is organized in LemonStand Demo store.

Billing Information Page

The billing information page for this scenario does not contain the country and state menus, because the country and state are already known. Instead of the drop-down menus, we can use the hidden form elements with values loaded from the database. Below is the example code of the billing information page. The page should be based on the shop:checkout_billing_info action.

<h3>One-step checkout</h3>

<?= open_form() ?>
<?= flash_message() ?>

  <label for="first_name">First Name</label>
  <input name="first_name" value="<?= h($billing_info->first_name) ?>" id="first_name" type="text"/><br/>
  
  <label for="last_name">Last Name</label>
  <input name="last_name" value="<?= h($billing_info->last_name) ?>" id="last_name" type="text"/><br/>
  
  <label for="email">Email</label>
  <input id="email" name="email" value="<?= h($billing_info->email) ?>" type="text"/><br/>
  
  <label for="street_address">Street Address</label>
  <input id="street_address" name="street_address" type="text" value="<?= h($billing_info->street_address) ?>"/><br/>

  <label for="city">City</label>
  <input id="city" type="text" name="city" value="<?= h($billing_info->city) ?>"/><br/>

  <label for="zip">Zip/Postal Code</label>
  <input id="zip" type="text" name="zip" value="<?= h($billing_info->zip) ?>"/><br/>
  
  <input type="hidden" name="country" value="<?= Shop_Country::create()->find_by_code('US')->id ?>"/>
  <input type="hidden" name="state" value="<?= Shop_CountryState::create()->find_by_code('CA')->id ?>"/>
  
  <input
    type="image"
    src="/resources/images/btn_next.gif"
    alt="Next"
    onclick="return $(this).getForm().sendRequest('create_local_order')"/>
</form>

In the bottom of the page is the image link which sends the AJAX request to the server, asking to execute the create_local_order AJAX handler. We need to create this handler manually. This method will perform the following steps:

  1. Assign the billing information data to, specified by the customer in the form.
  2. Copy the billing information into the shipping information, inside the server checkout data storage (the Shop_CheckoutData class).
  3. Assign the credit_card payment method to the checkout data storage
  4. Assign the free_shipping shipping option to the checkout data storage
  5. Redirect the browser to the order preview page. We suppose that the order preview page has the /checkout_order_preview URL.

Below is a code of the create_local_order handler. This code should be pasted into the AJAX Handlers field of the AJAX tab of the Edit Page form.

function create_local_order($controller, $page, $params)
{
  if (!Shop_Cart::list_active_items())
    throw new Exception('Your cart is empty!');

  $controller->exec_action_handler('shop:on_checkoutSetBillingInfo');
  Shop_CheckoutData::copy_billing_to_shipping();
  Shop_CheckoutData::set_payment_method(Shop_PaymentMethod::find_by_api_code('credit_card')->id);
  Shop_CheckoutData::set_shipping_method(Shop_ShippingOption::find_by_api_code('free_shipping')->id);
  
  Phpr::$response->redirect('/checkout_order_preview');
}

Order Review page

The order review page displays the information gathered during the checkout process along with complete order information. Also this page contains the Place Order button. This page should be based on the shop:checkout_order_review action. Example of the order review page code:

<h3>Order Review</h3>

<?= open_form() ?>
  <?
    $bill_to_str = $billing_info->as_string();
    $ship_to_str = $shipping_info->as_string();
    $items = Shop_Cart::list_active_items();
  ?>
  
  <table>
    <thead>
      <tr>
        <th>Cart Items</th>
        <th>Quantity</th>
        <th>Price</th>
        <th>Discount</th>
        <th>Total</th>
      </tr>
    </thead>
    <tbody>
      <? 
        foreach ($items as $item): 
        $options_str = $item->options_str();
      ?>
      <tr>
        <td>
          <strong><?= h($item->product->name) ?></strong>
          <? if (strlen($options_str)): ?>
            <br/><?= h($options_str) ?>.
          <? endif ?>
          <? if ($item->extra_options): ?>
            <? foreach ($item->extra_options as $option): ?>
              <br/>
              + <?= h($option->description) ?>:
              <?= format_currency($option->price) ?>
            <? endforeach ?>
          <? endif ?>
        </td>
        <td><?= $item->quantity ?></td>
        <td><?= format_currency($item->single_price()) ?></td>
        <td><?= format_currency($item->discount()) ?></td>
        <th><?= format_currency($item->total_price()) ?></th>
      </tr>
      <? endforeach ?>
    </tbody>
  </table>
  
  <table>
    <tr>
      <td>Subtotal: </td>
      <th><?= format_currency($subtotal) ?></th>
    </tr>
    <tr>
      <td>Discount: </td>
      <th><?= format_currency($discount) ?></th>
    </tr>
    <? foreach ($product_taxes as $tax): ?>
      <tr>
        <td><?= ($tax->name) ?>: </td>
        <th><?= format_currency($tax->total) ?></th>
      </tr>
    <? endforeach ?>
    <tr>
      <td>Shipping: </td>
      <th><?= format_currency($shipping_quote) ?></th>
    </tr>
    <? foreach ($shipping_taxes as $tax): ?>
      <tr>
        <td>Shipping tax (<?= ($tax->name) ?>): </td>
        <th><?= format_currency($tax->rate) ?></th>
      </tr>
    <? endforeach ?>
  </table>
  
  <h3>Total</h3>
  <p><?= format_currency($total) ?></p>
  
  <input
    type="image"
    src="/resources/images/btn_place_order.gif"
    alt="Place Order and Pay"
    onclick="return $(this).getForm().sendRequest('shop:on_checkoutPlaceOrder')"/>
</form>

See also:


Previous: Implementing the Step-By-Step Checkout
Return to Checkout Process