Jump to content
seb1188

New: Auto change currency ased on customer's IPA location

Recommended Posts

Well this is my first ever contribution. Wasn't sure where to post about it so I thought I'd just stick it in General...

If something similar already exists somewhere then my apologies, but I couldn't find it anywhere myself.

 

Find it here:

http://addons.oscommerce.com/info/6450

 

 

What it does:

It looks up the location of a customer's IP address and changes the currency to wahtever the database says belongs to that country, using 2 letter ISO codes. Once set, the use of sessions means the user can still manually change currency, as it won't query the IP address again after the first page request per session.

 

It uses an API from http://www.wipmani.com

 

To see it working, visit my store at http://www.thesebweb.com

If you now go there again, but using a proxy, you'll see the currency won't change until you clear your sessions and cookies. Then it'll change to the currency of the country of the proxy.

How are people getting on with this module? I see the URL's provided above are not working. Does the fact that Wipmania is down have an affect on this module?

Share this post


Link to post
Share on other sites

Thanks for adding to the contribution. I hope it works OK for everyone now. If wipmania goes down a lot you can always use your own database of reverse IP lookup (this was my original plan), there are some available free, but getting all that data onto your server would be a horrendous job as it seems to fail part way through due to its size.

 

Oh and I moved my site to koonukiwear.com if you want to see it working.

Edited by seb1188

osCommerce is GREAT. When it works...

Share this post


Link to post
Share on other sites

Thank you very much for your contribution. It has helped immensely. I have a question that I hope you can answer.

 

My client sells products to the US and now to Canada. He will charge Americans in USD and Canadians in CAD. While the currency is changed to where they are when they initially hit the site, they can change it and then attempt to checkout. For example, a Canadian could come to the site, see everything in CAD, but then change the currency to USD and proceed to checkout in USD. We want them their total in CAD so we can charge them in CAD.

 

What would be the best way to force users to checkout under their country's currency? I'm fine with them browsing products under different currencies (even after they've logged in) but once they hit checkout_shipping, they need to be under their proper currency so that when it's listed in the admin, my client can charge the amount to them in their funds. Since we know their country (they've logged in), can we check the new code column your contribution added and change the currency? That is, if they're Canadian, can we change the currency value to CAD so they proceed with checkout in CAD? Where would be the best spot to do this? Or, should users be prevented from changing the currency at all? This could still pose problems if the IP check is incorrect though. I think forcing the currency back is the way to go.

 

I guess the simple question is: How do I ensure customers checkout in their country's currency?

Share this post


Link to post
Share on other sites

Hi all, I have recently been testing it in my live store and it seems to work well. HOWEVER, it has a strage behaviour that I'm not sure how to fix;

 

Details, my store's default currency is CAD and I set this contibution to change US customers to USD. All other countries remain in CAD...

 

Here is the strange part.... Some (2 orders from the same city - Edmonton) Canada customers receive there Order Process email with the currency for each "unit" in USD and the total is CAD

 

1 x ITEM (229) = USD $4.56

------------------------------------------------------

Sub-Total: CAD $94.59

 

The order within orders.php shows correctly however...

 

1 x TIEM 229 5% CAD $4.70 CAD $4.70 CAD $4.70 CAD $4.70 Sub-Total: CAD $94.59

 

This ONLY happened with 2 orders... and only shows in the order process email...

 

The only corolation I can find with the 2 orders is the city... Any ideas?

Share this post


Link to post
Share on other sites

Hi Folks,

 

I tried to install it twice but always gives me this error

 

Fatal error: Call to undefined function: curl_init() in /mnt/webk/b1/05/51421805/htdocs/Libreria/catalog/includes/application_top.php on line 314

 

Line 314 is: $ch = curl_init(); in application_top.php

 

The first time I thought the was becouse my server does not working with cURL so I update my acount but still I can not make it work. It give the same error.

 

Anyone can help me?

 

Dank's ;)

Share this post


Link to post
Share on other sites

Hi All, I'm not sure if anyone is using this addon - or following this thread... I'm not a professional coder by any stretch - just a shop owner with enough knowledge to be dangerous.

 

I have re-wrote this addon to use the ip2location module created for this addon - http://addons.oscommerce.com/info/6955

 

I did this to improve the realiabiliy of the addon. Thinking the wipmania API is only 99.9%  - that would mean one in evey 1000 hits the API fails (that is several customers per day for me).

 

I was having issues, I had presumed, where 1 in every 100+ or so orders customers are 0 (no currecy, symbol or decimal). In additional I was receving phone calls about 1 every 2 or 3 days with the complaint of no prices showing.

 

So, although my addon works - it did not fix the issues mentioned above. So, I NOW presume the issues caused by the code I carried forwared in appliation top but not sure why or where? I presumed this if statement would return default currency if the location was blank?

if ($location == ''){
		// $location is blank, use default method so we don't get $0 prices or in some cases no product listed.
		$currency = (USE_DEFAULT_LANGUAGE_CURRENCY == 'true') ? LANGUAGE_CURRENCY : DEFAULT_CURRENCY;

But aparently it's not working... or I'm not understanding????

 

Anyway here is my code...

	require_once (DIR_WS_MODULES . 'ip2location/ip2location.php');

	$ip = IP2Location_open(DIR_WS_MODULES . 'ip2location/IP-COUNTRY-REGION-CITY-SAMPLE.BIN', IP2LOCATION_STANDARD);
	$record = IP2Location_get_all($ip, $_SERVER['REMOTE_ADDR']);
	IP2Location_close($ip);
		
	$location = $record->country_short;
	
	if ($location == ''){
		// $location is blank, use default method so we don't get $0 prices or in some cases no product listed.
		$currency = (USE_DEFAULT_LANGUAGE_CURRENCY == 'true') ? LANGUAGE_CURRENCY : DEFAULT_CURRENCY;
	}else{
		//since it has not been determined, find the currency it needs to be changed to
		$currency_id_result=tep_db_query("SELECT countries_currencyid FROM countries WHERE countries_iso_code_2='".$location."'");
		
		while($currency_row=tep_db_fetch_array($currency_id_result)) {
			$currency_id=$currency_row['countries_currencyid'];
		};
	
		//create session variable to show that it has now been determined
		$currency=$currency_id;
		$_SESSION['locationset']=$location;
		$_SESSION['currency']=$currency;
	}

//END OF ALTERATIONS

My latest version of this code "seems" reliable.... However, I'm don't understand why the above is not working and my new code changes the last lines to hard code the currency... Making it less useable by the community in general

		//create session variable to show that it has now been determined
		if ($currency_id != 'CAD') {
		$currency='USD'; }
		else {
		$currency='CAD'; }
		$_SESSION['locationset']=$location;
		$_SESSION['currency']=$currency;

Does this mean its not setting the session??? Or is the "if statement" mentioned above not placed correctly????

 

Share this post


Link to post
Share on other sites

I am looking to adjust my oscommerce shopping cart V 2.3.1 to change currency automatically when visitor view based on currency, such as if visitors/customer from USA currency show by USD if open from UK currency show GBP.  

Please, can any developer / anyone help me, I am not coder.


Best Regards,

Mohammed Reiad

Founder & Owner, Bazaar in Egypt

 

Egypt Call. +2 0100 116 4837

Share this post


Link to post
Share on other sites

Hello,

 

Sometimes http://www.wipmania.com/ returns XX when he can't determine the country.

 

I added a new country in the database , table : countries

 

countries_id : 300

countries_name : Unknown Country   <-- What you want

countries_iso_code_2  : XX <--- VERY IMPORTANT

countries_iso_code_3 : XXX  <---for example

address_format_id : 1  <-- what you want

countries_currencyid : EUR      <-- your default currency

 

And the prices to 0 disappear for me.

 

To be tested.

 

This good add-on works for me inOSC 2.3.1

 

Thanks to the author.

Share this post


Link to post
Share on other sites

Hi All, I'm not sure if anyone is using this addon - or following this thread... I'm not a professional coder by any stretch - just a shop owner with enough knowledge to be dangerous.

 

I have re-wrote this addon to use the ip2location module created for this addon - http://addons.oscommerce.com/info/6955

 

I did this to improve the realiabiliy of the addon. Thinking the wipmania API is only 99.9%  - that would mean one in evey 1000 hits the API fails (that is several customers per day for me).

 

I was having issues, I had presumed, where 1 in every 100+ or so orders customers are 0 (no currecy, symbol or decimal). In additional I was receving phone calls about 1 every 2 or 3 days with the complaint of no prices showing.

 

So, although my addon works - it did not fix the issues mentioned above. So, I NOW presume the issues caused by the code I carried forwared in appliation top but not sure why or where? I presumed this if statement would return default currency if the location was blank?

if ($location == ''){
		// $location is blank, use default method so we don't get $0 prices or in some cases no product listed.
		$currency = (USE_DEFAULT_LANGUAGE_CURRENCY == 'true') ? LANGUAGE_CURRENCY : DEFAULT_CURRENCY;

But aparently it's not working... or I'm not understanding????

 

Anyway here is my code...

	require_once (DIR_WS_MODULES . 'ip2location/ip2location.php');

	$ip = IP2Location_open(DIR_WS_MODULES . 'ip2location/IP-COUNTRY-REGION-CITY-SAMPLE.BIN', IP2LOCATION_STANDARD);
	$record = IP2Location_get_all($ip, $_SERVER['REMOTE_ADDR']);
	IP2Location_close($ip);
		
	$location = $record->country_short;
	
	if ($location == ''){
		// $location is blank, use default method so we don't get $0 prices or in some cases no product listed.
		$currency = (USE_DEFAULT_LANGUAGE_CURRENCY == 'true') ? LANGUAGE_CURRENCY : DEFAULT_CURRENCY;
	}else{
		//since it has not been determined, find the currency it needs to be changed to
		$currency_id_result=tep_db_query("SELECT countries_currencyid FROM countries WHERE countries_iso_code_2='".$location."'");
		
		while($currency_row=tep_db_fetch_array($currency_id_result)) {
			$currency_id=$currency_row['countries_currencyid'];
		};
	
		//create session variable to show that it has now been determined
		$currency=$currency_id;
		$_SESSION['locationset']=$location;
		$_SESSION['currency']=$currency;
	}

//END OF ALTERATIONS

My latest version of this code "seems" reliable.... However, I'm don't understand why the above is not working and my new code changes the last lines to hard code the currency... Making it less useable by the community in general

		//create session variable to show that it has now been determined
		if ($currency_id != 'CAD') {
		$currency='USD'; }
		else {
		$currency='CAD'; }
		$_SESSION['locationset']=$location;
		$_SESSION['currency']=$currency;

Does this mean its not setting the session??? Or is the "if statement" mentioned above not placed correctly????

 

Hi Scott,

 

I too am a fellow shop owner, not a trained coder, but can hack my way through some code...

 

Not sure if you are still looking at this program, but I am working on a variation for osCmax (it will also work in osCommerce to keep on topic here) and will post any changes needed to get it working. I do believe that nouveau9's suggestion just above this post will resolve your posted problem with a few miner tweaks. For example I do not think the countries_id needs to be 300, unless he wanted it always at teh very end of the countries list...

 

John :-#)#

Edited by Pinball

Share this post


Link to post
Share on other sites

Hi guy,

 

There my code that I write, the pb this code is made for the next release 2.4 and not 2.3. I have no time to propose an update on the module than I make before. In this case, I can propose you the module for 2.4.

It's very simple approach and you can update for the 2.3 easily.
The approach is under hook but you can create another hook or class fir 2.3. It's your choice.

 

To introduce the code, you need :

 

Update the hook for 2.3 (call jus below)

Update this function : getJsonCustomerData() about the cache

Update the install db for 2.3 approach.

change OSCOM::GetIpAddress() by the appropriate function osc 2.3 (tep_get_ip_address())

 

That's all I think.

 

insertl the hook at the bottom of application_top.php (of course updated for 2.3)

Registry::get('Hooks')->call('AllShop', 'CurrenciesGeolocalisation');

Hook system.

  class CurrenciesGeolocalisation {

    protected $spider_flag;

    public function __construct() {
      global $spider_flag;

      $this->UrlAPISSL = "https://ssl.geoplugin.net/json.gp?ip=";
      $this->SSLKey = CONFIGURATION_CURRENCIES_GEOLOCALISATION_SSLKEY;
      $this->UrlAPI = 'http://www.geoplugin.net/json.gp?ip=';
      $this->spiderFlag = $spider_flag;
      $this->ipCustomer = OSCOM::GetIpAddress();
    }

/*
 * indicate different informations on the customer
 * @[member=param] $localisation_array return an array on the localisation
 * @[member=access] public
*/
    private function setUrlAPI() {

      if (!empty($this->SSLKey) && !is_null($this->SSLKey)) {
        $url = $this->UrlAPISSL . $this->ipCustomer . '&k=' . $this->SSLKey;
      } else {
        $url = $this->UrlAPI . $this->ipCustomer;
      }
      return $url;
    }

//------------------------------------------------------
//  Debug
//------------------------------------------------------
/**
 * Display all git information inside a repository or sub directory
 * @[member=param] $result, repository to analyse
 * @[member=Return] $repo,values of array of all git information
 * @[member=access] public
 */
    public function displayDataAPI() {
      $data = '<pre>' . print_r($this->setUrlAPI(), true) . '</pre>';
      return $data;
    }

/**
 * getJsonCustomerData
 * @[member=param]
 * @[member=Return] $result all data for customer identification and insert in cahce
 * @[member=access] private
 */
    private function getJsonCustomerData()  {
      $OSCOM_Cache = Registry::get('Cache');

      $ip = str_replace('.', '_', $this->ipCustomer);

      if($OSCOM_Cache->read('geolocalisation-' . $ip, 60)) {
        $result = $OSCOM_Cache->getCache();
      } else {
        $url = file_get_contents($this->setUrlAPI() ); //content of readme.
        $data = json_decode($url);

        $result = $OSCOM_Cache->write($data, 'geolocalisation-' . $ip);
      }

      return $result;
    }


/**
 * getCustomerCountryCode
 * @[member=param]
 * @[member=Return] $country_code,code iso 2 of the country - FR
 * @[member=access] public
 */
    public function getCustomerCountryCode() {

      $data = $this->getJsonCustomerData();
      $country_code = $data->geoplugin_countryCode;

      return $country_code;
    }

/**
* getCustomerCountryName
* @[member=param]
* @[member=Return] $country_code, name of the country - FRANCE
* @[member=access] public
*/
    public function getCustomerCountryName() {

      $data = $this->getJsonCustomerData();
      $country_code = $data->geoplugin_countryName;

      return $country_code;
    }

/**
* getCustomerRegionCode
* @[member=param]
* @[member=Return] $region_code, region of the country name - Jura
* @[member=access] public
*/
    public function getCustomerRegionCode() {

      $data = $this->getJsonCustomerData();
      $region_code = $data->geoplugin_regionCode;

      return $region_code;
    }

/**
* getCustomerRegionName
* @[member=param]
* @[member=Return] $region, baem of region of the country name - Jura
* @[member=access] public
*/
    public function getCustomerRegionName() {

      $data = $this->getJsonCustomerData();
      $region = $data->geoplugin_regionName;

      return $region;
    }

/**
 * getCustomerContinent
 * @[member=param]
 * @[member=Return] $continent, conteninent of the country - NA / EU / AS ...
 * @[member=access] public
 */

    public function getCustomerContinent() {

      $data = $this->getJsonCustomerData();
      $continent = $data->geoplugin_continentCode;

      return $continent;
    }

/*
 * Currency in function the localisation
 * @[member=param] $new_currency return the currency in function the localisation
 * @[member=access] public
 * osc_get_currencies_location
*/
    public function GetCurrenciesLocation() {

      $country_code2 = $this->getCustomerCountryCode();

      if ($this->getCustomerContinent() == 'NA') {
        if ($country_code2 == 'CA') {
          if (DEFAULT_CURRENCY != 'CAD') {
            $new_currency = 'CAD';
          } else {
            $new_currency = DEFAULT_CURRENCY;
          }
        } elseif ($country_code2 == 'US') {
          if (DEFAULT_CURRENCY != 'USD') {
            $new_currency = 'USD';
          } else {
            $new_currency = DEFAULT_CURRENCY;
          }
        } else {
          $new_currency = DEFAULT_CURRENCY;
        }
      } elseif ($this->getCustomerContinent() == 'EU') {
        if ($country_code2 == 'EU') {
          if (DEFAULT_CURRENCY != 'EUR') {
            $new_currency = 'EUR';
          } else {
            $new_currency = DEFAULT_CURRENCY;
          }
        } else {
          $new_currency = DEFAULT_CURRENCY;
        }
      } else {
          $new_currency = DEFAULT_CURRENCY;
      }

      return $new_currency;
    }


/*
 * Define currency in function the localisation
 * @[member=param]
 * @[member=Return] : false is nothing else return the currency
 * @[member=access] public
 * osc_get_currencies_location
*/
    private function getCurrenciesByGeolocalization() {
        if (CONFIGURATION_CURRENCIES_GEOLOCALISATION == 'true') {
          $currencies_by_geolocalization =  $this->GetCurrenciesLocation();
        } else {
          $currencies_by_geolocalization = false;
        }
      return $currencies_by_geolocalization ;
    }

/*
 * Install db if does'nt exist
 * @[member=param]
 * @[member=access] private
 *
*/
    private function install()  {
      $OSCOM_Db = Registry::get('Db');
      $OSCOM_Language = Registry::get('Language');

      if ($OSCOM_Language->getID() == 1) {
         $OSCOM_Db->save('configuration', [
          'configuration_title' => 'Souhaitez-vous afficher une devise automatique par défaut en fonction du continent ?',
          'configuration_key' => 'CONFIGURATION_CURRENCIES_GEOLOCALISATION',
          'configuration_value' => 'false',
          'configuration_description' => 'En fonction de la provenance du client et de son continent, le tarif du produit prend par défaut la devise du continent du client.<br /><br /><u><strong>Note :</strong></u><br />- Les devises par défaut implémentées sont : USD, EUR, CAD <br />- Si le client provient d\'un autre continent, ce sera la devise par défaut qui s\'affichera.<br />- L\'ajustement automatique des devises en fonction de la langue ne fonctionne pas dans ce cas.<br />L\'analyse de l\'addresseIP du client est faite à partir de ce site : http://geoplugin.net.<br'>http://geoplugin.net.<br />Veuillez lire leurs instructions.<br /><br /><i>(Valeur True = Oui - Valeur False = Non)</i>',
          'configuration_group_id' => '1',
          'sort_order' => '9',
          'set_function' => 'osc_cfg_set_boolean_value(array(\'true\', \'false\'))',
          'date_added' => 'now()'
          ]
        );

        $OSCOM_Db->save('configuration', [
            'configuration_title' => 'Souhaitez-vous indiquer la clef pour une certification SSL de géolocalisation en fonction de la devise automatique continent (non obligatoire) ?',
            'configuration_key' => 'CONFIGURATION_CURRENCIES_GEOLOCALISATION_SSLKEY',
            'configuration_value' => '',
            'configuration_description' => 'Le site http://geoplugin.net peut vous fournir une clef qui vous permettra d\avoir une connexion sécurisée. Veuillez vous y référer pour plus d\'informations</i>',
            'configuration_group_id' => '1',
            'sort_order' => '9',
            'set_function' => '',
            'date_added' => 'now()'
          ]
        );
      } else {
         $OSCOM_Db->save('configuration', [
             'configuration_title' => 'Do you want display an automatic default currency by continent ?',
             'configuration_key' => 'CONFIGURATION_CURRENCIES_GEOLOCALISATION',
             'configuration_value' => 'false',
             'configuration_description' => 'Depending on the source of the client and the continent, the price is updated in function the customer continent.<br /><br /><u><strong>Note :</strong></u><br />- The default currency implemented are: USD, EUR, CAD <br />- If the customer comes from another continent, it will be the default currency that is displayed.<br />- The automatic adjustment of currencies depending the language does not work in this case.',
             'configuration_group_id' => '1',
             'sort_order' => '9',
             'set_function' => 'osc_cfg_set_boolean_value(array(\'true\', \'false\'))',
             'date_added' => 'now()'
           ]
         );

        $OSCOM_Db->save('configuration', [
            'configuration_title' => 'Do you want insert a Key for SSL certification for your automatic currencies by continent (no mandatory) ?',
            'configuration_key' => 'CONFIGURATION_CURRENCIES_GEOLOCALISATION_SSLKEY',
            'configuration_value' => '',
            'configuration_description' => 'The website http://geoplugin.net can propose you a SSL key for a secure connexion. Please go on website and see their documentation',
            'configuration_group_id' => '1',
            'sort_order' => '9',
            'set_function' => '',
            'date_added' => 'now()'
          ]
        );
      }
    }

    public function execute() {
      if (!defined(CONFIGURATION_CURRENCIES_GEOLOCALISATION) == true || CONFIGURATION_CURRENCIES_GEOLOCALISATION == null || empty(CONFIGURATION_CURRENCIES_GEOLOCALISATION)) {
        $this->install();
      }

      if ($this->spiderFlag === false) {
        if ($this->getCurrenciesByGeolocalization() != false) {
          $_SESSION['currency'] = $this->getCurrenciesByGeolocalization();
        }

        return $_SESSION['currency'];
      }
    }
 }


Regards
-----------------------------------------
Loïc

Contact me by skype for business
Contact me @gyakutsuki for an answer on the forum

Tuto for 2.4 :
- How to Display a new page with app
- How to make Header Tags under app APP
- How to make a
boostrap modal with external element
 

 

Share this post


Link to post
Share on other sites

Loic, looks like you wrote new code (based on http://www.geoplugin.net/json.gp?ip=) to do much the same job that the original program did with http://api.wipmania.com/.

 

However I'm no code jockey so I can't easily tell if this code is stand alone, or if it replaced the code that was originally intended to go in application_top.php - can you explain better what your code is supposed to do?

 

For example, this program should only happen once - when the customer goes to your site. Afterwards the customer should be able to change the currency to whatever they prefer, and this program snippet should not try to force them back to their IP signed currency.

Share this post


Link to post
Share on other sites

It can do that. First it force the devise because it identfy the ip and your configuration. After if you display the currency box, the customer can change. Do not test exactly; I will try.

Edited by Gyakutsuki


Regards
-----------------------------------------
Loïc

Contact me by skype for business
Contact me @gyakutsuki for an answer on the forum

Tuto for 2.4 :
- How to Display a new page with app
- How to make Header Tags under app APP
- How to make a
boostrap modal with external element
 

 

Share this post


Link to post
Share on other sites

Hi,

 

I've installed v1.2 of this contrib and it looks like wipmania.com is returning "US" as location when in fact I'm in Canada. I went to wipmania.com directly and they detected my location properly as Canada.

 

My store is in Canada, default currency is CAD, we want the currency to switch to USD only for US customers, everything else should be CAD.

I've tried @@greasemonkey's version using ip2location but I found that the prices didn't show up at all on Safari/Webkit.

 

I played with the 1.2 code a little to force USD or CAD (hard coded with no DB query), and the problem really appears to be that wipmania is returning "US" as my location (unless I go to their site). As opposed to wipmania returning "XX", or a blank $location.

So I'm stumped, why is wipmania giving me mixed results?
Or why is ip2location causing the no-price problem on Safari/Webkit, but not Chrome?

 

Any help is greatly appreciated!

Edited by cinolas

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×