chris thomas Posted January 9, 2009 Share Posted January 9, 2009 A few days back I found a thread on the net which was a copy of an old OSC forum thread. In it a number of people were venting frustration at a problem that was really causing me issues. The problem is.. * You want customers to be able to browse your store, and even go through to final checkout in their currency (say USD or AUD) * But at checkout confirmation you need the total to also be shown in your currency (GBP in my case), and for the order to be chaged in your currency also.... There does not seem (as far as I can see) to be a near solution i.e. in the style of a contribution that can fix the problem in one hit. However, there IS a way to get a solution and the end result works just as I needed it to. Please be aware that I have customized me OsC site quite a bit, and I have been learning PHP etc along the way, so I am no expert. Here is my approach. For now I will write it in basic outline + psuedo code. I can add better code examples when I have a little more time... 1. checkout_payment.php: * Here we need to pass on the currency type to the next page, where we will over-ride the standard variable to always force it to be GBP. To do this, I put a hidden form item in with the Continue button. The name of the form item is "currency_picked", and its value is set to $currency (the current user picked (or default) currency value) 2. checkout_confirmation.php: * At the top of this pages code, add a $currency_picked = $_REQUEST['currency_picked']. This gets the value passed on from the previous page. * We can now overide the $currency value with the one we want the customer to pay in, so again at the top of the page, $currency = 'GBP'; * Now a thorny problem. The page that is generated next will have a number of links in it. If the customer clicks one of those links, say to add another item to their basket. They will go to that link, and the currency will change to GBP (as $currency = GBP). So, we need a way to modify these links so they also specify the currency is changed back to the customers currency. To do this I used the PHP buffer feature. i.e. ob_start() will record everything that is normally sent to the browser. ob_start() can also have a callback function speficied for it, and this was used to search and replace .php? with .php?currency=USD, and then .php" (the " is important) with .php?currency=USD. The result of this, is that all links off this page now have the currency speficied as USD, so when you click those links, the following pages currency is USD. When the page finishes outputing, the buffering system flushes the buffer and sends its (slightly filtered) contents (with modified links) to the browser. * There are now a number of includes below that calculate and display basket items, and also workout the order sub-total, tax, discounts, total etc. We need some of that to be calculated in GBP, so now that the currency is set to GBP, this will be the case. But in other places we need the $currency to be the customers picked one. Specifically where the basket items are displayed, and the right BOX, where the order total is displayed. To do this, we need to temporarily switcharoo the currency values just where needed. So before each of their includes, do a.. $currency = $picked_currency; And straight after the include, switch back... $currency = 'GBP'; (like I said, its all a bit of a hacky fudge :) ) * Again, put a hidden form item in with the Continue button. The name of the form item is "currency_picked", and its value is set to $currency_picked. Again this preserves the customers picked currency. 3. checkout_process.php * This is a "hidden" page that does the final order processing, sends emails to the customer and enters all items to the database etc etc. We need the $currency_picked variable to be set correctly here, so, add to the top of the page $currency_picked=$_REQUEST['currency_picked']; 4. ot_total.php, ot_shipping.php etc * Each of these files is now designed to take in values that have been calculated in GBP, and then display them as the currently picked currency. Problem is we have now locked those two to be the same (both GBP), so its going to calculate and DISPLAY the order items in GBP. We want the each item to be calculated and stored in GBP, but DISPLAYED as the customers currency. To do this we need to hack the code that outputs each value. This code is in the function process(), and follows this form... $this->output[] = array( 'title' => 'Total:', 'text' => $currencies->format($order->info[], true, $order->info['currency'], $order->info['currency_value']), 'value' => $order->info['total']); In this form, it will simply store the final value in GBP, and show it in GBP, simply because $currency = GBP. So I take the $customers_picked currency, and use it to get the exchange rate for that currency from the same array used to build the currency flyout. This exchange rate is stored in $currency_value. I now change the code above to... $this->output[] = array( 'title' => 'Total:', 'text' => $currencies->format($order->info[], true, $currency_picked, $currency_value), 'value' => $order->info['total']); This now stores all values in GBP, but shows them to the customer, and on the invoice as USD. * To make it a little more user friendly, I check if the $currency = $currency_picked, and if it does, choose different 'title' text. In my case.. if both = GBP, title = "Total:" if no match, title = "Order will be billed as GBP £120.00 Total:" This makes it clear that although the total is shown in USD, that in fact they will be charged in £ GBP, and for the amount shown. In the database, all order totals are stored with the text showing the price in USD. But the value shown next to each is shown in GBP. So you now have a record of both, if you need to work in USD (for the customer) or in GBP, for your own accounts. I have only just implemented this sytem. I have had four orders come through since, and all seems fine. With this system, it will now make it much easier to calculate our accounts, as all items of the invoice are stored as GBP. If needed we can also gather the $USD (or whatever) values from the associated text, or by using the exhange rate stored in the order table. Hope this all makes sense? I'll try and fill in some of the blanks above with code when I get a little more time (if people are interested) Cheers Chris Thomas Link to comment Share on other sites More sharing options...
Jack_mcs Posted January 9, 2009 Share Posted January 9, 2009 See My Addons for Second Currency. Jack Support Links: For Hire: Contact me for anything you need help with for your shop: upgrading, hosting, repairs, code written, etc. All of My Addons Get the latest versions of my addons Recommended SEO Addons Link to comment Share on other sites More sharing options...
Guest Posted February 2, 2009 Share Posted February 2, 2009 See My Addons for Second Currency. Jack Hello, I dunno if I am being blind or stupid or both, but I cannot find the contribution... Link to comment Share on other sites More sharing options...
Jack_mcs Posted February 3, 2009 Share Posted February 3, 2009 It's there - i Just checked. Jack Support Links: For Hire: Contact me for anything you need help with for your shop: upgrading, hosting, repairs, code written, etc. All of My Addons Get the latest versions of my addons Recommended SEO Addons Link to comment Share on other sites More sharing options...
♥stubbsy Posted February 8, 2009 Share Posted February 8, 2009 Thats funny, your second currency conrtib appears if you search for it in the contributions area but its not in your 'list' of contributions when you click on the link in your signature. I've not looked at your conrib jack, but Ive been using this at the top of my checkout_process.php for a few years without any problems //mod to set payment to default currency $currency = DEFAULT_CURRENCY; It lets the customer browse the site in any currency allowed but checks out in the default currency All the best Dave Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.