# Encrypted Card ## Introduction Encrypted Card is used to collect and encrypt card number, expiration date, and CVV information. If you use a custom payment form and want to comply with PCI standards, it is recommended to use Encrypted Card. This method is based on the payment API. Before integration, merchant identity verification must be completed. Please confirm the following conditions: 1. You have registered as a merchant and obtained a valid **client key**. 2. You are able to call our payment API independently. ## Preparation You can install the PayKKa Checkout UI npm package or embed it into HTML via CDN: npm (Recommended) Install `@paykka/card-checkout-ui`: npm ```bash npm i @paykka/card-checkout-ui ``` pnpm ```bash pnpm i @paykka/card-checkout-ui ``` yarn ```bash yarn add @paykka/card-checkout-ui ``` To properly display the component, you need to import the styles globally: ```typescript import '@paykka/card-checkout-ui/style.css' ``` CDN Import Import Encrypted Card styles and scripts via CDN links in HTML. It is recommended to use the CDN link for your corresponding region: Europe ```html ``` Hong Kong ```html ``` ## Create DOM Create DOM elements in your checkout page to render the Encrypted Card. Encrypted Card supports displaying card number, expiration date, and CVV either **combined** or **separately**. You need to define this in your HTML in advance. Regardless of how you choose to display them, you need to wrap the elements that will contain the form fields with an ancestor element that has an `id` of `encryptedCardWrapper`. The `data-eci` attribute indicates the corresponding form field name. Here are examples of DOM definitions for both display methods: Separate Display ```html
``` Combined Display ```html
``` Encrypted Card will insert form fields into the specified locations based on the element's `id` and `data-eci` attributes. Please ensure you set the correct attribute names and values for the elements. ## Build Encrypted Card ### Build Parameters Parameters and events that can be passed when creating an Encrypted Card instance: Required parameters are marked with * | **Name** | **Description** | **Type** | | --- | --- | --- | | *merchantId | Merchant ID. | `string` | | *clientKey | Client key. | `string` | | locale | Language for form field display.- If not provided, browser language will be used. If browser language is not supported, `en-GB` will be used by default. - Currently supports 11 international languages, displayed in IETF BCP 47 format: - `de-DE`: German (Germany) - `en-GB`: English (UK) - `es-ES`: Spanish (Spain) - `fr-FR`: French (France) - `ja-JP`: Japanese (Japan) - `ko-KR`: Korean (Korea) - `pt-PT`: Portuguese (Portugal) - `ru-RU`: Russian (Russia) - `zh-CN`: Chinese (China) - `zh-HK`: Chinese (Hong Kong) - `zh-TW`: Chinese (Taiwan) | `string` | | brands | Array of valid [card brands](#card-brands).- After identity verification, merchant's available card brands will be obtained, and the intersection will be taken. - If not provided, merchant's available card brands will be used directly. | `string` | | styles | [Styles](#setting-encrypted-card-styles) for input fields, labels, and error messages. | `ElementStylesConfig` | | showLabel | Whether to display form field labels, defaults to `true`. | `boolean` | | sandbox | Whether to use Sandbox environment. | `boolean` | | onReady | Called after identity verification is complete, returns verification result. If verification is successful, returns available [card brands](#card-brands). | `(status: boolean, res?: { brands: string[] }) => void` | | onActivated | Triggered when form field rendering is complete, returns corresponding [field type](#field-types). | `(fieldType: FieldType) => void` | | onFocus | Triggered when form field gains focus, returns corresponding [field type](#field-types). | `(fieldType: FieldType) => void` | | onBlur | Triggered when form field loses focus, returns corresponding [field type](#field-types). | `(fieldType: FieldType) => void` | | onBinChanged | Triggered when card BIN information changes.- Returns value containing first 1-6 digits of card number and [card brand](#card-brands). - If user deletes card number or card number is less than 6 digits, `binValue` will be empty. | `(binInfo: { binValue: string; brand?: CardBrand }) => void` | | onBrand | Called when card brand is detected, returns corresponding [card brand](#card-brands). | `(brand?: CardBrand) => void` | | onCardEncrypted | Triggered when card information encryption is successful, returns [encryption result](#encryption-result). | `(encryptedInfo: EncryptCardRes) => void` | | onCardEncryptionFailed | Triggered when card information encryption fails. | `() => void` | | onValidationChanged | Notifies form field validation information, returns corresponding [field type](#field-types) and validation status. | `(validationInfo: { fieldType: FieldType; status: FormValidationStatus) }) => void` | ### Initialization Call the `init` method with Encrypted Card build parameters for initialization: npm ```javascript import { PayKKaEncryptedCard } from '@paykka/card-checkout-ui' const EncryptedCard = PayKKaEncryptedCard.init({ // [!code highlight] merchantId: 'xxx', clientKey: 'xxx', brands: ['VISA', 'MASTER_CARD'], showLabel: true, styles: { input: { base: { fontSize: '16px' }, focus: { color: 'blue' }, valid: { border: '1px solid yellowgreen', color: 'yellowgreen' }, invalid: { border: '1px solid red', color: 'red' } } } }) ``` CDN ```javascript const PayKKaEncryptedCard = window.PayKKaCardCheckoutEncryptedCard const EncryptedCard = PayKKaEncryptedCard.init({ // [!code highlight] merchantId: 'xxx', clientKey: 'xxx', brands: ['VISA', 'MASTER_CARD'], showLabel: true, styles: { input: { base: { fontSize: '16px' }, focus: { color: 'blue' }, valid: { border: '1px solid yellowgreen', color: 'yellowgreen' }, invalid: { border: '1px solid red', color: 'red' } } } }) ``` ## Setting Encrypted Card Styles Encrypted Card comes with default styles. You can customize styles for input fields, labels, and error messages in their corresponding states by passing `styles` during initialization. The `styles` object type is as follows, where `CSSStyleDeclaration` indicates we support most standard-compliant styles: ```typescript interface ElementStylesConfig { /** Input element styles */ input?: InputStylesConfig /** Label text styles */ label?: StylesConfig /** Error message styles */ errorMessage?: Partial } interface StylesConfig { /** Default styles */ base?: Partial /** Styles when validation passes */ valid?: Partial /** Styles when validation fails */ invalid?: Partial /** Styles when element is focused */ focus?: Partial } interface InputStylesConfig extends StylesConfig { /** Placeholder styles */ placeholder?: { /** Default styles */ base?: Partial /** Styles when element is focused */ focus?: Partial } /** Styles when hovering over element */ hover?: Partial } ``` Here's an example: ```javascript const EncryptedCard = PayKKaEncryptedCard.init({ styles: { input: { base: { fontSize: '20px', fontWeight: 'bold', padding: '0 0 0 12px', borderRadius: '0px', boxShadow: 'none' }, focus: { color: 'blue', caretColor: 'blue', border: '1px solid blue' }, valid: { border: '1px solid yellowgreen', color: 'yellowgreen' }, invalid: { border: '1px solid red', color: 'red' } }, label: { base: { fontSize: '20px', fontWeight: 'bold', margin: '0', color: 'purple' }, valid: { color: 'yellowgreen' }, invalid: { color: 'red' }, focus: { color: 'blue' } }, errorMessage: { fontSize: '20px', fontWeight: 'bold', margin: '0', color: 'yellow' } } }) ``` For styles other than input fields, labels, and error messages, you can directly write CSS code to override our default styles. ## Encryption Result When submitting the form, you need to call the `encrypt` method. If form validation passes, we will encrypt the form information: ```html ``` ```javascript const handleClick = () => { // Encrypt EncryptedCard.encrypt() // [!code highlight] } ``` Since encryption is asynchronous, you need to register the `onCardEncrypted` event callback to get the encryption result: ```javascript let encryptedRes = null const EncryptedCard = PayKKaEncryptedCard.init({ // Other properties omitted here onCardEncrypted: res => { // [!code highlight] console.log('Encryption successful', res) encryptedRes = res processPay() } }) const processPay = () => { // Call payment API and pass encrypted information encryptedRes } ``` The encryption result type definition is as follows: ```typescript interface EncryptCardRes { /** Encrypted card number */ encryptedCardNumber: string /** Encrypted CVV */ encryptedCVV: string /** Encrypted expiration year */ encryptedExpireYear: string /** Encrypted expiration month */ encryptedExpireMonth: string /** Card information */ cardInfo: { /** Card BIN */ bin: string /** Card brand */ brand: CardBrand /** Last 4 digits of card number */ last4: string } } ``` ## Property Descriptions ### Card Brands **`CardBrand`** Currently supported card brand enums and corresponding card brands: ```typescript type CardBrand = keyof typeof CardBrandCode enum CardBrandCode { /** Visa */ VISA = 'VISA', /** Master Card */ MASTER_CARD = 'MASTER_CARD', /** JCB */ JCB = 'JCB', /** American Express */ AMEX = 'AMEX', /** Discover */ DISCOVER = 'DISCOVER', /** Diners Club */ DINERS_CLUB = 'DINERS_CLUB' } ``` ### Field Types **`FieldType`** Form type enums and corresponding descriptions: ```typescript type FieldType = keyof typeof EFieldType enum EFieldType { /** Card Number */ CARD_NUMBER = 'CARD_NUMBER', /** CVV */ CVV = 'CVV', /** Expiration Date */ EXPIRE_DATE = 'EXPIRE_DATE' } ``` ### Validation Status **`FormValidationStatus`** Form validation status is divided into three types, with corresponding descriptions: - `unValidate`: Content is empty. - `success`: Validation successful. - `error`: Validation failed. ```typescript type FormValidationStatus = 'unValidate' | 'success' | 'error' ``` ## Example Here's a code example from form field initialization to encryption completion: ```html
``` ```javascript let encryptedRes = null const EncryptedCard = PayKKaEncryptedCard.init({ merchantId: 'xxx', clientKey: 'xxx', brands: ['VISA', 'MASTER_CARD'], showLabel: true, styles: { input: { base: { fontSize: '16px' }, focus: { color: 'blue' }, valid: { border: '1px solid yellowgreen', color: 'yellowgreen' }, invalid: { border: '1px solid red', color: 'red' } } }, onCardEncrypted: res => { console.log('Encryption successful', res) encryptedRes = res processPay() } }) const handleClick = () => { // Encrypt EncryptedCard.encrypt() } const processPay = () => { // Call payment API and pass encrypted information } ``` ## Sandbox Environment Integration For Sandbox environment integration, you need to import the Sandbox environment CDN and set `sandbox` to `true` during initialization. ```html ``` ```javascript const EncryptedCard = PayKKaEncryptedCard.init({ // Other properties omitted here sandbox: true // [!code highlight] }) ```