# 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]
})
```