--- title: PinPad API description: >- The PinPad API provides secure PIN entry functionality for POS UI extensions, allowing you to display modal PIN pad interfaces for secure PIN collection, validation, and processing with customizable options and callback handling. The API enables secure authentication workflows within your extensions. api_version: 2026-01 api_name: pos-ui-extensions source_url: html: >- https://shopify.dev/docs/api/pos-ui-extensions/latest/target-apis/platform-apis/pinpad-api md: >- https://shopify.dev/docs/api/pos-ui-extensions/latest/target-apis/platform-apis/pinpad-api.md --- # Pin​Pad API The PinPad API provides secure PIN entry functionality for POS UI extensions, allowing you to display modal PIN pad interfaces for secure PIN collection, validation, and processing with customizable options and callback handling. The API enables secure authentication workflows within your extensions. #### Use cases * **Staff authentication:** Implement secure authentication requiring PIN verification from staff. * **Access control:** Create access control for sensitive operations like refunds or voids. * **Authorization:** Build security features requiring PIN-based authorization for critical actions. * **Secure entry:** Create secure data entry workflows requiring PIN confirmation. ### Support Targets (28) ### Supported targets * [pos.​cart.​line-item-details.​action.​menu-item.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/cart-details#cart-details-targets) * [pos.​cart.​line-item-details.​action.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/cart-details#cart-details-action-modal-) * [pos.​customer-details.​action.​menu-item.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/customer-details#customer-details-action-menu-item-) * [pos.​customer-details.​action.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/customer-details#customer-details-action-modal-) * [pos.​customer-details.​block.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/customer-details#customer-details-targets) * [pos.​draft-order-details.​action.​menu-item.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/draft-order-details#draft-order-details-action-menu-item-) * [pos.​draft-order-details.​action.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/draft-order-details#draft-order-details-action-modal-) * [pos.​draft-order-details.​block.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/draft-order-details#draft-order-details-targets) * [pos.​exchange.​post.​action.​menu-item.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/post-exchange#post-exchange-action-menu-item-) * [pos.​exchange.​post.​action.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/post-exchange#post-exchange-action-modal-) * [pos.​exchange.​post.​block.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/post-exchange#post-exchange-targets) * [pos.​home.​modal.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/home-screen#home-screen-action-modal-) * [pos.​home.​tile.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/home-screen#home-screen-targets) * [pos.​order-details.​action.​menu-item.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/order-details#order-details-action-menu-item-) * [pos.​order-details.​action.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/order-details#order-details-action-modal-) * [pos.​order-details.​block.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/order-details#order-details-targets) * [pos.​product-details.​action.​menu-item.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/product-details#product-details-action-menu-item-) * [pos.​product-details.​action.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/product-details#product-details-action-modal-) * [pos.​product-details.​block.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/product-details#product-details-targets) * [pos.​purchase.​post.​action.​menu-item.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/post-purchase#post-purchase-action-menu-item-) * [pos.​purchase.​post.​action.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/post-purchase#post-purchase-action-modal-) * [pos.​purchase.​post.​block.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/post-purchase#post-purchase-targets) * [pos.​register-details.​action.​menu-item.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/register-details#register-details-targets) * [pos.​register-details.​action.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/register-details#register-details-action-modal-) * [pos.​register-details.​block.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/register-details#register-details-block-) * [pos.​return.​post.​action.​menu-item.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/post-return#post-return-action-menu-item-) * [pos.​return.​post.​action.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/post-return#post-return-action-modal-) * [pos.​return.​post.​block.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-01/targets/post-return#post-return-targets) ## Properties The `PinPadApi` object provides properties for displaying secure PIN entry interfaces. Access these properties through `shopify.pinPad` to show PIN pad modals and handle PIN validation. * **showPinPad** **(onSubmit: (pin: number\[]) => PinValidationResult | Promise\, options?: PinPadOptions) => void** **required** Shows a PIN pad to the user in a modal dialog. The `onSubmit` function is called when the PIN is submitted and should validate the PIN, returning `'accept'` or `'reject'`. • **When accepted**: The modal dismisses and triggers the `onDismissed` callback—perform any post-validation navigation in this callback rather than in `onSubmit`. • **When rejected**: Displays the optional `errorMessage` and keeps the modal open. Use for implementing secure authentication workflows, access control, or PIN-based verification systems. ### PinValidationResult Represents the validation outcome for an entered PIN. Indicates whether the PIN should be accepted or rejected, with optional error messaging for rejected PINs. ```ts {result: 'accept'} | {result: 'reject'; errorMessage?: string} ``` ### PinPadOptions Specifies configuration options for displaying the PIN pad interface. Includes callback functions for PIN entry events, dismissal handling, and customizable labels and messaging. * autoSubmit Whether the pin should be automatically submitted when the user has entered the maximum PIN length. Use for PIN entry experiences where users don't need to manually submit after entering the required digits. ```ts boolean ``` * label The content for the prompt on the pin pad. Use to provide clear instructions or context about what the PIN is being used for. ```ts string ``` * masked Whether the entered PIN should be masked for security. When \`true\`, PIN digits are hidden from view. Use for secure PIN entry where visual privacy is important. ```ts boolean ``` * maxPinLength The maximum length of the PIN (4-10 digits). Use to limit PIN length based on your security policies or authentication system constraints. ```ts PinLength ``` * minPinLength The minimum length of the PIN (4-10 digits). Use to enforce PIN length requirements based on your security policies or authentication system requirements. ```ts PinLength ``` * onDismissed The function to be called when the pin pad modal is dismissed. Receives a \`PinPadResult\` indicating whether PIN entry was completed and the entered PIN if available. Use for handling modal dismissal and processing final PIN results. ```ts (result: PinPadResult) => void ``` * onPinEntry The function to be called when a pin is entered. Use for real-time PIN validation, progress feedback, or implementing custom PIN entry handling logic. ```ts (pin: number[]) => void ``` * pinPadAction The call to action between the entry view and the keypad, consisting of a label and function that returns the pin. Use for custom PIN entry workflows or implementing specific authentication patterns. ```ts PinPadActionType ``` * title The title shown in the modal header. Use to provide context about the PIN entry purpose or identify the specific authentication requirement. ```ts string ``` ### PinLength The valid PIN length values (4-10 digits). Commonly used to configure minimum and maximum PIN length requirements. ```ts 4 | 5 | 6 | 7 | 8 | 9 | 10 ``` ### PinPadResult Represents the result of a PIN pad interaction, indicating whether PIN entry was completed and providing the entered PIN if available. * completed Whether the PIN entry was completed successfully. When \`true\`, the user entered a PIN and submitted it (or it was auto-submitted). When \`false\`, the user canceled the PIN pad modal without completing entry, typically by clicking a cancel button or dismissing the modal. ```ts boolean ``` * pin The entered PIN as an array of individual digits (for example, \`\[1, 2, 3, 4]\` for PIN "1234"). Each element is a number from 0-9. This array's length will be between \`minPinLength\` and \`maxPinLength\` inclusive. Only present when \`completed\` is \`true\`—when \`completed\` is \`false\`, this field is \`undefined\` since no PIN was entered. ```ts number[] ``` ### PinPadActionType Defines a custom action button for the PIN pad interface with a label and click handler. * label The content for the prompt on the pin pad. Use to provide clear instructions or context about what the PIN is being used for. ```ts string ``` * onClick Called when the action button is clicked. Can return the PIN digits directly as an array of numbers, or return a Promise that resolves to the PIN array. Use for implementing custom PIN retrieval logic or validation workflows. ```ts () => number[] | Promise ``` Examples ### Examples * #### Display a PIN pad and validate user input ##### Description Present a secure PIN pad interface to collect and validate user PINs for authentication or verification. This example shows how to use \`shopify.pinPad.show()\` to display a PIN entry modal with customizable options. By handling the entered PIN securely and processing the result, you can implement secure authentication workflows. ##### jsx ```jsx import { PinPadOptions } from '@shopify/ui-extensions/point-of-sale'; import { render } from 'preact'; export default async () => { render(, document.body); }; function Extension() { const VALID_PIN = '123456'; const options: PinPadOptions = { label: 'Enter PIN to proceed', title: 'PIN Pad Demo', masked: true, minPinLength: 6, maxPinLength: 8, }; const onShowTapped = () => { shopify.pinPad.showPinPad((pin) => { if (pin.join('') === VALID_PIN) { console.log('PIN is valid'); return { result: 'accept' }; } else { console.log('PIN is invalid'); return { result: 'reject', errorMessage: 'Invalid PIN, please try again', }; } }, options); }; return ( Show Pin Pad ); } ``` ## Best practices * **Implement secure PIN validation:** Validate PINs securely on your backend service rather than in client-side code, using the `onSubmit` callback to communicate with your secure validation endpoint. * **Provide clear user feedback:** Use appropriate labels, titles, and error messages to guide users through the PIN entry process. * **Handle PIN entry appropriately:** Implement proper error handling for PIN validation failures, provide retry mechanisms, and ensure sensitive PIN data is handled securely throughout the process. * **Configure appropriate PIN constraints:** Set reasonable PIN length requirements and masking options based on your security requirements and user experience considerations. ## Limitations PIN validation must be handled through the `onSubmit` callback and should be performed securely on your backend service rather than in client-side extension code.