Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Magento 1.9 wrong currency symbol in order confirmation email cart - when paying with PayPal - formatPrice()

I have Magento 1.9.0.1 running with GBP (£) as the base and default display currency, and Euros (€) as an allowed currency.

If the user chooses to checkout in Euros, the site all works except, if they pay by PayPal in their own currency, then the order confirmation email has a mistake. On my test below I checked out in Euros (€) but my PayPal account was using Pounds (£).

The cart's Item Price and Sub Total show in Euros, but with a £ symbol. The Sub Total, Delivery & Total all appear in Euros, with the correct € symbol.

The example below shows a basic representation with approximate prices:

Items       Quantity    Item Price    Sub Total
---         ---         ---           ---
Product     1           £150.00       £150.00  <<-- These £'s should be €'s
-----------------------------------------------
Sub Total:                  €150.00 
Delivery:                   €0.00 
Total:                      €150.00 
Grand Total to be Charged:  £100.00

I've tried to track it down, but I'm not sure where it goes wrong, and it's a nightmare to test. The email calls:

(Mage_Checkout_Helper_Data) $this->helper('checkout')->formatPrice(...);

That calls

(Mage_Core_Model_Store) $this->getQuote()->getStore()->formatPrice($price);

Which eventually finds its way to Zend currency methods, but I don't know where the currency symbol is getting lost.

This problem only occurs when checking out with PayPal, not when paying by CC directly through the site.

Can anyone point me in the right direction? Thanks

like image 584
Jamie G Avatar asked Sep 14 '15 12:09

Jamie G


1 Answers

In the confirmation email, there should be no call to $this->helper('checkout')->formatPrice(...) anywhere. If this is the case, the order email uses the checkout item templates instead of its own, which is probably caused by a not fully implemented custom product type or a bug in your theme.

The order totals show the right currency because the totals block uses the formatPrice() method of the order, which takes the currency of the order into account:

$this->getOrder()->formatPrice($total->getValue());

The templates for the single items also use $_order->formatPrice(...). But depending on the product type, different templates are used. This is the default template.

The blocks and templates for each product type are defined in sales.xml with the addItemRender action:

<sales_email_order_items>

    <block type="sales/order_email_items" name="items" template="email/order/items.phtml">
        <action method="addItemRender"><type>default</type><block>sales/order_email_items_order_default</block><template>email/order/items/order/default.phtml</template></action>
        <action method="addItemRender"><type>grouped</type><block>sales/order_email_items_order_grouped</block><template>email/order/items/order/default.phtml</template></action>
        <block type="sales/order_totals" name="order_totals" template="sales/order/totals.phtml">
            <action method="setLabelProperties"><value>colspan="3" align="right" style="padding:3px 9px"</value></action>
            <action method="setValueProperties"><value>align="right" style="padding:3px 9px"</value></action>
            <block type="tax/sales_order_tax" name="tax" template="tax/order/tax.phtml">
                <action method="setIsPlaneMode"><value>1</value></action>
            </block>
        </block>
    </block>
    <block type="core/text_list" name="additional.product.info" />
</sales_email_order_items>

Modules that add product types have to register their own renderers there, as it can be seen in bundle.xml:

<sales_email_order_items>
    <reference name="items">
        <action method="addItemRender"><type>bundle</type><block>bundle/sales_order_items_renderer</block><template>bundle/email/order/items/order/default.phtml</template></action>
    </reference>
</sales_email_order_items>

If this was not defined, the default renderer is the one from the checkout, where the order model itself is not used, just the single items (which have no currency information attached). There the price formatting is done by the checkout helper which has no information about the order, so it uses the currently selected store currency.

Why is this only a problem with online payments like PayPal? Because with other methods, where the order confirmation mail is created immediately with the "place order" button, the currently selected store currency is still the same as the order currency. But in the callback request from PayPal this context is lost and the default currency will be used instead.

What you need to do?

  1. Search for the <sales_email_order_items> layout handle in your layout XML files to see if the default item renderers are registered correctly
  2. Make sure that any custom product types also register their renderers
  3. Check the templates that are used by the item renderers. Maybe it's a bug in your theme and you just have to replace $this->_helper('checkout')->formatPrice() with $_order->formatPrice().
like image 186
Fabian Schmengler Avatar answered Oct 20 '22 18:10

Fabian Schmengler