Card payment options are not available in multi-currency store when the account has a different default currency
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
- Set up a site with WooPayments,
USlocation andUSDcurrency - Go to
Payments -> Settings, scroll down toAdvanced SettingsandEnable Multi-Currency - Go to
Settings -> WooCommerce -> Multi-currency, add additional currency and enableAutomatically switch customers to their local currency if it has been enabled - Open your store on the browser, go to My Account, (yourstore.com/my-account/) and log into your account
- Open Account details and change
Default currencyto something different fromUSD
TTP Payment setup flow
- Open Woo app and log into the same account and site
- Menu
- Payments
- Set Up Tap to Pay on iPhone
- Try a Payment
- Take Payment ($0.50)
- Notice there're no 'Card Reader' and 'Tap to Pay on iPhone' option
- Change
Default Currencyinyourstore.com/my-account/'Account details' tab back toUSD - 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
- Open Woo app and log into the same account and site
- Order
- Add Products
- Notice the price is shown in dollars
- 'Collect Payment'
- Notice now the total is shown in a customer
Default currency - Notice there're no 'Card Reader' and 'Tap to Pay on iPhone' option
- Change
Default Currencyinyourstore.com/my-account/'Account details' tab back toUSD - 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.
And customer whose account matches the account used in the app has a different default currency:
Screenshots
Expected behavior
The expected behavior is not clear. A few options:
- API should ignore Customer
default currencysettings when the account that is calling the API matches the Customer and always use primary store currency - The app should always explicitly set the default store currency as order currency, matching the behavior of WP-Admin
- The app should use
Order.currencyinstead ofStore's Currency Settingswhen possible, to indicate correctly that the order is being created with a different currency. Right now when creating the order app is always showing a default store currency when in fact the order is being created with the default customer currency
Isolating the problem (mark completed items with an [x]):
- [x] I have deactivated other plugins and confirmed this bug occurs when only WooCommerce plugin is active.
- [x] This bug happens with a default WordPress theme active, or Storefront.
- [x] I can reproduce this bug consistently using the steps above.
Mobile Environment Please include:
- Device:
- iOS version:
- WooCommerce iOS version:
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
Thanks for reporting! 👍
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:
CardPresentPaymentsConfigurationisSupportedCountryis false.OrderCardPresentPaymentEligibilityStoreorderIsEligibleForCardPresentPaymentis false
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.
Therefore, that only leaves the option of
orderIsEligibleForCardPresentPaymentreturning 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.
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.
@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.
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).
@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.
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 |
|---|---|
@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.
For now, Made PR to log this case:
- https://github.com/woocommerce/woocommerce-ios/pull/13626