Masterpass

pz-masterpass provides a set of modular and customizable components for Masterpass integration during checkout. This includes card management, OTP verification, and modal interactions.

Installation Method

You can use the following command to install the extension with the latest plugins:

npx @akinon/projectzero@latest --plugins

Masterpass Provider

Wraps your checkout context with Masterpass features. Use this at the top level of the checkout.

/src/app/[commerce]/[locale]/[currency]/orders/checkout/page.tsx

Usage Examples

Default Usage

<PluginModule
    component={Component.MasterpassProvider}
    props={{
translations: {
    genericErrorMessage: 'An error occurred. Please try again later.'
}
    }}
>
 ... ...
</PluginModule>

Customized Usage Additional Params

<PluginModule
  component={Component.MasterpassProvider}
  props={{
    additionalParams: {
      order_product_name_arr: ['TEST'],
      order_product_code_arr: ['TST'],
      order_qty_arr: ['1'],
      order_product_info_arr: ['test']
    }
  }}
>
 ... ...
</PluginModule>

Delete Confirmation Modal

Shows a modal when a user attempts to delete a saved card.

Props

Props
Type
Required
Description

translations

type of defaultTranslations

Optional

Used to customize the default texts.

renderer

RendererProps

Optional

Renderer functions that can be used to customize all subcomponents.

RendererProps

Props
Type
Description

open

boolean

It is information whether the modal is open or not.

setOpen

(open:boolean) => void

Used to manage modal on/off operation.

onConfirm

() => void

This is the function that will perform the deletion operation.

onCancel

() => void

This is the function that will be run if the user cancels the deletion process.

loading

boolean

Indicates the loading status during the deletion process.

error

string / null

Error message to be displayed if an error occurs during deletion.

Usage Examples

/src/apps/[commerce]/[locale]/[currency]/orders/checkot/page.tsx

Default Usage

<PluginModule
 component={Component.MasterpassDeleteConfirmationModal}
 props={{
   translations: {
     title: 'Are you sure you want to delete this card?',
     delete_button: 'Remove',
     cancel_button: 'Delete'
   }
 }}
/>

Customized Usage with Renderer

<PluginModule
 component={Component.MasterpassDeleteConfirmationModal}
 props={{
   renderer: {
     Content: ({ open, setOpen, onConfirm, onCancel, loading, error }) => (
       <Modal
         open={open}
         setOpen={setOpen}
         className="w-full sm:w-[28rem]"
         portalId="masterpass-remove-card-modal"
       >
         <div className="flex flex-col items-center p-5">
           <div className="text-xs mb-3">
             Are you sure you want to delete your card?
           </div>
           <Button onClick={onConfirm} className="bg-red-600 text-black">
             {loading ? 'Deletion...' : 'Delete'}
           </Button>
           <Button appearance="outlined" onClick={onCancel}>
             Cancel
           </Button>
           {error && (
             <p className="text-red-500 text-sm mt-2 text-center">
               🚨 {error}
             </p>
           )}
         </div>
       </Modal>
     )
   }
 }}
/>

OTP Modal

Displays an OTP verification modal after card action (add).

Props

Props
Type
Required
Description

translations

type of defaultTranslations

Optional

Used to customize the default texts.

renderer

RendererProps

Optional

Renderer functions that can be used to customize all subcomponents.

RendererProps

Props
Type
Description

open

boolean

It is information whether the modal is open or not.

setOpen

(open:boolean) => void

Used to manage modal on/off operation.

onSubmit

(data: { otp_code:string }) => void

Sends the OTP code entered by the user.

loading

boolean

Indicates the loading status during validation.

error

string / null

Error message to be displayed if there is an error.

resendSms

() => void

Function triggered when the user requests SMS again.

resendSmsFetching

boolean

Indicates the loading status during the resending process.

targetDate

number

When the countdown will end (as a timestamp).

otpRef

string / null

Transaction reference number, if applicable.

Usage Examples

/src/apps/[commerce]/[locale]/[currency]/orders/checkot/page.tsx

Default Usage

<PluginModule
 component={Component.MasterpassOtpModal}
 props={{
   translations: {
     enter_the_verification_code: 'Enter the verification code',
     sms_code: 'SMS Code',
     verify: 'Verify',
     resend_sms: 'Resend SMS',
     // Or pass response code to show custom message
     5001: 'Please enter the OTP sent to your mobile number'
   }
 }}
/>

Customized Usage with Renderer

<PluginModule
 component={Component.MasterpassOtpModal}
 props={{
   renderer: {
     Content: ({
       open,
       setOpen,
       onSubmit,
       loading,
       error,
       resendSms,
       resendSmsFetching,
       targetDate,
       otpRef
     }) => {
       const [code, setCode] = useState('');
       const [remainingSeconds, setRemainingSeconds] = useState(
         Math.ceil((targetDate - Date.now()) / 1000)
       );
       useEffect(() => {
         if (!targetDate) return;
         const interval = setInterval(() => {
           const secondsLeft = Math.ceil((targetDate - Date.now()) / 1000);
           setRemainingSeconds(secondsLeft);
           if (secondsLeft <= 0) {
             clearInterval(interval);
           }
         }, 1000);
         return () => clearInterval(interval);
       }, [targetDate]);
       return (
         <Modal
           open={open}
           setOpen={setOpen}
           className="w-full sm:w-[28rem]"
           portalId="otp-masterpass"
         >
           <div className="px-6 py-4">
             <h2 className="text-center text-xl text-primary-600 font-semibold">
               Verification Required
             </h2>
             <form
               onSubmit={(e) => {
                 e.preventDefault();
                 onSubmit({ otp_code: code });
               }}
               className="flex flex-col items-center mt-4"
             >
               <label
                 htmlFor="otp_code"
                 className="text-sm mb-1 text-gray-700"
               >
                 SMS Code
               </label>
               <input
                 id="otp_code"
                 maxLength={6}
                 value={code}
                 onChange={(e) => setCode(e.target.value)}
                 placeholder="••••••"
                 className="border p-2 rounded w-full max-w-[200px] text-center tracking-widest"
               />
               <Button
                 type="submit"
                 className="mt-4 px-4 py-2 bg-blue-600 text-black rounded"
               >
                 Verify
               </Button>
               {error && <p className="mt-2 text-xs text-red-500">{error}</p>}
             </form>
             <div className="mt-2 flex justify-center text-sm text-gray-600">
               {remainingSeconds > 0
                 ? `Time remaining: ${remainingSeconds} seconds`
                 : 'Time is up'}
             </div>
             <div className="mt-2 flex justify-center">
               <Button
                 onClick={resendSms}
                 disabled={loading}
                 className="mt-4 text-sm underline text-secondary-500"
               >
                 {resendSmsFetching
                   ? 'Code sent'
                   : 'Resend SMS code'}
               </Button>
             </div>
           </div>
         </Modal>
       );
     }
   }
 }}
/>

MasterpassLinkModal Component

Prompts user to link their Masterpass card if one is detected.

Props

Props
Type
Required
Description

translations

type of defaultTranslations

Optional

Used to customize the default texts.

renderer

RendererProps

Optional

Renderer functions that can be used to customize all subcomponents.

RendererProps

Props
Type
Description

open

boolean

It is information whether the modal is open or not.

setOpen

(open:boolean) => void

Used to manage modal on/off operation.

onClick

() => void

It is the function that is called when the user clicks the "Use" button.

loading

boolean

This is the loading status that will be displayed during the API request.

error

string / null

If there is an error in the API response, a message is displayed in this field.

Usage Examples

/src/app/[commerce]/[locale]/[currency]/orders/checkout/page.tsx

Default Usage

<PluginModule
 component={Component.MasterpassLinkModal}
 props={{
   translations: {
     use_masterpass_cards:
       'You have cards registered to your Masterpass account. Would you like to use your cards?',
     use: 'Use'
   }
 }}
/>

Customized Usage with Renderer

<PluginModule
 component={Component.MasterpassLinkModal}
 props={{
   renderer: {
     Content: ({ open, setOpen, onClick, loading, error }) => (
       <Modal
         open={open}
         setOpen={setOpen}
         className="w-full sm:w-[28rem]"
         portalId="masterpass-check-user"
       >
         <div className="p-10">
           <p className="text-sm text-center">
             You have cards registered to your Masterpass account. Do you want to use your cards?
           </p>
           <Button
             onClick={onClick}
             disabled={loading}
             className="bg-green-600 text-error w-full py-2 mt-4"
           >
             {loading ? 'Loading...' : 'Use'}
           </Button>
           {error && <p className="text-error text-sm">{error}</p>}
         </div>
       </Modal>
     )
   }
 }}
/>

MasterpassCardList Component

Displays all Masterpass-linked cards and allows selection or deletion.

Props

Props
Type
Required
Description

className

string

Optional

It adds an extra style class to the outer container of the component.

translations

{ [key: string]: string }

Optional

Used to customize the default texts.

renderer

RendererProps

Optional

Renderer functions that can be used to customize all subcomponents.

RendererProps

Props
Type
Description

Header

JSX.Element

Used to customize the title area at the top of the card list.

CardItem

(params: { card, selectedCard, onSelect, DeleteButton }) => JSX.Element

It allows you to fully customize the card element.

Loader

() => JSX.Element

Used to define a custom loader component to be displayed when loading cards.

ErrorFallback

(params: { error: string; onRetry: () => void }) => JSX.Element

Custom widget to be shown if an error occurs while loading cards.

SwitchPaymentButton

(props: { onClick: () => void; label: string }) => JSX.Element

Used to customize the "Pay with a new card" option.

Usage Examples

/src/views/checkout/steps/payment/options/credit-card/index.tsx

Default Usage

<PluginModule 
    component={Component.MasterpassCardList}
    props={{
        className: 'p-10',
        Translations:
            { 
    title: 'Select a card to pay with',
    pay_with_new_card: 'Pay with a new card',
    retryFetchCards: 'Retry Fetching Cards'
}
    }}
/>

Customized Usage with Renderer

<PluginModule
 component={Component.MasterpassCardList}
 props={{
   className: 'px-10',
   form: {
     control,
     register,
     errors,
     setFormValue,
     clearErrors
   },
   renderer: {
     Header: () => (
       <div className="flex items-center gap-2 mt-4 px-10 text-success">
         Select a card to pay
       </div>
     ),
     Loader: () => (
       <div className="flex justify-center items-center p-10">
         <span className="text-lg font-bold text-error">
           Loading your cards...
         </span>
       </div>
     ),
     ErrorFallback: ({ error, onRetry }) => (
       <div className="text-center p-8">
         <h2 className="text-red-500 text-xl mb-4">Oops! {error}</h2>
         <Button onClick={onRetry}>Try Again</Button>
       </div>
     ),
     CardItem: ({ card, onSelect, DeleteButton, selectedCard }) => (
       <li
         key={card.UniqueId}
         className="p-4 cursor-pointer rounded-[10px] border-gray border space-x-5 pl-5 mb-6 md:mb-2.5"
         onClick={() => onSelect(card)}
       >
         <div className="flex justify-between items-center">
           <div className="flex items-center">
             <Checkbox
               key={
                 selectedCard?.UniqueId === card.UniqueId
                   ? 'selected'
                   : 'not-selected'
               }
               checked={selectedCard?.UniqueId === card.UniqueId}
               onChange={() => onSelect(card)}
               className="mr-2"
             />
             <div>
               <h3 className="font-semibold">{card.Name}</h3>
               <p className="text-xs text-gray-500">{card.Value1}</p>
             </div>
           </div>
           <DeleteButton cardAliasName={card.Name} />
         </div>
       </li>
     ),
     SwitchPaymentButton: ({ onClick, label }) => (
       <div className="px-10">
         <button
           onClick={onClick}
           className="p-4 w-full text-left cursor-pointer rounded-[10px] border-gray border space-x-5 pl-5 mb-6 md:mb-2.5"
         >
           {label}
         </button>
       </div>
     )
   }
 }}
/>

MasterpassCardRegistration Component

Form to add a new Masterpass card and consent to store it.

Props

Props
Type
Required
Description

getValues

() => Record<string, string>

Required

Returns the values ​​of form fields.

className

string

Optional

Gives an additional CSS class to the outer container.

infoModalContent

React.ReactNode

Optional

Body content for the informational modal.

infoModalIcon

React.ReactNode

Optional

Used to override the notification icon.

translations

typeof defaultTranslations

Optional

Can be used to override default texts.

renderer

RendererProps

Optional

Renderer functions that can be used to customize all subcomponents.

RendererProps

Props
Type
Description

Content

props: { isChecked, toggle, setIsInfoModalOpen, onChange, onSubmit, loading, error, showGoBackLink?, onClickGoBackLink? }) => JSX.Element

Used to render the main content.

InfoModal

(props: { open: boolean; setOpen: (value: boolean) => void }) => JSX.Element

Can be used to override the notification modal.

Usage Examples

/src/views/checkout/steps/payment/options/credit-card/index.tsx

Default Usage

<PluginModule
 component={Component.MasterpassCardRegistration}
 props={{
   // Do not remove getValues, it is used to get the form values
   getValues,
   translations: {
     enter_card_name: 'Enter card name',
     continue: 'Continue',
     pay_with_my_masterpass_card: 'Pay with my Masterpass card',
     terms_and_conditions: 'Masterpass terms and conditions',
     card_registration_consent:
       'I want to store my card information in the Mastercard infrastructure and use it again in my next purchase.'
   }
 }}
/>

Customized Usage with className, infoModalContent, infoModalIcon

<PluginModule
 component={Component.MasterpassCardRegistration}
 props={{
   // Do not remove getValues, it is used to get the form values
   getValues,
   className: 'mt-5 mb-10 sm:px-10',
   infoModalContent: <div>Lorem...</div>,
   infoModalIcon: <Icon name="info" />,
   translations: {
     enter_card_name: 'Enter card name',
     continue: 'Continue',
     pay_with_my_masterpass_card: 'Pay with my Masterpass card',
     terms_and_conditions: 'Masterpass terms and conditions',
     card_registration_consent:
       'I want to store my card information in the Mastercard infrastructure and use it again in my next purchase.'
   }
 }}
/>

Customized Usage with Renderer

<PluginModule
 component={Component.MasterpassCardRegistration}
 props={{
   // Do not remove getValues, it is used to get the form values
   getValues,
   renderer: {
     InfoModal: ({ open, setOpen }) => (
       <Modal
         open={open}
         setOpen={setOpen}
         portalId="masterpass-info-modal"
       >
         masterpass information
       </Modal>
     ),
     Content: ({
       isChecked,
       toggle,
       setIsInfoModalOpen,
       onChange,
       onSubmit,
       loading,
       error,
       showGoBackLink,
       onClickGoBackLink
     }) => (
       <div className="bg-[#F8F8F8] mx-10 mb-5 px-2 py-1">
         <div className="flex items-center gap-2 pb-4 mb-4">
           <Checkbox checked={isChecked} onChange={toggle} />
           <h1>Masterpass</h1>
           <div>
             <Icon
               name="info"
               size={15}
               className="fill-[#000000] cursor-pointer"
               onClick={() => {
                 setIsInfoModalOpen(true);
               }}
             />
           </div>
         </div>
         <p className="text-xs">
           I want to store my card information in the Mastercard infrastructure and use it again in my next purchase.
         </p>
         {isChecked && (
           <>
             <Input
               label="Give your card a name"
               onChange={(e) =>
                 onChange((e.target as HTMLInputElement).value)
               }
               className="mt-2"
             />
             <Button
               onClick={onSubmit}
               className="bg-green-600 text-black w-full mt-3"
             >
               {loading ? 'Loading...' : 'Save'}
             </Button>
             {error && (
               <p className="text-xs text-red-600 mt-2">🚨 {error}</p>
             )}
           </>
         )}
         {showGoBackLink && (
           <div>
             <button
               onClick={onClickGoBackLink}
               className="text-xs text-red-600 underline mt-3"
             >
               I want to pay with my card registered to Masterpass.
             </button>
           </div>
         )}
       </div>
     )
   }
 }}
/>

Last updated

Was this helpful?