I know this is not directly part of this module, but I thought it would be good for people to find this code in this area, rather than in the uc_paypal module issue queue. Actually, it would be great to have a currency lookup function using the country id number. That would allow a much cleaner patch to go into the uc_paypal module for uc_multiprice support, instead of my "switch" hack.

OK, so this module is great at allowing us to change currencies, but with Paypal checkout, we're stuck with the currency that was selected in the Website Payments Standard settings. To get around this limitation you need to modify the uc_paypal.module in ubercart/payment.

STEP 1: Add the following code in the uc_paypal_wps_form function, just before $data = array( (around line 849 in the 6.x-2.0rc3 release):

// default currency selection
  $currency = variable_get('uc_paypal_wps_currency', 'USD');

// uc_multiprice module support
if (module_exists('uc_multiprice')) {
  $country_id = uc_multiprice_country_id();
  $result = db_query("SELECT iso2 FROM {countries_api_countries} WHERE numcode = %d", $country_id);
  $iso2 = db_fetch_object($result)->iso2;
  switch ($iso2) {
    case 'CA':
      $currency = 'CAD';
      break;
    case 'US':
    default:
      $currency = 'USD';
      break;
  }
}

You will have to add in the specific currency you want as a new case statement, as I couldn't find an existing API function to do this.

STEP 2: A bit further down in the code (within the $data = array( section, delete or comment out the following line:

'currency_code' => variable_get('uc_paypal_wps_currency', 'USD'),

and add the following immediately after:

'currency_code' => $currency,

Now, when you checkout with Paypal, the currency that was selected by the user will be used.

Comments

wakeuphate’s picture

Category: feature » support

I'm not 100% sure whether or not this is my error here, but when i set the uc_paypal_wps_currency, the paypal sandbox seems to just ignore it and run the currency as the store standard (GBP). - I've tried hard coding it by in the array adding 'currency_code' => 'EUR', to take away any possible problems with the code before.. - but it still defaults to GBP.. is this a sandbox issue, or is the module just overwriting what i'm setting?

if i call variable_set('uc_paypal_wpp_currency', 'EUR'); earlier in my code, at form-level ( not in the paypal module file ), it seems to fix it... quite curious whether or not this is the best way to attack this or not, or the issues it may cause?

edit: now that I've just looked at this again.. i'm setting uc_paypal_wpp_currency and in the original we were playing with uc_paypal_wps_currency .. I'm not sure what the difference is.. but i'll have a look around.. I'm sure someone else knows though :).

achilles085’s picture

what i notice is i don't have this table on my database {countries_api_countries} it doesn't exist.
Why is this? but the defined price for every country is correct when in cart form. Is there any way
how to show the currency in price field like 100 AUD or 200 NZD?

Docc’s picture

countries_api_countries is from the ip2country/ip2cc module.
@achilles085 - See: #546084: Let different prices show different currencies for multiple currencies status

achilles085’s picture

StatusFileSize
new15.5 KB
new3.95 KB

@Docc: i manually patched the files. am i doing it right or not?
please see attached files(these are newly patched files,I converted it to .txt)

Docc’s picture

Hey achilles i committed the patch from #546084 to HEAD. So you can download it from the CVS. If you run in any bugs please let me know.

Docc’s picture

Status: Active » Closed (fixed)

Closing this issue, any related issues please post at #546084: Let different prices show different currencies

Anonymous’s picture

I had a similar problem. I had a pretty simple setup, so I fixed it (based on the excellent suggestions above), by adding the following to uc_paypal.module's uc_paypal_wps_form:

  $countrycode = uc_multiprice_country_id();
  if ($countrycode == 36) {
  	$currency = 'AUD';
  }
  else {
  	$currency = 'USD';
  }

Then I followed Step 2 as mentioned in the first post.

pedrochristopher’s picture

Note that uc_paypal_wps_currency and uc_paypal_wpp_currency are different variables that you should set in your template.php file (or elsewhere) if you need paypal to check out in a specific currency. The former is for website payments standard, the latter, for website payments pro. So depending on which one you are using, you would set that variable. Or just to be on the safe side, set both! For instance in template.php:

  $currency_chars = $_if_limey_local_function() ? 'GBP' : 'USD';
  variable_set ('uc_paypal_wpp_currency', $currency_chars);
  variable_set ('uc_paypal_wps_currency', $currency_chars);
hixster’s picture

subscribing

stella’s picture

Project: UC Multiprice » Ubercart
Version: 6.x-1.0 » 6.x-2.6
Component: Code » Module integration
Category: support » feature
Status: Closed (fixed) » Needs review
StatusFileSize
new3.24 KB

PayPal Express Checkout doesn't support uc_multiprice module so the currency is always set to the default setting and never what the user selects during checkout.

Attached patch adds support for this, though could be potentially extended to only change the currency code for the currencies supported by PayPal.

Moving to ubercart issue queue.

Status: Needs review » Needs work

The last submitted patch, 512186.patch, failed testing.

longwave’s picture

In Ubercart 2.6 there is a new $order->currency property that can be used here, the PayPal module should use this instead and uc_multiprice should set it appropriately.

stefan81’s picture

I agree with longwave.

I have a working solution:

Insert new function, at the end of uc_multiprice.module:

/**
 * Save Currency to order
 */
function uc_multiprice_save_currency_to_order($order_id) {
	
	// get the country
	$country_code = db_result(db_query("SELECT billing_country FROM {uc_orders} WHERE order_id = %d", $order_id));
	
	// get the currency
	$currency_code = uc_multiprice_currency($country_code);

	// Save the currency code
	db_query("UPDATE {uc_orders} SET currency = '%s' WHERE order_id = %d", $currency_code, $order_id);
	
	}

Then make sure that the currency is saved at any occasion.

insert the following line inside the function uc_multiprice_order, below line 425:

      uc_multiprice_save_currency_to_order($arg1->order_id); // Save Currency

should look like:

function uc_multiprice_order($op, &$arg1, $arg2) {
  switch ($op) {
    case 'save':
      uc_multiprice_save_country_to_order($arg1->order_id);
      uc_multiprice_save_currency_to_order($arg1->order_id); // Save Currency
      break;
  }
}

insert the following line inside the function uc_multiprice_country_id, below line 587:

      uc_multiprice_save_currency_to_order($order_id); // Save Currency

should look like:

    // If we have an order, update the country associated with it.
    if (($order_id = intval($_SESSION['cart_order'])) > 0) {
      uc_multiprice_save_country_to_order($order_id);
      uc_multiprice_save_currency_to_order($order_id); // Save Currency
    }

and then alter uc_paypal.module:

replace the following line (958)

    'currency_code' => variable_get('uc_paypal_wps_currency', 'USD'),

with

    'currency_code' => $order->currency,

with a module check it should look like:

if (module_exists('uc_multiprice')) {
    'currency_code' => $order->currency,
} else {
    'currency_code' => variable_get('uc_paypal_wps_currency', 'USD'),
}

this works with me so far.

timezero’s picture

Is it possible to filter out the paypal payment option if the user selected a currency which paypal does not support?

fonant’s picture

Since the $order now stores the currency code in $order->currency for all orders (fixed in #607708: Allow defining currency code per order, I would suggest that the fix in uc_paypal.module is even simpler:

Change line 958 from:

'currency_code' => variable_get('uc_paypal_wps_currency', 'USD'),

to:

'currency_code' => $order->currency,

then any module that wants to modify the order's currency can simply update $order->currency to have the ISO code.

longwave’s picture

Version: 6.x-2.6 » 6.x-2.x-dev
Status: Needs work » Needs review
StatusFileSize
new5.48 KB

Patch attached that implements #15

tr’s picture

What happens when the order currency is not one of the currencies that PayPal supports?

longwave’s picture

PayPal will (presumably) throw an error. But this is surely better than the previous situation where the store owner had to configure the currency three times if using PayPal WPS and WPP; I can't see a use case for setting the store currency to one value and the PayPal currency to another.

tr’s picture

Yes, this is something that we should do, I'm just saying it should be done right. Meaning, either the patch should ensure only valid currencies get passed to PayPal or there should be error handling code to deal with the error that PayPal may or may not return if the currency is invalid.

yaworsk’s picture

I tried testing out this patch but am running into issues...

I'm trying to pass a specific currency to paypal depending on a user's selection (it's not intended to change the price, just the currency) - for now i've just created a module that implements hook_order as follows:

function custom_alter_order($op, &$arg1, $arg2) {
    if ($op == 'new') {
        $arg1->currency = 'CND';
    }
}

Despite having the patch applied, the currency doesn't seem to be being passed to paypal - every order on paypal still says USD and when I try to pay, I get an error saying the country isn't shippable.

stumped as to why teh proper currency code (i.e., 'CND') wasn't being sent to paypal, i replaced the existing function uc_paypal_api_request($request, $server) with only two dsm statements:

function uc_paypal_api_request($request, $server) {
dsm($request);
dsm($server);
}

yet somehow the paypal module is still redirecting and sending information?!? any ideas? I am using a sandbox account.

Also, out of curiosity, i wiped out the entire uc_paypal.module file contents and I get errors on the site about paying with paypal so i am looking at the right file I would assume...

longwave’s picture

Which of the PayPal methods are you using? WPP and EC use uc_paypal_api_request(), but WPS uses uc_paypal_wps_form() instead.

yaworsk’s picture

ah, thanks for that!!! Was pulling my hair out, should have gave up when it was so late and gone back at it fresh. So now I see where I made two dumb mistakes... first, yup, uc_paypal_wps_form was being called and second, the Canada code is CAD, not CND... paypal wasn't recognizing it and defaulting to USD.

Paypal rejecting the address as unshippable was related to teh address I was using - I probably have a setting somewhere only to ship to US addresses as when I use a US shipping address in UC and pass that to paypal, it all works in my sandbox.

Thanks for the speedy help, really appreciate it. So should confirm the patch is working for me.

tr’s picture

Version: 6.x-2.x-dev » 7.x-3.x-dev
Component: Module integration » Payment
Status: Needs review » Needs work

Changing status, which I evidently forgot to do in #19.

Also, new features should really go into 7.x-3.x first.

Patches welcome ...

longwave’s picture

Version: 6.x-2.x-dev » 7.x-3.x-dev

Re: #19 - if the currency is not available in the PayPal account the error is correctly handled; the order is left pending with the admin comment "Payment is pending at PayPal: You must manually accept or deny a payment of this currency from your Account Overview.", which I think is all we can do here.

edit: If the currency code does not exist at all, PayPal seems to assume USD instead.

longwave’s picture

Version: 7.x-3.x-dev » 6.x-2.x-dev
Status: Needs work » Needs review

As the patch is for 6.x-2.x and the other multicurrency patches target this branch, let's do this there to start with.

freelylw’s picture

any conclusion for how to change the currency in 6.x ???