Skip to content

fix(currency,payment,pricing,region,order,store,cart,core-flows,medusa,utils): repo wide currency_code normalization#13975

Merged
shahednasser merged 28 commits intodevelopfrom
fix/currency-code-repo-wide-normalization
Apr 10, 2026
Merged

fix(currency,payment,pricing,region,order,store,cart,core-flows,medusa,utils): repo wide currency_code normalization#13975
shahednasser merged 28 commits intodevelopfrom
fix/currency-code-repo-wide-normalization

Conversation

@NicolasGorga
Copy link
Copy Markdown
Contributor

@NicolasGorga NicolasGorga commented Nov 5, 2025

Summary

What — What changes are introduced in this PR?

Introduces new util function normalizeCurrencyCode to be used across the project were currency codes are stored and used for filters. Replaces existent isolated normalizations with the function and adds the missing normalization when handling currency codes in the PricingModule.

Why — Why are these changes relevant or necessary?

The objective is to have consistency across currency code handling and avoid potential bugs for storing the currency codes as uppercase in some places and lowercase in others.

How — How have these changes been implemented?

New normalizeCurrencyCode function acts as the centralized place to normalize the currency codes and should be used whenever storing and or searching a currency code.

Testing — How have these changes been tested, or how can the reviewer test the feature?

Added unit tests for the function + updated existent integration tests.


Examples

Provide examples or code snippets that demonstrate how this feature works, or how it can be used in practice.
This helps with documentation and ensures maintainers can quickly understand and verify the change.

// Example usage

Checklist

Please ensure the following before requesting a review:

  • I have added a changeset for this PR
    • Every non-breaking change should be marked as a patch
    • To add a changeset, run yarn changeset and follow the prompts
  • The changes are covered by relevant tests
  • I have verified the code works as intended locally
  • I have linked the related issue(s) if applicable

Additional Context

Add any additional context, related issues, or references that might help the reviewer understand this PR.

fixes #13956


Note

Centralizes currency code lowercasing via normalizeCurrencyCode, applies it across services and queries, adds a DB migration to lowercase existing data, and updates tests to expect lowercase codes.

  • Utils:
    • Add normalizeCurrencyCode (lowercases codes) with unit tests and export.
  • Data Migration:
    • New script packages/medusa/src/migration-scripts/migrate-normalize-currency-codes-normalization.ts lowercases currency_code in cart, payment_collection, payment_session, payment, order, order_transaction, price, region, store_currency.
  • Modules/Services:
    • Pricing: Normalize on read/write (repository calculatePrices, service price hashing/upsert/constraints), propagate lowercase in price lists/sets/preferences.
    • Payment: Normalize on create/update of collections/sessions/payments and provider interactions.
    • Order: Normalize currency_code on order creation and order transactions.
    • Cart: Normalize on cart create/update.
    • Region: Normalize input currency_code; trim/name handling unchanged.
    • Store: Normalize supported_currencies[].currency_code on create/update.
    • Core Flows: Import helper uses normalizeCurrencyCode for variant_price_* parsing.
    • Currency: Normalize code filter in list/retrieve.
  • Tests:
    • Update integration tests to expect lowercase currency_code throughout (pricing, payment, indexing/search).

Written by Cursor Bugbot for commit b07bb4e. This will update automatically on new commits. Configure here.

@NicolasGorga NicolasGorga requested a review from a team as a code owner November 5, 2025 16:24
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Nov 5, 2025

🦋 Changeset detected

Latest commit: d4e784e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 77 packages
Name Type
@medusajs/currency Patch
@medusajs/core-flows Patch
@medusajs/payment Patch
@medusajs/pricing Patch
@medusajs/region Patch
@medusajs/order Patch
@medusajs/store Patch
@medusajs/cart Patch
@medusajs/utils Patch
@medusajs/medusa Patch
@medusajs/test-utils Patch
integration-tests-http Patch
@medusajs/event-bus-redis Patch
@medusajs/framework Patch
@medusajs/modules-sdk Patch
@medusajs/orchestration Patch
@medusajs/workflows-sdk Patch
@medusajs/cli Patch
@medusajs/medusa-oas-cli Patch
@medusajs/analytics Patch
@medusajs/api-key Patch
@medusajs/auth Patch
@medusajs/caching Patch
@medusajs/customer Patch
@medusajs/file Patch
@medusajs/fulfillment Patch
@medusajs/index Patch
@medusajs/inventory Patch
@medusajs/link-modules Patch
@medusajs/locking Patch
@medusajs/notification Patch
@medusajs/product Patch
@medusajs/promotion Patch
@medusajs/rbac Patch
@medusajs/sales-channel Patch
@medusajs/settings Patch
@medusajs/stock-location Patch
@medusajs/tax Patch
@medusajs/translation Patch
@medusajs/user Patch
@medusajs/workflow-engine-inmemory Patch
@medusajs/workflow-engine-redis Patch
@medusajs/draft-order Patch
@medusajs/cache-inmemory Patch
@medusajs/cache-redis Patch
@medusajs/event-bus-local Patch
@medusajs/analytics-local Patch
@medusajs/analytics-posthog Patch
@medusajs/auth-emailpass Patch
@medusajs/auth-github Patch
@medusajs/auth-google Patch
@medusajs/caching-redis Patch
@medusajs/file-local Patch
@medusajs/file-s3 Patch
@medusajs/fulfillment-manual Patch
@medusajs/locking-postgres Patch
@medusajs/locking-redis Patch
@medusajs/notification-local Patch
@medusajs/notification-sendgrid Patch
@medusajs/payment-stripe Patch
@medusajs/oas-github-ci Patch
@medusajs/js-sdk Patch
@medusajs/types Patch
@medusajs/http-types-generator Patch
@medusajs/deps Patch
@medusajs/telemetry Patch
@medusajs/admin-bundler Patch
@medusajs/admin-sdk Patch
@medusajs/admin-shared Patch
@medusajs/admin-vite-plugin Patch
@medusajs/dashboard Patch
@medusajs/icons Patch
@medusajs/toolbox Patch
@medusajs/ui-preset Patch
create-medusa-app Patch
medusa-dev-cli Patch
@medusajs/ui Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown

vercel bot commented Nov 5, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

9 Skipped Deployments
Project Deployment Actions Updated (UTC)
api-reference Ignored Ignored Apr 10, 2026 0:08am
api-reference-v2 Ignored Ignored Preview Apr 10, 2026 0:08am
bloom-docs Ignored Ignored Preview Apr 10, 2026 0:08am
cloud-docs Ignored Ignored Preview Apr 10, 2026 0:08am
docs-ui Ignored Ignored Preview Apr 10, 2026 0:08am
docs-v2 Ignored Ignored Preview Apr 10, 2026 0:08am
medusa-docs Ignored Ignored Preview Apr 10, 2026 0:08am
resources-docs Ignored Ignored Preview Apr 10, 2026 0:08am
user-guide Ignored Ignored Preview Apr 10, 2026 0:08am

Request Review

@NicolasGorga NicolasGorga changed the title Fix/currency code repo wide normalization fix(currency,core-flows,pricing,region,store,utils): normalize currency codes as lowercase project with dedicated method Nov 5, 2025
Copy link
Copy Markdown
Contributor

@adrien2p adrien2p left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we are missing a migration script to update all currency code in the database that are not lower cased no?

@NicolasGorga
Copy link
Copy Markdown
Contributor Author

I believe we are missing a migration script to update all currency code in the database that are not lower cased no?

Oh forgot about that, will include it.

@NicolasGorga
Copy link
Copy Markdown
Contributor Author

@adrien2p Hey could you check the migration script? We basically need to migrate price table, so variant and price list prices. I searched the current workflows we have and didn't find a straightforward approach to use them in this context, so opted for using knex inside a transaction (since there is no compensation function in the step i created), wyt?

Copy link
Copy Markdown
Contributor

@adrien2p adrien2p left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also check other modules that are using currency_code? this pr primarely focuse on the pricing and it might be the objective but just want to throw it outloud

@NicolasGorga
Copy link
Copy Markdown
Contributor Author

Should we also check other modules that are using currency_code? this pr primarely focuse on the pricing and it might be the objective but just want to throw it outloud

I checked all other modules, and the problematic one is the Pricing module. For other usages, what I did is replace the direct manipulation with the new common dedicated util normalizeCurrencyCode.

@adrien2p
Copy link
Copy Markdown
Contributor

Should we also check other modules that are using currency_code? this pr primarely focuse on the pricing and it might be the objective but just want to throw it outloud

I checked all other modules, and the problematic one is the Pricing module. For other usages, what I did is replace the direct manipulation with the new common dedicated util normalizeCurrencyCode.

I was more thinking of cart, order, payment etc, they dont need that or it was in a separate pr?

@NicolasGorga
Copy link
Copy Markdown
Contributor Author

@adrien2p With the latest update i did to the test, this would now be breaking right? Since existing filters using index.graph that have an uppercased currency_code will no longer return results they previously did.

The thing is tricky, since i know we can hook the normalization probably in PostgresProvider.quey() but if we target the currency_code field, it means we are potentially normalizing custom modules other than the core Pricing module. Whatever we do is a tradeoff, wyt?

@adrien2p
Copy link
Copy Markdown
Contributor

@adrien2p With the latest update i did to the test, this would now be breaking right? Since existing filters using index.graph that have an uppercased currency_code will no longer return results they previously did.

The thing is tricky, since i know we can hook the normalization probably in PostgresProvider.quey() but if we target the currency_code field, it means we are potentially normalizing custom modules other than the core Pricing module. Whatever we do is a tradeoff, wyt?

I can see two options:

  • We tell people that they might need to trigger a full resync of the index
  • We write a migration to update the index data for specific entity name

wdyt?

@github-actions
Copy link
Copy Markdown
Contributor

This PR is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.

@github-actions
Copy link
Copy Markdown
Contributor

This PR is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.

@github-actions github-actions bot added the Stale label Feb 19, 2026
@github-actions
Copy link
Copy Markdown
Contributor

This PR was closed because it has been stalled for 5 days with no activity.

@medusa-os-bot
Copy link
Copy Markdown

medusa-os-bot bot commented Apr 9, 2026

Thank you for your contribution!

After reviewing this PR, there is one open concern that needs to be resolved before we can move forward:

Required changes:

  • Resolve the search index migration gap — The data migration script lowercases currency_code in the raw DB tables (cart, payment_collection, payment_session, payment, order, order_transaction, price, region, store_currency), but the search index (Postgres Index module) still holds a denormalized copy of this data. After migration, searches/filters on currency_code via index.graph using lowercase codes will fail to match index records that were indexed with uppercase codes. This was discussed in the thread (Dec 18) with two options proposed — either add an index data migration for the specific entity names, or document a required full resync for users upgrading. Please pick one and implement or document it.

Notes:

  • The migration script uses raw knex SQL directly, which differs from the existing pattern in migrate-tax-region-provider.ts (workflow-based). This is acceptable for a pure data update with no compensation needed, but be aware the existing scripts use the workflow approach.
  • The normalize-for-import.ts change (replacing .toLowerCase() with normalizeCurrencyCode()) looks correct. However, line ~202 leaves region.currency_code unnormalized — this is fine as long as the region module normalizes on write (which this PR adds), but worth double-checking that the region service change covers this path end-to-end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: currency_code validation on create product route does not enforce lowercase

3 participants