EPaySe
New

Browser Details SDK

A lightweight, zero-dependency JavaScript SDK that collects browser environment data required for S2S payment processing with the EPaySe API.

Lightweight

Under 1KB minified. No bloat — just the browser data fields required by the EPaySe S2S API.

Zero Dependencies

Pure ES5 IIFE — no build tools, no npm install required. Drop a single script tag and you're ready.

Cross-Browser

Works in all modern browsers and IE11+. Collects all 12 browser fields required by the EPaySe S2S API.

Installation

Add the SDK to your checkout page via a script tag:

HTML
HTML CDN
<!-- Production -->
<script src="https://staging-gateway.epayse.com/js/epayse-browser.js"></script>

<!-- Sandbox (for testing) -->
<script src="https://staging-sandbox-gateway.epayse.com/js/epayse-browser.js"></script>

Or copy and self-host the full source if you prefer to serve it from your own infrastructure:

JavaScript
Self-host (Copy & Paste)
/*!
 * EPaySe Browser Details SDK v1.0.0
 * Collects browser environment data for the EPaySe S2S Payment API.
 * License: MIT
 */
(function(root) {
    'use strict';

    var VERSION = '1.0.0';

    function getBrowserDetails() {
        return {
            userAgent: navigator.userAgent,
            language: navigator.language || navigator.userLanguage || '',
            screenWidth: screen.width,
            screenHeight: screen.height,
            timeZone: new Date().getTimezoneOffset(),
            acceptHeader: '',
            colorDepth: screen.colorDepth || 24,
            windowWidth: window.innerWidth || 0,
            windowHeight: window.innerHeight || 0,
            timeZoneName: (typeof Intl !== 'undefined' && Intl.DateTimeFormat)
                ? Intl.DateTimeFormat().resolvedOptions().timeZone
                : '',
            javaEnabled: false,
            javascriptEnabled: true
        };
    }

    function injectHiddenFields(formSelector) {
        var form = typeof formSelector === 'string'
            ? document.querySelector(formSelector)
            : formSelector;

        if (!form || form.tagName !== 'FORM') {
            console.warn('[EPaySe] injectHiddenFields: form not found or invalid');
            return null;
        }

        var details = getBrowserDetails();
        var keys = Object.keys(details);

        for (var i = 0; i < keys.length; i++) {
            var key = keys[i];
            var fieldName = 'browserDetails[' + key + ']';
            var existing = form.querySelector('input[name="' + fieldName + '"]');
            var input = existing || document.createElement('input');
            input.type = 'hidden';
            input.name = fieldName;
            input.value = details[key] === null ? '' : String(details[key]);
            if (!existing) form.appendChild(input);
        }

        return details;
    }

    root.EPaySe = root.EPaySe || {};
    root.EPaySe.browser = {
        version: VERSION,
        getBrowserDetails: getBrowserDetails,
        injectHiddenFields: injectHiddenFields
    };

}(typeof self !== 'undefined' ? self : this));

Quick Usage

Call getBrowserDetails() to collect all browser fields at any point after the page loads:

JavaScript
getBrowserDetails()
const details = EPaySe.browser.getBrowserDetails();
console.log(details);

// Example output:
// {
//   userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...",
//   language: "en-US",
//   screenWidth: 1920,
//   screenHeight: 1080,
//   timeZone: -420,
//   acceptHeader: "",           // ← must be set server-side
//   colorDepth: 24,
//   windowWidth: 1440,
//   windowHeight: 900,
//   timeZoneName: "Asia/Bangkok",
//   javaEnabled: false,
//   javascriptEnabled: true
// }

Form Integration

Use injectHiddenFields() to automatically append all browser data as hidden inputs to your payment form before it is submitted. This is the simplest integration path for server-rendered checkout pages.

HTML
HTML Form + injectHiddenFields()
<!-- Your payment form -->
<form id="payment-form" method="POST" action="/checkout">
    <input type="text" name="card_number" placeholder="Card Number" />
    <input type="text" name="expiry" placeholder="MM/YY" />
    <input type="text" name="cvv" placeholder="CVV" />
    <button type="submit">Pay Now</button>
</form>

<script src="https://staging-gateway.epayse.com/js/epayse-browser.js"></script>
<script>
    document.getElementById('payment-form').addEventListener('submit', function() {
        // Inject all browser fields as hidden inputs before submission
        EPaySe.browser.injectHiddenFields('#payment-form');
    });
</script>

Fetch API Pattern

For single-page applications or JavaScript-driven checkouts, collect the data and include it in your JSON payload:

JavaScript
Fetch API Integration
const details = EPaySe.browser.getBrowserDetails();

fetch('/your-backend/create-payment', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
        amount: 10000,
        currency: 'USD',
        browserDetails: details
    })
})
.then(res => res.json())
.then(data => {
    if (data.checkout_url) {
        window.location.href = data.checkout_url;
    }
});

Server-Side Integration

Your backend receives the browser details and forwards them to the EPaySe S2S API. The server must set acceptHeader from the customer's HTTP request before forwarding — the SDK always returns an empty string for this field.

PHP
PHP / Laravel — Create S2S Payment
<?php

// In your payment controller endpoint
public function createPayment(Request $request): JsonResponse
{
    // Merge browser details with server-supplied acceptHeader
    $browserDetails = $request->input('browserDetails', []);
    $browserDetails['acceptHeader'] = $request->header('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8');

    $timestamp = time();
    $nonce = bin2hex(random_bytes(16));

    $payload = json_encode([
        'amount'         => $request->input('amount'),
        'currency'       => $request->input('currency'),
        'orderId'        => $request->input('order_id'),
        'returnUrl'      => route('payment.callback'),
        'cancelUrl'      => route('payment.cancel'),
        'browserDetails' => $browserDetails,
    ]);

    $signature = hash_hmac('sha256', $timestamp . $nonce . $payload, config('services.epayse.secret_key'));

    $response = Http::withHeaders([
        'X-Api-Key-Id'   => config('services.epayse.api_key'),
        'X-Signature' => $signature,
        'X-Timestamp' => $timestamp,
        'X-Nonce'     => $nonce,
    ])->withBody($payload, 'application/json')
      ->post('https://api.epayse.com/api/v1/transaction/s2s');

    return response()->json($response->json());
}
JavaScript
Node.js / Express — Create S2S Payment
// Express.js example
const crypto = require('crypto');

app.post('/create-payment', async (req, res) => {
    const { amount, currency, browserDetails } = req.body;

    // Add server-side Accept header
    browserDetails.acceptHeader = req.headers['accept'] || 'text/html,application/xhtml+xml,*/*';

    const timestamp = Math.floor(Date.now() / 1000);
    const nonce = crypto.randomBytes(16).toString('hex');

    const payload = JSON.stringify({
        amount,
        currency,
        orderId: `ORD-${Date.now()}`,
        returnUrl: 'https://yoursite.com/payment/callback',
        cancelUrl: 'https://yoursite.com/payment/cancel',
        browserDetails,
    });

    const signature = crypto
        .createHmac('sha256', process.env.EPAYSE_SECRET_KEY)
        .update(timestamp + nonce + payload)
        .digest('hex');

    const response = await fetch('https://api.epayse.com/api/v1/transaction/s2s', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-Api-Key-Id': process.env.EPAYSE_API_KEY,
            'X-Signature': signature,
            'X-Timestamp': timestamp,
            'X-Nonce': nonce,
        },
        body: payload,
    });

    res.json(await response.json());
});

Field Reference

All 12 fields are required by the EPaySe S2S API.

FieldTypeSourceDescription
userAgentstringBrowserFull browser user agent string
languagestringBrowserBrowser language (e.g. en-US)
screenWidthnumberBrowserTotal screen width in pixels
screenHeightnumberBrowserTotal screen height in pixels
timeZonenumberBrowserUTC offset in minutes (e.g. -420 for UTC+7)
acceptHeaderstringServer-sideHTTP Accept header — must be set by your server from the customer's request
colorDepthnumberBrowserScreen color depth in bits (default 24)
windowWidthnumberBrowserBrowser viewport width in pixels
windowHeightnumberBrowserBrowser viewport height in pixels
timeZoneNamestringBrowserIANA timezone name (e.g. Asia/Bangkok)
javaEnabledbooleanBrowserAlways false — Java applets are universally disabled
javascriptEnabledbooleanBrowserAlways true — SDK is running, so JS is enabled

Related Resources

Learn more about the S2S API, JavaScript SDK, and authentication.