Beispiel #1
0
 public function testCheckoutForm()
 {
     $order = ShoppingCart::curr();
     $config = new SinglePageCheckoutComponentConfig($order);
     $form = new CheckoutForm($this->checkoutcontroller, "OrderForm", $config);
     $data = array("CustomerDetailsCheckoutComponent_FirstName" => "Jane", "CustomerDetailsCheckoutComponent_Surname" => "Smith", "CustomerDetailsCheckoutComponent_Email" => "*****@*****.**", "ShippingAddressCheckoutComponent_Country" => "NZ", "ShippingAddressCheckoutComponent_Address" => "1234 Green Lane", "ShippingAddressCheckoutComponent_AddressLine2" => "Building 2", "ShippingAddressCheckoutComponent_City" => "Bleasdfweorville", "ShippingAddressCheckoutComponent_State" => "Trumpo", "ShippingAddressCheckoutComponent_PostalCode" => "4123", "ShippingAddressCheckoutComponent_Phone" => "032092277", "BillingAddressCheckoutComponent_Country" => "NZ", "BillingAddressCheckoutComponent_Address" => "1234 Green Lane", "BillingAddressCheckoutComponent_AddressLine2" => "Building 2", "BillingAddressCheckoutComponent_City" => "Bleasdfweorville", "BillingAddressCheckoutComponent_State" => "Trumpo", "BillingAddressCheckoutComponent_PostalCode" => "4123", "BillingAddressCheckoutComponent_Phone" => "032092277", "PaymentCheckoutComponent_PaymentMethod" => "Dummy", "NotesCheckoutComponent_Notes" => "Leave it around the back", "TermsCheckoutComponent_ReadTermsAndConditions" => "1");
     $form->loadDataFrom($data, true);
     $valid = $form->validate();
     $errors = $form->getValidator()->getErrors();
     $this->assertTrue($valid);
     $form->checkoutSubmit($data, $form);
     $this->assertEquals("Jane", $order->FirstName);
     $shipping = $order->ShippingAddress();
     $this->assertEquals("NZ", $shipping->Country);
     $this->assertEquals("Cart", $order->Status);
     $this->markTestIncomplete('test invalid data');
     $this->markTestIncomplete('test components individually');
 }
 public function testCheckoutFormForSingleCountrySiteWithReadonlyFieldsForCountry()
 {
     // Set as a single country site
     $this->loadFixture("shop/tests/fixtures/singlecountry.yml");
     $singlecountry = SiteConfig::current_site_config();
     $this->assertEquals("NZ", $singlecountry->getSingleCountry(), "Confirm that website is setup as a single country site");
     $order = ShoppingCart::curr();
     $config = new SinglePageCheckoutComponentConfig($order);
     $form = new CheckoutForm($this->checkoutcontroller, "OrderForm", $config);
     // no country fields due to readonly field
     $dataCountryAbsent = array("CustomerDetailsCheckoutComponent_FirstName" => "Jane", "CustomerDetailsCheckoutComponent_Surname" => "Smith", "CustomerDetailsCheckoutComponent_Email" => "*****@*****.**", "ShippingAddressCheckoutComponent_Address" => "1234 Green Lane", "ShippingAddressCheckoutComponent_AddressLine2" => "Building 2", "ShippingAddressCheckoutComponent_City" => "Bleasdfweorville", "ShippingAddressCheckoutComponent_State" => "Trumpo", "ShippingAddressCheckoutComponent_PostalCode" => "4123", "ShippingAddressCheckoutComponent_Phone" => "032092277", "BillingAddressCheckoutComponent_Address" => "1234 Green Lane", "BillingAddressCheckoutComponent_AddressLine2" => "Building 2", "BillingAddressCheckoutComponent_City" => "Bleasdfweorville", "BillingAddressCheckoutComponent_State" => "Trumpo", "BillingAddressCheckoutComponent_PostalCode" => "4123", "BillingAddressCheckoutComponent_Phone" => "032092277", "PaymentCheckoutComponent_PaymentMethod" => "Dummy", "NotesCheckoutComponent_Notes" => "Leave it around the back", "TermsCheckoutComponent_ReadTermsAndConditions" => "1");
     $form->loadDataFrom($dataCountryAbsent, true);
     $valid = $form->validate();
     $errors = $form->getValidator()->getErrors();
     $this->assertTrue($valid, print_r($errors, true));
     $this->assertTrue($form->Fields()->fieldByName("ShippingAddressCheckoutComponent_Country_readonly")->isReadonly(), "Shipping Address Country field is readonly");
     $this->assertTrue($form->Fields()->fieldByName("BillingAddressCheckoutComponent_Country_readonly")->isReadonly(), "Billing Address Country field is readonly");
     $form->checkoutSubmit($dataCountryAbsent, $form);
     $shipping = $order->ShippingAddress();
     $this->assertEquals("NZ", $shipping->Country);
     $billing = $order->BillingAddress();
     $this->assertEquals("NZ", $billing->Country);
 }
 /**
  * Update the order form cart, called via AJAX with current order form data.
  * Renders the cart and sends that back for displaying on the order form page.
  * 
  * @param SS_HTTPRequest $data Form data sent via AJAX POST.
  * @return String Rendered cart for the order form, template include 'CheckoutFormOrder'.
  */
 function updateOrderFormCart(SS_HTTPRequest $data)
 {
     if ($data->isPOST()) {
         $fields = array();
         $validator = new OrderFormValidator();
         $member = Customer::currentUser() ? Customer::currentUser() : singleton('Customer');
         $order = CartControllerExtension::get_current_order();
         //Update the Order
         $order->addAddressesAtCheckout($data->postVars());
         $order->addModifiersAtCheckout($data->postVars());
         //TODO update personal details, notes and payment type?
         //Create the part of the form that displays the Order
         $this->addItemFields($fields, $validator, $order);
         $this->addModifierFields($fields, $validator, $order);
         //This is going to go through and add modifiers based on current Form DATA
         //TODO This should be constructed for non-dropdown fields as well
         //Update modifier form fields so that the dropdown values are correct
         $newModifierData = array();
         $subTotalModifiers = isset($fields['SubTotalModifiers']) ? $fields['SubTotalModifiers'] : array();
         $totalModifiers = isset($fields['Modifiers']) ? $fields['Modifiers'] : array();
         $modifierFields = array_merge($subTotalModifiers, $totalModifiers);
         foreach ($modifierFields as $field) {
             if (method_exists($field, 'updateValue')) {
                 $field->updateValue($order);
             }
             $modifierClassName = get_class($field->getModifier());
             $newModifierData['Modifiers'][$modifierClassName] = $field->Value();
         }
         //Add modifiers to the order again so that the new values are used
         $order->addModifiersAtCheckout($newModifierData);
         $actions = new FieldSet(new FormAction('ProcessOrder', _t('CheckoutPage.PROCEED_TO_PAY', "Proceed to pay")));
         $form = new CheckoutForm($this, 'OrderForm', $fields, $actions, $validator, $order);
         $form->disableSecurityToken();
         $form->validate();
         return $form->renderWith('CheckoutFormOrder');
     }
 }
    /**
     * Displays and processes the checkout form. This is our big function which
     * validates everything and calls for order completion when done.
     * TODO: Would be better broken into small functions to aid unit testing.
     */
    public function actionCheckout()
    {
        // We shouldn't be in this controller if we don't have any products in
        // our cart.
        if (!Yii::app()->shoppingcart->itemCount) {
            Yii::log("Attempted to check out with no cart items", 'info', 'application.' . __CLASS__ . "." . __FUNCTION__);
            Yii::app()->user->setFlash('warning', Yii::t('cart', 'Oops, you cannot checkout. You have no items in your cart.'));
            if (!Yii::app()->user->isGuest && Yii::app()->user->fullname == "Guest") {
                // Probably here because of cancelling an AIM payment.
                Yii::log("Checkout as Guest .. logging out", 'info', 'application.' . __CLASS__ . "." . __FUNCTION__);
                Yii::app()->user->logout();
            }
            $this->redirect($this->createAbsoluteUrl("/cart", array(), 'http'));
        }
        $this->pageTitle = _xls_get_conf('STORE_NAME') . ' : Checkout';
        // Set breadcrumbs.
        $this->breadcrumbs = array(Yii::t('global', 'Edit Cart') => array('/cart'), Yii::t('global', 'Checkout') => array('cart/checkout'));
        $model = new CheckoutForm();
        $model->objAddresses = CustomerAddress::getActiveAddresses();
        // If this cart was built from another person's wish list.
        if (Yii::app()->shoppingcart->HasShippableGift) {
            $model->objAddresses = array_merge($model->objAddresses, Yii::app()->shoppingcart->GiftAddress);
        }
        if (isset($_POST['CheckoutForm'])) {
            $strLogLevel = Yii::app()->getComponent('log')->routes[0]->levels;
            if (stripos($strLogLevel, ",info")) {
                $arrSubmitted = $_POST['CheckoutForm'];
                // Redact sensitive information.
                if (isset($arrSubmitted['cardNumber'])) {
                    $arrSubmitted['cardNumber'] = "A " . strlen($arrSubmitted['cardNumber']) . " digit number here";
                }
                if (isset($arrSubmitted['cardCVV'])) {
                    $arrSubmitted['cardCVV'] = "A " . strlen($arrSubmitted['cardCVV']) . " digit number here";
                }
                Yii::log("*** CHECKOUT FORM *** Submission data: " . print_r($arrSubmitted, true), 'info', 'application.' . __CLASS__ . "." . __FUNCTION__);
            }
            $model->attributes = $_POST['CheckoutForm'];
            if (Yii::app()->params['SHIP_SAME_BILLSHIP']) {
                $model->billingSameAsShipping = 1;
            }
            // Force lower case on emails.
            $model->contactEmail = strtolower($model->contactEmail);
            $model->contactEmail_repeat = strtolower($model->contactEmail_repeat);
            $cacheModel = clone $model;
            unset($cacheModel->cardNumber);
            unset($cacheModel->cardCVV);
            unset($cacheModel->cardExpiryMonth);
            unset($cacheModel->cardExpiryYear);
            Yii::app()->session['checkout.cache'] = $cacheModel;
            if (!Yii::app()->user->IsGuest) {
                $model->setScenario('formSubmitExistingAccount');
            } elseif ($model->createPassword) {
                $model->setScenario('formSubmitCreatingAccount');
            } else {
                $model->setScenario('formSubmitGuest');
            }
            // Copy address book to field if necessary.
            $model->fillFieldsFromPreselect();
            // Validate our primary CheckoutForm model here.
            $valid = $model->validate();
            //For any payment processor with its own form -- not including CC -- validate here
            if ($model->paymentProvider) {
                $objPaymentModule = Modules::model()->findByPk($model->paymentProvider);
                $objComponent = Yii::app()->getComponent($objPaymentModule->module);
                if (isset($objComponent->subform)) {
                    Yii::log("Form validation for card provider  " . strip_tags($objComponent->name()), 'info', 'application.' . __CLASS__ . "." . __FUNCTION__);
                    $paymentSubform = $objComponent->subform;
                    $paymentSubformModel = new $paymentSubform();
                    $paymentSubformModel->attributes = isset($_POST[$paymentSubform]) ? $_POST[$paymentSubform] : array();
                    $subValidate = $paymentSubformModel->validate();
                    $valid = $subValidate && $valid;
                } else {
                    Yii::log("Payment module " . strip_tags($objComponent->name()), 'info', 'application.' . __CLASS__ . "." . __FUNCTION__);
                }
            }
            //If this came in as AJAX validation, return the results and exit
            if (Yii::app()->getRequest()->getIsAjaxRequest()) {
                echo $valid;
                Yii::app()->end();
            }
            //If all our validation passed, run our checkout procedure
            if ($valid) {
                Yii::log("All actionCheckout validation passed, attempting to complete checkout", 'info', 'application.' . __CLASS__ . "." . __FUNCTION__);
                $objCart = Yii::app()->shoppingcart;
                //Assign CartID if not currently assigned
                //If we have provided a password
                if ($model->createPassword) {
                    Yii::log("Password was part of CheckoutForm", 'info', 'application.' . __CLASS__ . "." . __FUNCTION__);
                    // Test to see if we can log in with the provided password.
                    $identity = new UserIdentity($model->contactEmail, $model->createPassword);
                    $identity->authenticate();
                    switch ($identity->errorCode) {
                        case UserIdentity::ERROR_PASSWORD_INVALID:
                            //Oops, email is already in system but not with that password
                            Yii::app()->user->setFlash('error', Yii::t('global', 'This email address already exists but that is not the correct password so we cannot log you in.'));
                            Yii::log($model->contactEmail . " login from checkout with invalid password", 'error', 'application.' . __CLASS__ . "." . __FUNCTION__);
                            $this->refresh();
                            return;
                        case UserIdentity::ERROR_USERNAME_INVALID:
                            $objCustomer = Customer::CreateFromCheckoutForm($model);
                            $identity = new UserIdentity($model->contactEmail, $model->createPassword);
                            $identity->authenticate();
                            if ($identity->errorCode !== UserIdentity::ERROR_NONE) {
                                Yii::log("Error logging in after creating account for " . $model->contactEmail . ". Error:" . $identity->errorCode . " Cannot continue", 'error', 'application.' . __CLASS__ . "." . __FUNCTION__);
                                Yii::app()->user->setFlash('error', Yii::t('global', 'Error logging in after creating account. Cannot continue.'));
                                $this->refresh();
                                return;
                            }
                            break;
                        case UserIdentity::ERROR_NONE:
                            break;
                        default:
                            Yii::log("Error: Unhandled errorCode " . $identity->errorCode, 'error', 'application.' . __CLASS__ . "." . __FUNCTION__);
                            break;
                    }
                    $intTaxCode = Yii::app()->shoppingcart->tax_code_id;
                    //Save tax code already chosen
                    Yii::app()->user->login($identity, 3600 * 24 * 30);
                    Yii::app()->user->setState('createdoncheckout', 1);
                    Yii::app()->shoppingcart->tax_code_id = $intTaxCode;
                }
                // If we're not logged in, create guest account, or get our logged in ID.
                if (Yii::app()->user->isGuest) {
                    Yii::log("Creating Guest account to complete checkout", 'info', 'application.' . __CLASS__ . "." . __FUNCTION__);
                    if (is_null($objCart->customer_id)) {
                        //create a new guest ID
                        $identity = new GuestIdentity();
                        Yii::app()->user->login($identity, 300);
                        $intCustomerId = $objCart->customer_id = $identity->getId();
                        $this->intGuestCheckout = 1;
                        $objCustomer = Customer::model()->findByPk($intCustomerId);
                        $objCustomer->first_name = $model->contactFirstName;
                        $objCustomer->last_name = $model->contactLastName;
                        $objCustomer->mainphone = $model->contactPhone;
                        $objCustomer->email = $model->contactEmail;
                        $objCustomer->save();
                    } else {
                        $intCustomerId = $objCart->customer_id;
                        $objCustomer = Customer::model()->findByPk($intCustomerId);
                    }
                } else {
                    $intCustomerId = Yii::app()->user->getId();
                    $objCustomer = Customer::model()->findByPk($intCustomerId);
                }
                $objCart->customer_id = $intCustomerId;
                if (trim($objCart->currency) == '') {
                    $objCart->currency = _xls_get_conf('CURRENCY_DEFAULT', 'USD');
                }
                $objCart->save();
                //If shipping address is value, then choose that
                //otherwise enter new shipping address
                //and assign value
                if ($model->intShippingAddress) {
                    $objCart->shipaddress_id = $model->intShippingAddress;
                } else {
                    Yii::log("Creating new shipping address", 'info', 'application.' . __CLASS__ . "." . __FUNCTION__);
                    if (empty($model->shippingLabel)) {
                        $model->shippingLabel = Yii::t('global', 'Unlabeled Address');
                    }
                    $objAddress = new CustomerAddress();
                    $objAddress->customer_id = $intCustomerId;
                    $objAddress->address_label = $model->shippingLabel;
                    $objAddress->first_name = $model->shippingFirstName;
                    $objAddress->last_name = $model->shippingLastName;
                    $objAddress->address1 = $model->shippingAddress1;
                    $objAddress->address2 = $model->shippingAddress2;
                    $objAddress->city = $model->shippingCity;
                    $objAddress->state_id = $model->shippingState;
                    $objAddress->postal = $model->shippingPostal;
                    $objAddress->country_id = $model->shippingCountry;
                    $objAddress->residential = $model->shippingResidential;
                    if (!$objAddress->save()) {
                        Yii::app()->user->setFlash('error', print_r($objAddress->getErrors(), true));
                        Yii::log("Error creating CustomerAddress Shipping " . print_r($objAddress->getErrors(), true), 'error', 'application.' . __CLASS__ . "." . __FUNCTION__);
                        $this->refresh();
                    }
                    $objCart->shipaddress_id = $model->intShippingAddress = $objAddress->id;
                    unset($objAddress);
                }
                if ($objCustomer instanceof Customer) {
                    if (is_null($objCustomer->default_shipping_id)) {
                        $objCustomer->default_shipping_id = $model->intShippingAddress;
                        $objCustomer->save();
                        try {
                            $objCart->setTaxCodeByDefaultShippingAddress();
                        } catch (Exception $e) {
                            Yii::log("Error updating customer cart " . $e->getMessage(), 'error', 'application.' . __CLASS__ . "." . __FUNCTION__);
                        }
                        $objCart->recalculateAndSave();
                    }
                }
                // If billing address is value, then choose that otherwise enter
                // new billing address and assign value.
                if ($model->intBillingAddress) {
                    $objCart->billaddress_id = $model->intBillingAddress;
                } elseif ($model->billingSameAsShipping) {
                    $objCart->billaddress_id = $model->intBillingAddress = $model->intShippingAddress;
                } else {
                    if (empty($model->billingLabel)) {
                        $model->billingLabel = Yii::t('checkout', 'Unlabeled address');
                    }
                    if (!Yii::app()->user->isGuest) {
                        $objCustomer = Customer::GetCurrent();
                        if ($objCustomer instanceof Customer) {
                            $model->contactFirstName = $objCustomer->first_name;
                            $model->contactLastName = $objCustomer->last_name;
                        }
                    }
                    $objAddress = new CustomerAddress();
                    $objAddress->customer_id = $intCustomerId;
                    $objAddress->address_label = $model->billingLabel;
                    $objAddress->first_name = $model->contactFirstName;
                    $objAddress->last_name = $model->contactLastName;
                    $objAddress->company = $model->contactCompany;
                    $objAddress->address1 = $model->billingAddress1;
                    $objAddress->address2 = $model->billingAddress2;
                    $objAddress->city = $model->billingCity;
                    $objAddress->state_id = $model->billingState;
                    $objAddress->postal = $model->billingPostal;
                    $objAddress->country_id = $model->billingCountry;
                    $objAddress->phone = $model->contactPhone;
                    $objAddress->residential = $model->billingResidential;
                    if (!$objAddress->save()) {
                        Yii::app()->user->setFlash('error', print_r($objAddress->getErrors(), true));
                        Yii::log("Error creating CustomerAddress Billing " . print_r($objAddress->getErrors(), true), 'error', 'application.' . __CLASS__ . "." . __FUNCTION__);
                        $this->refresh();
                    }
                    $objCart->billaddress_id = $model->intBillingAddress = $objAddress->id;
                    unset($objAddress);
                }
                if ($objCustomer instanceof Customer) {
                    if (is_null($objCustomer->default_billing_id)) {
                        $objCustomer->default_billing_id = $model->intBillingAddress;
                        $objCustomer->save();
                    }
                }
                // Mark order as awaiting payment.
                Yii::log("Marking as " . OrderStatus::AwaitingPayment, 'info', 'application.' . __CLASS__ . "." . __FUNCTION__);
                $objCart->cart_type = CartType::awaitpayment;
                $objCart->status = OrderStatus::AwaitingPayment;
                $objCart->downloaded = 0;
                $objCart->origin = _xls_get_ip();
                $objCart->save();
                //save cart so far
                // Assign next WO number, and LinkID.
                $objCart->SetIdStr();
                Yii::log("Order assigned " . $objCart->id_str, 'info', 'application.' . __CLASS__ . "." . __FUNCTION__);
                $objCart->linkid = $objCart->GenerateLink();
                // Get Shipping Information.
                // Prices are stored in session from Calculate Shipping.
                // TODO: rewrite to use the "selectedCartScenario" mechanism.
                $objShippingModule = Modules::model()->findByPk($model->shippingProvider);
                $arrShippingOptionPrice = Yii::app()->session->get('ship.prices.cache', null);
                if ($arrShippingOptionPrice === null) {
                    Yii::app()->user->setFlash('error', Yii::t('global', 'Oops, something went wrong, please try submitting your order again.'));
                    Yii::log('Cannot checkout: ship.prices.cache was not cached. This should never happen.', 'error', 'application.' . __CLASS__ . "." . __FUNCTION__);
                    // Must use false here to prevent process termination or
                    // the UTs die completely when this occurs.
                    $this->refresh(false);
                    return;
                }
                $fltShippingSell = $arrShippingOptionPrice[$model->shippingProvider][$model->shippingPriority];
                $fltShippingCost = $fltShippingSell - $objShippingModule->markup;
                // If the chosen shipping module has In-Store pickup, charge
                // store local tax.
                if (Yii::app()->getComponent($objShippingModule->module)->IsStorePickup) {
                    Yii::log("In Store pickup chosen, requires store tax code", 'info', 'application.' . __CLASS__ . "." . __FUNCTION__);
                    $objCart->tax_code_id = TaxCode::getDefaultCode();
                    $objCart->recalculateAndSave();
                }
                // If we have a shipping object already, update it, otherwise create it.
                if (isset($objCart->shipping)) {
                    $objShipping = $objCart->shipping;
                    //update
                } else {
                    //create
                    $objShipping = new CartShipping();
                    if (!$objShipping->save()) {
                        print_r($objShipping->getErrors());
                    }
                }
                $objShipping->shipping_module = $objShippingModule->module;
                Yii::log("Shipping module is " . $objShipping->shipping_module, 'info', 'application.' . __CLASS__ . "." . __FUNCTION__);
                $providerLabel = Yii::app()->session['ship.providerLabels.cache'][$model->shippingProvider];
                $priorityLabel = Yii::app()->session['ship.priorityLabels.cache'][$model->shippingProvider][$model->shippingPriority];
                if (stripos($priorityLabel, $providerLabel) !== false) {
                    $strLabel = $priorityLabel;
                } else {
                    $strLabel = $providerLabel . ' ' . $priorityLabel;
                }
                $objShipping->shipping_data = $strLabel;
                $objShipping->shipping_method = $objShippingModule->product;
                $objShipping->shipping_cost = $fltShippingCost;
                $objShipping->shipping_sell = $fltShippingSell;
                $objShipping->save();
                $objCart->shipping_id = $objShipping->id;
                $objCart->save();
                //save cart so far
                // Update the cart totals.
                $objCart->recalculateAndSave();
                // Get payment Information.
                $objPaymentModule = Modules::model()->findByPk($model->paymentProvider);
                // If we have a payment object already, update it, otherwise create it.
                if (isset($objCart->payment)) {
                    $objPayment = $objCart->payment;
                    //update
                } else {
                    //create
                    $objPayment = new CartPayment();
                    if (!$objPayment->save()) {
                        print_r($objPayment->getErrors());
                    }
                }
                Yii::log("Payment method is " . $objPaymentModule->payment_method, 'info', 'application.' . __CLASS__ . "." . __FUNCTION__);
                $objPayment->payment_method = $objPaymentModule->payment_method;
                $objPayment->payment_module = $objPaymentModule->module;
                $objPayment->save();
                $objCart->payment_id = $objPayment->id;
                $objCart->save();
                /* RUN PAYMENT HERE */
                Yii::log("Running payment on " . $objCart->id_str, 'info', 'application.' . __CLASS__ . "." . __FUNCTION__);
                // See if we have a subform for our payment module, set that as
                // part of running payment module.
                if (isset($paymentSubformModel)) {
                    $arrPaymentResult = Yii::app()->getComponent($objPaymentModule->module)->setCheckoutForm($model)->setSubForm($paymentSubformModel)->run();
                } else {
                    $arrPaymentResult = Yii::app()->getComponent($objPaymentModule->module)->setCheckoutForm($model)->run();
                }
                // If we have a full Jump submit form, render it out here.
                if (isset($arrPaymentResult['jump_form'])) {
                    Yii::log("Using payment jump form", 'info', 'application.' . __CLASS__ . "." . __FUNCTION__);
                    $objCart->printed_notes .= $model->orderNotes;
                    $this->completeUpdatePromoCode();
                    $this->layout = '//layouts/jumper';
                    Yii::app()->clientScript->registerScript('submit', '$(document).ready(function(){
						$("form:first").submit();
						});');
                    $this->render('jumper', array('form' => $arrPaymentResult['jump_form']));
                    Yii::app()->shoppingcart->releaseCart();
                    return;
                }
                // At this point, if we have a JumpURL, off we go...
                if (isset($arrPaymentResult['jump_url']) && $arrPaymentResult['jump_url']) {
                    Yii::log("Using payment jump url", 'info', 'application.' . __CLASS__ . "." . __FUNCTION__);
                    // Redirect to another URL for payment.
                    $objCart->printed_notes .= $model->orderNotes;
                    $this->completeUpdatePromoCode();
                    Yii::app()->shoppingcart->releaseCart();
                    Yii::app()->controller->redirect($arrPaymentResult['jump_url']);
                    return;
                }
                // to support error messages that occur with Cayan during the createTransaction process
                // see the extension for more info
                if (isset($arrPaymentResult['errorMessage'])) {
                    Yii::app()->user->setFlash('error', $arrPaymentResult['errorMessage']);
                    $this->redirect($this->createAbsoluteUrl('/cart/checkout'));
                }
                // If we are this far, we're using an Advanced Payment (or
                // non-payment like COD) so save the result of the payment
                // process (may be pass or fail).
                $objPayment->payment_data = $arrPaymentResult['result'];
                $objPayment->payment_amount = $arrPaymentResult['amount_paid'];
                $objPayment->datetime_posted = isset($retVal['payment_date']) ? date("Y-m-d H:i:s", strtotime($retVal['payment_date'])) : new CDbExpression('NOW()');
                $objPayment->save();
                if (isset($arrPaymentResult['success']) && $arrPaymentResult['success']) {
                    Yii::log("Payment Success! Wrapping up processing", 'info', 'application.' . __CLASS__ . "." . __FUNCTION__);
                    //We have successful payment, so close out the order and show the receipt
                    $objCart->printed_notes .= $model->orderNotes;
                    $this->completeUpdatePromoCode();
                    self::EmailReceipts($objCart);
                    Yii::log('Receipt e-mails added to the queue', 'info', __CLASS__ . '.' . __FUNCTION__);
                    self::FinalizeCheckout($objCart);
                    return;
                } else {
                    Yii::app()->user->setFlash('error', isset($arrPaymentResult['result']) ? $arrPaymentResult['result'] : "UNKNOWN ERROR");
                }
            } else {
                Yii::log("Error submitting form " . print_r($model->getErrors(), true), 'error', 'application.' . __CLASS__ . "." . __FUNCTION__);
                Yii::app()->user->setFlash('error', Yii::t('cart', 'Please check your form for errors.'));
                if (YII_DEBUG) {
                    Yii::app()->user->setFlash('error', "DEBUG: " . _xls_convert_errors_display(_xls_convert_errors($model->getErrors())));
                }
            }
        } else {
            if (isset(Yii::app()->session['checkout.cache'])) {
                $model = Yii::app()->session['checkout.cache'];
                $model->clearErrors();
            } else {
                //If this is the first time we're displaying the Checkout form, set some defaults
                $model->setScenario('formSubmit');
                $model->billingCountry = _xls_get_conf('DEFAULT_COUNTRY');
                $model->shippingCountry = _xls_get_conf('DEFAULT_COUNTRY');
                $model->billingSameAsShipping = 1;
                $model->billingResidential = 1;
                $model->shippingResidential = 1;
                //Set our default payment module to first on the list
                $obj = new CheckoutForm();
                $data = array_keys($obj->getPaymentMethods());
                if (count($data) > 0) {
                    $model->paymentProvider = $data[0];
                }
                if (!Yii::app()->user->isGuest) {
                    //For logged in users, preset to customer account information
                    $objCustomer = Customer::GetCurrent();
                    if (!$objCustomer instanceof Customer) {
                        //somehow we're logged in without a valid Customer object
                        Yii::app()->user->logout();
                        $url = Yii::app()->createUrl('site/index');
                        $this->redirect($url);
                    }
                    $model->contactFirstName = $objCustomer->first_name;
                    $model->contactLastName = $objCustomer->last_name;
                    $model->contactPhone = $objCustomer->mainphone;
                    $model->contactEmail = $objCustomer->email;
                    if (!empty($objCustomer->defaultBilling)) {
                        $model->intBillingAddress = $objCustomer->default_billing_id;
                    }
                    if (!empty($objCustomer->defaultShipping)) {
                        $model->intShippingAddress = $objCustomer->default_shipping_id;
                    }
                } else {
                    //Set some defaults for guest checkouts
                    $model->receiveNewsletter = Yii::app()->params['DISABLE_ALLOW_NEWSLETTER'] == 1 ? 0 : 1;
                }
            }
        }
        $this->objCart = Yii::app()->shoppingcart;
        // When CheckoutForm is initialized the shippingProvider and
        // shippingPriority are null.  The AJAX validation sends empty
        // strings for these fields until a shipping option is selected.
        if (is_null($model->shippingProvider) || $model->shippingProvider === '') {
            // Use -1 to indicate that the shipping provider has not been chosen.
            $model->shippingProvider = '-1';
        }
        if (is_null($model->shippingPriority) || $model->shippingPriority === '') {
            // Use -1 to indicate that the shipping priority has not been chosen.
            $model->shippingPriority = '-1';
        }
        //If we have a default shipping address on, hide our Shipping box
        if (!empty($model->intShippingAddress) && count($model->objAddresses) > 0) {
            Yii::app()->clientScript->registerScript('shipping', '$(document).ready(function(){
				$("#CustomerContactShippingAddress").hide();
				});');
            // These need to go at POS_END because they need to be ran after
            // SinglePageCheckout has been instantiated. Further granularity in
            // the load order can be achieved by passing an integer to the
            // $position parameter. @See CClientScript::registerScript.
            Yii::app()->clientScript->registerScript('shippingforceclick', '$(document).ready(function(){
				singlePageCheckout.calculateShipping();
				});', CClientScript::POS_END);
        }
        //If we have a default billing address on, hide our Billing box
        if (!empty($model->intBillingAddress) && count($model->objAddresses) > 0) {
            Yii::app()->clientScript->registerScript('billingadd', '$(document).ready(function(){
				$("#CustomerContactBillingAddressAdd").hide();
				});');
        }
        //If Same as Billing checkbox is on, hide our Billing box
        if ($model->billingSameAsShipping) {
            Yii::app()->clientScript->registerScript('billing', 'if ($("#CheckoutForm_billingSameAsShipping:checked").length>0)
				$("#CustomerContactBillingAddress").hide();');
        }
        $paymentForms = $model->getAlternativePaymentMethodsThatUseSubForms();
        // If we have chosen a payment provider (indicating this is a refresh),
        // repick here.
        if ($model->paymentProvider > 0) {
            $objPaymentModule = Modules::model()->findByPk($model->paymentProvider);
            if ($objPaymentModule instanceof Modules) {
                $objModule = Yii::app()->getComponent($objPaymentModule->module);
                if (!$objModule) {
                    Yii::log("Error missing module " . $objPaymentModule->module, 'error', 'application.' . __CLASS__ . "." . __FUNCTION__);
                    $model->paymentProvider = null;
                } else {
                    $subForm = $objModule->subform;
                    if (isset($subForm)) {
                        if (isset($_POST[$subForm])) {
                            $paymentForms[$objPaymentModule->id]->attributes = $_POST[$subForm];
                            $paymentForms[$objPaymentModule->id]->validate();
                        }
                    }
                    Yii::app()->clientScript->registerScript('payment', sprintf('$(document).ready(function(){
							singlePageCheckout.changePayment(%s)
							});', CJSON::encode($model->paymentProvider)), CClientScript::POS_END);
                }
            } else {
                $model->paymentProvider = null;
            }
        }
        // Disable button on Submit to prevent double-clicking.
        $cs = Yii::app()->clientScript;
        $cs->registerScript('submit', '$("checkout:submit").mouseup(function() {
			$(this).attr("disabled",true);
			$(this).parents("form").submit();
			})', CClientScript::POS_READY);
        // This registers a backwards-compatibility shim for the pre-3.2.2
        // single-page checkout. 3.2.2 moved much of the JavaScript out of
        // checkout.php and _cartjs.php into WsSinglePageCheckout.js to
        // improve testability. This shim exists to support stores with a
        // customized checkout that is based on a version before 3.2.2. At
        // some point, we should find a way to move customers customers forward
        // and remove this shim.
        $cs->registerScript('compatibility-shim', '$(document).ready(function(){
				if (typeof singlePageCheckout === "undefined" && typeof updateShippingPriority === "function") {
					singlePageCheckout = {
						calculateShipping: function() { $("#btnCalculate").click(); },
						changePayment: function(paymentProviderId) { changePayment(paymentProviderId); },
						pickShippingProvider: function(providerId) { updateShippingPriority(providerId); },
						updateCart: function(priorityId) { updateCart(priorityId); }
					};
				}
			})', CClientScript::POS_BEGIN);
        // Clear out anything we don't to survive the round trip.
        $model->cardNumber = null;
        $model->cardCVV = null;
        $this->render('checkout', array('model' => $model, 'paymentForms' => $paymentForms));
    }