Launch Hosted Experience

A Standalone, Full-Featured Rewards Application in a New Tab

Abstract

The Cardlytics Hosted Experience is a white-labeled, token-based solution designed to provide users with a full-featured rewards application that opens in a new browser tab. Unlike the embedded SDK that displays content within an iframe, the hosted approach offers display user experience with complete browser real estate while maintaining your brand through reverse proxy configuration.


Quickstart

Follow these 3 simple steps to integrate the Cardlytics Hosted Experience into your web application.

Step 1: Get Your Credentials

These will be used to authenticate your backend and generate hosted session tokens.

Required Credentials:

  • client_id - Your unique publisher identifier
  • client_secret - Your secure authentication secret
  • application_id - Your application identifier for configuration

Step 2: Create a Secure Backend Endpoint for Hosted Session Token

You'll need to create a backend API that securely calls the Cardlytics hosted session API. This endpoint will be used to retrieve a hosted session token for authenticated users.

Backend (Server to Server) call:

const express = require('express');
const axios = require('axios');
const crypto = require('crypto');
const router = express.Router();

router.post('/api/get_cardlytics_hosted_session', async (req, res) => {
    // Ensure user is authenticated
    if (!req.user || !req.user.id) {
        return res.status(401).json({ error: 'User not authenticated' });
    }

    // Obfuscate customer ID using HMAC-SHA-256
    const obfuscatedCustomerId = crypto
        .createHmac('sha256', process.env.CARDLYTICS_HMAC_SECRET)
        .update(req.user.id.toString())
        .digest('hex');

    const payload = {
        clientId: process.env.CARDLYTICS_CLIENT_ID,
        secret: process.env.CARDLYTICS_CLIENT_SECRET
    };
    
    const response = await axios.post(
        'https://publisher-rewards-api.cardlytics.com/v2/session/startSession',
        payload,
        { 
            headers: { 
                'Content-Type': 'application/json',
                'x-source-customer-id': obfuscatedCustomerId
            }
        }
    );
    
    const sessionToken = response.data.sessionToken;
    res.json({ 
        sessionToken, 
        isLoggedIn: true
    });
});

module.exports = router;

Step 3: Launch Hosted Experience from Frontend

Add a button or link to your page that opens the hosted rewards experience in a new tab.

async function getHostedTokenImplementation() {
    // Call the API you implemented in step 2
    const response = await fetch('/api/get_cardlytics_hosted_session', { 
        method: 'POST',
        credentials: 'include' // Include auth cookies
    });
    const data = await response.json();
    return data;
}

async function openHostedRewards() {
    try {
        const { hostedToken } = await getHostedTokenImplementation();
        
        // Open hosted experience in new tab using your rewards domain
        // Refers to Step 1 for application_id 
        const hostedUrl = `https://yourrewardsdomain.com/rewards?applicationId=12345&token=${hostedToken}`;
        window.open(hostedUrl, '_blank');
    } catch (error) {
        console.error('Failed to open rewards:', error);
        // Handle error appropriately
    }
}

// Attach to a button on your page
document.getElementById('openRewardsBtn').addEventListener("click", openHostedRewards);
<button id="openRewardsBtn">Open Rewards</button>

Infrastructure Setup (Required for Hosted Integration)

Reverse Proxy Configuration

To maintain your brand and rewards domain control, you must set up a reverse proxy to route requests from your rewards domain to the Cardlytics infrastructure. Here we are showing two options for setting up the reverse proxy, feel free to choose a reverse proxy solution with your favorite proxy.

Option 1: Nginx Configuration

server {
    listen 443 ssl;
    server_name yourrewardsdomain.com;
    
    # SSL configuration
    ssl_certificate /path/to/your/certificate.crt;
    ssl_certificate_key /path/to/your/private.key;
    
    # Proxy rewards path to Cardlytics
    location /rewards {
        proxy_pass https://offers.cardlytics.com;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # Handle CORS and security headers
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
    }
    
    # Your existing application routes
    location / {
        # Your application configuration
    }
}

Option 2: CloudFront/CDN Configuration

{
  "Origins": [
    {
      "Id": "cardlytics-rewards",
      "DomainName": "offers.cardlytics.com",
      "CustomOriginConfig": {
        "HTTPPort": 443,
        "OriginProtocolPolicy": "https-only",
        "OriginSslProtocols": {
          "Quantity": 1,
          "Items": ["TLSv1.2"]
        }
      }
    }
  ],
  "DefaultCacheBehavior": {
    "TargetOriginId": "your-main-origin"
  },
  "CacheBehaviors": [
    {
      "PathPattern": "/rewards*",
      "TargetOriginId": "cardlytics-rewards",
      "ViewerProtocolPolicy": "redirect-to-https",
      "Compress": true,
      "ForwardedValues": {
        "QueryString": true,
        "Headers": ["Authorization", "X-Forwarded-Host"]
      }
    }
  ]
}

Domain Configuration

Contact your Cardlytics integration manager to:

  1. Whitelist your rewards domain for hosted integration
  2. Configure CORS settings to allow your rewards domain

Error Handling

Token Expiration

The hosted token expires after 1 hour. Handle expiration gracefully:

// Listen for messages from hosted experience
window.addEventListener('message', (event) => {
    if (event.origin !== 'https://yourrewardsdomain.com') return;
    
    if (event.data.type === 'TOKEN_EXPIRED') {
        // Redirect user back to main application
        window.location.href = '/dashboard?message=session_expired';
    }
    
    if (event.data.type === 'UNAUTHORIZED') {
        // Handle 401 errors
        window.location.href = '/login?redirect=rewards';
    }
});

Security Considerations

  1. HTTPS Required: All communication must use TLS encryption
  2. Token Security: Hosted tokens should only be used once and expire after 1 hour
  3. Domain Validation: Ensure reverse proxy configuration restricts access appropriately
  4. User Authentication: Always validate user authentication before generating hosted tokens
  5. CORS Configuration: Work with Cardlytics to properly configure allowed origins

Customizing the Theme

The hosted experience supports the same theming options for Web SDK. See for more information.