Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ node/coverage/*
### VS Code ###
*.vscode

### Claude Code ###
.claude/

### OSX ###
.DS_Store
.AppleDouble
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

### Added

- Fetch `commertialOffer.priceToken` in the product queries and forward it as `priceToken` on the `addToCart` payload of `AutocompleteBlock` and `CategoryBlock`, so the Checkout can close the cart with the signed price while the Pricing is unavailable (Pricing Fallback V2)

## [3.16.8] - 2026-06-29

### Fixed
Expand Down
36 changes: 21 additions & 15 deletions react/AutocompleteBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,18 @@ const AutocompleteBlock: FunctionComponent<any & WrappedComponentProps> = ({
const selectedSku =
data.product.items.length === 1 ? data.product.items[0].itemId : null

const seller = selectedSku
const defaultSeller = selectedSku
? data.product.items[0].sellers.find((item: any) => {
return item.sellerDefault === true
}).sellerId
})
: null

const seller = selectedSku ? defaultSeller.sellerId : null

// Signed price from the search response, forwarded on addToCart so the
// Checkout can close the cart even while the Pricing is unavailable
const priceToken = defaultSeller?.commertialOffer?.priceToken ?? null

let multiplier = 1

if (data.product.items.length === 1) {
Expand All @@ -203,7 +209,7 @@ const AutocompleteBlock: FunctionComponent<any & WrappedComponentProps> = ({
...state,
selectedItem:
!!product && product.length
? { ...product[0], value: selectedSku, seller, data }
? { ...product[0], value: selectedSku, seller, priceToken, data }
: null,
unitMultiplier: multiplier,
quantitySelected: multiplier,
Expand All @@ -214,24 +220,21 @@ const AutocompleteBlock: FunctionComponent<any & WrappedComponentProps> = ({
}

const selectSku = (value: string) => {
const seller = selectedItem.data.product.items
.find((item: any) => {
return item.itemId === value
})
.sellers.find((s: any) => {
return s.sellerDefault === true
}).sellerId
const matchedItem = selectedItem.data.product.items.find(
(item) => item.itemId === value
)

const defaultSeller = matchedItem.sellers.find((s: any) => {
return s.sellerDefault === true
})

const newSelected = {
...selectedItem,
seller,
seller: defaultSeller.sellerId,
priceToken: defaultSeller.commertialOffer?.priceToken ?? null,
value,
}

const matchedItem = selectedItem.data.product.items.find(
(item) => item.itemId === value
)

setState({
...state,
selectedItem: newSelected,
Expand Down Expand Up @@ -262,6 +265,9 @@ const AutocompleteBlock: FunctionComponent<any & WrappedComponentProps> = ({
unitMultiplier
),
seller: selectedItem.seller,
...(selectedItem.priceToken
? { priceToken: selectedItem.priceToken }
: {}),
},
]

Expand Down
23 changes: 22 additions & 1 deletion react/CategoryBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ const CategoryBlock: FunctionComponent<WrappedComponentProps & any> = ({
categoryItems: {},
quantitySelected: {},
defaultSeller: {},
// Signed price of the selected seller, by SKU, as returned by the search
priceTokens: {},
// All the items with their respective units
unitMultiplierList: {},
})
Expand All @@ -52,6 +54,7 @@ const CategoryBlock: FunctionComponent<WrappedComponentProps & any> = ({
categoryItems,
quantitySelected,
defaultSeller,
priceTokens,
unitMultiplierList,
} = state

Expand Down Expand Up @@ -274,13 +277,16 @@ const CategoryBlock: FunctionComponent<WrappedComponentProps & any> = ({

if (skus?.length) {
const items = skus.map((item: any) => {
const priceToken = priceTokens[item]

return {
id: parseInt(item, 10),
quantity: calculateDivisible(
parseFloat(quantitySelected[item]),
item
),
seller: defaultSeller[item],
...(priceToken ? { priceToken } : {}),
}
})

Expand Down Expand Up @@ -373,19 +379,34 @@ const CategoryBlock: FunctionComponent<WrappedComponentProps & any> = ({

newQtd[content.itemId] = e.target.value
const newSeller = defaultSeller
const newPriceTokens = priceTokens
const seller = content.sellers.find((s: any) => {
return s.sellerDefault === true
})

newSeller[content.itemId] =
const sellerId =
seller?.sellerId ||
(content.sellers.length
? content.sellers[0].sellerId
: '1')

// the token has to come from the very seller sent
// on addToCart, since it signs that seller's price
const selectedSeller = content.sellers.find(
(s: any) => {
return s.sellerId === sellerId
}
)

newSeller[content.itemId] = sellerId
newPriceTokens[content.itemId] =
selectedSeller?.commertialOffer?.priceToken ??
null

_setState({
quantitySelected: newQtd,
defaultSeller: newSeller,
priceTokens: newPriceTokens,
})
}}
onBlur={() => {
Expand Down
3 changes: 3 additions & 0 deletions react/queries/product.gql
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ query Product($skuId: ID!) {
sellerId
sellerName
sellerDefault
commertialOffer {
priceToken
}
}
referenceId {
Key
Expand Down
3 changes: 3 additions & 0 deletions react/queries/productsByCategory.gql
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ query SearchByCategory($selectedFacets: [SelectedFacetInput]) {
sellerId
sellerName
sellerDefault
commertialOffer {
priceToken
}
}
images(quantity: 1) {
imageUrl
Expand Down