function checkout()
 {
     global $Shopp;
     if ($Shopp->Cart->data->Totals->total == 0) {
         shopp_redirect($Shopp->link('checkout'));
     }
     $this->transaction = $this->buildCheckoutRequest($Shopp->Cart);
     $Response = $this->send($this->urls['checkout']);
     if (!empty($Response)) {
         if ($Response->getElement('error')) {
             return $this->error();
         }
         $redirect = false;
         $redirect = $Response->getElementContent('redirect-url');
         if ($redirect) {
             // Empty cart on successful sending the order to Google
             $Shopp->Cart->unload();
             session_destroy();
             // Start new cart session, just in case they come back for more
             $Shopp->Cart = new Cart();
             session_start();
             shopp_redirect($redirect);
         }
     }
     return false;
 }
 /**
  * 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));
 }
 function checkout()
 {
     global $Shopp;
     if (empty($_POST['checkout'])) {
         return false;
     }
     // Save checkout data
     $Order = $Shopp->Cart->data->Order;
     if (isset($_POST['data'])) {
         $Order->data = $_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($Order->Shipping)) {
         $Order->Shipping = new Shipping();
     }
     if ($_POST['shipping']) {
         $Order->Shipping->updates($_POST['shipping']);
     }
     if (!empty($_POST['shipmethod'])) {
         $Order->Shipping->method = $_POST['shipmethod'];
     } else {
         $Order->Shipping->method = key($Shopp->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 = $Shopp->Cart->data->Totals->total;
     $Shopp->Cart->updated();
     $Shopp->Cart->totals();
     if ($Shopp->Cart->validate() !== true) {
         $_POST['checkout'] = false;
         return;
     } else {
         $Order->Customer->updates($_POST);
     }
     // Catch changes from validation
     if ($Shopp->Cart->orderisfree()) {
         return $_POST['checkout'] = 'confirmed';
     }
     shopp_redirect(add_query_arg('shopp_xco', '2Checkout/2Checkout', $Shopp->link('confirm-order', false)));
 }
 /**
  * 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();
     }
 }
 function process()
 {
     global $Shopp;
     $Shopping =& $Shopp->Shopping;
     $Order =& $Shopp->Order;
     require_once SHOPP_ADDONS . '/BillmateCore/BillMate.php';
     include_once SHOPP_ADDONS . "/BillmateCore/lib/xmlrpc.inc";
     include_once SHOPP_ADDONS . "/BillmateCore/lib/xmlrpcs.inc";
     $pno = $this->Order->partpaymentpno;
     $phone = $this->Order->partpaymentphone;
     $eid = (int) $this->settings['eid'];
     $key = $this->settings['secretkey'];
     $ssl = true;
     $debug = false;
     $k = new BillMate($eid, $key, $ssl, $debug, $this->settings['testmode'] == 'on');
     $Customer = $this->Order->Customer;
     $Billing = $this->Order->Billing;
     $Shipping = $this->Order->Shipping;
     $country = $zone = $locale = $global = false;
     $country = $Billing->country;
     $country_to_currency = array('NO' => 'NOK', 'SE' => 'SEK', 'FI' => 'EUR', 'DK' => 'DKK', 'DE' => 'EUR', 'NL' => 'EUR');
     $ship_address = $bill_address = array();
     $countryData = BillmateCountry::getCountryData($Shipping->country);
     $ship_address = array('email' => $Customer->email, 'telno' => $Customer->phone, 'cellno' => '', 'fname' => $Customer->firstname, 'lname' => $Customer->lastname, 'company' => $Customer->company, 'careof' => '', 'street' => $Shipping->address, 'house_number' => isset($house_no) ? $house_no : '', 'house_extension' => isset($house_ext) ? $house_ext : '', 'zip' => $Shipping->postcode, 'city' => $Shipping->city, 'country' => $countryData['country']);
     $bill_address = array('email' => $Customer->email, 'telno' => $Customer->phone, 'cellno' => '', 'fname' => $Customer->firstname, 'lname' => $Customer->lastname, 'company' => $Customer->company, 'careof' => '', 'street' => $Billing->address, 'house_number' => '', 'house_extension' => '', 'zip' => $Billing->postcode, 'city' => $Billing->city, 'country' => $countryData['country']);
     foreach ($ship_address as $key => $col) {
         $ship_address[$key] = utf8_decode(Encoding::fixUTF8($col));
     }
     foreach ($bill_address as $key => $col) {
         $bill_address[$key] = utf8_decode(Encoding::fixUTF8($col));
     }
     extract($countryData);
     //new ShoppError(var_export($Shipping->country,1), 'invalid_personal_number');
     //shopp_safe_redirect(shoppurl(false,'checkout'));
     $goods_list = array();
     foreach ($this->Order->Cart->contents as $item) {
         // echo links for the items
         $flag = stripos($item->name, 'billmate fee') === false ? stripos($item->name, 'billmate invoice fee') === false ? 0 : 16 : 0;
         $goods_list[] = array('qty' => (int) $item->quantity, 'goods' => array('artno' => $item->product, 'title' => $item->name, 'price' => round($item->unitprice * 100, 0), 'vat' => round($item->taxrate * 100, 0), 'discount' => 0.0, 'flags' => $flag));
         $taxrate = $item->taxrate;
     }
     if ($this->Order->Cart->Totals->discount > 0) {
         $rate = (100 + $taxrate * 100) / 100;
         $totalAmt = $this->Order->Cart->Totals->discount;
         $price = $totalAmt - $totalAmt / $rate;
         $discount = $totalAmt - $price;
         $goods_list[] = array('qty' => 1, 'goods' => array('artno' => __('discount', 'shopp-billmate-partpayment'), 'title' => __('Discount', 'shopp-billmate-partpayment'), 'price' => -1 * abs(round($this->Order->Cart->Totals->discount * 100, 0)), 'vat' => $taxrate * 100, 'discount' => 0, 'flags' => $flag));
     }
     if (!empty($this->Order->Cart->Totals->shipping)) {
         $taxrate = $taxrate * 100;
         //$rate = (100+$taxrate)/100;
         $totalAmt = $this->Order->Cart->Totals->shipping;
         //$price = $totalAmt-($totalAmt/$rate);
         // $shipping = $totalAmt - $price;
         $goods_list[] = array('qty' => (int) 1, 'goods' => array('artno' => __('Shipping', 'shopp-billmate-partpayment'), 'title' => __('Shipping', 'shopp-billmate-partpayment'), 'price' => round($totalAmt * 100, 0), 'vat' => $taxrate, 'discount' => 0, 'flags' => 8));
     }
     $pclass = (int) $this->Order->pclass;
     $transaction = array("order1" => (string) $this->txnid(), "comment" => (string) "", "flags" => 0, "reference" => "", "reference_code" => "", "currency" => $currency, "country" => $country, "language" => $language, "pclass" => $pclass, "shipInfo" => array("delay_adjust" => "1"), "travelInfo" => array(), "incomeInfo" => array(), "bankInfo" => array(), "sid" => array("time" => microtime(true)), "extraInfo" => array(array("cust_no" => (string) $order_info['customer_id'])));
     try {
         $result1 = $k->AddInvoice($pno, $bill_address, $ship_address, $goods_list, $transaction);
     } catch (Exception $ex) {
     }
     $this->Order->partpaymentpno = '';
     $this->Order->partpaymentphone = '';
     $this->Order->pclass = false;
     if (!is_array($result1)) {
         new ShoppError(__('It is not possible to pay with that method and to choose a different payment method or use a different personal number', 'shopp-billmate-partpayment'), 'billmate_error', SHOPP_TRXN_ERR);
         shopp_redirect(shoppurl(false, 'checkout'));
         die;
     } else {
         $this->Order->billmateId = $result1[0];
     }
     $this->Order->transaction($this->txnid());
     return true;
 }
Example #6
0
 /**
  * Handle bulk actions.
  *
  * @since 1.4
  *
  * @return void
  **/
 public function action()
 {
     if (false === $this->request('action')) {
         return;
     }
     $selected = (array) $this->request('selected');
     $action = Shopp::__('Updated');
     if ('delete' == $this->request('action')) {
         $handler = array($this, 'delete');
         $action = Shopp::__('Deleted');
     } elseif (is_numeric($this->request('action'))) {
         $handler = array($this, 'status');
     }
     $processed = 0;
     foreach ($selected as $selection) {
         if (call_user_func($handler, $selection)) {
             $processed++;
         }
     }
     if (1 == $processed) {
         $this->notice(Shopp::__('%s Order <strong>#%d</strong>.', $action, reset($selected)));
     } elseif ($processed > 1) {
         $this->notice(Shopp::__('%s <strong>%d</strong> orders.', $action, $processed));
     }
     shopp_redirect($this->url(array('action' => false, 'selected' => false)));
 }
 function details()
 {
     global $Shopp;
     if (!isset($Shopp->Cart->data->PayPalExpress->token) && !isset($Shopp->Cart->data->PayPalExpress->payerid)) {
         return false;
     }
     $_ = $this->headers();
     $_['METHOD'] = "GetExpressCheckoutDetails";
     $_['TOKEN'] = $Shopp->Cart->data->PayPalExpress->token;
     $this->transaction = $this->encode($_);
     $this->send();
     if (!$this->Response) {
         // Try one more time
         $this->transaction = $this->encode($_);
         $this->send();
     }
     $Customer = $Shopp->Cart->data->Order->Customer;
     $Customer->firstname = $this->Response->firstname;
     $Customer->lastname = $this->Response->lastname;
     $Customer->email = $this->Response->email;
     $Customer->phone = $this->Response->phonenum;
     $Shipping = $Shopp->Cart->data->Order->Shipping;
     $Shipping->address = $this->Response->shiptostreet;
     $Shipping->xaddress = $this->Response->shiptostreet2;
     $Shipping->city = $this->Response->shiptocity;
     $Shipping->state = $this->Response->shiptostate;
     $Shipping->country = $this->Response->shiptocountrycode;
     $Shipping->postcode = $this->Response->shiptozip;
     if (empty($Shipping->state) && empty($Shipping->country)) {
         add_filter('shopp_cart_taxrate', array(&$this, 'notax'));
     }
     $Billing = $Shopp->Cart->data->Order->Billing;
     $Billing->cardtype = "PayPal";
     $Billing->address = $Shipping->address;
     $Billing->xaddress = $Shipping->xaddress;
     $Billing->city = $Shipping->city;
     $Billing->state = $Shipping->state;
     $Billing->country = $this->Response->countrycode;
     $Billing->postcode = $Shipping->postcode;
     $Shopp->Cart->updated();
     $Shopp->Cart->totals();
     $targets = $Shopp->Settings->get('target_markets');
     if (!in_array($Billing->country, array_keys($targets))) {
         new ShoppError(__('The location you are purchasing from is outside of our market regions. This transaction cannot be processed.', 'Shopp'), 'paypalexpress_market', SHOPP_TRXN_ERR);
         shopp_redirect($Shopp->link('cart'));
     }
 }
Example #8
0
 function returned()
 {
     global $Shopp;
     if (empty($_POST)) {
         $_POST = $_GET;
     }
     if (empty($_POST)) {
         shop_redirect(shoppurl(false, 'checkout'));
         return;
     }
     if ($_POST['status'] != 0) {
         new ShoppError(__("Error Recieved from Billmate Cardpay:", 'shopp-billmate-cardpay') . $_POST['error_message'], 2);
         shopp_redirect(shoppurl(false, 'checkout', false));
         return false;
     }
     // Check for unique transaction id
     $Purchase = new Purchase($_POST['trans_id'], 'txnid');
     $Shopp->Order->trans_id = $_POST['trans_id'];
     $Shopp->Order->billmatestatus = 'Success';
     $this->billmate_transaction();
     if (!empty($Purchase->id)) {
         $Shopp->Purchase = $Purchase;
         $Shopp->Order->purchase = $Purchase->id;
         shopp_redirect(shoppurl(false, 'thanks', false));
         return false;
     }
     // Run order processing
     do_action('shopp_process_order');
 }
 function order()
 {
     global $Shopp;
     $txnstatus = false;
     $ipnstatus = $this->verifyipn();
     // Validate the order notification
     if ($ipnstatus != "VERIFIED") {
         $txnstatus = $ipnstatus;
         new ShoppError('An unverifiable order notification was received from PayPal. Possible fraudulent order attempt! The order will be created, but the order payment status must be manually set to "Charged" when the payment can be verified.', 'paypal_txn_verification', SHOPP_TRXN_ERR);
     }
     if (!$txnstatus) {
         $txnstatus = $this->status[$_POST['payment_status']];
     }
     $Order = $Shopp->Cart->data->Order;
     $Order->Totals = $Shopp->Cart->data->Totals;
     $Order->Items = $Shopp->Cart->contents;
     $Order->Cart = $Shopp->Cart->session;
     if (SHOPP_DEBUG) {
         new ShoppError('IPN notification validated.', false, SHOPP_DEBUG_ERR);
     }
     // Transaction successful, save the order
     $authentication = $Shopp->Settings->get('account_system');
     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) {
             $user = get_userdata($Order->Customer->wpuser);
             $Order->Customer->wpuser = $user->ID;
             if (SHOPP_DEBUG) {
                 new ShoppError('Customer logged in, linking Shopp customer account to existing WordPress account.', false, SHOPP_DEBUG_ERR);
             }
         }
         // 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) && isset($Order->Customer->password)) {
         $Order->Customer->password = wp_hash_password($Order->Customer->password);
     }
     $Order->Customer->save();
     $Order->Billing->customer = $Order->Customer->id;
     $Order->Billing->cardtype = "PayPal";
     $Order->Billing->save();
     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;
     }
     $Purchase = new Purchase();
     $Purchase->customer = $Order->Customer->id;
     $Purchase->billing = $Order->Billing->id;
     $Purchase->shipping = $Order->Shipping->id;
     $Purchase->data = $Order->data;
     $Purchase->promos = $Promos;
     $Purchase->copydata($Order->Customer);
     $Purchase->copydata($Order->Billing);
     $Purchase->copydata($Order->Shipping, 'ship');
     $Purchase->copydata($Shopp->Cart->data->Totals);
     $Purchase->freight = $Shopp->Cart->data->Totals->shipping;
     $Purchase->gateway = "PayPal" . (isset($_POST['test_ipn']) && $_POST['test_ipn'] == "1" ? " Sandbox" : "");
     $Purchase->transactionid = $_POST['txn_id'];
     $Purchase->transtatus = $txnstatus;
     $Purchase->fees = $_POST['mc_fee'];
     $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();
         }
     }
     // Empty cart on successful order
     $Shopp->Cart->unload();
     session_destroy();
     // Start new cart session
     $Shopp->Cart = new Cart();
     session_start();
     // Keep the user loggedin
     if ($Shopp->Cart->data->login) {
         $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'));
     }
     shopp_redirect($Shopp->link('receipt', false));
 }
 /**
  * request()
  * Processes cart requests and updates the cart
  * accordingly */
 function request()
 {
     global $Shopp;
     do_action('shopp_cart_request');
     if (isset($_REQUEST['checkout'])) {
         shopp_redirect($Shopp->link('checkout', true));
     }
     if (isset($_REQUEST['shopping'])) {
         shopp_redirect($Shopp->link('catalog'));
     }
     if (isset($_REQUEST['shipping'])) {
         $countries = $Shopp->Settings->get('countries');
         $regions = $Shopp->Settings->get('regions');
         $_REQUEST['shipping']['region'] = $regions[$countries[$_REQUEST['shipping']['country']]['region']];
         if (!empty($_REQUEST['shipping']['postcode'])) {
             // Protect input field from XSS
             $_REQUEST['shipping']['postcode'] = attribute_escape($_REQUEST['shipping']['postcode']);
         }
         unset($countries, $regions);
         $this->shipzone($_REQUEST['shipping']);
     } else {
         if (!isset($this->data->Order->Shipping->country)) {
             $base = $Shopp->Settings->get('base_operations');
             $_REQUEST['shipping']['country'] = $base['country'];
             $this->shipzone($_REQUEST['shipping']);
         }
     }
     if (!empty($_REQUEST['promocode'])) {
         $this->data->PromoCodeResult = "";
         if (!in_array($_REQUEST['promocode'], $this->data->PromoCodes)) {
             $this->data->PromoCode = attribute_escape($_REQUEST['promocode']);
             // Protect from XSS
             $this->updated();
         } else {
             $this->data->PromoCodeResult = __("That code has already been applied.", "Shopp");
         }
     }
     if (isset($_REQUEST['remove'])) {
         $_REQUEST['cart'] = "remove";
     }
     if (isset($_REQUEST['update'])) {
         $_REQUEST['cart'] = "update";
     }
     if (isset($_REQUEST['empty'])) {
         $_REQUEST['cart'] = "empty";
     }
     if (!isset($_REQUEST['quantity'])) {
         $_REQUEST['quantity'] = 1;
     }
     switch ($_REQUEST['cart']) {
         case "add":
             if (isset($_REQUEST['product'])) {
                 $quantity = empty($product['quantity']) && $product['quantity'] !== 0 ? 1 : $product['quantity'];
                 // Add 1 by default
                 $Product = new Product($_REQUEST['product']);
                 $pricing = false;
                 if (!empty($_REQUEST['options']) && !empty($_REQUEST['options'][0])) {
                     $pricing = $_REQUEST['options'];
                 } else {
                     $pricing = $_REQUEST['price'];
                 }
                 $category = false;
                 if (!empty($_REQUEST['category'])) {
                     $category = $_REQUEST['category'];
                 }
                 if (isset($_REQUEST['data'])) {
                     $data = $_REQUEST['data'];
                 } else {
                     $data = array();
                 }
                 if (isset($_REQUEST['item'])) {
                     $result = $this->change($_REQUEST['item'], $Product, $pricing);
                 } else {
                     $result = $this->add($quantity, $Product, $pricing, $category, $data);
                 }
             }
             if (isset($_REQUEST['products']) && is_array($_REQUEST['products'])) {
                 foreach ($_REQUEST['products'] as $id => $product) {
                     $quantity = empty($product['quantity']) && $product['quantity'] !== 0 ? 1 : $product['quantity'];
                     // Add 1 by default
                     $Product = new Product($product['product']);
                     $pricing = false;
                     if (!empty($product['options']) && !empty($product['options'][0])) {
                         $pricing = $product['options'];
                     } elseif (isset($product['price'])) {
                         $pricing = $product['price'];
                     }
                     $category = false;
                     if (!empty($product['category'])) {
                         $category = $product['category'];
                     }
                     if (!empty($product['data'])) {
                         $data = $product['data'];
                     } else {
                         $data = array();
                     }
                     if (!empty($Product->id)) {
                         if (isset($product['item'])) {
                             $result = $this->change($product['item'], $Product, $pricing);
                         } else {
                             $result = $this->add($quantity, $Product, $pricing, $category, $data);
                         }
                     }
                 }
             }
             break;
         case "remove":
             if (!empty($this->contents)) {
                 $this->remove(current($_REQUEST['remove']));
             }
             break;
         case "empty":
             $this->clear();
             break;
         default:
             if (isset($_REQUEST['item']) && isset($_REQUEST['quantity'])) {
                 $this->update($_REQUEST['item'], $_REQUEST['quantity']);
             } elseif (!empty($_REQUEST['items'])) {
                 foreach ($_REQUEST['items'] as $id => $item) {
                     if (isset($item['quantity'])) {
                         $item['quantity'] = ceil(preg_replace('/[^\\d\\.]+/', '', $item['quantity']));
                         if (!empty($item['quantity'])) {
                             $this->update($id, $item['quantity']);
                         }
                         if (isset($_REQUEST['remove'][$id])) {
                             $this->remove($_REQUEST['remove'][$id]);
                         }
                     }
                     if (isset($item['product']) && isset($item['price']) && $item['product'] == $this->contents[$id]->product && $item['price'] != $this->contents[$id]->price) {
                         $Product = new Product($item['product']);
                         $this->change($id, $Product, $item['price']);
                     }
                 }
             }
     }
     do_action('shopp_cart_updated', $this);
 }
 function reset_password($activation)
 {
     global $Shopp;
     $authentication = $Shopp->Settings->get('account_system');
     $user_data = false;
     $activation = preg_replace('/[^a-z0-9]/i', '', $activation);
     $errors = array();
     if (empty($activation) || !is_string($activation)) {
         $errors[] = new ShoppError(__('Invalid key'));
     }
     $RecoveryCustomer = new Customer($activation, 'activation');
     if (empty($RecoveryCustomer->id)) {
         $errors[] = new ShoppError(__('Invalid key'));
     }
     if (!empty($errors)) {
         return false;
     }
     // Generate a new random password
     $password = wp_generate_password();
     do_action_ref_array('password_reset', array(&$RecoveryCustomer, $password));
     $RecoveryCustomer->password = wp_hash_password($password);
     if ($authentication == "wordpress") {
         $user_data = get_userdata($RecoveryCustomer->wpuser);
         wp_set_password($password, $user_data->ID);
     }
     $RecoveryCustomer->activation = '';
     $RecoveryCustomer->save();
     $subject = apply_filters('shopp_reset_password_subject', sprintf(__('[%s] New Password', 'Shopp'), get_option('blogname')));
     $_ = array();
     $_[] = 'From: "' . get_option('blogname') . '" <' . $Shopp->Settings->get('merchant_email') . '>';
     $_[] = 'To: ' . $RecoveryCustomer->email;
     $_[] = 'Subject: ' . $subject;
     $_[] = '';
     $_[] = sprintf(__('Your new password for %s:', 'Shopp'), get_option('siteurl'));
     $_[] = '';
     if ($user_data) {
         $_[] = sprintf(__('Login name: %s', 'Shopp'), $user_data->user_login);
     }
     $_[] = sprintf(__('Password: %s'), $password) . "\r\n";
     $_[] = '';
     $_[] = __('Click here to login:'******' ' . $Shopp->link('account');
     $message = apply_filters('shopp_reset_password_message', join("\r\n", $_));
     if (!shopp_email($message)) {
         new ShoppError(__('The e-mail could not be sent.'), 'password_reset_email', SHOPP_ERR);
         shopp_redirect(add_query_arg('acct', 'recover', $Shopp->link('account')));
     } else {
         new ShoppError(__('Check your email address for your new password.', 'Shopp'), 'password_reset_email', SHOPP_ERR);
     }
     unset($_GET['acct']);
 }