/** * Get payment choice and have end user confirm and place order. * A user can choose a simple integration method which will redirect * them to the confirmation page. If they put their cc details directly * in the form to checkout with an advanced method, the confirmation * page is immediately rendered. * * @return void */ public function actionFinal() { $this->checkoutForm = MultiCheckoutForm::loadFromSessionOrNew(); $arrCheckbox = array('id' => 1, 'name' => 'MultiCheckoutForm[billingSameAsShipping]', 'label' => Yii::t('checkout', 'Use my shipping address as my billing address'), 'address' => $this->checkoutForm->strShippingAddress); $objCart = Yii::app()->shoppingcart; // check to see if we have any advanced methods and if not redirect to the simple payment action $arrModules = $this->checkoutForm->getAimPaymentMethods(); if (count($arrModules) < 1) { $this->redirect($this->createAbsoluteUrl('/checkout/paymentsimple')); } // set cardholder name to default i.e. contact name $this->checkoutForm->cardNameOnCard = $this->checkoutForm->contactFirstName . ' ' . $this->checkoutForm->contactLastName; // is an existing user changing their billing address? if (isset($_POST['BillingAddress']) && !isset($_POST['MultiCheckoutForm']['intBillingAddress'])) { $val = $_POST['BillingAddress']; if (is_numeric($val)) { if (isset($_POST['MultiCheckoutForm'])) { $this->checkoutForm->attributes = $_POST['MultiCheckoutForm']; } $this->checkoutForm->intBillingAddress = $val; $this->checkoutForm->fillAddressFields($val); $arrCheckbox['id'] = $val; $arrCheckbox['name'] = 'MultiCheckoutForm[intBillingAddress]'; $arrCheckbox['label'] = Yii::t('checkout', 'Use this as my billing address'); $arrCheckbox['address'] = $this->checkoutForm->strBillingAddress; $arrAddresses = CustomerAddress::getActiveAddresses(); // remove shipping address from the address array // to prevent someone attempting to edit it foreach ($arrAddresses as $key => $objAddress) { if ($objAddress->id === $this->checkoutForm->intShippingAddress) { unset($arrAddresses[$key]); break; } } $this->checkoutForm->objAddresses = $arrAddresses; $this->layout = '/layouts/checkout'; $this->render('paymentaddress', array('model' => $this->checkoutForm, 'checkbox' => $arrCheckbox, 'error' => $this->formatErrors(), 'paymentFormModules' => $this->checkoutForm->getAlternativePaymentMethodsThatUseSubForms())); } } elseif (isset($_POST['Payment']) || isset($_POST['Paypal'])) { if (isset($_POST['MultiCheckoutForm'])) { $this->checkoutForm->attributes = $_POST['MultiCheckoutForm']; if (_xls_get_conf('SHIP_SAME_BILLSHIP') == 1) { $this->checkoutForm->billingSameAsShipping = 1; } // get all the active alternative / offline payment methods $alternatePaymentMethods = $this->checkoutForm->getAlternativePaymentMethods(); if (array_key_exists($this->checkoutForm->paymentProvider, $alternatePaymentMethods) || isset($_POST['Paypal'])) { // end user has either chosen an alternative payment method or hit the Paypal button // clear sensitive data just in case $this->checkoutForm->clearCCdata(); // set billing address to be the same as shipping so that the form passes validation $this->checkoutForm->billingSameAsShipping = 1; $blnBillAddressHandled = true; // user chose paypal if (isset($_POST['Paypal'])) { $this->checkoutForm->paymentProvider = $_POST['Paypal']; } $this->checkoutForm->saveFormToSession(); // set scenario if ($objCart->shipping->isStorePickup) { $this->checkoutForm->setScenario('PaymentStorePickup'); // no customer addresses required } else { $this->checkoutForm->setScenario('PaymentSim'); // shipping address is required $blnBillAddressHandled = $this->checkoutForm->updateAddressId('billing'); // set billing address to shipping address to pass validation } // validate and update payment $objPayment = CartPayment::getOrCreateCartPayment(); if ($blnBillAddressHandled && $this->checkoutForm->validate() && $this->checkoutForm->handleSubform() && $objPayment->updateCartPayment($this->checkoutForm, $this->checkoutForm->subFormModel)) { // save the passed scenario $this->checkoutForm->passedScenario = $this->checkoutForm->getScenario(); $this->checkoutForm->saveFormToSession(); $this->redirect($this->createAbsoluteUrl('/checkout/confirmation')); } $this->checkoutForm->addErrors($objPayment->getErrors()); $this->publishJS('payment'); $this->publishJS('zippo'); $this->layout = '/layouts/checkout'; if (count($this->checkoutForm->objAddresses) > 0) { $this->render('paymentaddress', array('model' => $this->checkoutForm, 'checkbox' => $arrCheckbox, 'error' => $this->formatErrors(), 'paymentFormModules' => $this->checkoutForm->getAlternativePaymentMethodsThatUseSubForms())); } else { $this->render('payment', array('model' => $this->checkoutForm, 'error' => $this->formatErrors(), 'paymentFormModules' => $this->checkoutForm->getAlternativePaymentMethodsThatUseSubForms())); } } else { // if we are here, the end user has entered their card details directly (AIM) // ensure form is populated with billing address if (isset($this->checkoutForm->intBillingAddress)) { $this->checkoutForm->fillAddressFields($this->checkoutForm->intBillingAddress); $this->checkoutForm->billingSameAsShipping = null; } // payment processors require the cardNumber formatted as an // actual number so remove whitespace from the cardNumber $this->checkoutForm->cardNumber = _xls_number_only($this->checkoutForm->cardNumber); $this->checkoutForm->cardNumberLast4 = substr($this->checkoutForm->cardNumber, -4); // only the last 4 digits // prevent an exception if cardExpiry is left blank if (isset($this->checkoutForm->cardExpiry) && $this->checkoutForm->cardExpiry !== '') { $arrCardExpiry = explode('/', $this->checkoutForm->cardExpiry); $this->checkoutForm->cardExpiryMonth = $arrCardExpiry[0]; $this->checkoutForm->cardExpiryYear = $arrCardExpiry[1] + 2000; } // set scenario if ($objCart->shipping->isStorePickup) { $this->checkoutForm->setScenario('PaymentStorePickupCC'); // only billing address required } else { $this->checkoutForm->setScenario('Payment'); // shipping and billing address required } // validate the form $objPayment = CartPayment::getOrCreateCartPayment(); if ($this->checkoutForm->updateAddressId('billing') && $this->checkoutForm->validate() && $objPayment->updateCartPayment($this->checkoutForm)) { $this->layout = '/layouts/checkout-confirmation'; $this->render('confirmation', array('model' => $this->checkoutForm, 'cart' => Yii::app()->shoppingcart, 'shippingEstimatorOptions' => $this->_getShippingEstimatorOptions(), 'error' => $this->formatErrors())); } else { $this->checkoutForm->addErrors($objPayment->getErrors()); // clear sensitive data and force user to re-enter them $this->checkoutForm->clearCCdata(); $this->publishJS('payment'); $this->publishJS('zippo'); $this->layout = '/layouts/checkout'; if (count($this->checkoutForm->objAddresses) > 0) { $this->render('paymentaddress', array('model' => $this->checkoutForm, 'checkbox' => $arrCheckbox, 'error' => $this->formatErrors(), 'paymentFormModules' => $this->checkoutForm->getAlternativePaymentMethodsThatUseSubForms())); } else { $this->render('payment', array('model' => $this->checkoutForm, 'error' => $this->formatErrors(), 'paymentFormModules' => $this->checkoutForm->getAlternativePaymentMethodsThatUseSubForms())); } } } } } elseif (isset($_POST['Confirmation'])) { $haveCartItemsBeenUpdated = false; if (isset($_POST['MultiCheckoutForm'])) { $this->checkoutForm->attributes = $_POST['MultiCheckoutForm']; if ($objCart->shipping->isStorePickup) { $this->checkoutForm->setScenario('ConfirmationStorePickupCC'); // only billing address required } else { $this->checkoutForm->setScenario('Confirmation'); // shipping and billing address required } // validate form and cart if ($this->checkoutForm->updateCartCustomerId() && $this->checkoutForm->validate()) { // if the cart was modified stop checkout and re-render the page with the message to the end user if (Yii::app()->shoppingcart->wasCartModified === false) { // cart is as we expect, continue $result = $this->executeCheckoutProcess(); if (isset($result['success']) && isset($result['cartlink'])) { // send user to receipt $this->redirect($this->createAbsoluteUrl("/checkout/thankyou/" . $result['cartlink'])); } } } } $this->layout = '/layouts/checkout-confirmation'; $this->render('confirmation', array('model' => $this->checkoutForm, 'cart' => Yii::app()->shoppingcart, 'shippingEstimatorOptions' => $this->_getShippingEstimatorOptions(), 'error' => $this->formatErrors(), 'recalculateShippingOnLoad' => Yii::app()->shoppingcart->wasCartModified)); } else { $this->layout = '/layouts/checkout'; $this->publishJS('payment'); $this->publishJS('zippo'); // clear sensitive data $this->checkoutForm->clearCCdata(); // existing user with existing addresses if (count($this->checkoutForm->objAddresses) > 0) { $arrCheckbox['name'] = 'MultiCheckoutForm[intBillingAddress]'; // if the billing address was defined before, set the checkbox label if (isset($this->checkoutForm->intBillingAddress) && $this->checkoutForm->intBillingAddress !== $this->checkoutForm->intShippingAddress) { $arrCheckbox['label'] = Yii::t('checkout', 'Use this as my billing address'); } // get up to date address info $arrAddresses = CustomerAddress::getActiveAddresses(); // find the selected address id $selectedAddressId = null; $blnDefaultBilling = true; if (isset($_POST['BillingAddress']) === false && isset($this->checkoutForm->intBillingAddress) === false) { // Check to see if the customer has a default billing address set if ($objCart->customer->default_billing_id !== null) { $objTemp = $objCart->customer->defaultBilling; if ($objTemp->active == 1) { $selectedAddressId = $objTemp->id; } else { $blnDefaultBilling = false; } } else { $blnDefaultBilling = false; } if ($blnDefaultBilling === false) { // No default billing address available so just use the first address in the array $objAddress = current($arrAddresses); $selectedAddressId = $objAddress->id; } } else { $selectedAddressId = $this->checkoutForm->intShippingAddress; } // remove the selected address from the array foreach ($arrAddresses as $key => $objAddress) { if ($objAddress->id === $selectedAddressId) { $arrCheckbox['id'] = $objAddress->id; $arrCheckbox['address'] = _xls_string_address($objAddress); break; } } // remove the shipping address from the array foreach ($arrAddresses as $key => $objAddress) { if ($objAddress->id === $this->checkoutForm->intShippingAddress) { unset($arrAddresses[$key]); break; } } $this->checkoutForm->objAddresses = $arrAddresses; $this->checkoutForm->saveFormToSession(); $this->render('paymentaddress', array('model' => $this->checkoutForm, 'checkbox' => $arrCheckbox, 'error' => $this->formatErrors(), 'paymentFormModules' => $this->checkoutForm->getAlternativePaymentMethodsThatUseSubForms())); } else { $this->render('payment', array('model' => $this->checkoutForm, 'error' => $this->formatErrors(), 'paymentFormModules' => $this->checkoutForm->getAlternativePaymentMethodsThatUseSubForms())); } } }