magento / magento2

Prior to making any Submission(s), you must sign an Adobe Contributor License Agreement, available here at: https://opensource.adobe.com/cla.html. All Submissions you make to Adobe Inc. and its affiliates, assigns and subsidiaries (collectively “Adobe”) are subject to the terms of the Adobe Contributor License Agreement.
http://www.magento.com
Open Software License 3.0
11.5k stars 9.3k forks source link

Paypal through Braintree ( MultiStore + MultiCurrency ): Paypal Transitions Declined #10596

Closed valerioacerbis closed 7 years ago

valerioacerbis commented 7 years ago

Preconditions

Magento2.1.4 Magento2.1.7

I have 4 websites in a single installation magento2: (# 1) EU Website: EUR (# 2) UK Website: GBP (# 3) USA Website: USD (# 4) WORLD Website: USD

The default currency is GBP.

Steps to reproduce

If I make an order by selecting as a "paypal through braintree" payment gateway from the website (# 2), the order is processed correctly.

However, if you place a paypal through braintree order on other websites (# 1, # 3, # 4), the transaction is declined.

Expected result

Paypal transaction completed correctly in all currencies and across all websites.

Actual result

If you place a paypal through braintree order on other websites (# 1, # 3, # 4), the transaction is declined.

Support Braintree & Paypal Response

I contacted the supposrt of Braintree and this is her answer:

"Hi Valerio,

I am Maximilien from the Braintree Technical Support team, and I've heard about your issue from my PayPal colleague Andrea.

I understand that PayPal transactions processed in GBP, such as 5abntat2, work properly whereas transactions in EUR or USD such as fc0vtw12 or cd69ymyp are systematically failing with the error 2091 Currency of this transaction must match currency of your PayPal account.

After deep investigation I managed to find the origin of this issue which lies into your Magento integration. In order to explain what happens I need to explain how our PayPal Checkout flow works with the following workflow: The customer arrives on your payment page. Your website loads the PayPal button using the following code: [...] flow: 'checkout' amount: 10.00 // Dynamically set by your integration currency: 'USD' // Dynamically set by your integration [...] The customer clicks on the PayPal button, specifies his PayPal account and clicks on submit. The request is then sent to your server which creates a transaction specifying the merchant_account_id to charge in order to determine the currency.

That being said, let's look together in details at transaction cd69ymyp. The following logs represent the API request sent by your server to Braintree (step 4 of the workflow detailed above): May 18 07:51:39 Parameters: {"transaction"=>{"type"=>"sale", "customer"=>{"first_name"=>"name", "last_name"=>"lastname", "company"=>nil, "phone"=>"1234", "email"=>"email@gmail.com"}, "amount"=>"6.00", "payment_method_nonce"=>"97ecfd17-1564-0929-23b0-5c6b9cca5bac", "order_id"=>"2000000007", "merchant_account_id"=>"rossanoferrettiUSD", "channel"=>"Magento2_Cart_Community_BT", "device_data"=>"{\"correlation_id\":\"785a41b2a5f3ba85a38c94caede0429a\"}"}, "merchant_id"=>"n636kb5n4gj8rmq8"} As you can see, your server properly specified rossanoferrettiUSD as merchant_account_id in order to charge in USD. However, PayPal returned the error Currency of this transaction must match currency of your PayPal account.

Sticking to the same transaction, let's look at the logs of the PayPal pop-up initiation (step 3 of the workflow detailed above): May 18 07:50:51 Parameters: {"authorization_fingerprint"=>"c53e4537cefdce9fcc96a673acea623a915e651d2cd667cef8dc04904ad71368|created_at=2017-05-18T07:50:32.585959041+0000&merchant_account_id=rossanoferrettiUSD&merchant_id=n636kb5n4gj8rmq8&public_key=7qrsncwphg2ktjvf", "return_url"=>"https://checkout.paypal.com/pwpp/2.25.0/html/redirect-frame.html?channel=c869b68e-41ae-42ed-a14a-d1a95865389a", "cancel_url"=>"https://checkout.paypal.com/pwpp/2.25.0/html/cancel-frame.html?channel=c869b68e-41ae-42ed-a14a-d1a95865389a", "correlation_id"=>"c869b68e-41ae-42ed-a14a-d1a95865389a", "experience_profile"=>{"brand_name"=>"Rossano Ferretti Ltd", "locale_code"=>"gb", "no_shipping"=>"false", "address_override"=>"false"}, "amount"=>"6.00", "currency_iso_code"=>"GBP" , "recipient_name"=>"name lastname", "line1"=>"United States", "city"=>"miami", "country_code"=>"US", "pos We can clearly see "currency_iso_code"=>"GBP" which means that when your website loaded the PayPal button (step 2 of the workflow detailed above), it specified within the code currency: 'GBP' and it explains the error returned by PayPal. Indeed, your server is trying to charge in USD a transaction initiated in GBP.

In order to solve that issue, you need to make sure that during the step 2, your website dynamically specifies the proper currency in the code. I would recommend reaching out to your web developer in order to make that verification.

I hope this helps and I remain available if you need anything else!

Best, Maximilien F. Braintree"

Paypal's support also advised me to write directly to Magento's Github repo.

"Hi Valerio,

Thank you for contacting PayPal Merchant Technical Services. I understand that your Magento 2 store is not setting the correct PayPal currency on the client-side with Braintree integration. While Magento is a third-party cart system, where we have no control or visibility, I informed our Braintree team about this. I would also suggest contacting Magento directly by opening an issue on their Github repo here as their developers directly respond to questions there.

Sincerely, Orcun Merchant Technical Support PayPal"_

This is instead the answer of Paypal support:

Hi Valerio,

Thanks for reaching out!

I'm happy to assure you that PayPal through Braintree (and Express Checkout) is definitely capable of supporting multicurrency! I've therefore looked into our logs here, and have ascertained the issue.

On your client-side for PayPal, you're passing us the following details:

Jul 11 16:10:15 Parameters: {"return_url"=>"https://checkout.paypal.com/pwpp/2.25.0/html/redirect-frame.html?channel=c26dc3b2-aed7-4868-9be4-d3164c3c139f", "cancel_url"=>"https://checkout.paypal.com/pwpp/2.25.0/html/cancel-frame.html?channel=c26dc3b2-aed7-4868-9be4-d3164c3c139f", "correlation_id"=>"c26dc3b2-aed7-4868-9be4-d3164c3c139f", "experience_profile"=>{"brand_name"=>"Rossano Ferretti Ltd", "locale_code"=>"it", "no_shipping"=>"false", "address_override"=>"false"}, "amount"=>"6.01", "currency_iso_code"=>"GBP", "recipient_name"=>"Name Lastname", "line1"=>"via manzoni n.ro 10", "city"=>"Milano", "country_code"=>"IT", "postal_code"=>"25019" ....

As you can see, the currency is being set to GBP.

However, when passing us details for the transaction, we're receiving the following:

Jul 11 16:10:43 Parameters: {"transaction"=>{"type"=>"sale", "customer"=>{"first_name"=>"Name", "last_name"=>"Lastname", "company"=>nil, "phone"=>"123123123", "email"=>"email@xxx.com"}, "amount"=>"6.01", "payment_method_nonce"=>"bc5a8fd5-1c46-0a38-2412-3cde1b55e3d2", "order_id"=>"6000000049", "merchant_account_id"=>"rossanoferrettiEUR", "channel"=>"Magento2_Cart_Community_BT", "device_data"=>"{\"correlation_id\":\"bcbeed1998efd1c0b2a02579d33b9908\"}"}, "merchant_id"=>"n636kb5n4gj8rmq8"}

The Merchant Account ID we're receiving, rossanoferrettiEUR, is for a Euro Merchant Account.

As such, there's a mismatch between the currency the transaction was initially authorised for, and the currency the transaction attempt is being made in. This is why you're receiving the error 2091 - Currency of this transaction must match currency of your PayPal account.

If you ensure the currency code passed on the client side matches the currency of the Merchant ID passed in the server side call, this should resolve the issue for you.

Please feel free to let us know if you encounter any further issues!

Kind regards,

joni-jones commented 7 years ago

Hi, @valerioacerbis, seems you have not defined the Base currency for each website. Magento sends to Braintree PayPal the amount in a base currency and the base currency (according to your configuration it always will be GBP). In your case, each website should have own base currency configuration.

If you open Stores -> Configuration -> General -> Currency Setup -> Base Currency, you will see the next tip:

Base currency is used for all online payment transactions. The base currency scope is defined by the catalog price scope ("Catalog" > "Price" > "Catalog Price Scope").

By default the Catalog Price Scope is Global and the one base currency will be used for all websites, you need to change this option to Website and define the base currency for each website.

So described behavior is not an issue but misconfiguration for multiple websites.

valerioacerbis commented 7 years ago

Many Thanks @joni-jones.