/** * Return the PayPal form. * * @access public * @return string */ public function checkoutForm() { $objOrder = new IsotopeOrder(); if (!$objOrder->findBy('cart_id', $this->Isotope->Cart->id)) { $this->redirect($this->addToUrl('step=failed', true)); } list($endTag, $startScript, $endScript) = IsotopeFrontend::getElementAndScriptTags(); $strBuffer = ' <h2>' . $GLOBALS['TL_LANG']['MSC']['pay_with_redirect'][0] . '</h2> <p class="message">' . $GLOBALS['TL_LANG']['MSC']['pay_with_redirect'][1] . '</p> <form id="payment_form" action="https://www.' . ($this->debug ? 'sandbox.' : '') . 'paypal.com/cgi-bin/webscr" method="post"> <input type="hidden" name="cmd" value="_cart"' . $endTag . ' <input type="hidden" name="upload" value="1"' . $endTag . ' <input type="hidden" name="charset" value="UTF-8"' . $endTag . ' <input type="hidden" name="business" value="' . $this->paypal_account . '"' . $endTag . ' <input type="hidden" name="lc" value="' . strtoupper($GLOBALS['TL_LANGUAGE']) . '"' . $endTag; foreach ($this->Isotope->Cart->getProducts() as $objProduct) { $strOptions = ''; $arrOptions = $objProduct->getOptions(); if (is_array($arrOptions) && count($arrOptions)) { $options = array(); foreach ($arrOptions as $option) { $options[] = $option['label'] . ': ' . $option['value']; } $strOptions = ' (' . implode(', ', $options) . ')'; } $strBuffer .= ' <input type="hidden" name="item_number_' . ++$i . '" value="' . $objProduct->sku . '"' . $endTag . ' <input type="hidden" name="item_name_' . $i . '" value="' . $objProduct->name . $strOptions . '"' . $endTag . ' <input type="hidden" name="amount_' . $i . '" value="' . $objProduct->price . '"/> <input type="hidden" name="quantity_' . $i . '" value="' . $objProduct->quantity_requested . '"' . $endTag; } $fltDiscount = 0; foreach ($this->Isotope->Cart->getSurcharges() as $arrSurcharge) { if ($arrSurcharge['add'] === false) { continue; } // PayPal does only support one single discount item if ($arrSurcharge['total_price'] < 0) { $fltDiscount -= $arrSurcharge['total_price']; continue; } $strBuffer .= ' <input type="hidden" name="item_name_' . ++$i . '" value="' . $arrSurcharge['label'] . '"' . $endTag . ' <input type="hidden" name="amount_' . $i . '" value="' . $arrSurcharge['total_price'] . '"' . $endTag; } if ($fltDiscount > 0) { $strBuffer .= ' <input type="hidden" name="discount_amount_cart" value="' . $fltDiscount . '"' . $endTag; } $strBuffer .= ' <input type="hidden" name="no_shipping" value="1"' . $endTag . ' <input type="hidden" name="no_note" value="1"' . $endTag . ' <input type="hidden" name="currency_code" value="' . $this->Isotope->Config->currency . '"' . $endTag . ' <input type="hidden" name="button_subtype" value="services"' . $endTag . ' <input type="hidden" name="return" value="' . $this->Environment->base . IsotopeFrontend::addQueryStringToUrl('uid=' . $objOrder->uniqid, $this->addToUrl('step=complete')) . '"' . $endTag . ' <input type="hidden" name="cancel_return" value="' . $this->Environment->base . $this->addToUrl('step=failed') . '"' . $endTag . ' <input type="hidden" name="rm" value="1"' . $endTag . ' <input type="hidden" name="invoice" value="' . $objOrder->id . '"' . $endTag . ' <input type="hidden" name="address_override" value="' . ($this->debug ? '0' : '1') . '"' . $endTag . ' <input type="hidden" name="first_name" value="' . $this->Isotope->Cart->billingAddress['firstname'] . '"' . $endTag . ' <input type="hidden" name="last_name" value="' . $this->Isotope->Cart->billingAddress['lastname'] . '"' . $endTag . ' <input type="hidden" name="address1" value="' . $this->Isotope->Cart->billingAddress['street_1'] . '"' . $endTag . ' <input type="hidden" name="address2" value="' . $this->Isotope->Cart->billingAddress['street_2'] . '"' . $endTag . ' <input type="hidden" name="zip" value="' . $this->Isotope->Cart->billingAddress['postal'] . '"' . $endTag . ' <input type="hidden" name="city" value="' . $this->Isotope->Cart->billingAddress['city'] . '"' . $endTag . ' <input type="hidden" name="country" value="' . strtoupper($this->Isotope->Cart->billingAddress['country']) . '"' . $endTag . ' <input type="hidden" name="email" value="' . $this->Isotope->Cart->billingAddress['email'] . '"' . $endTag . ' <input type="hidden" name="night_phone_b" value="' . $this->Isotope->Cart->billingAddress['phone'] . '"' . $endTag . ' <input type="hidden" name="notify_url" value="' . $this->Environment->base . 'system/modules/isotope/postsale.php?mod=pay&id=' . $this->id . '"' . $endTag . ' <input type="hidden" name="bn" value="PP-BuyNowBF:btn_paynowCC_LG.gif:NonHosted"' . $endTag . ' <input type="' . (strlen($this->button) ? 'image" src="' . $this->button . '" border="0"' : 'submit" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['pay_with_redirect'][2]) . '"') . ' alt="PayPal - The safer, easier way to pay online!"' . $endTag . ' </form> ' . $startScript . ' window.addEvent( \'domready\' , function() { $(\'payment_form\').submit(); }); ' . $endScript; return $strBuffer; }
/** * Generate the module * @return void */ protected function compile() { $objOrders = $this->Database->execute("SELECT *, (SELECT COUNT(*) FROM tl_iso_order_items WHERE pid=tl_iso_orders.id) AS items FROM tl_iso_orders WHERE status!='' AND pid=" . $this->User->id . " AND config_id IN (" . implode(',', $this->iso_config_ids) . ") ORDER BY date DESC"); // No orders found, just display an "empty" message if (!$objOrders->numRows) { $this->Template = new FrontendTemplate('mod_message'); $this->Template->type = 'empty'; $this->Template->message = $GLOBALS['TL_LANG']['ERR']['emptyOrderHistory']; return; } $this->import('Isotope'); $arrOrders = array(); while ($objOrders->next()) { if ($this->Isotope->Config->id != $objOrders->config_id) { $this->Isotope->overrideConfig($objOrders->config_id); } $arrOrders[] = array('raw' => $objOrders->row(), 'date' => $this->parseDate($GLOBALS['TL_CONFIG']['dateFormat'], $objOrders->date), 'time' => $this->parseDate($GLOBALS['TL_CONFIG']['timeFormat'], $objOrders->date), 'datime' => $this->parseDate($GLOBALS['TL_CONFIG']['datimeFormat'], $objOrders->date), 'items' => $objOrders->items, 'grandTotal' => $this->Isotope->formatPriceWithCurrency($objOrders->grandTotal), 'status' => $GLOBALS['TL_LANG']['ORDER'][$objOrders->status], 'link' => $this->jumpTo ? IsotopeFrontend::addQueryStringToUrl('uid=' . $objOrders->uniqid, $this->jumpTo) : ''); } $this->Template->orders = $arrOrders; $this->Template->dateLabel = $GLOBALS['TL_LANG']['MSC']['iso_order_date']; $this->Template->statusLabel = $GLOBALS['TL_LANG']['MSC']['iso_order_status']; $this->Template->subTotalLabel = $GLOBALS['TL_LANG']['MSC']['subTotalLabel']; $this->Template->grandTotalLabel = $GLOBALS['TL_LANG']['MSC']['grandTotalLabel']; $this->Template->quantityLabel = $GLOBALS['TL_LANG']['MSC']['iso_quantity_header']; $this->Template->detailsLabel = $GLOBALS['TL_LANG']['MSC']['detailLabel']; }
public function checkoutForm() { $this->import('Isotope'); $fields = ''; // Get the current order, review page will create the data $objOrder = $this->Database->prepare("SELECT * FROM tl_iso_orders WHERE cart_id=?")->limit(1)->execute($this->Isotope->Cart->id); $doNotSubmit = false; $strBuffer = ''; $arrPayment = $this->Input->post('payment'); $arrCCTypes = deserialize($this->allowed_cc_types); //standard keys foreach ($arrCCTypes as $type) { // numeric keys specific to Cybersource // @todo merchant bank makes a difference! $arrAllowedCCTypes[] = $this->arrCardTypes[$type]; } $intStartYear = (int) date('Y', time()); //4-digit year for ($i = 0; $i <= 7; $i++) { $arrYears[] = (string) $intStartYear + $i; } //card_accountNumber,card_cardType,card_expirationMonth,card_expirationYear,card_cvNumber $arrFields = array('card_accountNumber' => array('label' => &$GLOBALS['TL_LANG']['ISO']['cc_num'], 'inputType' => 'text', 'eval' => array('mandatory' => true, 'rgxp' => 'digit', 'tableless' => true)), 'card_cardType' => array('label' => &$GLOBALS['TL_LANG']['ISO']['cc_type'], 'inputType' => 'select', 'options' => $arrAllowedCCTypes, 'eval' => array('mandatory' => true, 'rgxp' => 'digit', 'tableless' => true), 'reference' => &$GLOBALS['ISO_LANG']['CCT']), 'card_expirationMonth' => array('label' => &$GLOBALS['TL_LANG']['ISO']['cc_exp_month'], 'inputType' => 'select', 'options' => array('01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'), 'eval' => array('mandatory' => true, 'tableless' => true, 'includeBlankOption' => true)), 'card_expirationYear' => array('label' => &$GLOBALS['TL_LANG']['ISO']['cc_exp_year'], 'inputType' => 'select', 'options' => $arrYears, 'eval' => array('mandatory' => true, 'tableless' => true, 'includeBlankOption' => true)), 'card_cvNumber' => array('label' => &$GLOBALS['TL_LANG']['ISO']['cc_ccv'], 'inputType' => 'text', 'eval' => array('mandatory' => true, 'tableless' => true))); foreach ($arrFields as $field => $arrData) { $strClass = $GLOBALS['TL_FFL'][$arrData['inputType']]; // Continue if the class is not defined if (!$this->classFileExists($strClass)) { continue; } $objWidget = new $strClass($this->prepareForWidget($arrData, 'payment[' . $field . ']')); // Validate input if ($this->Input->post('FORM_SUBMIT') == 'iso_mod_checkout_payment' && $arrPayment['module'] == $this->id) { $objWidget->validate(); if ($objWidget->hasErrors()) { $doNotSubmit = true; } } elseif ($objWidget->mandatory && !strlen($arrPayment[$field])) { $doNotSubmit = true; } $strBuffer .= $objWidget->parse(); } global $objPage; $objOrder = $this->Database->prepare("SELECT * FROM tl_iso_orders WHERE cart_id=?")->limit(1)->execute($this->Isotope->Cart->id); $intTotal = round($this->Isotope->Cart->grandTotal, 2); $arrSubdivision = explode('-', $this->Isotope->Cart->billingAddress['subdivision']); if (!$doNotSubmit && $this->Input->post('FORM_SUBMIT') == 'payment_form') { try { $objSoapClient = new CybersourceClient('https://ics2ws' . ($this->debug ? 'test' : '') . '.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.26.wsdl', array(), $this->cybersource_merchant_id, $this->cybersource_trans_key); $objRequest = new stdClass(); $objRequest->merchantID = $this->cybersource_merchant_id; // Before using this example, replace the generic value with your own. $objRequest->merchantReferenceCode = $objOrder->id; // To help us troubleshoot any problems that you may encounter, // please include the following information about your PHP application. $objRequest->clientLibrary = "PHP"; $objRequest->clientLibraryVersion = phpversion(); $objRequest->clientEnvironment = php_uname(); // This section builds the transaction information // service with complete billing, payment card, and purchase (two items) information. $objCCAuthService = new stdClass(); $objCCAuthService->run = "true"; $objRequest->ccAuthService = $objCCAuthService; $objBillTo = new stdClass(); $objBillTo->firstName = $this->Isotope->Cart->billingAddress['firstname']; $objBillTo->lastName = $this->Isotope->Cart->billingAddress['lastname']; $objBillTo->street1 = $this->Isotope->Cart->billingAddress['street_1']; $objBillTo->city = $this->Isotope->Cart->billingAddress['city']; $objBillTo->state = $arrSubdivision[1]; $objBillTo->postalCode = $this->Isotope->Cart->billingAddress['postal']; $objBillTo->country = $this->Isotope->Cart->billingAddress['country']; $objBillTo->email = $this->Isotope->Cart->billingAddress['email']; $objBillTo->ipAddress = $this->Environment->ip; $objRequest->billTo = $objBillTo; $objCard = new stdClass(); $objCard->accountNumber = $arrPayment['card_accountNumber']; $objCard->expirationMonth = $arrPayment['card_expirationMonth']; $objCard->expirationYear = $arrPayment['card_expirationYear']; //if($this->requireCardType) $objCard->cardType = $arrPayment['card_cardType']; if ($this->requireCCV) { $objCard->cvNumber = $arrPayment['card_cvNumber']; } $objRequest->card = $objCard; $objPurchaseTotals = new stdClass(); $objPurchaseTotals->currency = $this->Isotope->Config->currency; $objPurchaseTotals->grandTotalAmount = round($this->Isotope->Cart->grandTotal, 2); $objRequest->purchaseTotals = $objPurchaseTotals; /*$arrProducts = $this->Isotope->Cart->getProducts(); foreach($arrProducts as $i=>$objProduct) { $objItem = new stdClass(); $objItem->unitPrice = $objProduct->price; $objItem->quantity = $objProduct->quantity; $objItem->id = $objProduct->id; $arrItems[] = $objItem; } $objRequest->item = $arrItems;*/ //, $strLocation, $strAction, $strVersion, $strMerchantId, $strTransactionKey $objReply = $objSoapClient->runTransaction($objRequest); $arrPaymentData['transaction_response'] = $objReply->decision; $arrPaymentData['transaction_response_code'] = $objReply->reasonCode; $arrPaymentData['request_id'] = $objReply->requestID; $arrPaymentData['request_token'] = $objReply->requestToken; $arrSet['payment_data'] = serialize($arrPaymentData); switch ($objReply->decision) { case 'ACCEPT': $arrPaymentData['cc_last_four'] = substr($strCCNum, strlen($strCCNum) - 4, 4); break; default: $blnFail = true; break; } $this->Database->prepare("UPDATE tl_iso_orders %s WHERE id={$objOrder->id}")->set($arrSet)->executeUncached(); if ($blnFail) { $this->log('Invalid payment data received.', 'PaymentCybersource checkoutForm()', TL_ERROR); $this->redirect(IsotopeFrontend::addQueryStringToUrl('error=' . $objReply->reasonCode)); } $this->redirect($this->addToUrl('step=complete', true)); } catch (SoapFault $exception) { var_dump(get_class($exception)); var_dump($exception); } } list($endTag) = IsotopeFrontend::getElementAndScriptTags(); return ' <h2>' . $this->label . '</h2>' . ($this->Input->get('error') == '' ? '' : '<p class="error message">' . $GLOBALS['TL_LANG']['CYB'][$this->Input->get('error')] . '</p>') . '<form id="payment_form" action="' . $this->Environment->request . '" method="post"> <input type="hidden" name="FORM_SUBMIT" value="payment_form"' . $endTag . ' <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"' . $endTag . $strBuffer . ' <input type="submit" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['confirmOrder']) . '"' . $endTag . ' </form>'; }
/** * Generate the module * @return void */ protected function compile() { $objOrder = new IsotopeOrder(); if (!$objOrder->findBy('uniqid', $this->Input->get('uid'))) { $this->Template = new FrontendTemplate('mod_message'); $this->Template->type = 'error'; $this->Template->message = $GLOBALS['TL_LANG']['ERR']['orderNotFound']; return; } $arrOrder = $objOrder->getData(); $this->Template->setData($arrOrder); $this->import('Isotope'); $this->Isotope->overrideConfig($objOrder->config_id); // Article reader $arrPage = $this->Database->prepare("SELECT * FROM tl_page WHERE id=?")->limit(1)->execute($this->jumpTo)->fetchAssoc(); $arrAllDownloads = array(); $arrItems = array(); $arrProducts = $objOrder->getProducts(); foreach ($arrProducts as $i => $objProduct) { $arrDownloads = array(); $objDownloads = $this->Database->prepare("SELECT p.*, o.* FROM tl_iso_order_downloads o LEFT OUTER JOIN tl_iso_downloads p ON o.download_id=p.id WHERE o.pid=?")->execute($objProduct->cart_id); while ($objDownloads->next()) { $blnDownloadable = ($objOrder->status == 'complete' || intval($objOrder->date_paid) > 0 && intval($objOrder->date_paid) <= time()) && ($objDownloads->downloads_remaining === '' || $objDownloads->downloads_remaining > 0) ? true : false; // Send file to the browser if (strlen($this->Input->get('file')) && $this->Input->get('file') == $objDownloads->id && $blnDownloadable) { if (!$this->backend && $objDownloads->downloads_remaining !== '') { $this->Database->prepare("UPDATE tl_iso_order_downloads SET downloads_remaining=? WHERE id=?")->execute($objDownloads->downloads_remaining - 1, $objDownloads->id); } $this->sendFileToBrowser($objDownloads->singleSRC); } $arrDownload = array('raw' => $objDownloads->row(), 'title' => $objDownloads->title, 'href' => TL_MODE == 'FE' ? IsotopeFrontend::addQueryStringToUrl('file=' . $objDownloads->id) : '', 'remaining' => $objDownloads->downloads_allowed > 0 ? sprintf($GLOBALS['TL_LANG']['MSC']['downloadsRemaining'], intval($objDownloads->downloads_remaining)) : '', 'downloadable' => $blnDownloadable); $arrDownloads[] = $arrDownload; $arrAllDownloads[] = $arrDownload; } $arrItems[] = array('raw' => $objProduct->getData(), 'sku' => $objProduct->sku, 'name' => $objProduct->name, 'image' => $objProduct->images->main_image, 'product_options' => $objProduct->getOptions(), 'quantity' => $objProduct->quantity_requested, 'price' => $this->Isotope->formatPriceWithCurrency($objProduct->price), 'total' => $this->Isotope->formatPriceWithCurrency($objProduct->total_price), 'href' => $this->jumpTo ? $this->generateFrontendUrl($arrPage, '/product/' . $objProduct->alias) : '', 'tax_id' => $objProduct->tax_id, 'downloads' => $arrDownloads); } $this->Template->info = deserialize($objOrder->checkout_info, true); $this->Template->items = IsotopeFrontend::generateRowClass($arrItems, 'row', 'rowClass', 0, ISO_CLASS_COUNT | ISO_CLASS_FIRSTLAST | ISO_CLASS_EVENODD); $this->Template->downloads = $arrAllDownloads; $this->Template->downloadsLabel = $GLOBALS['TL_LANG']['MSC']['downloadsLabel']; $this->Template->raw = $arrOrder; $this->Template->date = $this->parseDate($GLOBALS['TL_CONFIG']['dateFormat'], $objOrder->date); $this->Template->time = $this->parseDate($GLOBALS['TL_CONFIG']['timeFormat'], $objOrder->date); $this->Template->datim = $this->parseDate($GLOBALS['TL_CONFIG']['datimFormat'], $objOrder->date); $this->Template->orderDetailsHeadline = sprintf($GLOBALS['TL_LANG']['MSC']['orderDetailsHeadline'], $objOrder->order_id, $this->Template->datim); $this->Template->orderStatus = sprintf($GLOBALS['TL_LANG']['MSC']['orderStatusHeadline'], $GLOBALS['TL_LANG']['ORDER'][$objOrder->status]); $this->Template->orderStatusKey = $objOrder->status; $this->Template->subTotalPrice = $this->Isotope->formatPriceWithCurrency($objOrder->subTotal); $this->Template->grandTotal = $this->Isotope->formatPriceWithCurrency($objOrder->grandTotal); $this->Template->subTotalLabel = $GLOBALS['TL_LANG']['MSC']['subTotalLabel']; $this->Template->grandTotalLabel = $GLOBALS['TL_LANG']['MSC']['grandTotalLabel']; $this->Template->surcharges = IsotopeFrontend::formatSurcharges($objOrder->getSurcharges()); $this->Template->billing_label = $GLOBALS['TL_LANG']['ISO']['billing_address']; $this->Template->billing_address = $this->Isotope->generateAddressString($objOrder->billing_address, $this->Isotope->Config->billing_fields); if (strlen($objOrder->shipping_method)) { $arrShippingAddress = $objOrder->shipping_address; if (!is_array($arrShippingAddress) || $arrShippingAddress['id'] == -1) { $this->Template->has_shipping = false; $this->Template->billing_label = $GLOBALS['TL_LANG']['ISO']['billing_shipping_address']; } else { $this->Template->has_shipping = true; $this->Template->shipping_label = $GLOBALS['TL_LANG']['ISO']['shipping_address']; $this->Template->shipping_address = $this->Isotope->generateAddressString($arrShippingAddress, $this->Isotope->Config->shipping_fields); } } }
/** * Return the payment form. * * @access public * @return string */ public function checkoutForm() { $objOrder = new IsotopeOrder(); if (!$objOrder->findBy('cart_id', $this->Isotope->Cart->id)) { $this->redirect($this->addToUrl('step=failed', true)); } $arrAddress = $this->Isotope->Cart->billingAddress; $strFailedUrl = $this->Environment->base . $this->addToUrl('step=failed'); $arrParam = array('PSPID' => $this->postfinance_pspid, 'orderID' => $objOrder->id, 'amount' => round($this->Isotope->Cart->grandTotal * 100), 'currency' => $this->Isotope->Config->currency, 'language' => $GLOBALS['TL_LANGUAGE'] . '_' . strtoupper($GLOBALS['TL_LANGUAGE']), 'CN' => $arrAddress['firstname'] . ' ' . $arrAddress['lastname'], 'EMAIL' => $arrAddress['email'], 'ownerZIP' => $arrAddress['postal'], 'owneraddress' => $arrAddress['street_1'], 'owneraddress2' => $arrAddress['street_2'], 'ownercty' => $arrAddress['country'], 'ownertown' => $arrAddress['city'], 'ownertelno' => $arrAddress['phone'], 'accepturl' => $this->Environment->base . IsotopeFrontend::addQueryStringToUrl('uid=' . $objOrder->uniqid, $this->addToUrl('step=complete')), 'declineurl' => $strFailedUrl, 'exceptionurl' => $strFailedUrl, 'paramplus' => 'mod=pay&id=' . $this->id); // SHA-1 must be generated on alphabetically sorted keys. Cant use ksort because it does not ignore key case. uksort($arrParam, 'strcasecmp'); $strSHASign = ''; foreach ($arrParam as $k => $v) { if ($v == '') { continue; } $strSHASign .= strtoupper($k) . '=' . $v . $this->postfinance_secret; } $arrParam['SHASign'] = sha1($strSHASign); $objTemplate = new FrontendTemplate('iso_payment_postfinance'); $objTemplate->action = 'https://e-payment.postfinance.ch/ncol/' . ($this->debug ? 'test' : 'prod') . '/orderstandard.asp'; $objTemplate->params = $arrParam; $objTemplate->slabel = $GLOBALS['TL_LANG']['MSC']['pay_with_cc'][2]; $objTemplate->id = $this->id; return $objTemplate->parse(); }
/** * Generate module * @return void */ protected function compile() { // Order has been completed (postsale request) if ($this->strCurrentStep == 'complete' && $this->Input->get('uid') != '') { $objOrder = new IsotopeOrder(); if ($objOrder->findBy('uniqid', $this->Input->get('uid'))) { // Order is complete, forward to confirmation page if ($objOrder->complete()) { IsotopeFrontend::clearTimeout(); $this->redirect(IsotopeFrontend::addQueryStringToUrl('uid=' . $objOrder->uniqid, $this->orderCompleteJumpTo)); } // Order is not complete, wait for it if (IsotopeFrontend::setTimeout()) { $this->Template = new FrontendTemplate('mod_message'); $this->Template->type = 'processing'; $this->Template->message = $GLOBALS['TL_LANG']['MSC']['payment_processing']; return; } } } // Return error message if cart is empty if (!$this->Isotope->Cart->items) { $this->Template = new FrontendTemplate('mod_message'); $this->Template->type = 'empty'; $this->Template->message = $GLOBALS['TL_LANG']['MSC']['noItemsInCart']; return; } // Insufficient cart subtotal if ($this->Isotope->Config->cartMinSubtotal > 0 && $this->Isotope->Config->cartMinSubtotal > $this->Isotope->Cart->subTotal) { $this->Template = new FrontendTemplate('mod_message'); $this->Template->type = 'error'; $this->Template->message = sprintf($GLOBALS['TL_LANG']['ERR']['cartMinSubtotal'], $this->Isotope->formatPriceWithCurrency($this->Isotope->Config->cartMinSubtotal)); return; } // Redirect to login page if not logged in if ($this->iso_checkout_method == 'member' && FE_USER_LOGGED_IN !== true) { $objPage = $this->Database->prepare("SELECT id,alias FROM tl_page WHERE id=?")->limit(1)->execute($this->iso_login_jumpTo); if (!$objPage->numRows) { $this->Template = new FrontendTemplate('mod_message'); $this->Template->type = 'error'; $this->Template->message = $GLOBALS['TL_LANG']['ERR']['isoLoginRequired']; return; } $this->redirect($this->generateFrontendUrl($objPage->row())); } elseif ($this->iso_checkout_method == 'guest' && FE_USER_LOGGED_IN === true) { $this->Template = new FrontendTemplate('mod_message'); $this->Template->type = 'error'; $this->Template->message = 'User checkout not allowed'; return; } if (!$this->iso_forward_review && !strlen($this->Input->get('step'))) { $this->redirectToNextStep(); } // Default template settings. Must be set at beginning so they can be overwritten later (eg. trough callback) $this->Template->action = ampersand($this->Environment->request, ENCODE_AMPERSANDS); $this->Template->formId = $this->strFormId; $this->Template->formSubmit = $this->strFormId; $this->Template->enctype = 'application/x-www-form-urlencoded'; $this->Template->previousLabel = specialchars($GLOBALS['TL_LANG']['MSC']['previousStep']); $this->Template->nextLabel = specialchars($GLOBALS['TL_LANG']['MSC']['nextStep']); $this->Template->nextClass = 'next'; $this->Template->showPrevious = true; $this->Template->showNext = true; $this->Template->showForm = true; // Remove shipping step if no items are shipped if (!$this->Isotope->Cart->requiresShipping) { unset($GLOBALS['ISO_CHECKOUT_STEPS']['shipping']); // Remove payment step if items are free of charge. We need to do this here because shipping might have a price. if (!$this->Isotope->Cart->requiresPayment) { unset($GLOBALS['ISO_CHECKOUT_STEPS']['payment']); } } if ($this->strCurrentStep == 'failed') { $this->Database->prepare("UPDATE tl_iso_orders SET status='on_hold' WHERE cart_id=?")->execute($this->Isotope->Cart->id); $this->Template->mtype = 'error'; $this->Template->message = strlen($this->Input->get('reason')) ? $this->Input->get('reason') : $GLOBALS['TL_LANG']['ERR']['orderFailed']; $this->strCurrentStep = 'review'; } // Run trough all steps until we find the current one or one reports failure foreach ($GLOBALS['ISO_CHECKOUT_STEPS'] as $step => $arrCallbacks) { // Step could be removed while looping if (!isset($GLOBALS['ISO_CHECKOUT_STEPS'][$step])) { continue; } $this->strFormId = 'iso_mod_checkout_' . $step; $this->Template->formId = $this->strFormId; $this->Template->formSubmit = $this->strFormId; $strBuffer = ''; foreach ($arrCallbacks as $callback) { if ($callback[0] == 'ModuleIsotopeCheckout') { $strBuffer .= $this->{$callback[1]}(); } else { $this->import($callback[0]); $strBuffer .= $this->{$callback[0]}->{$callback[1]}($this); } // the user wanted to proceed but the current step is not completed yet if ($this->doNotSubmit && $step != $this->strCurrentStep) { $this->redirect($this->addToUrl('step=' . $step, true)); } } if ($step == $this->strCurrentStep) { break; } } if ($this->strCurrentStep == 'process') { $this->writeOrder(); $strBuffer = $this->Isotope->Cart->hasPayment ? $this->Isotope->Cart->Payment->checkoutForm($this) : false; if ($strBuffer === false) { $this->redirect($this->addToUrl('step=complete', true)); } $this->Template->showForm = false; $this->doNotSubmit = true; } if ($this->strCurrentStep == 'complete') { $strBuffer = $this->Isotope->Cart->hasPayment ? $this->Isotope->Cart->Payment->processPayment() : true; if ($strBuffer === true) { $objOrder = new IsotopeOrder(); // If checkout is successful, complete order and redirect to confirmation page if ($objOrder->findBy('cart_id', $this->Isotope->Cart->id) && $objOrder->checkout($this->Isotope->Cart) && $objOrder->complete()) { $this->redirect(IsotopeFrontend::addQueryStringToUrl('uid=' . $objOrder->uniqid, $this->orderCompleteJumpTo)); } // Checkout failed, show error message $this->redirect($this->addToUrl('step=failed', true)); } elseif ($strBuffer === false) { $this->redirect($this->addToUrl('step=failed', true)); } else { $this->Template->showNext = false; $this->Template->showPrevious = false; } } $this->Template->fields = $strBuffer; if (!strlen($this->strCurrentStep)) { $this->strCurrentStep = $step; } // Show checkout steps $arrStepKeys = array_keys($GLOBALS['ISO_CHECKOUT_STEPS']); $blnPassed = true; $total = count($arrStepKeys) - 1; $arrSteps = array(); if ($this->strCurrentStep != 'process' && $this->strCurrentStep != 'complete') { foreach ($arrStepKeys as $i => $step) { if ($this->strCurrentStep == $step) { $blnPassed = false; } $blnActive = $this->strCurrentStep == $step ? true : false; $arrSteps[] = array('isActive' => $blnActive, 'class' => 'step_' . $i . ($i == 0 ? ' first' : '') . ($i == $total ? ' last' : '') . ($blnActive ? ' active' : '') . ($blnPassed ? ' passed' : '') . (!$blnPassed && !$blnActive ? ' upcoming' : '') . ' ' . $step, 'label' => strlen($GLOBALS['TL_LANG']['ISO']['checkout_' . $step]) ? $GLOBALS['TL_LANG']['ISO']['checkout_' . $step] : $step, 'href' => $blnPassed ? $this->addToUrl('step=' . $step, true) : '', 'title' => specialchars(sprintf($GLOBALS['TL_LANG']['MSC']['checkboutStepBack'], strlen($GLOBALS['TL_LANG']['ISO']['checkout_' . $step]) ? $GLOBALS['TL_LANG']['ISO']['checkout_' . $step] : $step))); } } $this->Template->steps = $arrSteps; $this->Template->activeStep = $GLOBALS['ISO_LANG']['MSC']['activeStep']; // Hide back buttons it this is the first step if (array_search($this->strCurrentStep, $arrStepKeys) === 0) { $this->Template->showPrevious = false; } elseif (array_search($this->strCurrentStep, $arrStepKeys) === $total) { $this->Template->nextClass = 'confirm'; $this->Template->nextLabel = specialchars($GLOBALS['TL_LANG']['MSC']['confirmOrder']); } // User pressed "back" button if (strlen($this->Input->post('previousStep'))) { $this->redirectToPreviousStep(); } elseif ($this->Input->post('FORM_SUBMIT') == $this->strFormId && !$this->doNotSubmit) { $this->redirectToNextStep(); } }