Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Expand
titlefrontend/src/pages/cart/payment/order-payment/use-order-payment.ts

Add a new state for the new payment method:

const [isPaycometNewMethodSelected, setIsPaycometNewMethodSelected] = useState('');

Update the handlePaymentMethodSelected adding the new method:

Code Block
languagetypescript
  const handlePaymentMethodSelected = (newFdAccountId?: string) => {
    if (!newFdAccountId) {
      payment.setCheckoutPaymentMethodId('');
      return;
    }
    
    // ... rest of the code
    setIsPaycometNewMethodSelected(''); // New line
  };

Clear our new method in the useEffect logic that already exist:

Code Block
languagetypescript
  // when checkout payment method have been updated from payment context
  // the flags to show add new credit card or add gift card
  // have to be updated.
  useEffect(() => {
      // ... rest of the code
      setIsPaycometNewMethodSelected('');
    }
  }, [setCheckoutPaymentMethodId, checkoutPaymentMethodId]);

Update the placeOrder function to deal with the new method:

  • Option 1:

    • Adjust the if condition for paycomet processor to deal with the new method:

      Code Block
      languagetypescript
      } else if (payment.isPaycomet) {
              // ... rest of the code
              if (payCometValues.isPaypal) {
                // ... rest of the code
              } else {
                commitInput// =add {a new condition here for our new method, like the sodexo  one
      creditType: payCometValues.cardType,         let paymentMethodBrandValue = undefined;
      order,          if (isPaycometSodexoMethodSelected || payment:isPaycometChequeGourmetMethodSelected) {
                  paymentMethodBrandValue = //isPaycometSodexoMethodSelected
      ... rest of the code          ? PaymentMethodBrand.SODEXO
         // adjust this condition  below to  deal with Sodexo and also with our new method: PaymentMethodBrand.CHEQUE_GOURMET;
                }
             paymentMethodBrand: isPaycometSodexoMethodSelected  commitInput = {
                  ?// PaymentMethodBrand...SODEXO rest of the code
                  : undefined,};
                  }
        // ... rest of the code
                  },
                  skipCoolingPeriod: true,
                };
              

  • Option 2:

    • Separate this logic in another reusable block and then pass the new paymentMethodBrand (as a kind of builder pattern or something similar). We can discuss that on an A&D section.

Adjust the processOrderWithAccount function for the new method like this Sodexo example:

Code Block
languagetypescript
        // ... rest of the code
        const isPaymentWithVoucher =
          paymentAccount.paymentMethodBrand === PaymentMethodBrand.SODEXO_VOUCHER ||
          paymentAccount.paymentMethodBrand === PaymentMethodBrand.CHEQUE_GOURMET_VOUCHER;
        if (payment.checkoutPaymentMethodId === CASH_ACCOUNT_IDENTIFIER || isPaymentWithVoucher) {
          const paymentDetails: IPayment = {
            cashPayment: true,
            fullName,
            paymentMethodBrand: paymentAccount?.paymentMethodBrand ?? undefined,
          };

          if (payment.isVrPayment) {
            // The GraphQL endpoint for VR Payment expects this object even
            // for Cash orders, otherwise the order creation fails
            paymentDetails.vrPaymentInput = {
              merchantAccount: '',
              pspReference: '',
              storePaymentMethod: true,
            };
          }

          return commitOrder({
            ...commitInput,
            creditType: CASH_ACCOUNT_IDENTIFIER,
            payment: paymentDetails,
          });
        }

Adjust the handleOrderCommit to place the order with the new method:

Code Block
languagetypescript
      // Add new condition here as the isPaymentWithVoucher from the Sodexo example
      
      const isPaymentWithVoucher = isPaymentWithSodexoVoucher || isPaymentWithChequeGourmetVoucher;

      if (
        (showAddPaymentMethod ||
          isAdyenBlikMethodSelected ||
          reloadAddPaymentMethod ||
          isPayPalRegistration) &&
        !(selectedPaymentMethod?.cash || isPaymentWithVoucher || payment.isFreeOrderPayment)
      ) {
        await placeOrder();
      } else {
        await placeOrderWithAccount();
      }
  • Extend the getCurrentSelectedMethodType:

Expand
titlefrontend/src/components/payment-method/utils/get-current-selected-method-type.ts

Add the new payment in the enum CurrentSelectedMethodType:

  • frontend/src/components/payment-method/types.ts:

Code Block
languagetypescript
export enum CurrentSelectedMethodType {
  // ... rest of the code
  ADD_NEW_PAYMENT_NEW_METHOD = 'addNewPaymentNewMethod',
}

Adjust the IPaymentMethodProps:

Code Block
languagetypescript
export interface IPaymentMethodProps {
  // ... rest of the code
  setIsPaycometNewMethodSelected?: Dispatch<SetStateAction<string>>;
  isPaycometNewMethodSelected?: string;
}

Add the new condition in getCurrentSelectedMethodType:

Code Block

type GetCurrentSelectedMethodTypeParams = {
  // ... rest of the code
  isPaycometNewMethodSelected?: string;
};

function getCurrentSelectedMethodType({
  // ... rest of the code
  isPaycometNewMethodSelected
}: GetCurrentSelectedMethodTypeParams): CurrentSelectedMethodType {
  let currentSelectedMethodType = CurrentSelectedMethodType.ADD_NEW_PAYMENT_METHOD;
  // ... rest of the code
  if (isPaycometNewMethodSelected === 'card') {
    currentSelectedMethodType = CurrentSelectedMethodType.ADD_NEW_PAYMENT_NEW_METHOD;
  }
  // ... rest of the code
}

  • Adjust order-payment comp:

Expand
titlefrontend/src/pages/cart/payment/order-payment/payment.tsx

Return the new create state from useOrderPayment:

Code Block
languagetypescript
  const {
   // ... rest of the code
   isPaycometNewMethodSelected, // new line here
  } = useOrderPayment({
    serverOrder,
    onPriceOrder,
    enableOrderTimedFire,
  });

Pass the returned value to the getCurrentSelectedMethodType:

Code Block
languagetypescript
  const currentSelectedMethodType = getCurrentSelectedMethodType({
    isPaycometNewMethodSelected,
  });

Pass the new method to the <PaymentMethod> comp:

Code Block
languagetypescript
<PaymentMethod
   // ... rest of the code
   isPaycometNewMethodSelected={isPaycometNewMethodSelected}
/>

Task X: Add the new method in payment-method structure

  • Create new styled component for the new payment method

Expand
titlefrontend/src/components/payment-method/styled.ts
Code Block
languagetypescript
// ... rest of the file
export const StyledNewMethodCardIcon = styled(IconNewMethod)`
  ${cardIconSize}
`;
  • Add a new type

Expand
titlefrontend/src/components/payment-method/payment-method-options/types.ts
Code Block
languagetypescript
export type PaymentMethodOptionProps = {
  // ... rest of the file
  setIsPaycometNewMethodSelected?: Dispatch<SetStateAction<string>>;
};
  • Add the new method in payment-method comp

Expand
titleworkspaces/frontend/src/components/payment-method/index.tsx

Add new props in PaymentMethod:

Code Block
languagetypescript

function PaymentMethod({
  // ... rest of the code
  isPaycometNewMethodSelected,
  setIsPaycometNewMethodSelected,
}: IPaymentMethodProps) {
  // ... rest of the code
  
  // pass the new prop in the getCurrentSelectedMethodType
  const currentSelectedMethodType = getCurrentSelectedMethodType({
    isPaycometNewMethodSelected
  });
});

Create new item inside PaymentMethod comp:

Code Block
languagejsx
// ... rest of the file
const SelectedNewMethodOptionItem = (
  <PaymentMethodAddNewItemOption
    data-testid="payment-new-method-name"
    text={formatMessage({ id: 'addNewPaymentNewMethod' })}
    Icon={<StyledNewMethodCardIcon />}
    onClick={getSelectedMethodClickHandler()}
    selected
  />
);

Add the new method in the map structure:

Code Block
  const CurrentSelectedMethodMap = {
    // ... rest of the file
    [CurrentSelectedMethodType.ADD_NEW_PAYMENT_METHOD]: SelectedNewMethodOptionItem,
  };

Pass the new prop in the <PaymentMethodOptions> comp:

Code Block
languagetsx
 <PaymentMethodOptions
    setIsPaycometNewMethodSelected={setIsPaycometNewMethodSelected}
  />
  • Add the new method in payment-method-options comp

Expand
titlefrontend/src/components/payment-method/payment-method-options/payment-method-options.tsx

Add the new prop in PaymentMethodOptions comp:

Code Block
languagetypescript
function PaymentMethodOptions({
  // .. rest of the file
  setIsPaycometNewMethodSelected
}: PaymentMethodOptionProps) {
  const enableNewMethod = useFlag(LaunchDarklyFlag.ENABLE_CREDIT_CARD_AT_HOME_PAYCOMET); // new line

});

Add new condition in handleUnselectedMethodClick, handleAddNewCardOptionClick, handleAddNewGiftCardOptionClick, handlePaypalOptionClick and handleAdyenIdealOptionClick to clear our new state:

Code Block
languagetypescript
  if (setIsPaycometSodexoOptionSelected) {
    setIsPaycometNewMethodSelected('');
  }

Add a new handle for our new method (using useCallback) where we’ll clear the other methods and set your:

Code Block
languagetypescript
  const handleNewMethodOptionClick = useCallback(
    (e: React.FormEvent<HTMLButtonElement>, newMethodType: string) => {
      e.preventDefault();
      setIsAddNewCardOptionSelected(false);
      setIsAddNewGiftCardOptionSelected(false);
      if (setIsPaycometPaypalOptionSelected) {
        setIsPaycometPaypalOptionSelected(false);
      }
      if (setIsAdyenIdealOptionSelected) {
        setIsAdyenIdealOptionSelected(false);
      }
      if (setIsAdyenBlikOptionSelected) {
        setIsAdyenBlikOptionSelected(false);
      }
      if (setIsPaycometSodexoOptionSelected) {
        setIsPaycometSodexoOptionSelected('');
      }
      if (setIsPaycometSodexoOptionSelected) {
        setIsPaycometSodexoOptionSelected('');
      }
      // our new method here
      if (setIsPaycometNewMethodSelected) {
        setIsPaycometNewMethodSelected(newMethodType);
        if (newMethodType === 'card') {
          setIsAddNewCardOptionSelected(true);
        }
      }

      handleSelect();
      setCollapsed(true);
    },
    [
     // callback dependencies here
    ]
  );

Add in the enableSortPaymentMethods && unSelectedMethods.map a new block for our new method:

Code Block
languagetsx
{method?.sodexo && method?.transient && (
  <StyledOption>
    <PaymentMethodOptionItemDivider />
    <PaymentMethodAddNewItemOption
      data-testid="add-new-method-credit-card-payment"
      text={formatMessage({ id: newMethodLabel(isGuestOrder) })}
      Icon={<StyledNewMethodCardIcon />}
      onClick={e => handleNewMethodOptionClick(e, 'card')}
      isLoading={isLoadingPopup}
    />
  </StyledOption>
)}

Add a new block for for the case where we not have the enableSortPaymentMethods as true:

Code Block
languagetsx
{!enableSortPaymentMethods && enableNewMethod && (
  <StyledOption>
    <PaymentMethodOptionItemDivider />
    <PaymentMethodAddNewItemOption
      data-testid="add-sodexo-credit-card-payment"
      text={formatMessage({ id: newMethodLabel(isGuestOrder) })}
      Icon={<StyledNewMethodCardIcon />}
      onClick={e => handleNewMethodOptionClick(e, 'card')}
      isLoading={isLoadingPopup}
    /
/ ...
>
rest
 
of
 
the codeOption 2:
</StyledOption>
)}

Task 2: Create and add a new method in payment-method-option structure

...