# Widget Integration
source: https://developer.mastercard.com/eligibility-api/documentation/tutorials-and-guides/widget-tutorial/widget-integration/index.md

## Overview {#overview}

This tutorial guides you through integrating the Mastercard Benefits Widget into your web application. The widget provides a secure, embeddable component for card benefit validation and card identifier generation.

### What you will learn {#what-you-will-learn}

1. Set up domain whitelisting and authentication
2. Initialize and embed the widget
3. Handle widget events and responses
4. Customize widget appearance (optional)

### Pre-requisites {#pre-requisites}

To complete this tutorial, you will need:

1. Valid Mastercard Developer Zone account
2. Approved project with API credentials
3. Whitelisted domains (both sandbox and production)
4. HTTPS-enabled website
5. Modern browser support (Chrome 60+, Firefox 55+, Safari 12+, Edge 79+)
6. You must be onboarded to Eligibility and have access to APIs in sandbox environment. For more details, refer to our [quick start guide](https://developer.mastercard.com/eligibility-api/documentation/tutorials-and-guides/guide-quickstart/index.md)

### APIs used in this tutorial {#apis-used-in-this-tutorial}

* Refer to Mastercard Eligibility [API reference](https://developer.mastercard.com/eligibility-api/documentation/api-reference/index.md) section.

## Step 1 - Domain Whitelisting Setup {#step-1---domain-whitelisting-setup}

### Request Domain Whitelisting {#request-domain-whitelisting}

Before integrating the widget, you must whitelist your domains with Mastercard:

1. Contact your Mastercard coordinator
2. Provide all domains where the widget will be implemented:

* Sandbox domain(s)
* Production domain(s)

3. Include your project details and vendor code request
4. Allow 3-5 business days for approval

> **Important**: Domain whitelisting is mandatory before token generation. The widget will not render on non-whitelisted domains.

### Vendor Code Assignment {#vendor-code-assignment}

After domain approval, you will receive from your Mastercard coordinator:

* Unique **Vendor Code** for Sandbox environment
* Unique **Vendor Code** for Production environment
* These codes are required for widget configuration

## Step 2 - Authentication Token Generation {#step-2---authentication-token-generation}

### Implement Server-Side Token Endpoint {#implement-server-side-token-endpoint}

The widget requires an access token for authentication. You must implement a server-side endpoint to generate tokens using your API credentials.

#### Token API Request {#token-api-request}


API Reference: `GET /widgets/access-tokens`

#### Authentication Flow {#authentication-flow}

![Widget Authentication Overview](https://static.developer.mastercard.com/content/eligibility-api/images/widget-overview.png)

1. Your backend calls Mastercard's authentication service
2. Receives a time-limited access token
3. Passes token to frontend for widget initialization
4. Widget validates token before rendering

#### Example: Generate Token (Java) {#example-generate-token-java}

```java
import com.mastercard.developer.interceptors.OkHttpOAuth1Interceptor;
import com.mastercard.developer.utils.AuthenticationUtils;
import okhttp3.OkHttpClient;
import org.openapitools.client.ApiClient;
import org.openapitools.client.api.WidgetAccessTokenApi;
import org.openapitools.client.model.BenefitsAccessToken;

public class WidgetTokenService {
    
    private static final String API_BASE_PATH = "https://sandbox.api.mastercard.com/loyalty/eligibility";
    
    public BenefitsAccessToken generateAccessToken() throws Exception {
        // Load your signing key
        PrivateKey signingKey = AuthenticationUtils.loadSigningKey(
            new FileInputStream("path/to/your-key.p12"),
            "keyalias",
            "keystorepassword"
        );
        
        // Configure API client with OAuth1 signing
        ApiClient client = new ApiClient();
        OkHttpClient.Builder httpClientBuilder = client.getHttpClient().newBuilder();
        
        client.setHttpClient(
            httpClientBuilder
                .addInterceptor(new OkHttpOAuth1Interceptor(CONSUMER_KEY, signingKey))
                .build()
        );
        client.setBasePath(API_BASE_PATH);
        
        // Generate token
        WidgetAccessTokenApi widgetAccessTokenApi = new WidgetAccessTokenApi(client);
        BenefitsAccessToken accessToken = widgetAccessTokenApi.generateBenefitsAccessToken();
        
        return accessToken;
    }
}
```

#### Token Response {#token-response}

```json
{
  "accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

> **Note**: Tokens expire after the specified duration. Implement token refresh logic in your application.

## Step 3 - Widget Integration {#step-3---widget-integration}

### Add Widget Script {#add-widget-script}

Add the JavaScript file to your webpage `<head>` section:

```html
<!DOCTYPE html>
<html>
<head>
    <title>Benefits Widget Integration</title>
    <!-- Include Widget Script -->
    <script src="https://mtf.benefits.mastercard.com/widgets/benefits-widget.js"></script>
    <script>
        benefits.defineCustomElements();
    </script>
</head>
<body>
    <!-- Widget container -->
    <benefits-search></benefits-search>
</body>
</html>
```

> **Production URL** : `https://benefits.mastercard.com/widgets/benefits-widget.js`

### Initialize Widget {#initialize-widget}

#### Basic Initialization {#basic-initialization}

```javascript
// Fetch token from your backend
async function initializeWidget() {
    try {
        // Call your backend endpoint
        const response = await fetch('/api/widget/token');
        const data = await response.json();
        
        // Initialize widget with token
        benefits.init(data.accessToken);
        
    } catch (error) {
        console.error('Widget initialization failed:', error);
    }
}

// Initialize on page load
document.addEventListener('DOMContentLoaded', initializeWidget);
```

### Widget Configuration {#widget-configuration}

#### Minimal Configuration (Benefits Widget) {#minimal-configuration-benefits-widget}

```html
<benefits-search data='{
    "vendorCode": "VENDOR123",
    "widgetType": "benefits"
}'></benefits-search>
```

#### Minimal Configuration (Identifier Widget) {#minimal-configuration-identifier-widget}

```html
<benefits-search data='{
    "vendorCode": "VENDOR123",
    "widgetType": "identifier"
}'></benefits-search>
```

#### Configuration Properties {#configuration-properties}

|   Property   | Required |  Type  |                 Description                 |    Example    |
|--------------|----------|--------|---------------------------------------------|---------------|
| `vendorCode` | **Yes**  | string | Unique vendor identifier from Mastercard    | `"VENDOR123"` |
| `widgetType` | **Yes**  | string | Widget mode: `"benefits"` or `"identifier"` | `"benefits"`  |

#### Custom Styling Example {#custom-styling-example}

```html
<benefits-search data='{
    "vendorCode": "VENDOR123",
    "widgetType": "benefits",
    "pan": {
        "label": "Card Number",
        "placeholder": "Enter your 16-digit card number",
        "borderRadius": "8px",
        "fontSize": "16px"
    },
    "submit": {
        "label": "Check Benefits",
        "backgroundColor": "#0277bd",
        "color": "#ffffff",
        "borderRadius": "8px"
    }
}'></benefits-search>
```

> **Note** : For complete styling options, refer to the [Widget Customization](https://developer.mastercard.com/eligibility-api/documentation/tutorials-and-guides/widget-tutorial/widget-customization/index.md).

### Widget UI States {#widget-ui-states}

#### Active State {#active-state}

![Active Widget](https://static.developer.mastercard.com/content/eligibility-api/images/benefits-widget-ui.png)

#### Disabled State (Initialization Failed) {#disabled-state-initialization-failed}

![Disabled Widget](https://static.developer.mastercard.com/content/eligibility-api/images/benefits-widget-ui-initialize-file.png)

## Step 4 - Event Handling {#step-4---event-handling}

### Implement Event Listeners {#implement-event-listeners}

The widget emits events for various states. Implement listeners to handle responses.

#### 1. Benefit Details Loaded Event {#1-benefit-details-loaded-event}

Triggered when benefit data is successfully retrieved.

```javascript
document.querySelector('benefits-search').addEventListener('benefitDetailsLoaded', (event) => {
    const benefitData = event.detail;
    console.log('Benefits loaded:', benefitData);
    
    // Process benefit information
    displayBenefits(benefitData);
});
```

**Success Response Example:**

```json
{
    "benefitInfoList": [
        {
            "benefitBundleId": "f97e77e4-ecab-40b0-802f-799596f0e3a4",
            "benefitBundleName": "US Core Credit",
            "benefitID": "2495",
            "benefitName": "Extended Warranty WTY",
            "benefitCd": "WTY",
            "macbenefitCategory": "Shopping",
            "benefitEffDt": "01/01/2014",
            "serviceProviderName": "US Test Sedgwick Informational"
        }
    ],
    "products": [
        {
            "productCd": "MCC",
            "productName": "Mixed Product"
        }
    ],
    "issuerDetails": {
        "icaCode": "2134",
        "icaCountry": "USA",
        "icaLegalName": "Bank Group, N.A."
    },
    "responseCode": "200",
    "responseMessage": "Benefits data fetched successfully"
}
```

#### 2. Card Identifier Generated Event {#2-card-identifier-generated-event}

Triggered when a secure card identifier is generated (identifier widget only).

```javascript
document.querySelector('benefits-search').addEventListener('cardIdentifierGenerated', (event) => {
    const identifierData = event.detail;
    console.log('Card identifier generated:', identifierData);
    
    // Store identifier for future use
    storeCardIdentifier(identifierData.cardNumberId);
});
```

**Success Response Example:**

```json
{
    "cardNumberId": "550e8400-e29b-41d4-a716-446655440000"
}
```

#### 3. API Request Failed Event {#3-api-request-failed-event}

Triggered when API requests fail. Provides error details for debugging.

```javascript
document.querySelector('benefits-search').addEventListener('apiRequestFailed', (event) => {
    const errorData = event.detail;
    console.error('API request failed:', errorData);
    
    // Handle error based on type
    handleWidgetError(errorData);
});
```

**Error Response Example:**

```json
{
    "type": "API_ERROR",
    "data": {
        "type": "benefits",
        "message": "Failed to fetch data",
        "details": {
            "errorCode": "404",
            "errorDescription": "Resource not found"
        }
    },
    "source": "benefits-widget-iframe"
}
```

#### 4. Request Submitted Event {#4-request-submitted-event}

Triggered when form is submitted to show loading state.

```javascript
document.querySelector('benefits-search').addEventListener('requestSubmitted', (event) => {
    console.log('Request submitted, loading...');
    
    // Show loading indicator
    showLoadingIndicator();
});
```

### Complete Event Handling Example {#complete-event-handling-example}

```javascript
const widgetElement = document.querySelector('benefits-search');

// Handle all widget events
widgetElement.addEventListener('benefitDetailsLoaded', (event) => {
    hideLoadingIndicator();
    displayBenefits(event.detail);
});

widgetElement.addEventListener('cardIdentifierGenerated', (event) => {
    hideLoadingIndicator();
    storeCardIdentifier(event.detail.cardNumberId);
});

widgetElement.addEventListener('apiRequestFailed', (event) => {
    hideLoadingIndicator();
    handleWidgetError(event.detail);
});

widgetElement.addEventListener('requestSubmitted', (event) => {
    showLoadingIndicator();
});
```

## Step 5 - Testing Integration {#step-5---testing-integration}

### Test in Sandbox Environment {#test-in-sandbox-environment}

1. Use sandbox URL: `https://mtf.benefits.mastercard.com/widgets/benefits-widget.js`
2. Use sandbox vendor code provided by Mastercard
3. Test with sample card numbers provided in sandbox documentation

### Verify Integration {#verify-integration}

Test the following scenarios:

1. **Widget Loads Successfully**

* Widget renders on whitelisted domain
* Input field and submit button are enabled

2. **Token Validation**

* Widget accepts valid tokens
* Widget disables for invalid/expired tokens

3. **Event Handling**

* All event listeners trigger correctly
* Response data is properly parsed

4. **Error Handling**

* Invalid card numbers show appropriate errors
* Network errors are handled gracefully

### Debug Common Issues {#debug-common-issues}

|          Issue          |            Cause             |                 Solution                  |
|-------------------------|------------------------------|-------------------------------------------|
| Widget not rendering    | Domain not whitelisted       | Verify domain with Mastercard coordinator |
| Widget disabled on load | Token invalid/expired        | Check token generation endpoint           |
| No events firing        | Event listeners not attached | Ensure listeners are added before init    |
| CORS errors             | Incorrect API endpoint       | Verify sandbox/production URLs            |

## Next Steps {#next-steps}

* Review [API Reference](https://developer.mastercard.com/eligibility-api/documentation/api-reference/index.md) for detailed endpoint documentation
* Explore [Use Cases](https://developer.mastercard.com/eligibility-api/documentation/usecases/index.md) for implementation examples
* Check [Code and Formats](https://developer.mastercard.com/eligibility-api/documentation/code-and-formats/index.md) for error response formats
* Read [Eligibility Tutorial](https://developer.mastercard.com/eligibility-api/documentation/tutorials-and-guides/eligibility-tutorial/index.md) for backend API integration

*** ** * ** ***

For support or questions, refer to the [Support](https://developer.mastercard.com/eligibility-api/documentation/support/index.md) section.
