Magento multiple currencies on a single domain with no subdirectories - php

I am trying to set up a website that allows about 6 different currencies. I originally was able to achieve this quite well using the currency exchange rates built into Magento and the customer could select which currency they prefered and all prices were displayed in that currency. However I recently discovered that despite the prices being in that currency Magento will still process the transactions in the base currency, in this case GBP. In fact it doesn't tell the customer this is what will happen until right at the end of the order which in my opinion is a very bad thing, some customers might also be charged more by their banks for the currency conversion.
As PayPal has been configured to allow payments in the 6 currencies I would like the customers to be able to pay in those currencies.
I have since found out that due to the way Magento has been built that this is no easy task and instead you should set up a new 'website' for each of the currencies, then I can set a base currency for each website. This sounds easy enough, however the tutorials about this all seem to force each website to have its own unique url - such as either us.website.com or website.com/us - but in this case that will not do and we need everything to use only the one base url website.com.
Does anyone know if this is possible?
I have been able to change the store by manually adding the following to index.php and I was thinking one possible solution would be to remember the users selection in the session and then load the correct store here. Would this be efficient or is there a better way to do this that I have overlooked?
/* Override store code */
if (isset($_GET['code']))
{
$mageRunCode = $_GET['code'];
$mageRunType = 'website';
}
Mage::run($mageRunCode, $mageRunType);
The website is running Magento Community Edition v1.7.0.2.

I have been able to achieve this using something similar to the following in index.php
if (isset($_GET["currency"]) || !isset($_COOKIE["basewebsite"]))
{
// List of available stores
$stores = array('usd','aud','eur');
$website = 'base'; // Default store ID
if (isset($_GET['currency']) && in_array($_GET['currency'], $stores))
{
$website = $_GET['currency'];
}
// Set cookie to remember selection
setcookie("basewebsite", $website);
$_COOKIE['basewebsite'] = $website;
}
else
{
$website = $_COOKIE['basewebsite'];
}
/* Store or website code */
$mageRunCode = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : $website;
/* Run store or run website */
$mageRunType = isset($_SERVER['MAGE_RUN_TYPE']) ? $_SERVER['MAGE_RUN_TYPE'] : 'website';
Mage::run($mageRunCode, $mageRunType);
With this I can then change the website by simply adding ?currency=usd to the end of any Magento url. The selection is then remembered by the cookie and the correct website is loaded with any further requests.
This question hasn't received many views but if anyone does spot a better solution then please do let me know!

Related

Send a mail to Admin with a BO link to specific customer in Prestashop 1.6

In Prestashop 1.6, from a FrontController, I have to send a mail to the administrator of the Shop.
This part works well but I got problems to include a link to the administration page of a specific customer.
The only thing I miss is the name of the administration directory. I would be able to parse and concatenate the PS_ADMIN_DIR constant but it is not available from the FrontController.
I'm kinda stuck here.
Here is the code :
$admin_customer_link =
_PS_BASE_URL_
.__PS_BASE_URI__
/* Missing the Administration directory name here */
.$this->context->link->getAdminLink('AdminCustomers', false)
."&id_customer=".(int)$customer->id."&viewcustomer";
The output I got :
http://127.0.0.1:8080/prestashop/index.php?controller=AdminCustomers&id_customer=2&viewcustomer
The output I need :
http://127.0.0.1:8080/prestashop/administration/index.php?controller=AdminCustomers&id_customer=2&viewcustomer
Any help will be appreciated.
There is no (standard) way to know the administration folder from a front controller, otherwise all the security will flushed down the toilet :).
What you can do is to retrieve the administration folder from the module 'configuration' or when you install it, and save it somewhere, at the moment I suggest into the database but maybe there is a more safely mode.
Something like:
public function install()
{
// your stuff
$current_dir = $_SERVER['PHP_SELF']; // this give you the current dir (administration folder included)
$administration_folder = /* Clean your string with a string replace or preg */
Configuration::updateValue('PS_MYMOD_ADMIN_DIR', $administration_folder);
return true;
}
Then in your front controller retrieve it by:
$adminfolder = Configuration::get('PS_MYMOD_ADMIN_DIR');
However I hope you know that you're creating a security breach through e-mail...
Hope it helps
Since the use of the administration directory name from the Front End and sending a link to the administration in e-mail is not a good idea for security purpose, I choose to implement this another way.
Instead of send the administration customer's page link to the webmaster by e-mail, I create a new customer Thread and message. After that, I send an e-mail to the customer service. So, when they log in the Back Office, they see a new notification who leads them to the specific user.
Here is the code :
ModuleFrontController
// Create a new Customer Thread
$ct = new CustomerThread();
if (isset($customer->id)) {
$ct->id_customer = (int)$customer->id;
}
$ct->id_shop = (int)$this->context->shop->id;
$ct->id_contact = $contact->id;
$ct->id_lang = (int)$this->context->language->id;
$ct->email = $customer->email;
$ct->status = 'open';
$ct->token = Tools::passwdGen(12);
$ct->add();
// Add a new message to the Customer Thread
if ($ct->id) {
$cm = new CustomerMessage();
$cm->id_customer_thread = $ct->id;
$cm->message = $message;
$cm->ip_address = (int)ip2long(Tools::getRemoteAddr());
$cm->user_agent = $_SERVER['HTTP_USER_AGENT'];
$cm->add();
}
Hope it helps someone in the same situation.

How to set the admin attribute in a WHMCS addon module

I am in the process of creating several WHMCS modules, one of the modules to process an invoice in our own bookkeeping system uses the WHMCS internal API like:
add_hook('InvoicePaid', 1, function ($params)
{
$invoiceid = $params['invoiceid'];
$command = "getinvoice";
$adminuser = "";
$values["invoiceid"] = $invoiceid;
$results = localAPI($command,$values,$adminuser);
if ($results['result']!="success") echo "An Error Occurred: ".$results['result'];
//get netto price and description of first item
$netto = $results['subtotal'];
$desc = $results['items']["item"][0]["description"];
//... other code not needed for question.
}
The module is tested manually by creating an invoice and setting it as paid by an admin user, in this case it works and the price and description are processed.
However, when a normal user pays an invoice, the module gives both $netto and $desc as empty strings.
My suspicions are that this is because of the empty $adminuser parameter, but what value should it be? Do I have to set it to an existing admin username of the system? Or is there a username you can always use?
If it has to be a system admin username, how would other people know that they have to change this before integrating the module?
You do need to have an $adminuser in place. I believe you can almost 90% of the time assume an admin id of 1 would be valid for most setups. In my modules I have a field in the settings where the customer can select which one to use, and it defaults to use a 1 in the event they haven't saved anything yet.

Magento - Store Views and multiple currencies - Checkout using base currency always

I have a magento website
We have a store
In a store we have multiple store views (US, EU and UK)
Each store view has it's own currency, etc.
The base currency is GBP at the default config (main)
My problem is that the display currencies work well. Each store view has it's own individual price (no automatic conversion). Everything seems to be working and in order. However, on the final payment emails and actual connection with payment providers (PayPal/Sage). The base currency is always used. Although the display appears in the currency for each store view.
My question is why are the store view currencies not used with PayPal, emails, etc. Although the amounts, display currency, etc work fine?
It turns out that Base Currency can be set on each Store View. However, this option was not presented on the admin side. I had to change the system.xml
app/code/core/Mage/Directory/etc/system.xml
<label>Base Currency</label>
I have to set the appropriate to change from 0 to 1
<show_in_store>1</show_in_store>
Once this was done, I could see Base Currency under "Currency Options" even within a store view. This now works well and everything seems to be working fine.
No PHP code changes or any additional plugins required.
When I had run into this issue with a rather large Magento store, this quick fix worked pretty well for me: Magento knowledge-base paypal base currency tweak
Just note that, that fix probably won't work out of the box but it'll take some tweaking
Here it is some solutions.
You might custom some codes
If you are using Paypal Express,
\app\code\core\Mage\Paypal\Model\Express.php
protected function _placeOrder(Mage_Sales_Model_Order_Payment $payment, $amount)
{
$order = $payment->getOrder();
// prepare api call
$token = $payment->getAdditionalInformation(Mage_Paypal_Model_Express_Checkout::PAYMENT_INFO_TRANSPORT_TOKEN);
$api = $this->_pro->getApi()
->setToken($token)
->setPayerId($payment->
getAdditionalInformation(Mage_Paypal_Model_Express_Checkout::PAYMENT_INFO_TRANSPORT_PAYER_ID))
->setAmount($amount)
->setPaymentAction($this->_pro->getConfig()->paymentAction)
->setNotifyUrl(Mage::getUrl('paypal/ipn/'))
->setInvNum($order->getIncrementId())
**->setCurrencyCode($order->getOrderCurrencyCode())** // should be used getOrderCurrencyCode();
->setPaypalCart(Mage::getModel('paypal/cart', array($order)))
->setIsLineItemsEnabled($this->_pro->getConfig()->lineItemsEnabled)
;
if ($order->getIsVirtual()) {
$api->setAddress($order->getBillingAddress())->setSuppressShipping(true);
} else {
$api->setAddress($order->getShippingAddress());
$api->setBillingAddress($order->getBillingAddress());
}
// call api and get details from it
$api->callDoExpressCheckoutPayment();
$this->_importToPayment($api, $payment);
return $this;
}
\app\code\core\Mage\Paypal\Model\Standard.php
public function getStandardCheckoutFormFields()
{
$orderIncrementId = $this->getCheckout()->getLastRealOrderId();
$order = Mage::getModel('sales/order')->loadByIncrementId($orderIncrementId);
/* #var $api Mage_Paypal_Model_Api_Standard */
$api = Mage::getModel('paypal/api_standard')->setConfigObject($this->getConfig());
$api->setOrderId($orderIncrementId)
**->setCurrencyCode($order->getOrderCurrencyCode())** // should be used getOrderCurrencyCode();
//->setPaymentAction()
->setOrder($order)
->setNotifyUrl(Mage::getUrl('paypal/ipn/'))
->setReturnUrl(Mage::getUrl('paypal/standard/success'))
->setCancelUrl(Mage::getUrl('paypal/standard/cancel'));
// export address
$isOrderVirtual = $order->getIsVirtual();
$address = $isOrderVirtual ? $order->getBillingAddress() : $order->getShippingAddress();
if ($isOrderVirtual) {
$api->setNoShipping(true);
} elseif ($address->validate()) {
$api->setAddress($address);
}
// add cart totals and line items
$api->setPaypalCart(Mage::getModel('paypal/cart', array($order)))
->setIsLineItemsEnabled($this->_config->lineItemsEnabled)
;
$api->setCartSummary($this->_getAggregatedCartSummary());
$api->setLocale($api->getLocaleCode());
$result = $api->getStandardCheckoutRequest();
return $result;
}

Product URL in a shared shopping cart in Magento multi-store websites

I have Magento multi-store websites that I want that the user will be able to add products to his shopping cart from all the website and pay once.
I successfully done it using this article.
But when the user click on the product in the shopping cart, he is not redirected to the right website. It's a limitation the described in the article at the end.
The link for editing items in the cart will redirect customer to
original cart website. It is possible to change it, you can override
getUrl method for cart items block or override controller.
I couldn't find any explaination to how to do this override.
Someone can help me do this?
Thanks
In my case i seen file of cart's item.phtml, it was using getproducturl().
So, I modified that method in file /app/code/core/Mage/Checkout/Block/Cart/Item/Renderer.php line 152.
I made condition that if its main website don't change otherwise it adds stores code in url like www.example/store1/Producturl.
I hope This will Help You.
As You Require The File method. Check belowed code.
public function getProductUrl()
{
if (!is_null($this->_productUrl)) {
return $this->_productUrl;
}
if ($this->getItem()->getRedirectUrl()) {
return $this->getItem()->getRedirectUrl();
}
$product = $this->getProduct();
$option = $this->getItem()->getOptionByCode('product_type');
if ($option) {
$product = $option->getProduct();
}
$webids = $product->getWebsiteIds();
$wid = array();
foreach($webids as $webid){
$wid[] = $webid;
}
if(!in_array(1,$wid)){
$website = Mage::app()->getWebsite($wid[0])->getCode();
$org_url = $product->getUrlModel()->getUrl($product);
$mod_url = str_replace("www.example.com/index.php/","www.example.com/".$website."/index.php/",$org_url);
return $mod_url;
}
return $product->getUrlModel()->getUrl($product);
}
As my first website id was "1", that's why i used in_array(1.$wid). You Can use your main website id over there. and in str_replace u can use baseurl() method of main website instead of static value i used.

linking to magento website based on currency

Basically i need to link to my website, but i need the currency to change based on what link is used.
i need this for google adwords, if i am targeting ireland in adwords, i need my website to display euros. if i am targeting the U.K. i need it to display in Pounds and so on.
the website is developed in magento, and i have a select box at the top of my page that changes the currency throughout the website.
Any ideas how i can do this, the website is www.funkychristmasjumpers.com
Credit per this link on the Magento forums
You could always add the following bit of code to the top of your /template/directory/currency.phtml file in your theme. I've tested this in a 1.7.0.2 instance and it works nicely.
You just add cy=code to the end of the URL, so for www.funkychristmasjumpers.com it would be http://www.funkychristmasjumpers.com?cy=USD to default to USD. The code applies the currency and then redirects back to the target page
$currentCurrency = $this->getCurrentCurrencyCode();
if(!isset($currentCurrency)) $currentCurrency = 'NA';
$currencies = array("GBP","USD","EUR");
if(isset($_GET['cy']))
{
if (in_array(strtoupper($_GET['cy']),$currencies)) {
if(strtoupper($_GET['cy']) != $currentCurrency)
{
header("Location: ".$this->helper('directory/url')->getSwitchCurrencyUrl()."currency/".$_GET['cy']);
exit;
}
}
}

Categories