Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
45aca2a
Unified utility normalizeCurrencyCode function
NicolasGorga Nov 5, 2025
0e4e1c4
Use new utility function to replace current isolated currency code no…
NicolasGorga Nov 5, 2025
57dc443
Update arg type
NicolasGorga Nov 5, 2025
41797b6
Add missing currency code normalization in pricing module
NicolasGorga Nov 5, 2025
27b8795
New util function tests
NicolasGorga Nov 5, 2025
5a11104
Update previous pricing module tests to include lowercased currency c…
NicolasGorga Nov 5, 2025
c2e2852
Add changeset
NicolasGorga Nov 5, 2025
a9981bb
Update arg type and throw if something else is provided
NicolasGorga Nov 5, 2025
02a3a51
Migration script v1
NicolasGorga Nov 5, 2025
de16984
Include in transaction for compensation
NicolasGorga Nov 5, 2025
20e272f
Merge branch 'develop' into fix/currency-code-repo-wide-normalization
NicolasGorga Nov 5, 2025
6400928
Merge branch 'develop' into fix/currency-code-repo-wide-normalization
NicolasGorga Nov 12, 2025
3762010
Remove unnecessary workflow, execute knex directly inside script
NicolasGorga Nov 25, 2025
d63b9fc
Review fixes
NicolasGorga Nov 25, 2025
9c7d26f
Add missing currency_code normalization to modules
NicolasGorga Nov 26, 2025
f0013d2
Avoid overriding currency_code when not provided
NicolasGorga Nov 26, 2025
0942b4d
Update tests
NicolasGorga Nov 26, 2025
95330ad
Updated changeset
NicolasGorga Nov 26, 2025
dfc0256
Update script to normalize all potentially affected tables
NicolasGorga Nov 26, 2025
922aba2
Keep one changeset
NicolasGorga Dec 5, 2025
ba64c97
Merge branch 'develop' into fix/currency-code-repo-wide-normalization
NicolasGorga Dec 5, 2025
568d7d9
Merge branch 'develop' into fix/currency-code-repo-wide-normalization
NicolasGorga Dec 8, 2025
ec56874
Merge remote-tracking branch 'origin/develop' into fix/currency-code-…
NicolasGorga Dec 17, 2025
dc5c936
Update tests
NicolasGorga Dec 17, 2025
b07bb4e
Update test
NicolasGorga Dec 18, 2025
f00689e
Merge branch 'develop' into fix/currency-code-repo-wide-normalization
NicolasGorga Jan 18, 2026
ac96c89
Merge branch 'develop' into fix/currency-code-repo-wide-normalization
NicolasGorga Apr 9, 2026
d4e784e
Migration to normalize prices ingested by index module
NicolasGorga Apr 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .changeset/free-rings-happen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
"@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
---

fix(currency,payment,pricing,region,order,store,cart,core-flows,medusa,utils): repo wide currency_code normalization
24 changes: 12 additions & 12 deletions integration-tests/modules/__tests__/index/query-index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,12 @@ medusaIntegrationTestRunner({
],
prices: expect.arrayContaining([
{
currency_code: "CAD",
currency_code: "cad",
amount: 20,
id: expect.any(String),
},
{
currency_code: "USD",
currency_code: "usd",
amount: 80,
id: expect.any(String),
},
Expand All @@ -294,12 +294,12 @@ medusaIntegrationTestRunner({
prices: expect.arrayContaining([
{
amount: 20,
currency_code: "CAD",
currency_code: "cad",
id: expect.any(String),
},
{
amount: 80,
currency_code: "USD",
currency_code: "usd",
id: expect.any(String),
},
]),
Expand Down Expand Up @@ -337,12 +337,12 @@ medusaIntegrationTestRunner({
prices: expect.arrayContaining([
{
amount: 30,
currency_code: "USD",
currency_code: "usd",
id: expect.any(String),
},
{
amount: 50,
currency_code: "EUR",
currency_code: "eur",
id: expect.any(String),
},
]),
Expand Down Expand Up @@ -400,7 +400,7 @@ medusaIntegrationTestRunner({
"variants.prices.currency_code",
],
filters: {
"variants.prices.currency_code": "USD",
"variants.prices.currency_code": "usd",
},
pagination: {
take: 1,
Expand All @@ -422,12 +422,12 @@ medusaIntegrationTestRunner({
prices: expect.arrayContaining([
{
amount: 20,
currency_code: "CAD",
currency_code: "cad",
id: expect.any(String),
},
{
amount: 80,
currency_code: "USD",
currency_code: "usd",
id: expect.any(String),
},
]),
Expand All @@ -448,7 +448,7 @@ medusaIntegrationTestRunner({
filters: {
variants: {
prices: {
currency_code: "USD",
currency_code: "usd",
},
},
},
Expand Down Expand Up @@ -476,12 +476,12 @@ medusaIntegrationTestRunner({
prices: expect.arrayContaining([
{
amount: 30,
currency_code: "USD",
currency_code: "usd",
id: expect.any(String),
},
{
amount: 50,
currency_code: "EUR",
currency_code: "eur",
id: expect.any(String),
},
]),
Expand Down
4 changes: 2 additions & 2 deletions integration-tests/modules/__tests__/index/search.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ medusaIntegrationTestRunner({
variants: {
prices: {
amount: { $gt: 50 },
currency_code: { $eq: "AUD" },
currency_code: { $eq: "aud" },
},
},
},
Expand Down Expand Up @@ -179,7 +179,7 @@ medusaIntegrationTestRunner({
for (const variant of variants) {
expect(variant.prices.length).toBe(1)
expect(variant.prices[0].amount).toBeGreaterThan(50)
expect(variant.prices[0].currency_code).toBe("AUD")
expect(variant.prices[0].currency_code).toBe("aud")
}
})

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ProductTypes } from "@medusajs/framework/types"
import type { HttpTypes, RegionTypes } from "@medusajs/framework/types"
import { MedusaError, lowerCaseFirst } from "@medusajs/framework/utils"
import { MedusaError, lowerCaseFirst, normalizeCurrencyCode } from "@medusajs/framework/utils"

// We want to convert the csv data format to a standard DTO format.
export const normalizeForImport = (
Expand Down Expand Up @@ -183,7 +183,7 @@ const normalizeVariantForImport = (
if (!priceKey.endsWith("]")) {
response["prices"] = [
...(response["prices"] || []),
{ currency_code: priceKey.toLowerCase(), amount: normalizedValue },
{ currency_code: normalizeCurrencyCode(priceKey), amount: normalizedValue },
]
} else {
const regionName = priceKey.split("_").slice(0, -1).join(" ")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { normalizeCurrencyCode } from "../normalize-currency-code"

describe("normalizeCurrencyCode", () => {
it("returns lowercased currency code", () => {
const uppercased = "USD"
const result = normalizeCurrencyCode(uppercased)

expect(result).toEqual("usd")
})

it("throws when value is not a string", () => {
const errorMessage = "Currency code needs to be a string"

expect(() => {
normalizeCurrencyCode(1 as unknown as string)
}).toThrow(errorMessage)
expect(() => {
normalizeCurrencyCode(undefined as unknown as string)
}).toThrow(errorMessage)
})
})
1 change: 1 addition & 0 deletions packages/core/utils/src/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export * from "./medusa-container"
export * from "./merge-metadata"
export * from "./merge-plugin-modules"
export * from "./normalize-csv-value"
export * from "./normalize-currency-code"
export * from "./normalize-import-path-with-source"
export * from "./normalize-locale"
export * from "./object-from-string-path"
Expand Down
13 changes: 13 additions & 0 deletions packages/core/utils/src/common/normalize-currency-code.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { MedusaError, MedusaErrorTypes } from "./errors"
import { isString } from "./is-string"

/**
* Normalizes `currencyCode` by transforming it to lowercase
*/
export function normalizeCurrencyCode(currencyCode: string) {
if (!isString(currencyCode)) {
throw new MedusaError(MedusaErrorTypes.INVALID_ARGUMENT, "Currency code needs to be a string")
}

return currencyCode.toLowerCase()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { ContainerRegistrationKeys } from "@medusajs/framework/utils"
import { ExecArgs } from "@medusajs/types"

export default async function migrateNormalizeCurrencyCodes({
container,
}: ExecArgs) {
const knex = container.resolve(ContainerRegistrationKeys.PG_CONNECTION)

await knex.transaction(async (trx) => {
const tables = [
"cart",
"payment_collection",
"payment_session",
"payment",
"order",
"order_transaction",
"price",
"region",
"store_currency",
]

for (const table of tables) {
await trx(table)
.whereNotNull("currency_code")
.update({
currency_code: knex.raw("LOWER(currency_code)"),
})
}

await trx.raw(`
UPDATE index_data
SET data = jsonb_set(data, '{currency_code}', to_jsonb(LOWER(data->>'currency_code')))
WHERE name = 'Price'
AND data->>'currency_code' IS NOT NULL
AND data->>'currency_code' <> LOWER(data->>'currency_code')
`)
})
}
22 changes: 20 additions & 2 deletions packages/modules/cart/src/services/cart-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
MedusaError,
ModulesSdkUtils,
promiseAll,
normalizeCurrencyCode,
} from "@medusajs/framework/utils"
import {
Address,
Expand Down Expand Up @@ -297,7 +298,13 @@ export default class CartModuleService
const cartsWithItems = data.map(({ items, ...cart }) => {
const cartId = generateEntityId((cart as any).id, "cart")
return {
cart: { ...cart, id: cartId },
cart: {
...cart,
currency_code: cart.currency_code
? normalizeCurrencyCode(cart.currency_code)
: cart.currency_code,
id: cartId,
},
items: items || [],
}
})
Expand Down Expand Up @@ -395,10 +402,18 @@ export default class CartModuleService
{
id: dataOrIdOrSelector,
...data,
...(data?.currency_code
? { currency_code: normalizeCurrencyCode(data.currency_code) }
: {}),
},
]
} else if (Array.isArray(dataOrIdOrSelector)) {
toUpdate = dataOrIdOrSelector
toUpdate = dataOrIdOrSelector.map((d) => ({
...d,
...(d.currency_code
? { currency_code: normalizeCurrencyCode(d.currency_code) }
: {}),
}))
} else {
const carts = await this.cartService_.list(
{ ...dataOrIdOrSelector },
Expand All @@ -410,6 +425,9 @@ export default class CartModuleService
return {
...data,
id: cart.id,
...(data?.currency_code
? { currency_code: normalizeCurrencyCode(data.currency_code) }
: {}),
}
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
ModulesSdkTypes,
} from "@medusajs/framework/types"

import { MedusaService } from "@medusajs/framework/utils"
import { MedusaService, normalizeCurrencyCode } from "@medusajs/framework/utils"
import { Currency } from "@models"

type InjectedDependencies = {
Expand Down Expand Up @@ -86,7 +86,7 @@ export default class CurrencyModuleService
FilterableCurrencyProps
>(filters, (fieldName, value) => {
if (fieldName === "code" && !!value) {
return value.toLowerCase()
return normalizeCurrencyCode(value)
}

return value
Expand Down
12 changes: 11 additions & 1 deletion packages/modules/order/src/services/order-module-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
MedusaContext,
MedusaError,
ModulesSdkUtils,
normalizeCurrencyCode,
OrderChangeStatus,
OrderStatus,
promiseAll,
Expand Down Expand Up @@ -793,6 +794,10 @@ export default class OrderModuleService
totals: calculated.summary,
}

if (ord.currency_code) {
ord.currency_code = normalizeCurrencyCode(ord.currency_code)
}

ord.custom_display_id = await this.generateCustomDisplayId_.bind(this)(
data_,
sharedContext
Expand Down Expand Up @@ -3694,8 +3699,13 @@ export default class OrderModuleService
}
}

const normalizedData = data.map((d) => ({
...d,
currency_code: normalizeCurrencyCode(d.currency_code ?? ""),
}))

const created = (await this.orderTransactionService_.create(
data,
normalizedData,
sharedContext
)) as (InferEntityType<typeof OrderTransaction> & { order_id: string })[]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ moduleIntegrationTestRunner<IPaymentModuleService>({
payment_providers: [],
payment_sessions: [],
payments: [],
currency_code: "USD",
currency_code: "usd",
amount: 200,
})
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ moduleIntegrationTestRunner<IPaymentModuleService>({
payment_providers: [],
payment_sessions: [],
payments: [],
currency_code: "USD",
currency_code: "usd",
amount: 200,
})
)
Expand Down
Loading
Loading