{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-docs/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["site-link"]},"type":"markdown"},"seo":{"title":"Components","meta":[{"name":"robots","content":"noindex, nofollow"},{"name":"pingdom","content":"sh3MDv8mJpWhCWSTdGtN"}]},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"components","__idx":0},"children":["Components"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Shift4 Components are web UI elements that securely collect sensitive information (like card number, expiration, and CVC for card payments) in your payment forms. The use of Shift4 ensures that sensitive payment data never touches your server or your website."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To use Shift4 Components you need to include ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Shift4.js"]}," library and initialize it with your public key:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"html","header":{"controls":{"copy":{}}},"source":"<script type=\"text/javascript\" src=\"https://js.dev.shift4.com/shift4.js\"></script>\n\n<script type=\"text/javascript\">\n  // Initialize Shift4 object with your public key\n  var shift4 = Shift4(\"pu_test_WVMFC9GFuvm54b0uorifKkCh\");\n</script>\n","lang":"html"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Once the library is configured, there are two ways to use Shift4 Components to collect card data:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["use separate components for number, expiry, and CVC"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["use a single component for all card details"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Please check our guidelines for CSP ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/csp-integration"},"children":["here"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"single-component-for-all-card-details","__idx":1},"children":["Single component for all card details"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This approach is the fastest and easiest to implement. It is also preferred when you have limited space for a payment form."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["First, you need to create a placeholder tag in the HTML code of your website:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"html","header":{"controls":{"copy":{}}},"source":"<div id=\"card\"></div>\n","lang":"html"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Then in JavaScript code, you need to create a Single Line and mount it to that placeholder tag:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"var card = shift4.createComponent(\"card\").mount(\"#card\");\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Later, when all card data have been provided by a customer, you need to create a token from that Single Line:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"shift4.createToken(card).then(/*...*/).catch(/*...*/);\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Complete and working code can be found in our ",{"$$mdtype":"Tag","name":"SiteLink","attributes":{"href":"/examples/single-line"},"children":["Single Line example"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"separate-components-for-number-expiry-and-cvc","__idx":2},"children":["Separate components for number, expiry and CVC"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When you want full control over your payment form, you can use separate components for each field. This approach requires little more code than using a single component, but it is also fast and easy to implement."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["First, you need to create a placeholder tag for each component. To simplify the creation of components, we group these placeholders under one common tag, and we used the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["data-shift4"]}," attribute to specify a type of component:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"html","header":{"controls":{"copy":{}}},"source":"<div id=\"payment-form\">\n    <div data-shift4=\"number\"></div>\n    <div data-shift4=\"expiry\"></div>\n    <div data-shift4=\"cvc\"></div>\n</div>\n","lang":"html"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Doing it this way allows to create of a component group and automatically creates and mounts all components in that group:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"var components = shift4.createComponentGroup().automount(\"#payment-form\");\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Later, when all card data have been provided by a customer, you need to create a token from that component group:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"shift4.createToken(components).then(/*...*/).catch(/*...*/);\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Complete and working code can be found in our ",{"$$mdtype":"Tag","name":"SiteLink","attributes":{"href":"/examples/custom-form"},"children":["Custom Form example"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"creating-components-manually","__idx":3},"children":["Creating components manually"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["An alternative approach to using the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["data-shift4"]}," attribute and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["automount"]}," method is to manually create each component. To do this, you don't need to have a common parent element, but you need some other way to locate placeholder tags (for example, using the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["id"]}," attribute):"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"html","header":{"controls":{"copy":{}}},"source":"<div id=\"number\"></div>\n<div id=\"expiry\"></div>\n<div id=\"cvc\"></div>\n","lang":"html"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Then in JavaScript, you need to create a component group and then create and mount each component in that group:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"var components = shift4.createComponentGroup();\ncomponents.createComponent(\"number\").mount(\"#number\");\ncomponents.createComponent(\"expiry\").mount(\"#expiry\");\ncomponents.createComponent(\"cvc\").mount(\"#cvc\");\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"using-separate-component-for-expiration-month-and-year","__idx":4},"children":["Using separate component for expiration month and year"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Another alternative possibility is to use two components for the card expiration date - separate components for expiration month and year."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To do so, you must create two placeholder tags and use component types ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["expiryMonth"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["expiryYear"]},". It can be done by using ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["data-shift4"]}," attribute and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["automount()"]}," or manual component creation."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"component-styling","__idx":5},"children":["Component styling"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can customize the visuals of Shift4 components on your webpage by setting the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["height"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["style"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fonts"]}," attributes in options. The options are applicable either to a single component or a component group. They are merged but only for top level attributes, ie.: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["finalOptions = {...componentGroupOptions, ...componentOptions}"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For the full list of supported style properties, pseudo-classes and font attributes, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/js/styling"},"children":["Styling"]}," in the JS reference."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"let shift4 = Shift4(\"pu_test_WVMFC9GFuvm54b0uorifKkCh\");\n\nlet options = {\n  height: '38px',\n  style: {\n    base: {\n      color: '#44d',\n      fontSize: '30px',\n      fontFamily: 'Orbitron',\n      '::placeholder': {\n        color: '#99f'\n      },\n    },\n    invalid: {\n      color: '#f00',\n      '::placeholder': {\n        color: '#f99'\n      },\n    }\n  },\n  fonts: [{\n    family: 'Orbitron',\n    style: 'normal',\n    weight: 400,\n    display: 'swap',\n    src: \"url(https://fonts.gstatic.com/s/orbitron/v25/yMJRMIlzdpvBhQQL_Qq7dy0.woff2) format('woff2');\"\n  }]\n};\n\nlet components = shift4.createComponentGroup(options);\nlet number = components.createComponent(\"number\").mount(\"#number\");\nlet expiry = components.createComponent(\"expiry\").mount(\"#expiry\");\nlet cvc = components.createComponent(\"cvc\").mount(\"#cvc\");\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["createComponent()"]}," method accepts an optional second argument with options for that single component - ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["createComponent(\"expiry\", { height: '48px' })"]},". The placeholder to render into is never passed to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["createComponent()"]},"; it is always given to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["mount()"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"adding-an-event-listener","__idx":6},"children":["Adding an event listener"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["It is possible to attach an Event Listener using ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["on"]}," method to listen for the change event. You will need to specify the event type as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["change"]}," and provide a handler function that will be executed when the event occurs."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["In the handler function, you can access properties such as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["empty"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cardBrand"]}," to determine the state of the component when the change event is triggered."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The following piece of code exemplifies blocking a flow based on a card brand."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"var card = shift4.createComponent(\"card\").mount(\"#card\");\ncard.on('change', event => {\n  if (event.cardBrand !== \"visa\") {\n    // disable the button\n  } else {\n    // enable the button\n  }\n})\n","lang":"javascript"},"children":[]}]},"headings":[{"value":"Components","id":"components","depth":1},{"value":"Single component for all card details","id":"single-component-for-all-card-details","depth":2},{"value":"Separate components for number, expiry and CVC","id":"separate-components-for-number-expiry-and-cvc","depth":2},{"value":"Creating components manually","id":"creating-components-manually","depth":2},{"value":"Using separate component for expiration month and year","id":"using-separate-component-for-expiration-month-and-year","depth":2},{"value":"Component styling","id":"component-styling","depth":2},{"value":"Adding an event listener","id":"adding-an-event-listener","depth":2}],"frontmatter":{"title":"Components","description":"Reference for Shift4 Components - secure web UI elements that collect card details, including mounting, styling and event listeners.","seo":{"title":"Components"}},"lastModified":"2026-11-03T07:18:18.846Z","pagePropGetterError":{"message":"","name":""}},"slug":"/docs/components","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}