# New card

Learn about customisation options for the new card component.

## Styling

```typescript
const newCardConfig: NewCardComponentConfig = {
  componentStyles: {
    base: CSSProperties,
    valid: CSSProperties,
    invalid: CSSProperties,
    input: CSSProperties
  },
  fields: {
    cardNumber: {
      containerId: string,
      CardNumberComponentConfig
    },
    expiryDate: {
      containerId: string,
      CardExpiryDateComponentConfig
    },
    cvc: {
     containerId: string,
     isShow: boolean,
     CardCvcComponentConfig
    },
    holderName: {
      containerId: string,
      isShow: boolean,
      CardHolderNameComponentConfig
    },
    cardBrandSelector: {
      containerId: string,
      CardBrandSelectorComponentConfig
      },
    cardConsent: {
      containerId: string,
      isShow: boolean,
      CardConsentComponentConfig
     }
  },
  showLoadingState: boolean,
  loadingStateTimeout: number,
  submit: CardSubmitComponentConfig,
  dynamicCardImageComponent: DynamicCardImageComponentConfig,
  displayRequiredIcon: boolean
};
```

| Property | Description |
|  --- | --- |
| `componentStyles`ComponentStyles | Custom styling for the component. |
| `componentStyles.base`CSSProperties | Base styling for the component. |
| `componentStyles.valid`CSSProperties | Styling for the component when it's valid. |
| `componentStyles.invalid`CSSProperties | Styling for the component when it's not valid. |
| `componentStyles.input`CSSProperties | Styling for the input element. |
| `showLoadingState`boolean | Whether to display a loading state. |
| `loadingStateTimeout`number | The loading state timeout, in milliseconds. |
| `submit`CardSubmitComponentConfig | Configuration for the card submit component. See [Card submit](/guides/checkout/components/web/card/card-submit). |
| `dynamicCardImageComponent`DynamicCardImageComponent | Configuration for the dynamic card image component. See [Dynamic card image](/guides/checkout/components/web/card/dynamic-card-image). |
| `displayRequiredIcon`boolean | Whether to display an icon for all required fields. |


The `submit` property accepts all card submit component configurations, including the `onCustomValidation` callback for validating merchant-owned fields alongside SDK component validation. See [Card submit](/guides/checkout/components/web/card/card-submit) for all available submit configuration options.

## Callbacks

```typescript
const newCardConfig: NewCardComponentConfig = {
 onChange: (state: ComponentState) => void,
 onBlur: (event: any) => void,
 onFocus: (event: any) => void,
 onValidation: (data: ValidationResult[]) => void,
 onPostTokenisation?: (data: { gatewayTokenId: string }) => void
};
```

| Callback | Description |
|  --- | --- |
| `onChange: (state: ComponentState) => void` | Event handler for when component state changes. |
| `onBlur: (event: any) => void` | Event handler for when component loses focus. |
| `onFocus: (event: any) => void` | Event handler for when component gains focus. |
| `onValidation: (data: ValidationResult[]) => void` | Event handler for when validation is performed. |
| `onPostTokenisation: (data: { gatewayTokenId: string }) => void` | Event handler for after card tokenisation completes. Receives a data object with the gateway token ID. Use this to retrieve full token details from your backend. Store the ID if you plan to [pay with a stored gateway token](/guides/checkout/components/web/card/click-once#pay-with-a-stored-gateway-token) on a later click-once checkout. |


For more information about callbacks, see [Events](/guides/checkout/components/web/card/events).

## Example

```typescript
const newCardConfig: NewCardComponentConfig = {
  displayRequiredIcon: true,
  showLoadingState: true,
  loadingStateTimeout: 3000,
  styles: {
    base: {
      padding: "16px",
      border: "1px solid #e0e0e0",
      borderRadius: "8px"
    },
    valid: {
      borderColor: "#00cc66"
    },
    invalid: {
      borderColor: "#ff3333"
    },
    input: {
      fontSize: "16px",
      color: "#333333"
    }
  },
  fields: {
    cardNumber: {
      containerId: "card-number-container",
      required: true
    },
    expiryDate: {
      containerId: "expiry-container",
      required: true
    },
    cvc: {
      containerId: "cvc-container",
      isShow: true,
      required: true
    },
    holderName: {
      containerId: "holder-name-container",
      isShow: true,
      required: false
    }
  },
  onChange: (state) => {
    console.log("State changed:", state.isValid);
  },
  onFocus: (event) => {
    console.log("Field focused");
  },
  onBlur: (event) => {
    console.log("Field blurred");
  },
  onValidation: (data) => {
    console.log("Validation results:", data);
  },
  onPostTokenisation: async (data) => {
    console.log("Tokenisation complete. Gateway Token ID:", data.gatewayTokenId);
    
    // Get full token details from backend if needed
    const tokenDetails = await getTokenDetailsFromBackend(data.gatewayTokenId);
    console.log("Token details retrieved:", tokenDetails);
  },
  submit: {
    submitText: "Complete payment",
    avsRequest: true,
    billingAddressComponents: {
      billingAddressComponent: billingAddress
    },
    // Validate merchant fields alongside SDK billing address
    onCustomValidation: async () => {
      let isValid = true;
      
      // Validate shipping address
      const shippingAddress = document.getElementById('shipping-address').value;
      if (!shippingAddress || shippingAddress.trim().length < 5) {
        showFieldError('shipping-address', 'Please enter a valid shipping address');
        isValid = false;
      }
      
      // Validate terms acceptance
      const termsAccepted = document.getElementById('terms-checkbox').checked;
      if (!termsAccepted) {
        showFieldError('terms', 'You must accept the terms and conditions');
        isValid = false;
      }
      
      return isValid;
    },
    onPreAuthorisation: async (data) => {
      return { psd2Data: {} };
    },
    onPostAuthorisation: (result) => {
      console.log('Payment completed:', result.merchantTransactionId);
      window.location.href = '/success';
    }
  }
};
```