public function Process3DCallBack() { $orderStatus=$this->_Handle3DCallBackResponse(); if($orderStatus) { if(CompletePendingOrder($_COOKIE['SHOP_ORDER_TOKEN'], $orderStatus)) { // Everything is fine, send the customer to the thank you page. @ob_end_clean(); //header("Location: ".$GLOBALS['ShopPathSSL']."/finishorder.php"); //it needs to redirect the parent window for PayPal website payments pro, because 3D secure authoriation form is loaded in an iframe on the page echo "<script>top.location.href='".$GLOBALS['ShopPathSSL']."/finishorder.php';</script>"; die(); } } }
/** * Create a new order in ISC based on a new-order-notification from google * * @return void **/ private function CreateOrder() { $this->LoadCart($this->module->cartid); $pendingOrder = $this->CalculateOrder(); $cartItems = $GLOBALS['ISC_CLASS_CART']->api->GetProductsInCart(); $checkoutSession = $_SESSION['CHECKOUT']; $pendingData = $checkoutSession['PENDING_DATA']; // Get a list of the vendors for all of the items in the cart, and loop through them // to build all of the pending orders $cartContent = $GLOBALS['ISC_CLASS_CHECKOUT']->BreakdownCartByAddressVendorforshipping(); //Changed to merging function by Simha $vendorOrderInfo = array(); foreach ($cartContent as $vendorId => $addresses) { foreach ($addresses as $addressId => $products) { $allDigital = 1; $productArray = array(); foreach ($products as $cartItemId => $product) { // A physical product, mark as so if ($product['data']['prodtype'] == PT_PHYSICAL) { $allDigital = 0; } // Mark the quantity of this item $productArray[$cartItemId] = $product['quantity']; } $vendorInfo = $pendingData['VENDORS'][$vendorId . '_' . $addressId]; $vendorData = array('itemtotal' => $vendorInfo['ITEM_TOTAL'], 'taxcost' => $vendorInfo['TAX_COST'], 'totalcost' => $vendorInfo['ORDER_TOTAL'], 'shippingcost' => $_SESSION['CHECKOUT']['SHIPPING'][$vendorId . '_0']['COST'], 'handlingcost' => $_SESSION['CHECKOUT']['SHIPPING'][$vendorId . '_0']['HANDLING'], 'shippingprovider' => $_SESSION['CHECKOUT']['SHIPPING'][$vendorId . '_0']['PROVIDER'], 'shippingmodule' => $_SESSION['CHECKOUT']['SHIPPING'][$vendorId . '_0']['MODULE'], 'isdigitalorder' => $allDigital, 'products' => $productArray); // Shipping zones can be configured per vendor, so we need to be sure // to pass this along correctly too if (isset($vendorInfo['SHIPPING_ZONE'])) { $shippingZone = GetShippingZoneById($vendorInfo['SHIPPING_ZONE']); if (is_array($shippingZone)) { $vendorData['ordshippingzoneid'] = $shippingZone['zoneid']; $vendorData['ordshippingzone'] = $shippingZone['zonename']; } } $vendorOrderInfo[$vendorId . '_' . $addressId] = $vendorData; } } $this->module->DebugLog($vendorData); // Work out the cost of the order, shipping etc $pendingOrder['ipaddress'] = ''; $pendingOrder['vendorinfo'] = $vendorOrderInfo; $pendingToken = CreateOrder($pendingOrder, $cartItems); if ($pendingToken === false) { $GLOBALS['ISC_CLASS_LOG']->LogSystemError($this->logtype, sprint(GetLang('GoogleCheckoutMissingCart'), isc_html_escape($this->module->cartid))); return; } $order = LoadPendingOrderByToken($pendingToken); $googleid = $this->response->data['new-order-notification']['google-order-number']['VALUE']; $this->SendGoogleNewOrderId($googleid, $order['orderid']); $updatedOrder = array('ordpayproviderid' => $googleid, 'ordpaymentstatus' => 'captured'); $this->module->DebugLog($order); $orderIds = array($order['orderid']); // Update the orders in the database $GLOBALS['ISC_CLASS_DB']->UpdateQuery('orders', $updatedOrder, "orderid IN (" . implode(',', $orderIds) . ")"); $completed = CompletePendingOrder($pendingToken, ORDER_STATUS_PENDING, false); if ($this->response->data['new-order-notification']['buyer-marketing-preferences']['email-allowed']['VALUE'] == 'true') { $this->SubscribeCustomerToLists($order['orderid']); } if (!$completed) { $GLOBALS['ISC_CLASS_LOG']->LogSystemError($this->logtype, sprintf(GetLang('GoogleCheckoutCantCompleteOrder'), isc_html_escape($pendingToken), isc_html_escape(var_export($completed, true)))); return; } $orderClass = GetClass('ISC_ORDER'); $orderClass->EmptyCartAndKillCheckout(); $GLOBALS['ISC_CLASS_LOG']->LogSystemSuccess($this->logtype, sprintf(GetLang('GoogleCheckoutOrderCreated'), (int) $order['orderid'], isc_html_escape($googleid))); }
/** * Update the status of an order. * * @param mixed Either an array of order IDs to update, or an integer for a single order ID. * @param int The new status of the order. * @param boolean Should emails be sent out if the email on status change feature is enabled? * @param boolean Set to true if this status update is in a pingback from a payment module and payment modules should not be notified of the change. * @return boolean True if successful. */ function UpdateOrderStatus($orderIds, $status, $email=true, $preventModuleUpdateCallback=false) { if(!is_array($orderIds)) { $orderIds = array($orderIds); } foreach($orderIds as $orderId) { $order = GetOrder($orderId, false); if (!$order || !$order['orderid']) { return false; } // Start transaction $GLOBALS['ISC_CLASS_DB']->Query("START TRANSACTION"); $existing_status = $order['ordstatus']; // If the order is incomplete, it needs to be completed first if($existing_status == 0) { CompletePendingOrder($order['ordtoken'], $status, $email); } $updatedOrder = array( "ordstatus" => (int)$status, "ordlastmodified" => time(), ); // If the order status is 2 or 10 (completed, shipped) then set the orddateshipped timestamp if (OrderIsComplete($status)) { $updatedOrder['orddateshipped'] = time(); } // Update the status for this order if ($GLOBALS['ISC_CLASS_DB']->UpdateQuery("orders", $updatedOrder, "orderid=" . (int)$orderId)) { // Fetch the name of the status this order was changed to $query = sprintf("SELECT statusdesc FROM [|PREFIX|]order_status WHERE statusid='%d'", $GLOBALS['ISC_CLASS_DB']->Quote($status)); $result2 = $GLOBALS['ISC_CLASS_DB']->Query($query); $statusName = $GLOBALS['ISC_CLASS_DB']->FetchOne($result2); // Log this action if we are in the control panel if (defined('ISC_ADMIN_CP')) { $GLOBALS['ISC_CLASS_LOG']->LogAdminAction($orderId, $statusName); } // This order was marked as refunded or cancelled if ($status == ORDER_STATUS_REFUNDED || $status == ORDER_STATUS_CANCELLED) { // If the inventory levels for products in this order have previously been changed, we need to // return the inventory too if ($order['ordinventoryupdated'] == 1) { UpdateInventoryOnReturn($orderId); } // Marked as refunded or cancelled, need to cancel the gift certificates in this order too if there are any $updatedCertificates = array( "giftcertstatus" => 3 ); $GLOBALS['ISC_CLASS_DB']->UpdateQuery("gift_certificates", $updatedCertificates, "giftcertorderid='" . $GLOBALS['ISC_CLASS_DB']->Quote($orderId) . "'"); } // This order was marked as completed/shipped as long as the inventory hasn't been adjusted previously else if (OrderIsComplete($status)) { if ($order['ordinventoryupdated'] == 0) { DecreaseInventoryFromOrder($orderId); } // Send out gift certificates if the order wasn't already complete if (!OrderIsComplete($existing_status)) { $GLOBALS['ISC_CLASS_GIFT_CERTIFICATES'] = GetClass('ISC_GIFTCERTIFICATES'); $GLOBALS['ISC_CLASS_GIFT_CERTIFICATES']->ActivateGiftCertificates($orderId); } } } // Was there an error? If not, commit if ($GLOBALS['ISC_CLASS_DB']->Error() == "") { $GLOBALS['ISC_CLASS_DB']->Query("COMMIT"); // Does the customer now need to be notified for this status change? $statuses = explode(",", GetConfig('OrderStatusNotifications')); if (in_array($status, $statuses) && $email == true) { foreach($orderIds as $orderId) { EmailOnStatusChange($orderId, $status); } } // If the checkout module that was used for an order is still enabled and has a function // to handle a status change, then call that function if($preventModuleUpdateCallback == false) { $valid_checkout_modules = GetAvailableModules('checkout', true, true); $valid_checkout_module_ids = array(); foreach ($valid_checkout_modules as $valid_module) { $valid_checkout_module_ids[] = $valid_module['id']; } foreach($orderIds as $orderId) { $order = GetOrder($orderId, false); if (in_array($order['orderpaymentmodule'], $valid_checkout_module_ids)) { GetModuleById('checkout', $checkout_module, $order['orderpaymentmodule']); if (method_exists($checkout_module, 'HandleStatusChange')) { call_user_func(array($checkout_module, 'HandleStatusChange'), $orderId, $existing_status, $status, 0); } } } } return true; } else { return false; } } return false; }
/** * Create a new order in ISC based on a new-order-notification from google * * @return void **/ private function CreateOrder() { if(!$this->LoadCart($this->module->cartid)) { // Todo: What is the correct way to fail here? return; } // Ensure split shipping is disabled $this->quote->setIsSplitShipping(false); // Set the billing address for the order $billingAddress = $this->GetAddressFromResponse($this->response->data[$this->response->root]['buyer-billing-address']); $this->quote->getBillingAddress() ->setAddressByArray($billingAddress); if(!$this->quote->isDigital()) { // Set the shipping address for the order $shippingAddress = $this->GetAddressFromResponse($this->response->data[$this->response->root]['buyer-shipping-address']); $this->quote->getShippingAddress() ->setAddressByArray($shippingAddress); // Attempt to find shipping costs in the response from Google if (isset($this->response->data[$this->response->root]['order-adjustment']['shipping']['merchant-calculated-shipping-adjustment'])) { $shipping = $this->response->data[$this->response->root]['order-adjustment']['shipping']['merchant-calculated-shipping-adjustment']; } else { $shipping = array ( 'shipping-cost' => array ( 'VALUE' => 0 ), 'shipping-name' => array ( 'VALUE' => '' ), ); } $this->quote->getShippingAddress() ->setShippingMethod( $shipping['shipping-cost']['VALUE'], $shipping['shipping-name']['VALUE'], $this->getShippingProviderModuleByName($shipping['shipping-name']['VALUE']) ); } $this->handleNewOrderNotificationCouponAdjustment(); $this->handleNewOrderNotificationGiftCertificateAdjustment(); $selectedCurrency = getCurrencyById($GLOBALS['CurrentCurrency']); $newOrder = array( 'orderpaymentmodule' => 'checkout_googlecheckout', 'ordcurrencyid' => $selectedCurrency['currencyid'], 'ordcurrencyexchangerate' => $selectedCurrency['currencyexchangerate'], 'ordipaddress' => '', 'extraInfo' => array(), 'quote' => $this->quote, ); $entity = new ISC_ENTITY_ORDER(); $orderId = $entity->add($newOrder); // Failed to create the order if(!$orderId) { $GLOBALS['ISC_CLASS_LOG']->LogSystemError($this->logtype, sprintf(GetLang('GoogleCheckoutMissingCart'), isc_html_escape($this->module->cartid))); return; } $order = getOrder($orderId); $googleid = $this->response->data['new-order-notification']['google-order-number']['VALUE']; $this->SendGoogleNewOrderId($googleid, $order['orderid']); $updatedOrder = array( 'ordpayproviderid' => $googleid, ); $orderIds = array($order['orderid']); // Update the orders in the database $GLOBALS['ISC_CLASS_DB']->UpdateQuery('orders', $updatedOrder, "orderid IN (".implode(',', $orderIds).")"); $completed = CompletePendingOrder($order['ordtoken'], ORDER_STATUS_PENDING, false); if ($this->response->data['new-order-notification']['buyer-marketing-preferences']['email-allowed']['VALUE'] == 'true') { $this->SubscribeCustomerToLists($order['orderid']); } if (!$completed) { $GLOBALS['ISC_CLASS_LOG']->LogSystemError($this->logtype, sprintf(GetLang('GoogleCheckoutCantCompleteOrder'), isc_html_escape($pendingToken), isc_html_escape(var_export($completed, true)))); return; } EmptyCartAndKillCheckout(); $GLOBALS['ISC_CLASS_LOG']->LogSystemSuccess($this->logtype, sprintf(GetLang('GoogleCheckoutOrderCreated'), (int) $order['orderid'], isc_html_escape($googleid))); }
/** * Process details for a particular payment gateway inline. */ private function ProcessOrderPayment() { // ensure products are in stock $this->CheckStockLevels(); $order_token = ""; if(isset($_COOKIE['SHOP_ORDER_TOKEN'])) { $order_token = $_COOKIE['SHOP_ORDER_TOKEN']; } // If the order token is empty then something has gone wrong. if($order_token == '') { @ob_end_clean(); header("Location: ".$GLOBALS['ShopPathSSL']."/checkout.php?action=confirm_order"); die(); } // Load the pending order $orders = LoadPendingOrdersByToken($order_token); if(!is_array($orders)) { @ob_end_clean(); header("Location: ".$GLOBALS['ShopPathSSL']."/checkout.php?action=confirm_order"); die(); } if ($orders['status'] != ORDER_STATUS_INCOMPLETE) { // has this order already been completed? redirect to finish order @ob_end_clean(); header("Location: ".$GLOBALS['ShopPathSSL']."/finishorder.php"); die(); } // Get the payment module if(!GetModuleById('checkout', $provider, $orders['paymentmodule'])) { @ob_end_clean(); header("Location: ".$GLOBALS['ShopPathSSL']."/checkout.php?action=confirm_order"); die(); } $provider->SetOrderData($orders); if(isset($_SESSION['CHECKOUT']['ProviderListHTML']) && method_exists($provider, 'DoExpressCheckoutPayment')) { $provider->DoExpressCheckoutPayment(); die(); } // Does this method have it's own processing method? if(method_exists($provider, "ProcessPaymentForm")) { $result = $provider->ProcessPaymentForm(); if($result) { $paymentStatus = $provider->GetPaymentStatus(); $orderStatus = GetOrderStatusFromPaymentStatus($paymentStatus); if(CompletePendingOrder($order_token, $orderStatus)) { // Everything is fine, send the customer to the thank you page. redirect(getConfig('ShopPathSSL').'/finishorder.php'); } } // Otherwise there was an error $this->ShowPaymentForm($provider); } // If we're still here then something from the above has gone wrong. Show the confirm page again redirect(getConfig('ShopPathSSL').'/checkout.php?action=confirm_order'); }
/** * Complete the order after the customer is brought back from the payment provider */ public function FinishOrder() { // Orders are still incomplete, so we need to validate them if($this->pendingData['status'] == ORDER_STATUS_INCOMPLETE) { // Verify the pending order $newStatus = VerifyPendingOrder($this->orderToken); // Order was declined and we're rejecting all declined payments if($newStatus == ORDER_STATUS_DECLINED) { $Msg = sprintf(GetLang('ErroOrderDeclined'), GetConfig('OrderEmail'), GetConfig('OrderEmail')); $this->BadOrder(GetLang('YourPaymentWasDeclined'), $Msg); } // This order is valid elseif($newStatus !== false) { $prodOrdered = array(); $items = getCustomerQuote()->getItems(); foreach($items as $item) { $productId = $item->getProductId(); if($productId > 0) { $prodOrdered[] = $productId; } $_SESSION['ProductJustOrdered'] = implode(',',$prodOrdered); } if(CompletePendingOrder($this->orderToken, $newStatus)) { // Order was saved. Show the confirmation screen and email an invoice to the customer $this->ThanksForYourOrder(); return; } } // If we're still here, either the order didnt complete or the order was invalid $this->BadOrder(); } // Order is already complete - there's a good chance the customer has refreshed the page, // or they've come back from somewhere like PayPal who in the mean time has already sent // us a ping back to validate and begin processing the order - show the thank you page else if($this->pendingData['status'] == ORDER_STATUS_DECLINED) { $Msg = sprintf(GetLang('ErroOrderDeclined'), GetConfig('OrderEmail'), GetConfig('OrderEmail')); $this->BadOrder(GetLang('YourPaymentWasDeclined'), $Msg); } else { $this->ThanksForYourOrder(); return; } }
/** * Complete the order after the customer is brought back from the payment provider */ public function FinishOrder() { $queries = array(); // Orders are still incomplete, so we need to validate them if ($this->pendingData['status'] == 0) { // Verify the pending order $newStatus = VerifyPendingOrder($this->orderToken); // This order is not valid if ($newStatus !== false) { if (CompletePendingOrder($this->orderToken, $newStatus)) { /* $cdate = strtotime(date('Y-m-d')); $edate = strtotime('2010-12-15'); if($cdate <= $edate) {*/ # This condition should be checked dynamically, For static its hardcoded -- Baskaran $this->AddSweepstakes($this->orderToken); // } // Order was saved. Show the confirmation screen and email an invoice to the customer $this->ThanksForYourOrder(); return; } } // If we're still here, something bad has happened to the order // Order was declined and we're rejecting all declined payments if ($newStatus == ORDER_STATUS_DECLINED) { $Msg = sprintf(GetLang('ErroOrderDeclined'), GetConfig('OrderEmail'), GetConfig('OrderEmail')); $this->BadOrder(GetLang('YourPaymentWasDeclined'), $Msg); } else { $this->BadOrder(); } } else { if ($this->pendingData['status'] == ORDER_STATUS_DECLINED) { $Msg = sprintf(GetLang('ErroOrderDeclined'), GetConfig('OrderEmail'), GetConfig('OrderEmail')); $this->BadOrder(GetLang('YourPaymentWasDeclined'), $Msg); } else { $this->ThanksForYourOrder(); return; } } }