# 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)
7. Embed the widget from a canonical, non‑redirected page (avoid wrapper/redirect URLs)
8. Update Referrer‑Policy to allow origin propagation (recommended: strict-origin-when-cross-origin)
9. Avoid suppressing referrer information entirely (i.e. avoid no-referrer)

### 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": "123e4567-e89b-12d3-a456-426614174000",
      "benefitBundleName": "Travel Insurance Bundle",
      "additionalCoverage": "Extended coverage for international travel",
      "appliesTo": "Cardholder and immediate family",
      "benefitCd": "TRV001",
      "benefitEffDt": "2024-01-01",
      "benefitExpDt": "2024-12-31",
      "benefitID": "BEN123456",
      "benefitName": "Travel Accident Insurance",
      "bundleType": "Insurance",
      "coverageType": "Comprehensive",
      "macBenefitCategory": "Travel",
      "occur": {
        "occurBeginTime": "00:00",
        "occurCurrency": "USD",
        "occurEndTime": "23:59",
        "occurMaxAmt": "500000",
        "occurMinAmt": "0",
        "occurMisc": "Per trip",
        "occurTimeUnit": "Trip"
      },
      "paymentType": "Automatic",
      "policy": {
        "policyCurrency": "USD",
        "policyMaxAmount": "1000000",
        "policyMaxOccurs": "Unlimited",
        "policyRegionRestriction": "Worldwide",
        "policyTimeLimit": "365",
        "policyTimeUnit": "Days"
      },
      "qualifyingRequirement": "Must use card for travel booking",
      "serviceProviderCode": "SP001",
      "serviceProviderName": "Global Travel Insurance Inc.",
      "benefitServicingId": "SERV001",
      "benefitServicingOptions": "24/7 emergency assistance",
      "customAttributes": [
        {
          "name": "emergencyContact",
          "value": "1-800-TRAVEL-HELP"
        },
        {
          "name": "coverageLimit",
          "value": "500000"
        },
        {
          "name": "deductible",
          "value": "250"
        }
      ],
      "vendorReference": "VEND-REF-001",
      "contractId": "CONTRACT-12345"
    }
  ],
  "products": [
    {
      "productCd": "PROD001",
      "productGrpCd": "GOLD",
      "productGrpName": "Gold Card Group",
      "productName": "Premium Gold Credit Card"
    },
    {
      "productCd": "PROD002",
      "productGrpCd": "PLATINUM",
      "productGrpName": "Platinum Card Group",
      "productName": "Platinum Credit Card"
    },
    {
      "productCd": "PROD003",
      "productGrpCd": "WORLD",
      "productGrpName": "World Elite Card Group",
      "productName": "World Elite Mastercard"
    }
  ],
  "issuerDetails": {
    "externalReference": "EXT-REF-12345",
    "parentICACode": "1234",
    "icaBusinessName": "Global Banking Corporation",
    "icaCode": "5678",
    "icaCountry": "USA",
    "icaLegalName": "Global Banking Corporation Ltd.",
    "icaRegion": "North America",
    "icaState": "New York"
  },
  "responseCode": "200",
  "responseMessage": "Benefits data fetched successfully",
  "responses": [
    {
      "responseCode": "200",
      "responseMessage": "Success"
    }
  ]
}
```

#### 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.
