Currency conversion

Help for integrating the Laravel package
Forum rules
Always add your Laravel, Aimeos and PHP version as well as your environment (Linux/Mac/Win)
Spam and unrelated posts will be removed immediately!
kdim95
Advanced
Posts: 207
Joined: 26 Aug 2022, 12:17

Currency conversion

Post by kdim95 » 30 Mar 2023, 13:54

Laravel framework version: 9.52.4
Aimeos Laravel version: ~2022.10
PHP Version: 8.2.4
Environment: Linux

Hello,

I'm looking to convert the currency to EUR with a fixed conversion rate for the PayPalExpress payment provider.

The problem is that the store will work only with one specific currency, but I want to change the currency when making the order. That is because PayPal does not work with the currency that the store will support, so I need to convert it to euro.

How should I make this change?

So far I've created a decorator for the payment service and added it to the provider, not sure if this is the correct approach.
My plan is to update the order with the new currency id and recalculate the value here.

Code: Select all

namespace Aimeos\MShop\Service\Provider\Decorator;

class CurrencyToEuro
	extends \Aimeos\MShop\Service\Provider\Decorator\Base
    implements \Aimeos\MShop\Service\Provider\Decorator\Iface
{
	public function process( \Aimeos\MShop\Order\Item\Iface $order, array $params = [] ) : ?\Aimeos\MShop\Common\Helper\Form\Iface
	{	
		$ref = ['order/base/address', 'order/base/coupon', 'order/base/product', 'order/base/service'];
		$orderBaseItem = $this->getOrderBase( $order->getBaseId(), $ref );
		
		$form = $this->getProvider()->process( $order, $params );
		
		return $form;
	}
}

User avatar
aimeos
Administrator
Posts: 7908
Joined: 01 Jan 1970, 00:00

Re: Currency conversion

Post by aimeos » 02 Apr 2023, 11:24

The only way this will work is if you overwrite the getAmount() method in a new provider extending from the PayPalExpress payment service provider and convert the currency amount right before it's sent to PayPal:
- https://github.com/aimeos/aimeos-core/b ... #L308-L342

For example in MShop/Service/Provider/Payment/MyPayPal.php

Code: Select all

class MyPayPal extends PayPalExpress
{
	protected function getAmount( \Aimeos\MShop\Price\Item\Iface $price, bool $costs = true, bool $tax = true,
		int $precision = null ) : string
	{
		// ...
	}
}
Use "MyPayPal" as name in the service panel as payment provider name.
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

kdim95
Advanced
Posts: 207
Joined: 26 Aug 2022, 12:17

Re: Currency conversion

Post by kdim95 » 03 Apr 2023, 16:02

Thank you, your suggestion helped me a lot!

I overrided the getAmount() and send() methods.

Inside the getAmount() I check if $price->getCurrencyId() is the currency ID I want to modify and convert the $amount to EUR using a fixed conversion rate.

Inside the send() method I check if there are the keys CURRENCYCODE and PAYMENTREQUEST_0_CURRENCYCODE and change the strings to EUR.

If the conversion rate is not fixed, another method will be required to get the correct conversion rate dynamically from somewhere, but I am unsure if the payment will pass if the callback comes and the conversion has changed.

Code: Select all

namespace Aimeos\MShop\Service\Provider\Payment;

class PayPalExpressCustom extends PayPalExpress
{
	
	private $conversionRate = <THE CONVERSION RATE>; // Currency conversion rate
	
	// Convert <THE CURRENCY CODE> to EUR
	protected function getAmount( \Aimeos\MShop\Price\Item\Iface $price, bool $costs = true, bool $tax = true, int $precision = null ) : string
	{
		$amount = parent::getAmount( $price, $costs, $tax, $precision );
		
		if( $price->getCurrencyId() !== '<THE CURRENCY CODE>' ) {
			return $amount;
		}
		
		$amount = $amount / $this->conversionRate;
		
		return number_format( $amount, $precision !== null ? $precision : $price->getPrecision(), '.', '' );;
	}
	
	// Change <THE CURRENCY CODE> currency code to EUR
	public function send( string $target, string $method, string $payload ) : string
	{
		$values = [];
		
		parse_str( $payload, $values );
		
		if( isset( $values['CURRENCYCODE'] ) && $values['CURRENCYCODE'] === '<THE CURRENCY CODE>' )
		{
			$values['CURRENCYCODE'] = 'EUR';
		}
		
		if( isset( $values['PAYMENTREQUEST_0_CURRENCYCODE'] ) && $values['PAYMENTREQUEST_0_CURRENCYCODE'] === '<THE CURRENCY CODE>' ) {
			$values['PAYMENTREQUEST_0_CURRENCYCODE'] = 'EUR';
		}
		
		$payload = http_build_query( $values, '', '&' );
		
		return parent::send($target, $method, $payload);
	}
}

Post Reply