woocommerce / woocommerce-ios

WooCommerce iOS app
https://www.woocommerce.com/mobile
GNU General Public License v2.0
299 stars 110 forks source link

Card payment options are not available in multi-currency store when the account has a different default currency #13580

Open staskus opened 1 month ago

staskus commented 1 month ago

Describe the bug

Testing Tap to Pay: After setting up TTP on my iPhone, I was invited to test it out with a $0.50 payments. However, IPP/TTP was not an option on the payment screen.

This issue is broader and affects all card payment (Card Reader, TTP) options and payment flows. If the store supports Multi-Currency and the account we use in the app has a different Default Currency set in Store's settings, then card payment options are not available. However, the Order itself indicates that it's being created with default store currency so it's not immediately clear why the options are unavailable.

To Reproduce

Before testing

  1. Set up a site with WooPayments, US location and USD currency
  2. Go to Payments -> Settings, scroll down to Advanced Settings and Enable Multi-Currency
  3. Go to Settings -> WooCommerce -> Multi-currency, add additional currency and enable Automatically switch customers to their local currency if it has been enabled
  4. Open your store on the browser, go to My Account, (yourstore.com/my-account/) and log into your account
  5. Open Account details and change Default currency to something different from USD

TTP Payment setup flow

  1. Open Woo app and log into the same account and site
  2. Menu
  3. Payments
  4. Set Up Tap to Pay on iPhone
  5. Try a Payment
  6. Take Payment ($0.50)
  7. Notice there're no 'Card Reader' and 'Tap to Pay on iPhone' option
  8. Change Default Currency in yourstore.com/my-account/ 'Account details' tab back to USD
  9. Repeat the steps, and notice Card Reader' and 'Tap to Pay on iPhone' option are available

https://github.com/user-attachments/assets/e4b411ed-a32b-499a-828a-2b151809f528

Order Creation flow

  1. Open Woo app and log into the same account and site
  2. Order
  3. Add Products
  4. Notice the price is shown in dollars
  5. 'Collect Payment'
  6. Notice now the total is shown in a customer Default currency
  7. Notice there're no 'Card Reader' and 'Tap to Pay on iPhone' option
  8. Change Default Currency in yourstore.com/my-account/ 'Account details' tab back to USD
  9. Repeat the steps, and notice Card Reader' and 'Tap to Pay on iPhone' option are available

https://github.com/user-attachments/assets/c6852ca4-01dc-479c-bdf8-b8ab48ea98d6

Investigation

TPP options are not shown since orderIsEligibleForCardPresentPayment call fails due to ineligible currency. It happens when Order.currency is different from default WooCommerce country/currency settings which determine TPP eligiblity and supported currencies. This issue only occurs when Multi-Currency settings are enabled (Payments > Settings > Advanced settings) and configured WooCommerce -> Settings -> Multi-Currency.

image

And customer whose account matches the account used in the app has a different default currency:

image

Screenshots

image image image

Expected behavior

The expected behavior is not clear. A few options:

Isolating the problem (mark completed items with an [x]):

Mobile Environment Please include:

WordPress Environment

```
System Status Report ``` ### WordPress Environment ### WordPress address (URL): [Redacted] Site address (URL): [Redacted] WC Version: 9.1.4 Legacy REST API Package Version: The Legacy REST API plugin is not installed on this site. Action Scheduler Version: ✔ 3.8.0 Log Directory Writable: ✔ WP Version: 6.6.1 WP Multisite: – WP Memory Limit: 512 MB WP Debug Mode: – WP Cron: ✔ Language: en_US External object cache: ✔ ### Server Environment ### Server Info: nginx PHP Version: 8.1.29 PHP Post Max Size: 2 GB PHP Time Limit: 1200 PHP Max Input Vars: 6144 cURL Version: 8.7.1 OpenSSL/1.1.1w SUHOSIN Installed: – MySQL Version: 10.6.18-MariaDB-log Max Upload Size: 2 GB Default Timezone is UTC: ✔ fsockopen/cURL: ✔ SoapClient: ✔ DOMDocument: ✔ GZip: ✔ Multibyte String: ✔ Remote Post: ✔ Remote Get: ✔ ### Database ### [REDACTED] ### Post Type Counts ### attachment: 47 aw_workflow: 4 customize_changeset: 1 global_product_addon: 1 jetpack_migration: 2 jp_img_sitemap: 6 jp_sitemap: 6 jp_sitemap_master: 6 mailpoet_page: 1 page: 9 post: 5 prl_engine: 1 product: 78 product_variation: 55 revision: 21 shop_coupon: 1 shop_order: 357 shop_order_placehold: 147 shop_order_refund: 11 shop_subscription: 31 wpcode: 7 wp_global_styles: 2 wp_navigation: 1 wp_template: 2 ### Security ### Secure connection (HTTPS): ✔ Hide errors from visitors: ✔ ### Active Plugins (41) ### WCS staging: by mb – 1.0 Akismet Anti-spam: Spam Protection: by Automattic - Anti-spam Team – 5.3.3 AutomateWoo - Birthdays Add-on: by WooCommerce – 1.3.40 AutomateWoo: by WooCommerce – 6.0.13 (update to version 6.0.31 is available) Blaze Ads: by Automattic – 0.3.2 Facebook for WooCommerce: by Facebook – 3.2.6 WordPress.com Editing Toolkit: by Automattic – 4.30504 Google for WooCommerce: by WooCommerce – 2.8.1 Gutenberg: by Gutenberg Team – 18.9.0 WPCode Lite: by WPCode – 2.2.0 Jetpack: by Automattic – 13.7-beta Layout Grid: by Automattic – 1.8.4 MailPoet Premium: by MailPoet – 4.58.0 MailPoet: by MailPoet – 4.58.2 Page Optimize: by Automattic – 0.5.5 Pinterest for WooCommerce: by WooCommerce – 1.4.5 TikTok: by TikTok – 1.2.8 Woo AI: by WooCommerce – 0.6.0 WooCommerce.com Update Manager: by Automattic – 1.0.3 Woo All Products For Subscriptions: by Woo – 6.0.1 Woo Back In Stock Notifications: by Woo – 2.0.1 WooCommerce Brands: by WooCommerce – 1.7.5 Woo Composite Products: by Woo – 10.0.1 Woo Conditional Shipping and Payments: by Woo – 2.0.1 Woo Gift Cards: by Woo – 2.0.1 Google Analytics for WooCommerce: by WooCommerce – 2.1.5 Woo Min/Max Quantities: by Woo – 5.0.1 WooCommerce Payments Dev Tools: by Automattic – WooPayments: by WooCommerce – 8.0.2 WooCommerce Points and Rewards: by WooCommerce – 1.8.7 Woo Product Add-ons: by Woo – 7.0.1 Woo Product Bundles: by Woo – 8.0.1 Woo Product Recommendations: by Woo – 4.0.1 WooCommerce Shipping & Tax: by WooCommerce – 2.7.0 WooCommerce Shipment Tracking: by WooCommerce – 2.5.0 WooCommerce USPS Shipping: by WooCommerce – 5.0.0 WooCommerce Subscription Downloads: by WooCommerce – 1.4.1 WooCommerce Subscriptions Gifting: by WooCommerce – 2.7.0 WooCommerce Subscriptions: by WooCommerce – 6.5.0 WooCommerce Table Rate Shipping: by WooCommerce – 3.3.0 WooCommerce: by Automattic – 9.1.4 ### Inactive Plugins (16) ### Advanced Shipment Tracking for WooCommerce: by zorem – 3.6.8 AutomateWoo - Refer A Friend Add-on: by WooCommerce – 2.7.11 (update to version 2.7.23 is available) Avalara AvaTax: by Avalara – 2.7.3 Classic Editor: by WordPress Contributors – 1.6.4 Crowdsignal Forms: by Automattic – 1.7.2 Crowdsignal Polls & Ratings: by Automattic Inc. – 3.1.2 Hello Dolly: by Matt Mullenweg – 1.7.2 Sequential Order Numbers for WooCommerce: by SkyVerge – 1.10.1 TaxJar - Sales Tax Automation for WooCommerce: by TaxJar – 4.2.2 WooCommerce Australia Post Shipping: by WooCommerce – 2.6.2 WooCommerce Beta Tester: by WooCommerce – 2.3.0 WooCommerce Canada Post Shipping: by WooCommerce – 3.0.0 WooCommerce EU VAT Number: by WooCommerce – 2.9.6 WooCommerce FedEx Shipping: by WooCommerce – 4.0.1 WooCommerce Royal Mail: by WooCommerce – 3.3.3 WooCommerce UPS Shipping: by WooCommerce – 3.7.0 ### Dropin Plugins () ### advanced-cache.php: advanced-cache.php object-cache.php: Memcached ### Must Use Plugins (1) ### wpcomsh-loader.php: by – ### Settings ### API Enabled: – Force SSL: – Currency: USD ($) Currency Position: left Thousand Separator: , Decimal Separator: . Number of Decimals: 2 Taxonomies: Product Types: bundle (bundle) composite (composite) external (external) grouped (grouped) simple (simple) subscription (subscription) variable (variable) variable subscription (variable-subscription) Taxonomies: Product Visibility: exclude-from-catalog (exclude-from-catalog) exclude-from-search (exclude-from-search) featured (featured) outofstock (outofstock) rated-1 (rated-1) rated-2 (rated-2) rated-3 (rated-3) rated-4 (rated-4) rated-5 (rated-5) Connected to WooCommerce.com: ✔ Enforce Approved Product Download Directories: ✔ HPOS feature enabled: ✔ Order datastore: Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore HPOS data sync enabled: – ### Logging ### Enabled: ✔ Handler: Automattic\WooCommerce\Internal\Admin\Logging\LogHandlerFileV2 Retention period: 30 days Level threshold: – Log directory size: 10 MB ### WC Pages ### Shop base: #8 - /shop/ Cart: #9 - /cart/ - This page's content is overridden by custom template content Checkout: #10 - /checkout/ - This page's content is overridden by custom template content My account: #11 - /my-account/ Terms and conditions: ❌ Page not set ### Theme ### Name: Tazza Version: 1.0.0 Author URL: https://automattic.com/ Child Theme: ❌ – If you are modifying WooCommerce on a parent theme that you did not build personally we recommend using a child theme. See: How to create a child theme WooCommerce Support: ✔ ### Templates ### Overrides: /wordpress/plugins/woocommerce/9.1.4/templates/block-notices/error.php /wordpress/plugins/woocommerce/9.1.4/templates/block-notices/notice.php /wordpress/plugins/woocommerce/9.1.4/templates/block-notices/success.php /wordpress/themes/premium/tazza/parts/mini-cart.html /wordpress/themes/premium/tazza/templates/single-product.html ### WooPayments ### Version: 8.0.2 Connected to WPCOM: Yes WPCOM Blog ID: 214253715 Account ID: acct_1PlVA5FoyZWkFl4H Payment Gateway: Enabled Test Mode: Enabled Enabled APMs: card,ideal WooPay: Enabled (no locations enabled) WooPay Incompatible Extensions: Yes Apple Pay / Google Pay: Enabled (product,cart,checkout) Fraud Protection Level: basic Multi-currency: Enabled Auth and Capture: Enabled Documents: Disabled Logging: Enabled ### Subscriptions ### WCS_DEBUG: ✔ No Subscriptions Mode: ✔ Live Subscriptions Live URL: https://superlativecentaur.wpcomstaging.com Subscriptions-core Library Version: 7.3.0 Subscription Statuses: wc-active: 15 wc-expired: 10 wc-on-hold: 5 wc-pending: 1 WooCommerce Account Connected: ✔ Yes Active Product Key: ❌ No Report Cache Enabled: ✔ Yes Cache Update Failures: ✔ 0 failure ### Store Setup ### Country / State: United States (US) — California ### Subscriptions by Payment Gateway ### Cash on delivery: wc-on-hold: 1 WooPayments: wc-active: 15 wc-expired: 10 wc-on-hold: 4 ### Payment Gateway Support ### WooPayments: products refunds multiple_subscriptions subscription_cancellation subscription_payment_method_change_admin subscription_payment_method_change_customer subscription_payment_method_change subscription_reactivation subscription_suspension subscriptions subscription_amount_changes subscription_date_changes tokenization add_payment_method Direct bank transfer: products Cash on delivery: products WooPayments (iDEAL): products refunds multiple_subscriptions subscription_cancellation subscription_payment_method_change_admin subscription_payment_method_change_customer subscription_payment_method_change subscription_reactivation subscription_suspension subscriptions subscription_amount_changes subscription_date_changes tokenization add_payment_method ### MailPoet ### Sending Method: MailPoet Send all site's emails with: Default WordPress sending method Task Scheduler method: Action Scheduler Cron ping URL: https://superlativecentaur.wpcomstaging.com?mailpoet_router&endpoint=cron_daemon&action=ping ### Back In Stock ### Database Version: 2.0.1 Loopback Test: ✔ ### Composite Products ### Database Version: 10.0.1 Loopback Test: ✔ Template Overrides: – ### Gift Cards ### Database Version: 2.0.1 Loopback Test: ✔ Task Queueing Test: ✔ ### Product Bundles ### Database Version: 8.0.1 Loopback Test: ✔ Template Overrides: – ### Admin ### Enabled Features: activity-panels analytics product-block-editor coupons core-profiler customize-store customer-effort-score-tracks import-products-task experimental-fashion-sample-products shipping-smart-defaults shipping-setting-tour homescreen marketing mobile-app-banner onboarding onboarding-tasks product-custom-fields remote-inbox-notifications remote-free-extensions payment-gateway-suggestions shipping-label-banner subscriptions store-alerts transient-notices woo-mobile-welcome wc-pay-promotion wc-pay-welcome-page Disabled Features: experimental-blocks minified-js navigation pattern-toolkit-full-composability product-pre-publish-modal printful settings async-product-editor-category-field launch-your-store product-editor-template-system Daily Cron: ✔ Next scheduled: 2024-08-14 10:24:56 +01:00 Options: ✔ Notes: 150 Onboarding: skipped ### Subscriptions Gifting ### Gifted Subscriptions Count: 1 ### All Products for Woo Subscriptions ### Template Overrides: – ### Action Scheduler ### Canceled: 11 Oldest: 2024-07-26 05:05:33 +0100 Newest: 2024-08-13 17:09:26 +0100 Complete: 52,302 Oldest: 2024-07-14 07:40:07 +0100 Newest: 2024-08-14 07:39:14 +0100 Failed: 27,586 Oldest: 2023-02-02 17:22:39 +0000 Newest: 2024-08-14 07:36:04 +0100 Pending: 41 Oldest: 2024-08-14 07:40:07 +0100 Newest: 2025-01-31 22:37:19 +0000 ### Product Recommendations ### Database Version: 4.0.1 Loopback Test: ✔ Task Queueing Test: ✔ Page Cache Test: Cache in use ### Status report information ### Generated at: 2024-08-14 07:39:22 +01:00 ```
```
dangermattic commented 1 month ago

Thanks for reporting! 👍

staskus commented 1 month ago

So far, I haven't been able reproduce the issue.

When this issue happens, both the 'Tap to Pay' and 'Card Reader' options are not visible in the 'Payment Methods view'.

The visibility of these options is controlled by the PaymentMethodsViewModel.updateCardPaymentVisibility() method.

From code it can happen for two reasons:

However if CardPresentPaymentsConfiguration isSupportedCountry is false, then TPP setup options shouldn't be visible in the first place. Therefore, that only leaves the option of orderIsEligibleForCardPresentPayment returning false.

rachelmcr commented 1 month ago

Therefore, that only leaves the option of orderIsEligibleForCardPresentPayment returning false.

I confirmed that's what is happening and it's because isCurrencyEligibleForCardPayment(cardPresentPaymentsConfiguration:) returns false. For some reason, the currency on the order is GBP even though the store uses USD and the "Take Payment" screen shows a dollar sign for the $0.50 amount.

staskus commented 1 month ago

Thanks, @rachelmcr! Maybe some preferences are coming from the locale and some from the store settings 🤔 . I'll check that.

Update:

For that to happen Order needs to arrive with currency set to GBP from the backend.

staskus commented 1 month ago

@rachelmc, do you know if multi-currency settings affect Order currencies in the app? I tried to look for reasons that you have a different Order currency from WooCommerce currency but no luck so far.

image
rachelmcr commented 1 month ago

Aha! I thought that only affected web customers, but the "Automatically switch customers to their local currency" setting matches the issue we're seeing with the currency on these test orders. I tried disabling multi-currency (in Payments > Settings > Advanced settings on the store) and then tried testing TTP in the app, and this time it worked! So that's likely the cause.

Note: I'd guess if we explicitly set the currency on the order created in the app, that could work around this issue. But it's also probably a low impact issue (given that I'd expect most merchants are geolocated in the same place as their store's main currency setting).

staskus commented 1 month ago

@rachelmcr good information, thanks! I tried to use VPN + Simulate GPS UK location myself but I didn't get switched to the currency.

One related issue in the app is that some views use CurrencySettings and others rely on Order.currency. This is where the discrepancy comes from the total currency displayed in the Payment view and then not showing TPP option in the next view. Store CurrencySettings is set to USD but Order.currency is set to GBP due to location.

A thing that we could potentially do is use Order.currency in the Payment view and/or allow switching the currency 🤔 Although I'm sure there are many things to consider.

staskus commented 1 month ago

Multi-currency issues manifest when creating an order on the web with one currency and then reopening it on the app.

Creating order on the web Opening the same order on the app
Image 2 Image 1
joshheald commented 1 month ago

@staskus The app makes the request to create the order, for TTP test payments, so even though we use the value from the backend, the app does have some say in this. I imagine we use the store's currency when we make the API request to create it, or perhaps we don't specify one.

staskus commented 4 weeks ago

For now, Made PR to log this case: