function firstStep()
{
    validateParameters($_POST);
    $planId = "basic";
    $passThrough = array("address" => $_POST['addr'], "extended_addr" => $_POST['extended_addr'], "city" => $_POST['city'], "state" => $_POST['state'], "zip_code" => $_POST['zip_code']);
    try {
        /*
         * Calling ChargeBee Checkout new Hosted Page API to checkout a new subscription
         * by passing plan id the customer would like to subscribe and also passing customer 
         * first name, last name, email and phone details. The resposne returned by ChargeBee
         * has hosted page url and the customer will be redirected to that url.
         * 
         * Note: Parameter embed(Boolean.TRUE) can be shown in iframe
         *       whereas parameter embed(Boolean.FALSE) can be shown as seperate page.
         * Note : Here customer object received from client side is sent directly 
         *        to ChargeBee.It is possible as the html form's input names are 
         *        in the format customer[<attribute name>] eg: customer[first_name] 
         *        and hence the $_POST["customer"] returns an associative array of the attributes.              
         */
        $hostUrl = getHostUrl();
        $result = Chargebee_HostedPage::CheckoutNew(array("subscription" => array("planId" => $planId), "customer" => $_POST['customer'], "embed" => "false", "passThruContent" => json_encode($passThrough), "redirectUrl" => $hostUrl . "/checkout_two_step/redirect_handler", "cancelUrl" => $hostUrl . "/checkout_two_step/signup.html"));
        $redirectUrl = $result->hostedPage()->url;
        $jsonResponse = array("forward" => $redirectUrl);
        print json_encode($jsonResponse, true);
    } catch (ChargeBee_InvalidRequestException $e) {
        handleInvalidRequestErrors($e, "subscription[plan_id]");
    } catch (Exception $e) {
        handleGeneralErrors($e);
    }
}
function callingIframeCheckoutPage()
{
    header('Content-Type: application/json');
    validateParameters($_POST);
    $planId = "basic";
    try {
        $result = ChargeBee_HostedPage::CheckoutNew(array("subscription" => array("planId" => $planId), "customer" => $_POST['customer'], "embed" => "true", "iframeMessaging" => "true"));
        /*
         * Sending hosted page url and hosted page id as response.
         */
        $response = array("url" => $result->hostedPage()->url, "hosted_page_id" => $result->hostedPage()->id, "site_name" => ChargeBee_Environment::defaultEnv()->getSite());
        print json_encode($response);
    } catch (ChargeBee_InvalidRequestException $e) {
        handleInvalidRequestErrors($e, "subscription[plan_id]");
    } catch (Exception $e) {
        handleGeneralErrors($e);
    }
}
if ($_POST) {
    validateParameters($_POST);
    try {
        $result = createSubscription();
        addShippingAddress($result->subscription(), $result->customer());
        $jsonResp = array();
        /*
         * Forwarding to success page after successful create subscription in ChargeBee.
         */
        $queryParameters = "name=" . urlencode($result->customer()->firstName) . "&planId=" . urlencode($result->subscription()->planId);
        $jsonResp["forward"] = "thankyou.html";
        echo json_encode($jsonResp, true);
    } catch (ChargeBee_PaymentException $e) {
        handleTempTokenErrors($e);
    } catch (ChargeBee_InvalidRequestException $e) {
        handleInvalidRequestErrors($e, "plan_id");
    } catch (Exception $e) {
        handleGeneralErrors($e);
    }
}
/* Creates the subscription in ChargeBee using the checkout details and 
 * stripe temporary token provided by stripe.
 */
function createSubscription()
{
    /*
     * Constructing a parameter array for create subscription api. 
     * It will have account information, the temporary token got from Stripe and
     * plan details.
     * For demo purpose a plan with id 'annual' is hard coded.
     * Other params are obtained from request object.
     */
    $result = ChargeBee_Subscription::create($createSubscriptionParam);
    /*
     * Adds shipping address to the subscription using the subscription Id 
     * returned during create subscription response.
     */
    addShippingAddress($result->subscription()->id, $result->customer());
    /*
     * Forwarding to thank you page.
     */
    $jsonResp = array("forward" => "thankyou.html");
    print json_encode($jsonResp, true);
} catch (ChargeBee_PaymentException $e) {
    handlePaymentException($e);
} catch (ChargeBee_InvalidRequestException $e) {
    if ($e->getParam() == "coupon") {
        handleCouponErrors($e);
    } else {
        handleInvalidRequestErrors($e, array("plan_id", "addons[id][0]", "addons[id][1]"));
    }
} catch (Exception $e) {
    handleGeneralErrors($e);
}
/*
 * Add Shipping address using the subscription id returned from 
 * create subscription response.
 */
function addShippingAddress($subscriptionId, $customer)
{
    ChargeBee_Address::update(array("label" => "shipping_address", "subscriptionId" => $subscriptionId, "firstName" => $customer->firstName, "lastName" => $customer->lastName, "addr" => $_POST['addr'], "extended_addr" => $_POST['extended_addr'], "city" => $_POST['city'], "state" => $_POST['state'], "zip" => $_POST['zip_code']));
}
    /*
     * Adding subscription and addons params to the create subscription estimate request
     */
    $params = array("subscription" => $subParams);
    $params["addons"] = $addons;
    $result = ChargeBee_Estimate::createSubscription($params);
    $estimate = $result->estimate();
} catch (ChargeBee_InvalidRequestException $e) {
    /*
     * Checking whether the error is due to coupon param. If the error is due to
     * coupon param then reason for error can be identified through "api_error_code" attribute.
     */
    if ($e->getParam() == "subscription[coupon]") {
        handleCouponErrors($e);
    } else {
        handleInvalidRequestErrors($e, array("subscription[plan_id]", "addons[id][0]", "addons[id][1]"));
    }
    return;
} catch (Exception $e) {
    handleGeneralErrors($e);
    return;
}
?>
<div class="row">
    <div class="col-xs-12">        
        <div class="page-header"><h3>Your Order Summary</h3></div>
        <ul class="text-right list-unstyled">
            
            <?php 
foreach ($estimate->lineItems as $li) {
    ?>
function updateShippingAddress()
{
    header('Content-Type: application/json');
    validateParameters($_POST);
    try {
        $result = ChargeBee_Subscription::update(getSubscriptionId(), array("shipping_address" => $_POST['shipping_address']));
        $jsonResponse = array("forward" => "/ssp-php/subscription");
        print json_encode($jsonResponse, true);
    } catch (ChargeBee_InvalidRequestException $e) {
        handleInvalidRequestErrors($e);
    } catch (Exception $e) {
        handleGeneralErrors($e);
    }
}