@@ -91,6 +91,7 @@ const Payment = ({
9191 const loginPasswordless = useAuthHelper ( AuthHelpers . LoginPasswordlessUser )
9292 const { isOpen : isOtpOpen , onOpen : onOtpOpen , onClose : onOtpClose } = useDisclosure ( )
9393 const otpDismissedRef = useRef ( false )
94+ const activeBasketIdRef = useRef ( null )
9495 const passwordlessConfigCallback = getConfig ( ) . app . login ?. passwordless ?. callbackURI
9596 const callbackURL = isAbsoluteURL ( passwordlessConfigCallback )
9697 ? passwordlessConfigCallback
@@ -185,15 +186,35 @@ const Payment = ({
185186 // Allow auth storage to settle before SCAPI calls
186187 await auth . refreshAccessToken ( )
187188
188- await recoverBasketAfterAuth ( {
189+ // Immediately mark OTP completed and close modal to prevent a brief re-open on remounts
190+ otpDismissedRef . current = true
191+ setEnableUserRegistration ?. ( false )
192+ onOtpClose ( )
193+
194+ const newBasketId = await recoverBasketAfterAuth ( {
189195 preLoginItems : basket ?. productItems || [ ] ,
190- shipmentSnapshot : basket ?. shipments ?. [ 0 ] || null ,
196+ shipment : basket ?. shipments ?. [ 0 ] || null ,
191197 doMerge : true
192198 } )
193- otpDismissedRef . current = true
199+ if ( newBasketId ) {
200+ activeBasketIdRef . current = newBasketId
201+ }
194202 // Ensure save-for-future is selected after successful registration
195203 setShouldSavePaymentMethod ( true )
196204
205+ // If user typed a new card and nothing is applied yet, apply it to the new basket id
206+ try {
207+ const values = paymentMethodForm ?. getValues ?. ( )
208+ const hasEnteredCard = values ?. number && values ?. holder && values ?. expiry
209+ const hasApplied = ( currentBasketQuery ?. data ?. paymentInstruments ?. length || 0 ) > 0
210+ if ( hasEnteredCard && ! hasApplied && newBasketId ) {
211+ await onPaymentSubmit ( values , newBasketId )
212+ await currentBasketQuery . refetch ( )
213+ }
214+ } catch ( _e ) {
215+ // best-effort; user can still place order manually
216+ }
217+
197218 showToast ( {
198219 variant : 'subtle' ,
199220 title : `${ formatMessage (
@@ -214,7 +235,7 @@ const Payment = ({
214235 isClosable : true
215236 } )
216237
217- onOtpClose ( )
238+ // modal already closed right after auth
218239 } catch ( error ) {
219240 let message = formatMessage ( API_ERROR_MESSAGE )
220241 if ( error . response ) {
@@ -235,8 +256,9 @@ const Payment = ({
235256 const handleSendEmailOtp = async ( email ) => {
236257 try {
237258 await authorizePasswordlessLogin . mutateAsync ( {
259+ // Pass fields at top-level. The helper maps to query/body correctly.
238260 userid : email ,
239- callbackURI : ` ${ callbackURL } ?mode=otp_email` ,
261+ callbackURI : callbackURL ,
240262 register_customer : true ,
241263 last_name : email ,
242264 email : email
@@ -300,7 +322,7 @@ const Payment = ({
300322 // eslint-disable-next-line @typescript-eslint/no-unused-vars
301323 const { removePromoCode, ...promoCodeProps } = usePromoCode ( )
302324
303- const onPaymentSubmit = async ( formValue ) => {
325+ const onPaymentSubmit = async ( formValue , forcedBasketId ) => {
304326 // The form gives us the expiration date as `MM/YY` - so we need to split it into
305327 // month and year to submit them as individual fields.
306328 const [ expirationMonth , expirationYear ] = formValue . expiry . split ( '/' )
@@ -322,7 +344,7 @@ const Payment = ({
322344 }
323345
324346 return addPaymentInstrumentToBasket ( {
325- parameters : { basketId : basket ?. basketId } ,
347+ parameters : { basketId : forcedBasketId || activeBasketIdRef . current || basket ?. basketId } ,
326348 body : paymentInstrument
327349 } )
328350 }
@@ -338,15 +360,18 @@ const Payment = ({
338360 const isRegistered = customer ?. isRegistered
339361 const hasSaved = customer ?. paymentInstruments ?. length > 0
340362 const alreadyApplied = ( basket ?. paymentInstruments ?. length || 0 ) > 0
341- if ( ! isRegistered || ! hasSaved || alreadyApplied ) return
363+ // If the shopper is currently typing a new card, skip auto-apply of saved
364+ const entered = paymentMethodForm ?. getValues ?. ( )
365+ const hasEnteredCard = entered ?. number && entered ?. holder && entered ?. expiry
366+ if ( ! isRegistered || ! hasSaved || alreadyApplied || hasEnteredCard ) return
342367 autoAppliedRef . current = true
343368 const preferred =
344369 customer . paymentInstruments . find ( ( pi ) => pi . default === true ) ||
345370 customer . paymentInstruments [ 0 ]
346371 try {
347372 setIsApplyingSavedPayment ( true )
348373 await addPaymentInstrumentToBasket ( {
349- parameters : { basketId : basket ?. basketId } ,
374+ parameters : { basketId : activeBasketIdRef . current || basket ?. basketId } ,
350375 body : {
351376 paymentMethodId : 'CREDIT_CARD' ,
352377 customerPaymentInstrumentId : preferred . paymentInstrumentId
@@ -394,7 +419,7 @@ const Payment = ({
394419 } else {
395420 setIsApplyingSavedPayment ( true )
396421 await addPaymentInstrumentToBasket ( {
397- parameters : { basketId : basket ?. basketId } ,
422+ parameters : { basketId : activeBasketIdRef . current || basket ?. basketId } ,
398423 body : {
399424 paymentMethodId : 'CREDIT_CARD' ,
400425 customerPaymentInstrumentId : paymentInstrumentId
@@ -423,15 +448,15 @@ const Payment = ({
423448 const { addressId, creationDate, lastModified, preferred, ...address } = billingAddress
424449 return await updateBillingAddressForBasket ( {
425450 body : address ,
426- parameters : { basketId : basket . basketId }
451+ parameters : { basketId : activeBasketIdRef . current || basket . basketId }
427452 } )
428453 }
429454
430455 const onPaymentRemoval = async ( ) => {
431456 try {
432457 await removePaymentInstrumentFromBasket ( {
433458 parameters : {
434- basketId : basket . basketId ,
459+ basketId : activeBasketIdRef . current || basket . basketId ,
435460 paymentInstrumentId : appliedPayment . paymentInstrumentId
436461 }
437462 } )
@@ -445,7 +470,7 @@ const Payment = ({
445470 const onSubmit = paymentMethodForm . handleSubmit ( async ( paymentFormValues ) => {
446471 try {
447472 if ( ! appliedPayment ) {
448- await onPaymentSubmit ( paymentFormValues )
473+ await onPaymentSubmit ( paymentFormValues , activeBasketIdRef . current )
449474 }
450475
451476 // Update billing address
0 commit comments