/** * checkout() * Handles checkout process */ function checkout($wp) { $pages = $this->Settings->get('pages'); // If checkout page requested // Note: we have to use custom detection here as // the wp->post vars are not available at this point // to make use of is_shopp_page() if ((SHOPP_PERMALINKS && isset($wp->query_vars['pagename']) && $wp->query_vars['pagename'] == $pages['checkout']['permalink'] || isset($wp->query_vars['page_id']) && $wp->query_vars['page_id'] == $pages['checkout']['id']) && $wp->query_vars['shopp_proc'] == "checkout") { $this->Cart->updated(); $this->Cart->totals(); if ($this->Cart->data->ShippingPostcodeError) { header('Location: ' . $this->link('cart')); exit; } // Force secure checkout page if its not already $secure = true; $gateway = $this->Settings->get('payment_gateway'); if (strpos($gateway, "TestMode") !== false || isset($wp->query_vars['shopp_xco']) || $this->Cart->orderisfree()) { $secure = false; } if ($secure && !$this->secure && !SHOPP_NOSSL) { header('Location: ' . $this->link('checkout', $secure)); exit; } } // Cancel this process if there is no order data if (!isset($this->Cart->data->Order)) { return; } $Order = $this->Cart->data->Order; // Intercept external checkout processing if (!empty($wp->query_vars['shopp_xco'])) { if ($this->gateway($wp->query_vars['shopp_xco'])) { if ($wp->query_vars['shopp_proc'] != "confirm-order" && !isset($_POST['checkout'])) { $this->Gateway->checkout(); $this->Gateway->error(); } } } // Cancel if no checkout process detected if (empty($_POST['checkout'])) { return true; } // Handoff to order processing if ($_POST['checkout'] == "confirmed") { return $this->Flow->order(); } // Cancel if checkout process is not ready for processing if ($_POST['checkout'] != "process") { return true; } // Cancel if processing a login from the checkout form if (isset($_POST['process-login']) && $_POST['process-login'] == "true") { return true; } // Start processing the checkout form $_POST = attribute_escape_deep($_POST); $_POST['billing']['cardexpires'] = sprintf("%02d%02d", $_POST['billing']['cardexpires-mm'], $_POST['billing']['cardexpires-yy']); // If the card number is provided over a secure connection // Change the cart to operate in secure mode if (isset($_POST['billing']['card']) && is_shopp_secure()) { $this->Cart->secured(true); } // Sanitize the card number to ensure it only contains numbers $_POST['billing']['card'] = preg_replace('/[^\\d]/', '', $_POST['billing']['card']); if (isset($_POST['data'])) { $Order->data = stripslashes_deep($_POST['data']); } if (empty($Order->Customer)) { $Order->Customer = new Customer(); } $Order->Customer->updates($_POST); if (isset($_POST['confirm-password'])) { $Order->Customer->confirm_password = $_POST['confirm-password']; } if (empty($Order->Billing)) { $Order->Billing = new Billing(); } $Order->Billing->updates($_POST['billing']); if (!empty($_POST['billing']['cardexpires-mm']) && !empty($_POST['billing']['cardexpires-yy'])) { $Order->Billing->cardexpires = mktime(0, 0, 0, $_POST['billing']['cardexpires-mm'], 1, $_POST['billing']['cardexpires-yy'] + 2000); } else { $Order->Billing->cardexpires = 0; } $Order->Billing->cvv = preg_replace('/[^\\d]/', '', $_POST['billing']['cvv']); if (empty($Order->Shipping)) { $Order->Shipping = new Shipping(); } if (isset($_POST['shipping'])) { $Order->Shipping->updates($_POST['shipping']); } if (!empty($_POST['shipmethod'])) { $Order->Shipping->method = $_POST['shipmethod']; } else { $Order->Shipping->method = key($this->Cart->data->ShipCosts); } // Override posted shipping updates with billing address if ($_POST['sameshipaddress'] == "on") { $Order->Shipping->updates($Order->Billing, array("_datatypes", "_table", "_key", "_lists", "id", "created", "modified")); } $estimatedTotal = $this->Cart->data->Totals->total; $this->Cart->updated(); $this->Cart->totals(); if ($this->Cart->validate() !== true) { return; } else { $Order->Customer->updates($_POST); } // Catch changes from validation // If the cart's total changes at all, confirm the order if ($estimatedTotal != $this->Cart->data->Totals->total || $this->Settings->get('order_confirmation') == "always") { $gateway = $this->Settings->get('payment_gateway'); $secure = true; if (strpos($gateway, "TestMode") !== false || isset($wp->query_vars['shopp_xco']) || $this->Cart->orderisfree()) { $secure = false; } shopp_redirect($this->link('confirm-order', $secure)); } else { $this->Flow->order(); } }
/** * order() * Processes orders by passing transaction information to the active * payment gateway */ function order($gateway = false) { global $Shopp; $Cart = $Shopp->Cart; $db = DB::get(); do_action('shopp_order_preprocessing'); $Order = $Shopp->Cart->data->Order; $Order->Totals = $Shopp->Cart->data->Totals; $Order->Items = $Shopp->Cart->contents; $Order->Cart = $Shopp->Cart->session; if ($Shopp->Gateway && !$Cart->orderisfree()) { // Use an external checkout payment gateway if (SHOPP_DEBUG) { new ShoppError('Processing order through a remote-payment gateway service.', false, SHOPP_DEBUG_ERR); } $Purchase = $Shopp->Gateway->process(); if (!$Purchase) { if (SHOPP_DEBUG) { new ShoppError('The remote-payment gateway encountered an error.', false, SHOPP_DEBUG_ERR); } $Shopp->Gateway->error(); return false; } if (SHOPP_DEBUG) { new ShoppError('Transaction successfully processed by remote-payment gateway service.', false, SHOPP_DEBUG_ERR); } } else { // Use local payment gateway set in payment settings $gateway = $Shopp->Settings->get('payment_gateway'); // Process a transaction if the order has a cost (is not free) if (!$Cart->orderisfree()) { if (!$Shopp->gateway($gateway)) { return false; } // Process the transaction through the payment gateway if (SHOPP_DEBUG) { new ShoppError('Processing order through local-payment gateway service.', false, SHOPP_DEBUG_ERR); } $processed = $Shopp->Gateway->process(); // exit(); // There was a problem processing the transaction, // grab the error response from the gateway so we can report it if (!$processed) { if (SHOPP_DEBUG) { new ShoppError('The local-payment gateway encountered an error.', false, SHOPP_DEBUG_ERR); } $Shopp->Gateway->error(); return false; } $gatewaymeta = $this->scan_gateway_meta(SHOPP_GATEWAYS . $gateway); $gatewayname = $gatewaymeta->name; $transactionid = $Shopp->Gateway->transactionid(); if (SHOPP_DEBUG) { new ShoppError('Transaction ' . $transactionid . ' successfully processed by local-payment gateway service ' . $gatewayname . '.', false, SHOPP_DEBUG_ERR); } } else { if (!$Cart->validorder()) { new ShoppError(__('There is not enough customer information to process the order.', 'Shopp'), 'invalid_order', SHOPP_TRXN_ERR); return false; } $gatewayname = __('N/A', 'Shopp'); $transactionid = __('(Free Order)', 'Shopp'); } $authentication = $Shopp->Settings->get('account_system'); // Transaction successful, save the order if ($authentication == "wordpress") { // Check if they've logged in // If the shopper is already logged-in, save their updated customer info if ($Shopp->Cart->data->login) { if (SHOPP_DEBUG) { new ShoppError('Customer logged in, linking Shopp customer account to existing WordPress account.', false, SHOPP_DEBUG_ERR); } get_currentuserinfo(); global $user_ID; $Order->Customer->wpuser = $user_ID; } // Create WordPress account (if necessary) if (!$Order->Customer->wpuser) { if (SHOPP_DEBUG) { new ShoppError('Creating a new WordPress account for this customer.', false, SHOPP_DEBUG_ERR); } if (!$Order->Customer->new_wpuser()) { new ShoppError(__('Account creation failed on order for customer id:' . $Order->Customer->id, "Shopp"), false, SHOPP_TRXN_ERR); } } } // Create a WP-compatible password hash to go in the db if (empty($Order->Customer->id)) { $Order->Customer->password = wp_hash_password($Order->Customer->password); } $Order->Customer->save(); $Order->Billing->customer = $Order->Customer->id; $Order->Billing->card = substr($Order->Billing->card, -4); $Order->Billing->save(); // Card data is truncated, switch the cart to normal mode if ($Shopp->Cart->secured() && is_shopp_secure()) { $Shopp->Cart->secured(false); } if (!empty($Order->Shipping->address)) { $Order->Shipping->customer = $Order->Customer->id; $Order->Shipping->save(); } $Promos = array(); foreach ($Shopp->Cart->data->PromosApplied as $promo) { $Promos[$promo->id] = $promo->name; } if ($Shopp->Cart->orderisfree()) { $orderisfree = true; } else { $orderisfree = false; } $Purchase = new Purchase(); $Purchase->customer = $Order->Customer->id; $Purchase->billing = $Order->Billing->id; $Purchase->shipping = $Order->Shipping->id; $Purchase->copydata($Order->Customer); $Purchase->copydata($Order->Billing); $Purchase->copydata($Order->Shipping, 'ship'); $Purchase->copydata($Shopp->Cart->data->Totals); $Purchase->data = $Order->data; $Purchase->promos = $Promos; $Purchase->freight = $Shopp->Cart->data->Totals->shipping; $Purchase->gateway = $gatewayname; $Purchase->transactionid = $transactionid; $Purchase->transtatus = "CHARGED"; $Purchase->ip = $Shopp->Cart->ip; $Purchase->save(); // echo "<pre>"; print_r($Purchase); echo "</pre>"; foreach ($Shopp->Cart->contents as $Item) { $Purchased = new Purchased(); $Purchased->copydata($Item); $Purchased->purchase = $Purchase->id; if (!empty($Purchased->download)) { $Purchased->keygen(); } $Purchased->save(); if ($Item->inventory) { $Item->unstock(); } } if (SHOPP_DEBUG) { new ShoppError('Purchase ' . $Purchase->id . ' was successfully saved to the database.', false, SHOPP_DEBUG_ERR); } } // Skip post order if no Purchase ID exists if (empty($Purchase->id)) { return true; } // Empty cart on successful order $Shopp->Cart->unload(); session_destroy(); // Start new cart session $Shopp->Cart = new Cart(); session_start(); // Keep the user logged in or log them in if they are a new customer if ($Shopp->Cart->data->login || $authentication != "none") { $Shopp->Cart->loggedin($Order->Customer); } // Save the purchase ID for later lookup $Shopp->Cart->data->Purchase = new Purchase($Purchase->id); $Shopp->Cart->data->Purchase->load_purchased(); // // $Shopp->Cart->save(); // Allow other WordPress plugins access to Purchase data to extend // what Shopp does after a successful transaction do_action_ref_array('shopp_order_success', array(&$Shopp->Cart->data->Purchase)); // Send email notifications // notification(addressee name, email, subject, email template, receipt template) $Purchase->notification("{$Purchase->firstname} {$Purchase->lastname}", $Purchase->email, __('Order Receipt', 'Shopp')); if ($Shopp->Settings->get('receipt_copy') == 1) { $Purchase->notification('', $Shopp->Settings->get('merchant_email'), __('New Order', 'Shopp')); } $ssl = true; // Test Mode will not require encrypted checkout if (strpos($gateway, "TestMode.php") !== false || isset($_GET['shopp_xco']) || $orderisfree || SHOPP_NOSSL) { $ssl = false; } shopp_redirect($Shopp->link('receipt', $ssl)); }
/** * securekey() * Generate the security key */ function securekey() { global $Shopp; require_once ABSPATH . WPINC . '/pluggable.php'; if (!is_shopp_secure()) { return false; } $expiration = time() + SHOPP_SESSION_TIMEOUT; if (defined('SECRET_AUTH_KEY') && SECRET_AUTH_KEY != '') { $key = SECRET_AUTH_KEY; } else { $key = md5(serialize($this->data) . time()); } $content = hash_hmac('sha256', $this->session . '|' . $expiration, $key); if (version_compare(phpversion(), '5.2.0', 'ge')) { setcookie(SHOPP_SECURE_KEY, $content, 0, '/', '', true, true); } else { setcookie(SHOPP_SECURE_KEY, $content, 0, '/', '', true); } return $content; }