Problem/Motivation
CurrencyRepository::getDefaultFractionDigits() reads the fraction digits from commerceguys/intl's base definitions, which follow the ISO 4217 list. When a currency is withdrawn from ISO 4217, the library drops it, and getDefaultFractionDigits() throws UnknownCurrencyException, even though the store still has the currency (and orders/payments in it).
Since payment gateways convert amounts through MinorUnitsConverter, refunding or capturing an existing payment in a withdrawn currency fails.
This has happened several times already:
- VEF (intl v1.0.2)
- HRK (intl v1.1.2, Croatia adopted the euro)
- SLL (intl v2.0.6)
- ANG, CUC, ZWL (intl v2.0.7)
- BGN (intl v2.0.8, Bulgaria adopted the euro)
Steps to reproduce
- Import BGN with an older
commerceguys/intlrelease (or have a store that already has it). - Update
commerceguys/intlto v2.0.8 or later. \Drupal::service('commerce_price.minor_units_converter')->toMinorUnits(new Price('10', 'BGN'));throwsUnknownCurrencyException.
Proposed resolution
When the currency is not defined by the library, fall back to the fraction digits of the stored commerce_currency entity. CurrencyRepository::get() already throws UnknownCurrencyException when the entity doesn't exist either, so the method's contract doesn't change.
New stores still can't import withdrawn currencies, which is expected.
Remaining tasks
- MR with the fallback and a kernel test.
Issue fork commerce-3625224
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #4
jsacksick commented