@@ -33,6 +33,8 @@ import { useUserInteractions } from '@/hooks/useUserInteractions'
3333import { useUserByUsername } from '@/hooks/useUserByUsername'
3434import { PaymentFlow } from '@/app/[...recipient]/client'
3535import MantecaFulfillment from '../Views/MantecaFulfillment.view'
36+ import { invitesApi } from '@/services/invites'
37+ import { EInviteType } from '@/services/services.types'
3638
3739export type PaymentFlowProps = {
3840 isExternalWalletFlow ?: boolean
@@ -66,7 +68,7 @@ export const PaymentForm = ({
6668} : PaymentFormProps ) => {
6769 const dispatch = useAppDispatch ( )
6870 const router = useRouter ( )
69- const { user } = useAuth ( )
71+ const { user, fetchUser } = useAuth ( )
7072 const { requestDetails, chargeDetails, daimoError, error : paymentStoreError , attachmentOptions } = usePaymentStore ( )
7173 const {
7274 setShowExternalWalletFulfillMethods,
@@ -91,6 +93,8 @@ export const PaymentForm = ({
9193 const [ inputTokenAmount , setInputTokenAmount ] = useState < string > (
9294 chargeDetails ?. tokenAmount || requestDetails ?. tokenAmount || amount || ''
9395 )
96+ const [ isAcceptingInvite , setIsAcceptingInvite ] = useState ( false )
97+ const [ inviteError , setInviteError ] = useState ( false )
9498
9599 // states
96100 const [ disconnectWagmiModal , setDisconnectWagmiModal ] = useState < boolean > ( false )
@@ -108,8 +112,9 @@ export const PaymentForm = ({
108112 const error = useMemo ( ( ) => {
109113 if ( paymentStoreError ) return ErrorHandler ( paymentStoreError )
110114 if ( initiatorError ) return ErrorHandler ( initiatorError )
115+ if ( inviteError ) return 'Something went wrong. Please try again or contact support.'
111116 return null
112- } , [ paymentStoreError , initiatorError ] )
117+ } , [ paymentStoreError , initiatorError , inviteError ] )
113118
114119 const {
115120 selectedTokenPrice,
@@ -314,8 +319,43 @@ export const PaymentForm = ({
314319 isActivePeanutWallet ,
315320 ] )
316321
322+ const handleAcceptInvite = async ( ) => {
323+ try {
324+ setIsAcceptingInvite ( true )
325+ const inviteCode = `${ recipient ?. identifier } INVITESYOU`
326+ const result = await invitesApi . acceptInvite ( inviteCode , EInviteType . PAYMENT_LINK )
327+
328+ if ( ! result . success ) {
329+ console . error ( 'Failed to accept invite' )
330+ setInviteError ( true )
331+ setIsAcceptingInvite ( false )
332+ return false
333+ }
334+
335+ // fetch user so that we have the latest state and user can access the app.
336+ // We dont need to wait for this, can happen in background.
337+ await fetchUser ( )
338+ setIsAcceptingInvite ( false )
339+ return true
340+ } catch ( error ) {
341+ console . error ( 'Failed to accept invite' , error )
342+ setInviteError ( true )
343+ setIsAcceptingInvite ( false )
344+ return false
345+ }
346+ }
347+
317348 const handleInitiatePayment = useCallback ( async ( ) => {
349+ // clear invite error
350+ if ( inviteError ) {
351+ setInviteError ( false )
352+ }
318353 if ( isActivePeanutWallet && isInsufficientBalanceError && ! isExternalWalletFlow ) {
354+ // If the user doesn't have app access, accept the invite before claiming the link
355+ if ( recipient . recipientType === 'USERNAME' && ! user ?. user . hasAppAccess ) {
356+ const isAccepted = await handleAcceptInvite ( )
357+ if ( ! isAccepted ) return
358+ }
319359 router . push ( '/add-money' )
320360 return
321361 }
@@ -416,6 +456,8 @@ export const PaymentForm = ({
416456 selectedChainID ,
417457 inputUsdValue ,
418458 requestedTokenPrice ,
459+ inviteError ,
460+ handleAcceptInvite ,
419461 ] )
420462
421463 const getButtonText = ( ) => {
@@ -654,7 +696,7 @@ export const PaymentForm = ({
654696 { isPeanutWalletConnected && ( ! error || isInsufficientBalanceError ) && (
655697 < Button
656698 variant = "purple"
657- loading = { isProcessing }
699+ loading = { isAcceptingInvite || isProcessing }
658700 shadowSize = "4"
659701 onClick = { handleInitiatePayment }
660702 disabled = { isButtonDisabled }
0 commit comments