The Web Offerwall JavaScript SDK: Complete Integration Guide (2026)

·

Offerwall Placement Strategy






The Web Offerwall JavaScript SDK: Complete Integration Guide (2026)



The Web Offerwall JavaScript SDK: Complete Integration Guide (2026)

Published August 22, 2026 — by the Perkox Developer Team

Offerwalls are not just for mobile apps. If you run a web application, a browser game, a PWA, or any site with a virtual currency or premium content system, an offerwall lets your users earn rewards by completing surveys, downloading apps, signing up for trials, and more. The Perkox Web Offerwall JavaScript SDK makes this straightforward: a single script tag or npm package gives you a full offerwall experience with reward callbacks, cross-origin safety, and server-side postback support.

This guide covers the full integration from prerequisites to production: installation (script tag or npm), initialization, showing the offerwall in iframe or popup mode, handling rewards client-side, setting up server-side postbacks, managing cross-origin communication, testing, debugging, and a five-question FAQ.

New to offerwalls? Read our introduction to offerwalls first. For mobile integrations, see the Android SDK guide. For the server-side reward flow, our postback guide is essential reading. You may also find the Dynamic API guide useful for server-side offer fetching, and the security best practices guide for protecting your integration.

Table of Contents

  1. Prerequisites
  2. Installation (Script Tag or npm)
  3. Initialization
  4. Showing the Offerwall (iframe vs popup)
  5. Handling Rewards Client-Side
  6. Server-Side Postback Setup
  7. Cross-Origin Considerations
  8. Testing and Debugging
  9. FAQ

1. Prerequisites

The Perkox Web SDK has minimal requirements, making it suitable for everything from static sites to complex SPAs:

Requirement Details
Perkox Publisher Account Required — sign up free at Perkox
App ID & API Key Available in the Perkox dashboard after registering your web app
Domain Registration Register your site’s domain(s) in the dashboard for postMessage security
JavaScript Environment Any modern browser (ES2020+). No framework required.
Backend Server Required for postback verification and user crediting
HTTPS Required in production. The SDK works on localhost over HTTP for development.
Register your domain: Before the SDK can communicate securely, add your domain (e.g. yourapp.com, www.yourapp.com) in the Perkox dashboard under App Settings → Allowed Origins. This prevents unauthorized sites from embedding your offerwall.

2. Installation (Script Tag or npm)

Perkox offers two installation methods depending on your build setup.

2.1 Script Tag (for static sites, vanilla JS, or non-bundled projects)

Add the SDK script tag in the <head> or before your closing </body> tag:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>My Web App</title>
  <!-- Perkox Web SDK -->
  <script src="https://cdn.perkox.com/sdk/web/perkox-offerwall.min.js"></script>
</head>
<body>
  <!-- Your app content -->
  <script>
    // Access via window.PerkoxOfferwall
    PerkoxOfferwall.initialize({
      appId: 'your-app-id',
      apiKey: 'your-api-key',
      userId: 'user-12345',
    });
  </script>
</body>
</html>

2.2 npm / yarn (for bundled projects: React, Vue, Angular, Svelte, etc.)

npm install @perkox/web-offerwall
# or
yarn add @perkox/web-offerwall
# or
pnpm add @perkox/web-offerwall

Then import in your application:

// ES module import
import { PerkoxOfferwall } from '@perkox/web-offerwall';

// CommonJS
const { PerkoxOfferwall } = require('@perkox/web-offerwall');

The npm package ships with full TypeScript definitions, so you get type safety in TS projects out of the box.

3. Initialization

Initialize the SDK once after your page or app loads. The initialization call configures the SDK with your credentials and sets the current user. This must happen before you show the offerwall.

import { PerkoxOfferwall } from '@perkox/web-offerwall';

// Initialize with your credentials
PerkoxOfferwall.initialize({
  appId: 'your-app-id',
  apiKey: 'your-api-key',
  userId: 'user-12345',         // your internal user ID
  isTestMode: false,            // set to true for development
  logLevel: 'error',            // 'none' | 'error' | 'info' | 'debug'
  onReady: () => {
    console.log('Perkox SDK ready');
  },
  onError: (error) => {
    console.error('Perkox SDK error:', error);
  },
});

TypeScript Interface

interface PerkoxWebInitOptions {
  appId: string;
  apiKey: string;
  userId: string;
  isTestMode?: boolean;
  logLevel?: 'none' | 'error' | 'info' | 'debug';
  customParams?: Record<string, string>;
  onReady?: () => void;
  onError?: (error: PerkoxError) => void;
}

interface PerkoxError {
  code: string;
  message: string;
}
Framework integration: In React, call initialize() in a top-level useEffect. In Vue, call it in onMounted of your root component. In Angular, call it in ngOnInit of your AppComponent. Initialize once, not on every route change.

4. Showing the Offerwall (iframe vs popup)

The web SDK supports two display modes: iframe (embedded inline) and popup (full-screen overlay window). Choose based on your UX needs.

4.1 iframe Mode (Embedded)

Iframe mode renders the offerwall inside a container element on your page. This is ideal for a dedicated “Earn Rewards” section within a web app.

// HTML: create a container
// <div id="perkox-offerwall-container" style="width:100%;height:600px;"></div>

PerkoxOfferwall.showOfferwall({
  mode: 'iframe',
  container: document.getElementById('perkox-offerwall-container'),
  placement: 'rewards_page',
  onClose: () => {
    console.log('Offerwall closed');
  },
});

The iframe fills the container’s dimensions. Set your container’s width and height via CSS to control the offerwall’s size.

4.2 Popup Mode (Full-Screen Overlay)

Popup mode opens a full-screen modal overlay on top of your page. This is better for mobile web and for button-triggered flows where you want the offerwall to take over the screen.

document.getElementById('earn-button').addEventListener('click', () => {
  PerkoxOfferwall.showOfferwall({
    mode: 'popup',
    placement: 'header_button',
    onClose: () => {
      console.log('Offerwall closed');
    },
  });
});

4.3 Comparison

Feature iframe Mode popup Mode
Display Embedded in container Full-screen overlay
Best for Rewards section in a web app Button-triggered flow
Mobile web Works but needs responsive container Excellent — uses full viewport
User dismissal Controlled by your page Close button in overlay
Nesting Inside your layout Above all content (z-index: 2147483647)

4.4 Checking Offer Availability

const hasOffers = await PerkoxOfferwall.hasOffersAvailable();

if (hasOffers) {
  // Show "Earn Rewards" button
  document.getElementById('earn-button').style.display = 'block';
} else {
  document.getElementById('earn-button').style.display = 'none';
}

5. Handling Rewards Client-Side

The SDK emits events when a user earns a reward, opens the offerwall, closes it, or encounters an error. Subscribe to these events to update your UI in real time — for example, showing a “You earned 50 coins!” toast or refreshing the user’s balance display.

import { PerkoxOfferwall, PerkoxEvents } from '@perkox/web-offerwall';

// Subscribe to reward events
PerkoxEvents.on('reward', (reward) => {
  console.log('Reward earned:', reward);
  showToast(`You earned ${reward.payout} coins!`);
  refreshUserBalance();
});

PerkoxEvents.on('offerwallOpen', () => {
  console.log('Offerwall opened');
});

PerkoxEvents.on('offerwallClose', () => {
  console.log('Offerwall closed');
});

PerkoxEvents.on('error', (error) => {
  console.error('Perkox error:', error);
});

// Unsubscribe when done (e.g., in React useEffect cleanup)
// PerkoxEvents.off('reward', handler);

Reward Object Structure

interface PerkoxReward {
  transactionId: string;    // unique per completion
  offerId: string;
  offerName: string;
  payout: number;           // in your virtual currency units
  payoutUSD: number;        // in USD cents
  userId: string;
  timestamp: number;        // Unix epoch ms
}
Client-side events are for UX only: A sophisticated user can trigger fake reward events via the browser console. Always credit actual balances based on the server-side postback. Use client events only for instant UI feedback — then reconcile with the postback.

6. Server-Side Postback Setup

The postback is the authoritative reward channel. When a user completes an offer, Perkox sends an HTTP request to your backend with transaction details and a cryptographic signature. Your server verifies the signature and credits the user.

Configuring the Postback URL

In the Perkox dashboard, navigate to App Settings → Postback and enter your endpoint:

https://api.yourapp.com/perkox/postback?user_id={user_id}&txn_id={txn_id}&payout={payout}&offer_id={offer_id}&signature={signature}

Server-Side Verification (Node.js / Express)

const express = require('express');
const crypto = require('crypto');

const app = express();
const PERKOX_SECRET = 'your-postback-secret';

app.get('/perkox/postback', async (req, res) => {
  const { user_id, txn_id, payout, offer_id, signature } = req.query;

  // Reconstruct signature
  const data = `${user_id}${txn_id}${payout}${offer_id}`;
  const expectedSig = crypto
    .createHmac('sha256', PERKOX_SECRET)
    .update(data)
    .digest('hex');

  if (signature !== expectedSig) {
    console.error('Invalid postback signature');
    return res.status(403).send('Invalid signature');
  }

  // Idempotency check — prevent double-crediting on retries
  const existing = await db.transactions.findById(txn_id);
  if (existing) {
    return res.status(200).send('OK'); // Already processed
  }

  // Store transaction and credit user
  await db.transactions.create({ id: txn_id, userId: user_id, amount: payout });
  await creditUser(user_id, parseInt(payout, 10));

  res.status(200).send('OK');
});

app.listen(3000);
Always return 200: Perkox retries postbacks that do not receive a 200 status code. Return 200 even for duplicate transactions to stop retries. See the complete postback guide for the full specification.

User ID Consistency

The userId you pass to initialize() on the client must match the user_id that appears in the postback. Use a stable, server-assigned user ID — never a random ID generated in the browser, because that ID would not survive a page reload or device switch.

// Good: fetch user ID from your backend
const user = await fetchCurrentUser();
PerkoxOfferwall.initialize({
  appId: 'your-app-id',
  apiKey: 'your-api-key',
  userId: user.id,  // stable backend ID
});

7. Cross-Origin Considerations

The Perkox web SDK uses postMessage for cross-origin communication between your page and the offerwall iframe/popup. This means you do not need to configure CORS headers on your server. However, there are a few things to keep in mind:

7.1 Allowed Origins

Register every domain where you will use the SDK in the Perkox dashboard. For example, if your app runs on both yourapp.com and www.yourapp.com, add both. The SDK checks the origin of incoming postMessage events and ignores messages from unregistered origins for security.

7.2 HTTPS Requirement

In production, the SDK requires HTTPS. Mixed-content browsers will block the offerwall iframe if your page is served over HTTP but the offerwall is HTTPS. For local development, http://localhost and http://127.0.0.1 are allowed automatically.

7.3 Content Security Policy (CSP)

If your site uses a Content Security Policy, add the Perkox CDN and offerwall domain to your script-src and frame-src directives:

Content-Security-Policy:
  script-src 'self' https://cdn.perkox.com;
  frame-src 'self' https://offerwall.perkox.com;
  connect-src 'self' https://api.perkox.com;

7.4 Subdomain Handling

If your app runs on wildcard subdomains (e.g., *.yourapp.com), register each subdomain or use the wildcard option in the dashboard. The SDK validates origins exactly, so app.yourapp.com and www.yourapp.com are treated as different origins.

8. Testing and Debugging

8.1 Test Mode

Enable test mode to display test offers that convert instantly. This lets you verify the full flow — show offerwall, complete offer, receive client event, receive postback — without real offer latency.

PerkoxOfferwall.initialize({
  appId: 'your-app-id',
  apiKey: 'your-api-key',
  userId: 'test-user-1',
  isTestMode: true,
  logLevel: 'debug',
});

8.2 Log Levels

Level Output
none No logs
error Errors only (production default)
info Errors + lifecycle events
debug Verbose logs including postMessage traffic

8.3 Browser DevTools

With logLevel: 'debug', the SDK logs all postMessage events to the console. You can also inspect the offerwall iframe directly in DevTools → Elements to see its DOM, and use the Network tab to watch API calls to api.perkox.com.

8.4 Postback Testing

Use the Postback Tester in the Perkox dashboard to send a test postback to your server. This verifies your endpoint, signature validation, and idempotency logic without completing a real offer. For server-side offer fetching and dynamic offer customization, see the Dynamic API guide.

8.5 Common Issues

Issue Cause Fix
Offerwall iframe blank Domain not registered in dashboard Add your domain to Allowed Origins
CSP blocking the SDK Content Security Policy too restrictive Add cdn.perkox.com and offerwall.perkox.com to CSP
No reward event received Event listener added after offerwall opened Subscribe to events before calling showOfferwall()
Postback not received Endpoint unreachable or not returning 200 Test with curl, check server logs, ensure 200 response
Mixed content warning Page on HTTP, SDK on HTTPS Serve your page over HTTPS in production
Popup blocked by browser Popup mode called outside user gesture Call showOfferwall() inside a click handler

9. FAQ

Should I use the iframe or popup display mode?

Use the iframe mode when you want the offerwall embedded inside a container on your page, such as a rewards section in a web app. Use the popup mode when you want a full-screen experience triggered by a button click. The popup mode is better for mobile web because it gives offers the full viewport.

Can I use the SDK with a bundler like Webpack or Vite?

Yes. The SDK is published on npm as @perkox/web-offerwall with full ESM and CommonJS support. Install it with npm or yarn and import it in your bundle. The script tag method is available for non-bundled sites.

Do I need a backend server, or can I handle everything client-side?

You need a backend server for secure reward crediting. The client-side SDK handles displaying the offerwall and emitting reward events for UX, but the actual crediting must happen via a server-side postback that you verify with an HMAC signature. Crediting based on client-side events alone is insecure.

Does the SDK work across different domains and subdomains?

Yes. The SDK uses postMessage for cross-origin communication between your page and the Perkox offerwall iframe/popup. No special CORS headers are needed on your server. You do need to register your domain(s) in the Perkox dashboard so the SDK accepts postMessage events from your origin.

Is the web SDK free to use?

Yes. The SDK is free to install and use. Perkox operates on a revenue-share model — you earn a percentage of each completed offer. There are no upfront costs, monthly fees, or minimum commitments.

Conclusion

The Perkox Web Offerwall JavaScript SDK gives web developers a clean, framework-agnostic way to integrate offerwall monetization. Whether you prefer a script tag or an npm package, an inline iframe or a full-screen popup, the SDK adapts to your architecture. With secure cross-origin communication via postMessage, typed event listeners, and a robust server-side postback system, you can go from install to first reward in a single afternoon.

Pair the web SDK with the server-side Dynamic API for maximum control over which offers your users see, and always follow the security best practices to protect your integration from abuse.

Ready to monetize your web app?

Create your free Perkox publisher account and get your API keys in minutes.

Sign up as a publisher →

Read the full API documentation →

Related guides: What is an Offerwall? · Android SDK Guide · Postback Guide · Dynamic API Guide · Security Best Practices


Start monetizing your app with Perkox.

One SDK. Android, iOS, React Native, Flutter, Unity. A premium reward layer for your non-paying users — live in about 10 minutes.

Related articles