# 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.

## <mark style="color:red;">**Installation Method**</mark>

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

```bash
npx @akinon/projectzero@latest --plugins
```

## <mark style="color:red;">**Masterpass Provider**</mark>

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

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

### <mark style="color:red;">**Usage Examples**</mark>

#### **Default Usage**

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

#### **Customized Usage Additional Params**

```javascript
<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>
```

## <mark style="color:red;">**Delete Confirmation Modal**</mark>

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

### <mark style="color:red;">**Props**</mark>

<table><thead><tr><th width="120.3125">Props</th><th width="166.22265625">Type</th><th width="104.3671875">Required</th><th>Description</th></tr></thead><tbody><tr><td>translations</td><td>type of defaultTranslations</td><td>Optional</td><td>Used to customize the default texts.</td></tr><tr><td>renderer</td><td>RendererProps</td><td>Optional</td><td>Renderer functions that can be used to customize all subcomponents.</td></tr></tbody></table>

### **RendererProps**

<table><thead><tr><th width="126.05078125">Props</th><th width="199.0625">Type</th><th>Description</th></tr></thead><tbody><tr><td>open</td><td>boolean</td><td>It is information whether the modal is open or not.</td></tr><tr><td>setOpen</td><td>(open:boolean) => void</td><td>Used to manage modal on/off operation.</td></tr><tr><td>onConfirm</td><td>() => void</td><td>This is the function that will perform the deletion operation.</td></tr><tr><td>onCancel</td><td>() => void</td><td>This is the function that will be run if the user cancels the deletion process.</td></tr><tr><td>loading</td><td>boolean</td><td>Indicates the loading status during the deletion process.</td></tr><tr><td>error</td><td>string / null</td><td>Error message to be displayed if an error occurs during deletion.</td></tr></tbody></table>

### <mark style="color:red;">**Usage Examples**</mark>

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

#### **Default Usage**

```javascript
<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**

```javascript
<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>
     )
   }
 }}
/>
```

## <mark style="color:red;">**OTP Modal**</mark>

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

### <mark style="color:red;">**Props**</mark>

<table><thead><tr><th width="116.3046875">Props</th><th width="171.21875">Type</th><th width="119.23828125">Required</th><th>Description</th></tr></thead><tbody><tr><td>translations</td><td>type of defaultTranslations</td><td>Optional</td><td>Used to customize the default texts.</td></tr><tr><td>renderer</td><td>RendererProps</td><td>Optional</td><td>Renderer functions that can be used to customize all subcomponents.</td></tr></tbody></table>

### <mark style="color:red;">**RendererProps**</mark>

<table><thead><tr><th width="130.86328125">Props</th><th width="196.55078125">Type</th><th>Description</th></tr></thead><tbody><tr><td>open</td><td>boolean</td><td>It is information whether the modal is open or not.</td></tr><tr><td>setOpen</td><td>(open:boolean) => void</td><td>Used to manage modal on/off operation.</td></tr><tr><td>onSubmit</td><td>(data: { otp_code:string }) => void</td><td>Sends the OTP code entered by the user.</td></tr><tr><td>loading</td><td>boolean</td><td>Indicates the loading status during validation.</td></tr><tr><td>error</td><td>string / null</td><td>Error message to be displayed if there is an error.</td></tr><tr><td>resendSms</td><td>() => void</td><td>Function triggered when the user requests SMS again.</td></tr><tr><td>resendSmsFetching</td><td>boolean</td><td>Indicates the loading status during the resending process.</td></tr><tr><td>targetDate</td><td>number</td><td>When the countdown will end (as a timestamp).</td></tr><tr><td>otpRef</td><td>string / null</td><td>Transaction reference number, if applicable.</td></tr></tbody></table>

### <mark style="color:red;">**Usage Examples**</mark>

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

#### **Default Usage**

```javascript
<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**

```javascript
<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>
       );
     }
   }
 }}
/>
```

## <mark style="color:red;">**MasterpassLinkModal Component**</mark>

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

### <mark style="color:red;">**Props**</mark>

<table><thead><tr><th width="132.078125">Props</th><th width="176.82421875">Type</th><th width="111.44921875">Required</th><th>Description</th></tr></thead><tbody><tr><td>translations</td><td>type of defaultTranslations</td><td>Optional</td><td>Used to customize the default texts.</td></tr><tr><td>renderer</td><td>RendererProps</td><td>Optional</td><td>Renderer functions that can be used to customize all subcomponents.</td></tr></tbody></table>

### <mark style="color:red;">**RendererProps**</mark>

<table><thead><tr><th width="115.51953125">Props</th><th width="197.484375">Type</th><th>Description</th></tr></thead><tbody><tr><td>open</td><td>boolean</td><td>It is information whether the modal is open or not.</td></tr><tr><td>setOpen</td><td>(open:boolean) => void</td><td>Used to manage modal on/off operation.</td></tr><tr><td>onClick</td><td>() => void</td><td>It is the function that is called when the user clicks the "Use" button.</td></tr><tr><td>loading</td><td>boolean</td><td>This is the loading status that will be displayed during the API request.</td></tr><tr><td>error</td><td>string / null</td><td>If there is an error in the API response, a message is displayed in this field.</td></tr></tbody></table>

### <mark style="color:red;">**Usage Examples**</mark>

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

#### **Default Usage**

```javascript
<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**

```javascript
<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>
     )
   }
 }}
/>
```

## <mark style="color:red;">**MasterpassCardList Component**</mark>

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

### <mark style="color:red;">**Props**</mark>

<table><thead><tr><th width="125.37890625">Props</th><th width="180.796875">Type</th><th width="125.76953125">Required</th><th>Description</th></tr></thead><tbody><tr><td>className</td><td>string</td><td>Optional</td><td>It adds an extra style class to the outer container of the component.</td></tr><tr><td>translations</td><td>{ [key: string]: string }</td><td>Optional</td><td>Used to customize the default texts.</td></tr><tr><td>renderer</td><td>RendererProps</td><td>Optional</td><td>Renderer functions that can be used to customize all subcomponents.</td></tr></tbody></table>

### <mark style="color:red;">**RendererProps**</mark>

<table><thead><tr><th width="142.03125">Props</th><th width="229.8515625">Type</th><th>Description</th></tr></thead><tbody><tr><td>Header</td><td>JSX.Element</td><td>Used to customize the title area at the top of the card list.</td></tr><tr><td>CardItem</td><td>(params: { card, selectedCard, onSelect, DeleteButton }) => JSX.Element</td><td>It allows you to fully customize the card element.</td></tr><tr><td>Loader</td><td>() => JSX.Element</td><td>Used to define a custom loader component to be displayed when loading cards.</td></tr><tr><td>ErrorFallback</td><td>(params: { error: string; onRetry: () => void }) => JSX.Element</td><td>Custom widget to be shown if an error occurs while loading cards.</td></tr><tr><td>SwitchPaymentButton</td><td>(props: { onClick: () => void; label: string }) => JSX.Element</td><td>Used to customize the "Pay with a new card" option.</td></tr></tbody></table>

### <mark style="color:red;">**Usage Examples**</mark>

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

**Default Usage**

```javascript
<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**

```javascript
<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>
     )
   }
 }}
/>
```

## <mark style="color:red;">**MasterpassCardRegistration Component**</mark>

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

### <mark style="color:red;">**Props**</mark>

<table><thead><tr><th width="162.23046875">Props</th><th width="153.41796875">Type</th><th width="132.453125">Required</th><th>Description</th></tr></thead><tbody><tr><td>getValues</td><td>() => Record&#x3C;string, string></td><td>Required</td><td>Returns the values ​​of form fields.</td></tr><tr><td>className</td><td>string</td><td>Optional</td><td>Gives an additional CSS class to the outer container.</td></tr><tr><td>infoModalContent</td><td>React.ReactNode</td><td>Optional</td><td>Body content for the informational modal.</td></tr><tr><td>infoModalIcon</td><td>React.ReactNode</td><td>Optional</td><td>Used to override the notification icon.</td></tr><tr><td>translations</td><td>typeof defaultTranslations</td><td>Optional</td><td>Can be used to override default texts.</td></tr><tr><td>renderer</td><td>RendererProps</td><td>Optional</td><td>Renderer functions that can be used to customize all subcomponents.</td></tr></tbody></table>

### <mark style="color:red;">**RendererProps**</mark>

<table><thead><tr><th width="124.82421875">Props</th><th width="271.28125">Type</th><th>Description</th></tr></thead><tbody><tr><td>Content</td><td>props: { isChecked, toggle, setIsInfoModalOpen, onChange, onSubmit, loading, error, showGoBackLink?, onClickGoBackLink? }) => JSX.Element</td><td>Used to render the main content.</td></tr><tr><td>InfoModal</td><td>(props: { open: boolean; setOpen: (value: boolean) => void }) => JSX.Element</td><td>Can be used to override the notification modal.</td></tr></tbody></table>

### <mark style="color:red;">**Usage Examples**</mark>

```bash
/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**

```javascript
<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**

```javascript
<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>
     )
   }
 }}
/>
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.akinon.com/technical-guides/project-zero/next.js/plugins/masterpass.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
