Skip to content

Commit 3533930

Browse files
syadupathi-sfdannyphan2000hajinsuha1kumaravinashcommercecloud
authored
@W-20540715 MERGE 1CC TO DEVELOP (#3552)
* One click checkout * changes to fix install, tests and lint - needs to be reviewed * Change log * revert the test change in pwa-kit-runtime * Change commerce-sdk-react package-lock in an attempt to get the CI working * Increase bundle size of template-retail-react-app by 1KB * @W-20542850 Remove promotion from Shipping Method summary view (#3563) * W-20542850 Remove promotion from Shipping Method summary view * add translations * W-19728108 Add amount to payment instrument in the basket (#3568) * W-19728108 Amount for the registered shopper (#3572) * W-20892453 Remove store pickup shipping option (#3575) * @W-20892497 Show Phone number in Contact Info summary (#3576) * W-20892497 Show Phone number in Contact Info summary * fix lint * @W-20892554 Show spinner when user registration checkbox is clicked (#3578) * W-20892554 Show spinner when user registration checkbox is clicked * add test * @W-20892592 Remove gift messaging for multi shipment (#3579) * W-20892592 Remove gift messaging for multi shipment * translations * @W-20892530 @W-20892577 Billing Address Validation and Using contact phone for user registration (#3583) * W-20892530 Billing Address Validation * W-20892577 save contact info phone * @W-20931438 Add spinner for place order button (#3587) * Add spinner for place order button * skip changelog * Update isomorphic version to the newly released version (#3592) * Fix SDK tests (#3593) * fix sdk tests and app bundle size * fix lint * @W-20931758 Allow guest shopper to change payment (#3591) * W-20931758 Allow guest shopper to change payment after applying it * changed the error code to use an existing one * @W-21000333: [BOPIS] Should skip pick up address (#3601) Signed-off-by: d.phan <d.phan@salesforce.com> * W-21005962 Disable user registration when billing address is not valid (#3605) * @W-21000338: [BOPIS] Auto-populate billing address with default address (#3602) Signed-off-by: d.phan <d.phan@salesforce.com> * @W-21006290: [BOPIS] Continue to Shipping Address label fix for BOPIS-only orders (#3604) * @W-21006290: [BOPIS] Continue to Shipping Address label fix for BOPIS-only orders Signed-off-by: d.phan <d.phan@salesforce.com> * add translations Signed-off-by: d.phan <d.phan@salesforce.com> * fix lint Signed-off-by: d.phan <d.phan@salesforce.com> * fix utest Signed-off-by: d.phan <d.phan@salesforce.com> --------- Signed-off-by: d.phan <d.phan@salesforce.com> * @W-21000344: [BOPIS] Pickup address component enhancement (#3607) Signed-off-by: d.phan <d.phan@salesforce.com> * W-21005976 Newly registered user can change payment (#3608) * @W-21038080: [1CC][PWA] Add new feature toggle in config to template files (#3609) * @W-21038080: [1CC][PWA] Add new feature toggle in config to template files Signed-off-by: d.phan <d.phan@salesforce.com> * add new changelog Signed-off-by: d.phan <d.phan@salesforce.com> --------- Signed-off-by: d.phan <d.phan@salesforce.com> * @W-21038080: Rework to use billing address phone number for guest shoppers (#3618) Signed-off-by: d.phan <d.phan@salesforce.com> * @ W-20540715 Address 1CC feature branch review comments (#3619) * address first set of comments * address rest of code review comments * reverting default.js changes * fix package versions * shipping options fix * attempt to fix flaky tests * test * passwordless mode updates * fix unit test * @W-20892603: Remove empty shipment fix (#3622) * @W-20892603: empty shipment fix Signed-off-by: d.phan <d.phan@salesforce.com> * trigger ci Signed-off-by: d.phan <d.phan@salesforce.com> --------- Signed-off-by: d.phan <d.phan@salesforce.com> * Update packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-contact-info.jsx Co-authored-by: Jinsu Ha <91205717+hajinsuha1@users.noreply.github.com> Signed-off-by: syadupathi-sf <66088780+syadupathi-sf@users.noreply.github.com> * revert to generic error message as per code review comment * activity event tracking for 1cc (#3627) * test failure (#3629) --------- Signed-off-by: d.phan <d.phan@salesforce.com> Signed-off-by: syadupathi-sf <66088780+syadupathi-sf@users.noreply.github.com> Co-authored-by: Danny Phan <125327707+dannyphan2000@users.noreply.github.com> Co-authored-by: Jinsu Ha <91205717+hajinsuha1@users.noreply.github.com> Co-authored-by: kumaravinashcommercecloud <kumaravinash@salesforce.com>
1 parent b8bc171 commit 3533930

File tree

104 files changed

+21757
-218
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+21757
-218
lines changed

packages/commerce-sdk-react/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## v5.0.0-dev (Jan 28, 2026)
2+
- Upgrade to commerce-sdk-isomorphic v5.0.0 and introduce Payment Instrument SCAPI integration [#3552](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3552)
3+
14
## v4.4.0-dev (Dec 17, 2025)
25
- [Bugfix]Ensure code_verifier can be optional in resetPassword call [#3567](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3567)
36
- [Improvement] Strengthening typescript types on custom endpoint options and fetchOptions types [#3589](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3589)

packages/commerce-sdk-react/package-lock.json

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/commerce-sdk-react/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@salesforce/commerce-sdk-react",
3-
"version": "4.4.0-dev",
3+
"version": "5.0.0-dev",
44
"description": "A library that provides react hooks for fetching data from Commerce Cloud",
55
"homepage": "https://github.com/SalesforceCommerceCloud/pwa-kit/tree/develop/packages/ecom-react-hooks#readme",
66
"bugs": {
@@ -40,7 +40,7 @@
4040
"version": "node ./scripts/version.js"
4141
},
4242
"dependencies": {
43-
"commerce-sdk-isomorphic": "4.2.0",
43+
"commerce-sdk-isomorphic": "5.0.0-preview.1",
4444
"js-cookie": "^3.0.1",
4545
"jwt-decode": "^4.0.0"
4646
},

packages/commerce-sdk-react/src/auth/index.ts

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,19 @@ type AuthorizePasswordlessParams = {
9696
userid: string
9797
mode?: 'email' | 'callback'
9898
locale?: string
99+
/** When true, SLAS will register the customer as part of the passwordless flow */
100+
register_customer?: boolean | string
101+
/** Optional registration details forwarded to SLAS when register_customer=true */
102+
first_name?: string
103+
last_name?: string
104+
email?: string
105+
phone_number?: string
99106
}
100107

101108
type GetPasswordLessAccessTokenParams = {
102109
pwdlessLoginToken: string
110+
/** When true, SLAS will register the customer if not already registered */
111+
register_customer?: boolean | string
103112
}
104113

105114
/**
@@ -125,6 +134,8 @@ type AuthDataKeys =
125134
| typeof DWSID_COOKIE_NAME
126135
| 'code_verifier'
127136
| 'uido'
137+
| 'idp_refresh_token'
138+
| 'dnt'
128139

129140
type AuthDataMap = Record<
130141
AuthDataKeys,
@@ -1283,7 +1294,19 @@ class Auth {
12831294
...(usid && {usid}),
12841295
...(parameters.locale && {locale: parameters.locale}),
12851296
userid: parameters.userid,
1286-
mode
1297+
mode,
1298+
...(parameters.register_customer !== undefined && {
1299+
registerCustomer:
1300+
typeof parameters.register_customer === 'boolean'
1301+
? parameters.register_customer
1302+
: parameters.register_customer === 'true'
1303+
? true
1304+
: false
1305+
}),
1306+
...(parameters.last_name && {lastName: parameters.last_name}),
1307+
...(parameters.email && {email: parameters.email}),
1308+
...(parameters.first_name && {firstName: parameters.first_name}),
1309+
...(parameters.phone_number && {phoneNumber: parameters.phone_number})
12871310
}
12881311
})
12891312
if (res && res.status !== 200) {
@@ -1299,14 +1322,22 @@ class Auth {
12991322
async getPasswordLessAccessToken(parameters: GetPasswordLessAccessTokenParams) {
13001323
const pwdlessLoginToken = parameters.pwdlessLoginToken || ''
13011324
const dntPref = this.getDnt({includeDefaults: true})
1325+
const usid = this.get('usid')
13021326
const token = await helpers.getPasswordLessAccessToken({
13031327
slasClient: this.client,
13041328
credentials: {
13051329
clientSecret: this.clientSecret
13061330
},
13071331
parameters: {
13081332
pwdlessLoginToken,
1309-
dnt: dntPref !== undefined ? String(dntPref) : undefined
1333+
dnt: dntPref !== undefined ? String(dntPref) : undefined,
1334+
...(usid && {usid}),
1335+
...(parameters.register_customer !== undefined && {
1336+
register_customer:
1337+
typeof parameters.register_customer === 'boolean'
1338+
? String(parameters.register_customer)
1339+
: parameters.register_customer
1340+
})
13101341
}
13111342
})
13121343
const isGuest = false

packages/commerce-sdk-react/src/hooks/ShopperCustomers/cache.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,36 @@ export const cacheUpdateMatrix: CacheUpdateMatrix<Client> = {
6767
]
6868
}
6969
},
70+
updateCustomerPaymentInstrument(customerId, {parameters}, response) {
71+
const newParams = {...parameters}
72+
return {
73+
update: [
74+
{
75+
queryKey: getCustomerPaymentInstrument.queryKey(newParams)
76+
},
77+
{
78+
queryKey: getCustomer.queryKey(newParams),
79+
updater: createUpdateFunction((customer: Customer) => {
80+
if (!customer.paymentInstruments) return customer
81+
const idx = customer.paymentInstruments.findIndex(
82+
({paymentInstrumentId}) =>
83+
paymentInstrumentId === parameters.paymentInstrumentId
84+
)
85+
if (idx >= 0) {
86+
customer.paymentInstruments[idx] = response as any
87+
// If this instrument is now default, unset others
88+
if ((response as any)?.default) {
89+
customer.paymentInstruments = customer.paymentInstruments.map(
90+
(pi, i) => (i === idx ? pi : {...pi, default: false})
91+
) as any
92+
}
93+
}
94+
return customer
95+
})
96+
}
97+
]
98+
}
99+
},
70100
createCustomerPaymentInstrument(customerId, {parameters}, response) {
71101
const newParams = {...parameters, paymentInstrumentId: response.paymentInstrumentId}
72102
return {

packages/commerce-sdk-react/src/hooks/ShopperCustomers/index.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ describe('Shopper Customers hooks', () => {
1818
// or add it to the `expected` array with a comment explaining "TODO" or "never" (and why).
1919
expect(unimplemented).toEqual([
2020
'getExternalProfile', // TODO: Implement when the endpoint exits closed beta
21+
'getPublicProductListItems', // TODO: Implement when the endpoint exits closed beta
2122
'registerExternalProfile' // TODO: Implement when the endpoint exits closed beta
2223
])
2324
})

packages/commerce-sdk-react/src/hooks/ShopperCustomers/mutation.test.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ const basePaymentInstrument: ShopperCustomersTypes.CustomerPaymentInstrument = {
5454
paymentBankAccount: {},
5555
paymentCard: {cardType: 'fake'},
5656
paymentInstrumentId: 'paymentInstrumentId',
57-
paymentMethodId: 'paymentMethodId'
57+
paymentMethodId: 'paymentMethodId',
58+
default: false
5859
}
5960
const baseCustomer: RequireKeys<
6061
ShopperCustomersTypes.Customer,
@@ -176,6 +177,50 @@ describe('ShopperCustomers mutations', () => {
176177
expect(result.current.mutation.data).toBeUndefined()
177178
assertRemoveQuery(result.current.query)
178179
})
180+
test('`updateCustomerPaymentInstrument` updates cache on success', async () => {
181+
// 0. Setup
182+
const customer = baseCustomer
183+
const oldData = basePaymentInstrument
184+
const newData: ShopperCustomersTypes.CustomerPaymentInstrument = {
185+
...basePaymentInstrument,
186+
default: true
187+
}
188+
const options = createOptions<'updateCustomerPaymentInstrument'>({
189+
// Only updating default flag for this test
190+
default: true as any
191+
})
192+
193+
mockQueryEndpoint(customersEndpoint, customer) // getCustomer
194+
mockQueryEndpoint(customersEndpoint, oldData) // getCustomerPaymentInstrument
195+
mockMutationEndpoints(customersEndpoint, newData) // this mutation
196+
mockQueryEndpoint(customersEndpoint, {test: 'this should not get used'}) // getCustomer refetch
197+
mockQueryEndpoint(customersEndpoint, {test: 'this should not get used'}) // getCustomerPaymentInstrument refetch
198+
199+
const {result} = renderHookWithProviders(() => ({
200+
customer: queries.useCustomer(queryOptions),
201+
mutation: useShopperCustomersMutation('updateCustomerPaymentInstrument'),
202+
query: queries.useCustomerPaymentInstrument(queryOptions)
203+
}))
204+
205+
// 1. Populate cache with initial data
206+
await waitAndExpectSuccess(() => result.current.customer)
207+
await waitAndExpectSuccess(() => result.current.query)
208+
expect(result.current.customer.data).toEqual(customer)
209+
expect(result.current.query.data).toEqual(oldData)
210+
211+
// 2. Do update mutation
212+
act(() => result.current.mutation.mutate(options))
213+
await waitAndExpectSuccess(() => result.current.mutation)
214+
expect(result.current.mutation.data).toEqual(newData)
215+
// query updated
216+
assertUpdateQuery(result.current.query, newData)
217+
// customer cache updated (instrument replaced)
218+
const expectedCustomer = {
219+
...customer,
220+
paymentInstruments: [newData]
221+
}
222+
assertUpdateQuery(result.current.customer, expectedCustomer as any)
223+
})
179224
test('`removeCustomerAddress` updates cache on success', async () => {
180225
// 0. Setup
181226
const customer = baseCustomer

packages/commerce-sdk-react/src/hooks/ShopperCustomers/mutation.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ export const ShopperCustomersMutations = {
7373
* @returns A TanStack Query mutation hook for interacting with the Shopper Customers `createCustomerPaymentInstrument` endpoint.
7474
*/
7575
CreateCustomerPaymentInstrument: 'createCustomerPaymentInstrument',
76+
/**
77+
* Updates a customer's payment instrument.
78+
* @returns A TanStack Query mutation hook for interacting with the Shopper Customers `updateCustomerPaymentInstrument` endpoint.
79+
*/
80+
UpdateCustomerPaymentInstrument: 'updateCustomerPaymentInstrument',
7681
/**
7782
* Deletes a customer's payment instrument.
7883
* @returns A TanStack Query mutation hook for interacting with the Shopper Customers `deleteCustomerPaymentInstrument` endpoint.

packages/commerce-sdk-react/src/hooks/ShopperExperience/index.test.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ import * as queries from './query'
1111
describe('Shopper Experience hooks', () => {
1212
test('all endpoints have hooks', () => {
1313
const unimplemtented = getUnimplementedEndpoints(ShopperExperience, queries)
14-
expect(unimplemtented).toEqual([])
14+
expect(unimplemtented).toEqual([
15+
'getContent', //TODO: implement later
16+
'getContentFolder', //TODO: implement later
17+
'getContentFolders', //TODO: implement later
18+
'getMultipleContent', //TODO: implement later
19+
'searchContent' //TODO: implement later
20+
])
1521
})
1622
})

packages/commerce-sdk-react/src/hooks/ShopperLogin/index.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@ describe('Shopper Login hooks', () => {
2020
// These endpoints all return data in the response headers, rather than body, so they
2121
// don't work well with the current implementation of mutation hooks.
2222
'authenticateCustomer',
23-
'getTrustedAgentAuthorizationToken'
23+
'authorizeWebauthnRegistration',
24+
'finishWebauthnAuthentication',
25+
'finishWebauthnUserRegistration',
26+
'getTrustedAgentAuthorizationToken',
27+
'startWebauthnAuthentication',
28+
'startWebauthnUserRegistration'
2429
])
2530
})
2631
test('all mutations have cache update logic', () => {

0 commit comments

Comments
 (0)