> ## Documentation Index
> Fetch the complete documentation index at: https://docs.overflow.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Card best practices

> Recommendations for shipping a robust card integration.

## Show every field you need

The card element renders card number, expiration, security code, cardholder name, and postal code by default. Hide only what you truly do not need:

```javascript theme={null}
overflow.card({
  fields: {
    holderName: { hidden: false },
    postalCode: { hidden: true },
  },
});
```

Postal code is often collected by a separate billing address element inside Checkout; hide it on the card in that case to avoid duplicate inputs.

## Gate your Pay button on `complete`

Card validation completes when every visible field passes format checks. Gate your submit button on `onChange`:

```javascript theme={null}
card.on('onChange', ({ complete }) => {
  payButton.disabled = !complete;
});
```

## Never send raw card data server-side

`onSubmit` returns an envelope of `encrypted*` fields (plus optional `holderName` and `postalCode`) that is safe to POST to your server. Forward it verbatim; do not attempt to unpack the encrypted fields client-side. The card number, expiration, and security code render inside a PCI-scoped secured iframe you cannot reach.

## Do not preload for above-the-fold checkout unnecessarily

If your Pay flow is not on the initial paint, do not add a `<link rel="preload">` for the SDK. Unused preloads waste bandwidth and log a console warning.

## Match your brand with tokens

Set colors, borders, and typography on the `Overflow` instance rather than trying to style the card element with your own CSS:

```javascript theme={null}
new Overflow('live_pub_...', {
  appearance: {
    variables: {
      colorPrimary: '#0a3783',
      colorBorder: '#ededed',
      borderRadius: '6px',
    },
  },
});
```

Custom CSS cannot reach into the secured iframe. See [Theming](/payment-elements/theming/overview).

## Handle `onError`

`onError` fires for both validation failures on submit and runtime errors. Surface a page-level message and let the shopper retry:

```javascript theme={null}
card.on('onError', ({ code, message, fieldErrors }) => {
  showBanner(message);
});
```

## Test with `test_pub_…`

Use a `test_pub_…` publishable key while you build. Swap to `live_pub_…` for production. The same code paths run on both; only the API environment changes.

## Next steps

* [Card reference](/payment-elements/elements/payment-methods/card/reference)
* [Handle validation errors](/payment-elements/guides/handle-validation-errors)
