예제 #1
0
 /**
  * Hides away the curl request
  *
  * @param      $url     API Endpoint to send request to
  * @param      $data    Request parameters - sent as POST
  * @param bool $skip_ssl_verify Skip SSL verification - useful for development (and local testing)
  * @return mixed
  * @throws APIException
  */
 public function request($url, $data, $skip_ssl_verify = FALSE)
 {
     if (is_string($data)) {
         $post_string = $data;
     } else {
         $post_string = http_build_query($data);
     }
     if (__DEBUG__) {
         ShopLogger::log('REQUEST ' . $url . ' ' . $post_string);
     }
     // Request
     $request = curl_init($url);
     curl_setopt($request, CURLOPT_HEADER, 0);
     curl_setopt($request, CURLOPT_RETURNTRANSFER, 1);
     curl_setopt($request, CURLOPT_POSTFIELDS, $post_string);
     if ($skip_ssl_verify) {
         curl_setopt($request, CURLOPT_SSL_VERIFYPEER, FALSE);
     } else {
         curl_setopt($request, CURLOPT_SSL_VERIFYPEER, TRUE);
     }
     $response = curl_exec($request);
     if (!$response) {
         $error = curl_error($request);
         throw new APIException("CURL error: " . $error);
     }
     if (__DEBUG__) {
         ShopLogger::log('RESPONSE ' . $response);
     }
     curl_close($request);
     return $response;
 }
예제 #2
0
 /**
  * Constructor; logs the error message and the stack trace to the shop log
  *
  * @param string    $message
  * @param int       $code
  * @param Exception $previous
  */
 public function __construct($message, $code = 0, Exception $previous = NULL)
 {
     $log_message = "APIException: <a href='#' class='logger_message_details'>" . $message . '</a>';
     $log_message .= '<div style="display:none">' . $this->getTraceAsString() . '</br>';
     $log_message .= print_r($_REQUEST, TRUE) . '</div>';
     ShopLogger::log($log_message);
     parent::__construct($message, $code, $previous);
 }
예제 #3
0
 /**
  * Constructor
  *
  * @param string    $message
  * @param int       $code
  * @param Exception $previous
  */
 public function __construct($message, $code = 0, Exception $previous = NULL)
 {
     ShopLogger::log("ShopException: <a href='#' class='logger_message_details'>" . $message . '</a><div style="display:none">' . $this->getTraceAsString() . '</div>');
     parent::__construct($message, $code, $previous);
 }
예제 #4
0
	/**
	 * Handle all incoming IPN notifications from 2checkout
	 */
	public function notify()
	{
		// Check the sender is 2Checkout
		$key = Context::get('md5_hash');

		$sale_id = Context::get('sale_id');
		$vendor_id = $this->sid;
		$invoice_id = Context::get('invoice_id');
		$secret_word = $this->secret_word;
		$expected_key = strtoupper(md5($sale_id . $vendor_id . $invoice_id . $secret_word));

		if(strtoupper($key) != $expected_key)
		{
			ShopLogger::log("Invalid 2checkout IPN message received - key " . $key . ' ' . print_r($_REQUEST, TRUE));
			return;
		}

		$message_type = Context::get('message_type');
		if($message_type != 'ORDER_CREATED')
		{
			ShopLogger::log("Unsupported IPN 2checkout message received: " . print_r($_REQUEST, TRUE));
			return;
		}

		$cart_srl = Context::get('vendor_order_id');
		$transaction_id = $sale_id; // Hopefully, this is order number

		$order_repository = new OrderRepository();

		// Check if order has already been created for this transaction
		$order = $order_repository->getOrderByTransactionId($transaction_id);
		if(!$order) // If not, create it
		{
			$cart = new Cart($cart_srl);
			$this->createNewOrderAndDeleteExistingCart($cart, $transaction_id);
		}
	}
 /**
  * Returns a plugin instance
  *
  * @param $name
  * @param $module_srl
  * @return mixed
  */
 public function getPlugin($name, $module_srl)
 {
     $data = $this->getPluginInfoFromDatabase($name, $module_srl);
     // Update code; add module srl to plugins that have module_srl = 0
     // TODO Remove this when releasing XE Shop
     if (!$data) {
         $data = $this->getPluginInfoFromDatabase($name, 0);
         if ($data) {
             ShopLogger::log("Upgrading plugin {$name} - setting module_srl from 0 to {$module_srl}");
             $this->fixPlugin($data->name, 0, $module_srl);
             $data->module_srl = $module_srl;
         }
     }
     // If plugin exists in the database, return it as is
     if ($data) {
         return $this->getPluginInstanceFromProperties($data);
     }
     // Otherwise, initialize it with info from the extension class and insert in database
     $plugin = $this->getPluginInstanceByName($name, $module_srl);
     $this->insertPlugin($plugin);
     return $this->getPlugin($name, $module_srl);
 }
예제 #6
0
		/**
		 * Send email to new users
		 */
		public function triggerSendSignUpEmail($member_args)
		{
			$site_module_info = Context::get('site_module_info');
			$module_srl = $site_module_info->index_module_srl;

			$shop = new ShopInfo($module_srl);

			// Don't send anything if sender and receiver email addresses are missing
			if(!$shop->getEmail() || !$member_args->email_address)
			{
				ShopLogger::log("Failed to send welcome email to user. Member email is not set." . print_r($member_args, TRUE));
				return;
			}

			global $lang;
			$email_subject = sprintf($lang->new_member_email_subject
				, $shop->getShopTitle()
			);

			$email_content = sprintf($lang->new_member_email_content
				, getFullSiteUrl('', 'act', 'dispShopHome')
				, $shop->getShopTitle()
				, getFullSiteUrl('', 'act', 'dispShopMyAccount')
				, getFullSiteUrl('', 'act', 'dispShopHome')
				, $shop->getShopTitle()
			);

			$oMail = new Mail();
			$oMail->setTitle($email_subject);
			$oMail->setContent($email_content);
			$oMail->setSender($shop->getShopTitle(), $shop->getShopEmail());
			$oMail->setReceiptor(FALSE, $member_args->email_address);
			$oMail->send();
		}
    /**
     * Handles all IPN notifications from Paypal
     */
    public function notify($cart)
    {
        // 1. Retrieve all POST data received and post back to paypal, to make sure
        // the request sender is not fake

        // Do not retrieve data with Context::getRequestVars() because it skips empty values
        // causing the Paypal validation to fail
        $args = $_POST;
        if(__DEBUG__)
        {
            ShopLogger::log("Received IPN Notification: " . http_build_query($args));
        }

        $response = $this->postDataBackToPaypalToValidateSenderIdentity($args);

        if($response->isVerified())
        {
            ShopLogger::log("Successfully validated IPN data");

            $payment_info = $this->getIPNPaymentInfo($args);

            if(!$payment_info->isRelatedToCartPayment())
                return;

            // 2. If the source of the POST is correct, we now need to check that data is also valid
            if(!$order = $this->orderCreatedForThisTransaction($payment_info->txn_id))
            {
                // check that receiver_email is your Primary PayPal email
                if(!$payment_info->paymentReceiverIsMe($this->business_account))
                {
                    ShopLogger::log("Possible fraud - invalid receiver email: " . $payment_info->receiver_email);
                    $this->markTransactionAsFailedInUserCart(
                        $payment_info->cart_srl,
                        $payment_info->txn_id,
                        "There was a problem processing your payment. Your order could not be completed."
                    );
                    return;
                }

                // check the payment_status is Completed
                if(!$payment_info->paymentIsComplete())
                {
                    ShopLogger::log("Payment is not completed. Payment status [" . $payment_info->payment_status. "] received");
                    $this->markTransactionAsFailedInUserCart(
                        $payment_info->cart_srl,
                        $payment_info->txn_id,
                        "Your payment was not completed. Your order was not created."
                    );
                    return;
                }

                $cart = new Cart($payment_info->cart_srl);
                if(!$payment_info->paymentIsForTheCorrectAmount($cart->getTotal(), $cart->getCurrency()))
                {
                    ShopLogger::log("Invalid payment. " . PHP_EOL
                        . "Payment amount [" . $payment_info->payment_amount . "] instead of " . $cart->getTotal() . PHP_EOL
                        . "Payment currency [" . $payment_info->payment_currency . "] instead of " . $cart->getCurrency()
                    );
                    $this->markTransactionAsFailedInUserCart(
                        $payment_info->cart_srl,
                        $payment_info->txn_id,
                        "Your payment was invalid. Your order was not created."
                    );
                    return;
                }

                // 3. If the source of the POST is correct, we can now use the data to create an order
                // based on the message received
                $this->createNewOrderAndDeleteExistingCart($cart, $payment_info->txn_id);
            }
        }
        else
        {
            ShopLogger::log("Invalid IPN data received: " . $response);
        }

    }
예제 #8
0
	/**
	 * Process the payment
	 *
	 * @param Cart $cart
	 * @param      $error_message
	 * @return bool|mixed
	 */
	public function processPayment(Cart $cart, &$error_message)
    {
		$cc_number = Context::get('cc_number');
		$cc_exp_month = Context::get('cc_exp_month');
		$cc_exp_year = Context::get('cc_exp_year');
		$cc_cvv = Context::get('cc_cvv');

		// Unset credit card info so that XE won't put it in session
		Context::set('cc_number', NULL);
		Context::set('cc_exp_month', NULL);
		Context::set('cc_exp_year', NULL);
		Context::set('cc_cvv', NULL);

		if(!$cc_number)
		{
			$error_message = "Please enter you credit card number"; return FALSE;
		}
		if(!$cc_exp_month || !$cc_exp_year)
		{
			$error_message = "Please enter you credit card expiration date"; return FALSE;
		}
		if(!$cc_cvv)
		{
			$error_message = "Please enter you credit card verification number"; return FALSE;
		}

		$cc_number = str_replace(array(' ', '-'), '', $cc_number);
		if (!preg_match ('/^4[0-9]{12}(?:[0-9]{3})?$/', $cc_number) // Visa
			&& !preg_match ('/^5[1-5][0-9]{14}$/', $cc_number) // MasterCard
			&& !preg_match ('/^3[47][0-9]{13}$/', $cc_number) // American Express
			&& !preg_match ('/^6(?:011|5[0-9]{2})[0-9]{12}$/', $cc_number) //Discover
		){
			$error_message = 'Please enter your credit card number!';
		}

		$cc_exp = sprintf('%02d%d', $cc_exp_month, $cc_exp_year);

        $transaction = new AuthorizeNetAim($this->api_login_id, $this->transaction_key);
		// 1. Set payment info
		$transaction->amount = $cart->getTotal();
        $transaction->card_num = $cc_number;
        $transaction->exp_date = $cc_exp;
		$transaction->invoice_num = $cart->cart_srl;

		// 2. Set billing address info
		$transaction->first_name = $cart->getCustomerFirstname();
		$transaction->last_name = $cart->getCustomerLastname();
		$transaction->company = $cart->getBillingAddress()->company;
		$transaction->address = $cart->getBillingAddress()->address;
		$transaction->city = $cart->getBillingAddress()->city;
		$transaction->zip = $cart->getBillingAddress()->postal_code;
		$transaction->country = $cart->getBillingAddress()->country;
		$transaction->email = $cart->getBillingAddress()->email;

		// 3. Set shipping address info
		$transaction->ship_to_first_name = $cart->getShippingAddress()->firstname;
		$transaction->ship_to_last_name = $cart->getShippingAddress()->lastname;
		$transaction->ship_to_company = $cart->getShippingAddress()->company;
		$transaction->ship_to_address = $cart->getShippingAddress()->address;
		$transaction->ship_to_city = $cart->getShippingAddress()->city;
		$transaction->ship_to_zip = $cart->getShippingAddress()->postal_code;
		$transaction->ship_to_country = $cart->getShippingAddress()->country;

        $response = $transaction->authorizeAndCapture();

        if ($response->approved) {
            return TRUE;
        } else {
			ShopLogger::log("Authorize.NET transaction failed: " . print_r($response, TRUE));
            $error_message = "There was a problem with charging your credit card; Please try again or try a different payment method";
            return FALSE;
        }
    }
예제 #9
0
 /**
  * Send email to user notifying him of the newly created order
  */
 public static function sendNewOrderEmails($order_srl)
 {
     $repo = new OrderRepository();
     $order = $repo->getOrderBySrl($order_srl);
     $shop = new ShopInfo($order->module_srl);
     // Don't send anything if shop email is not configured
     if (!$shop->getShopEmail()) {
         ShopLogger::log("Failed to send order email for order #{$order->order_srl}; Shop email is not configured");
         return;
     }
     self::sendNewOrderMailToCustomer($shop, $order);
     self::sendNewOrderMailToAdministrator($shop, $order);
 }
예제 #10
0
	/**
	 * Calculates shipping rates
	 *
	 * @param Cart   $cart    Shipping cart for which to calculate shipping; includes shipping address
	 * @param String $service Represents the specific service for which to calcualte shipping (e.g. Standard or Priority)
	 * @return null
	 */
	public function calculateShipping(Cart $cart, $service = NULL)
	{
		/** @var $unit The thing we will compare to the table rates: price, weight or item count */
		$unit = NULL;
		switch($this->type){
			case TableRateShipping::TYPE_PRICE_DESTINATION:
				$unit = $cart->getItemTotal(); // TODO Check if maybe getTotalAfterDiscount should be used instead
				break;
			case TableRateShipping::TYPE_WEIGHT_DESTINATION:
				$unit = $cart->getTotalWeight();
				break;
			case TableRateShipping::TYPE_ITEMS_COUNT_DESTINATION:
				$unit = count($cart->getProducts());
				break;
		}

		$shipping_address = $cart->getShippingAddress();
		$shipping_country = $shipping_address->country;

		$table_rates = $this->getTableRatesForCountry($shipping_country);
		$shipping_price = NULL;
		foreach($table_rates as $table_rate)
		{
			if($table_rate->unit <= $unit)
			{
				$shipping_price = $table_rate->price;
			}
			else
			{
				break;
			}
		}

		// If no shipping price was calculated, just take the last
		if(is_null($shipping_price))
		{
			ShopLogger::log("Couldn't match any rules from the table;");
			$shipping_price = $table_rate->price;
		}

		return $shipping_price;
	}