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

# Activate Card Widget

> Allow your customers to activate their physical card by entering the card number and security code.

The Activate Card widget allows your customers to activate their physical card by entering the card number (PAN) and security code (CVV).

<Frame>
  <img src="https://mintcdn.com/synctera/oMPibgBNXdRrv2-B/images/cards/widgets/activate-card.png?fit=max&auto=format&n=oMPibgBNXdRrv2-B&q=85&s=f4488a7056ca124fe3065cb2f3ecca40" alt="Activate Card" width="334" height="325" data-path="images/cards/widgets/activate-card.png" />
</Frame>

## Step 1: Load the Widget Script

Load the Activate Card widget script into your page by adding the following script tag:

<CodeGroup>
  ```html HTML theme={"system"}
  <script
    type="module"
    src="https://assets.synctera.com/widgets/activate/v1.1.1/index.js"
  ></script>
  ```

  ```javascript React theme={"system"}
  import { useEffect } from 'react';

  function ActivateCardForm({ widgetToken }) {
    useEffect(() => {
      const script = document.createElement('script');
      script.type = 'module';
      script.src = 'https://assets.synctera.com/widgets/activate/v1.1.1/index.js';
      document.head.appendChild(script);

      return () => {
        document.head.removeChild(script);
      };
    }, []);

    return (
      <activate-card
        token={widgetToken}
        env="production"
      />
    );
  }
  ```
</CodeGroup>

## Step 2: Get a Widget Token

Request a widget token from your backend using the Synctera API. The widget token is required for the widget to authenticate and submit data.

<CodeGroup>
  ```bash curl theme={"system"}
  curl -X GET "https://api.synctera.com/v2/cards/{card_id}/widget_token?widget_type=ACTIVATE" \
    -H "Authorization: Bearer {apiKey}" \
    -H "Content-Type: application/json"
  ```

  ```javascript Node.js theme={"system"}
  const response = await fetch(
    `https://api.synctera.com/v2/cards/${cardId}/widget_token?widget_type=ACTIVATE`,
    {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      }
    }
  );

  const { widget_token } = await response.json();
  ```
</CodeGroup>

<Warning>
  Widget tokens expire after **5 minutes** and are scoped to a specific card. Generate a new token on each page load or when the user initiates a new activation.
</Warning>

## Step 3: Add the Widget Component

Add the `<activate-card>` web component to your page:

```html theme={"system"}
<activate-card
  token="your-widget-token"
  env="production"
></activate-card>
```

***

## Configuration Options

| Property        | Type     | Required | Default     | Description                                                                            |
| --------------- | -------- | -------- | ----------- | -------------------------------------------------------------------------------------- |
| `token`         | `string` | Yes      | -           | Widget token obtained from the API                                                     |
| `env`           | `string` | Yes      | -           | Environment: `sandbox` or `production`                                                 |
| `theme`         | `string` | No       | `"default"` | Theme preset: `"default"` or `"night-shift"`                                           |
| `styles`        | `string` | No       | `{}`        | JSON string of [design tokens](/v2/docs/card-widgets-theming) for visual customization |
| `custom-labels` | `string` | No       | `{}`        | JSON string of custom labels for form fields                                           |

***

## Custom Labels

Customize the labels displayed in the widget:

```html theme={"system"}
<activate-card
  token="your-token"
  env="production"
  custom-labels='{
    "widgetTitle": "Activate Your New Card",
    "cardNumberLabel": "Card Number (PAN)",
    "securityCodeLabel": "Security Code",
    "submitButtonText": "Activate Now",
    "submitLoadingText": "Processing..."
  }'
></activate-card>
```

Available custom label keys:

* `widgetTitle` - Widget header text
* `cardNumberLabel` - Card number field label
* `securityCodeLabel` - CVV field label
* `cardPanPlaceholder` - Card number placeholder
* `cardCvvPlaceholder` - CVV placeholder
* `submitButtonText` - Submit button text
* `submitLoadingText` - Loading state text

***

## Event Handling

The widget dispatches lifecycle events across two phases:

| Phase              | Events                                 | Description                                                                                  |
| ------------------ | -------------------------------------- | -------------------------------------------------------------------------------------------- |
| **Initialization** | `load` or `error` (mutually exclusive) | Fires once when the widget first renders and its secure input fields load (or fail to load). |
| **Submission**     | `success` or `failure`                 | Fires after the user submits the form.                                                       |

* **`load`** — Widget initialized successfully, all fields are ready for user input.
* **`error`** — Widget failed to initialize (field load failure, network error, or timeout).
* **`success`** — Card activation completed successfully.
* **`failure`** — Card activation failed (incorrect card number, wrong CVV, expired widget token, or API error).

<Warning>
  `error` fires only during widget initialization (e.g., a secure input field failed to load). If the widget loads successfully but the user's submission fails — incorrect PAN, wrong CVV, expired token — that triggers `failure`, not `error`.
</Warning>

You can listen for events using either **`addEventListener`** or **callback properties**:

| Event                  | addEventListener                         | Callback property       |
| ---------------------- | ---------------------------------------- | ----------------------- |
| Initialization success | `widget.addEventListener('load', fn)`    | `widget.onLoad = fn`    |
| Initialization failure | `widget.addEventListener('error', fn)`   | `widget.onError = fn`   |
| Submission success     | `widget.addEventListener('success', fn)` | `widget.onSuccess = fn` |
| Submission failure     | `widget.addEventListener('failure', fn)` | `widget.onFailure = fn` |

### Load Event

Dispatched when all secure input fields have loaded and the widget is fully functional. Use it to hide loading UI or enable dependent controls.

| Property     | Type     | Description                        |
| ------------ | -------- | ---------------------------------- |
| `instanceId` | `string` | Unique ID for this widget instance |

```html theme={"system"}
<activate-card id="activate-widget" token="your-token" env="production"></activate-card>
<script>
  document.getElementById('activate-widget').addEventListener('load', (event) => {
    const { instanceId } = event.detail;
    console.log('Widget ready', instanceId);
  });
</script>
```

### Error Event

Dispatched when the widget fails to initialize. This means one or more secure input fields could not load, and the widget is not functional. Show an error message or retry UI to the user.

| Property       | Type       | Description                                    |
| -------------- | ---------- | ---------------------------------------------- |
| `instanceId`   | `string`   | Unique ID for this widget instance             |
| `error`        | `string`   | Human-readable error message (safe to display) |
| `failedFields` | `string[]` | List of field types that failed to load        |

```html theme={"system"}
<script>
  document.getElementById('activate-widget').addEventListener('error', (event) => {
    const { error, failedFields } = event.detail;
    console.error('Widget initialization failed:', error, failedFields);
    // Show error UI or offer a retry button
  });
</script>
```

<Warning>
  The `load` and `error` events are mutually exclusive — exactly one will fire during widget initialization. Always listen for both to handle all scenarios.
</Warning>

### Success and Failure Events

Dispatched after the user submits the activation form. Common `failure` reasons include incorrect card number, wrong CVV, and expired widget token.

The `success` event exposes only non-sensitive status metadata:

| Property     | Type     | Description                              |
| ------------ | -------- | ---------------------------------------- |
| `status`     | `string` | Submission status returned by the widget |
| `message`    | `string` | Optional human-readable success message  |
| `instanceId` | `string` | Unique ID for this widget instance       |

PAN and CVV are never included in host-page event details.

<CodeGroup>
  ```html addEventListener theme={"system"}
  <activate-card
    id="activate-widget"
    token="your-token"
    env="production"
  ></activate-card>

  <script>
    const widget = document.getElementById('activate-widget');

    widget.addEventListener('success', (event) => {
      const { status, message } = event.detail;
      console.log('Card activated successfully:', status, message);
      // Handle success - redirect or update UI
    });

    widget.addEventListener('failure', (event) => {
      console.error('Activation failed:', event.detail.error);
      // Handle failure - display message to user
    });
  </script>
  ```

  ```html Callback Properties theme={"system"}
  <activate-card
    id="activate-widget"
    token="your-token"
    env="production"
  ></activate-card>

  <script>
    const widget = document.getElementById('activate-widget');

    widget.onSuccess = (event) => {
      const { status, message } = event.detail;
      console.log('Card activated successfully:', status, message);
    };

    widget.onFailure = (event) => {
      console.error('Activation failed:', event.detail.error);
    };
  </script>
  ```
</CodeGroup>

***

## Complete Example

<CodeGroup>
  ```html Complete HTML Example theme={"system"}
  <!DOCTYPE html>
  <html lang="en">
    <head>
      <meta charset="utf-8" />
      <title>Activate Card</title>
      <script
        type="module"
        src="https://assets.synctera.com/widgets/activate/v1.1.1/index.js"
      ></script>
    </head>
    <body>
      <h1>Activate Your Card</h1>

      <div id="error-message" style="color: red; display: none;"></div>

      <activate-card
        id="activate-widget"
        env="production"
      ></activate-card>

      <script>
        async function initializeWidget() {
          try {
            // Fetch widget token from your backend
            const response = await fetch('/api/card-widget-token', {
              method: 'POST',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({
                card_id: 'your-card-id',
                widget_type: 'ACTIVATE'
              })
            });

            const { widget_token } = await response.json();

            // Set token on widget
            const widget = document.getElementById('activate-widget');
            widget.setAttribute('token', widget_token);

            // Set up event listeners
            widget.addEventListener('load', (event) => {
              console.log('Widget ready:', event.detail.instanceId);
            });

            widget.addEventListener('error', (event) => {
              const { error, failedFields, instanceId } = event.detail;
              console.error('Widget failed to initialize:', error, failedFields, instanceId);
              document.getElementById('error-message').textContent = error;
              document.getElementById('error-message').style.display = 'block';
            });

            widget.addEventListener('success', (event) => {
              const { status, message } = event.detail;
              console.log('Card activated:', status, message);
              alert('Card activated successfully!');
            });

            widget.addEventListener('failure', (event) => {
              document.getElementById('error-message').textContent = event.detail.error;
              document.getElementById('error-message').style.display = 'block';
            });

          } catch (error) {
            console.error('Failed to initialize widget:', error);
          }
        }

        window.addEventListener('DOMContentLoaded', initializeWidget);
      </script>
    </body>
  </html>
  ```

  ```javascript React Example (Callback Properties) theme={"system"}
  import { useEffect, useState, useRef } from 'react';

  function ActivateCardForm({ cardId }) {
    const [widgetToken, setWidgetToken] = useState(null);
    const [error, setError] = useState(null);
    const widgetRef = useRef(null);

    useEffect(() => {
      const script = document.createElement('script');
      script.type = 'module';
      script.src = 'https://assets.synctera.com/widgets/activate/v1.1.1/index.js';
      document.head.appendChild(script);

      fetch('/api/card-widget-token', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ card_id: cardId, widget_type: 'ACTIVATE' })
      })
        .then(res => res.json())
        .then(data => setWidgetToken(data.widget_token))
        .catch(err => setError(err.message));

      return () => {
        document.head.removeChild(script);
      };
    }, [cardId]);

    useEffect(() => {
      if (!widgetToken || !widgetRef.current) return;
      const widget = widgetRef.current;

      widget.onLoad = (event) => {
        console.log('Widget ready:', event.detail.instanceId);
      };

      widget.onError = (event) => {
        const { error, failedFields } = event.detail;
        console.error('Widget failed to initialize:', error, failedFields);
        setError(error);
      };

      widget.onSuccess = (event) => {
        const { status, message } = event.detail;
        console.log('Card activated:', status, message);
      };

      widget.onFailure = (event) => {
        setError(event.detail.error);
      };

      return () => {
        widget.onLoad = null;
        widget.onError = null;
        widget.onSuccess = null;
        widget.onFailure = null;
      };
    }, [widgetToken]);

    if (error) return <div style={{ color: 'red' }}>Error: {error}</div>;
    if (!widgetToken) return <div>Loading...</div>;

    return (
      <activate-card
        ref={widgetRef}
        token={widgetToken}
        env="production"
      />
    );
  }

  export default ActivateCardForm;
  ```
</CodeGroup>
