NAV

JavaScript SDK

Introduction

The JavaScript SDK provides an easy way to integrate EasyProcess + IDEM payment processing directly into your web application. With just a few lines of code, you can create secure payment forms that handle card processing, 3D Secure authentication, and real-time status updates.

Payment requests, refunds and webhooks are described in the API documentation.

Prerequisites

Contact your sales representative to enable the SDK for your account.

Configuration

Step 1: Enable SDK in Settings

Go to your merchant settings and configure the SDK:

Both keys are generated together by your account manager; ask them to regenerate the pair if the secret key ever reaches a page or a repository. Make sure to note your Merchant ID (an 8-digit number), as you will need it in the server call and in the page.

Quick Start

Step 1: Create the payment session on your server

Your server opens the payment session with your secret key. The amount, the currency, your order reference and the customer are set here, once, and the browser cannot change them. The response carries a session_id that you hand to your page.

Please take a look at the example, on the right or below if you're on mobile.

Create the payment session (server side, with the secret key)

curl -X POST https://gateway.idem-club.com/api/sdk/payment/session \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "merchant_id": "12345678",
    "amount": 49.99,
    "currency": "USD",
    "order_ref": "1234",
    "customer": {
      "email": "[email protected]",
      "firstname": "John",
      "lastname": "Doe",
      "address": "1 Main Street",
      "city": "New York",
      "state": "NY",
      "zipcode": "10001",
      "country": "US",
      "phone": "+13055550123"
    }
  }'
<?php
// Same call from PHP. $secretKey comes from your configuration, never from a page.
$ch = curl_init('https://gateway.idem-club.com/api/sdk/payment/session');
curl_setopt_array($ch, array(
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => array(
        'Authorization: Bearer ' . $secretKey,
        'Content-Type: application/json'
    ),
    CURLOPT_POSTFIELDS => json_encode(array(
        'merchant_id' => '12345678',
        'amount' => 49.99,
        'currency' => 'USD',
        'order_ref' => '1234',
        'customer' => array(
            'email' => '[email protected]', 'firstname' => 'John', 'lastname' => 'Doe',
            'address' => '1 Main Street', 'city' => 'New York', 'state' => 'NY',
            'zipcode' => '10001', 'country' => 'US', 'phone' => '+13055550123'
        )
    ))
));
$session = json_decode(curl_exec($ch), true);
curl_close($ch);
if (empty($session['success'])) {
    // $session['code'] and $session['message'] say why (see Error Codes): stop here
    throw new RuntimeException('Payment session refused: ' . (isset($session['code']) ? $session['code'] : 'no response'));
}
$sessionId = $session['session_id']; // hand it to your page (Step 3)

The response: {"success": true, "session_id": "…", "expires_at": "…", "status": "active", "attempts": 0, "reused": false}. The session lives 30 minutes and is tied to order_ref (25 characters maximum): calling again for the same order returns the same session ("reused": true) with its current status; the same order with another amount or currency is refused (order_ref_conflict). The customer fields are the ones of the card payment. Email, first name, last name, city and country are mandatory, and the state is mandatory for a US customer. A session without them is refused at payment time (invalid_customer). Send the address and the zip code too: the platform does not test them, but they go to the anti-fraud checks. An IDEM Club merchant also needs a mobile number, for a customer that IDEM Club does not know yet. A customer sent from the page is ignored.

All the dates that the platform sends you are in the Eastern time of the United States (America/New_York), and expires_at is one of them. This zone is EST in winter and EDT in summer, and the dates carry no timezone suffix. Read them with that zone, never with a fixed offset: a fixed offset is wrong for half of the year.

The session_id is a secret. Whoever holds it, together with your publishable key, can submit a card on that session and read its outcome. Do not log it, do not put it in a URL, do not show it to your support staff. Pass it to your page in the HTML you render, or through your own authenticated endpoint.

Step 2: Basic HTML Setup

Please take a look at the HTML example, on the right or below if you're on mobile.

Basic HTML Setup for the SDK

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Payment Page</title>

    <!-- SDK Files (use the correct domain for your environment) -->
    <!-- Prod: https://gateway.idem-club.com | Sandbox: https://gateway.idem-club.info -->
    <script src="https://gateway.idem-club.com/sdk/v1/sdk.min.js"></script>
    <!-- Minimal styling for the SDK -->
    <link rel="stylesheet" href="https://gateway.idem-club.com/sdk/v1/sdk.min.css">

    <!-- Optional: Your custom styles -->
    <style>
        #payment-container {
            max-width: 400px;
            margin: 50px auto;
            padding: 20px;
            border: 1px solid #ddd;
            border-radius: 8px;
        }
    </style>
</head>
<body>
    <div id="payment-container">
        <h2>Complete Payment</h2>
        <div id="payment-form"></div>
    </div>

    <script>
        // Your JavaScript goes here (see next section)
    </script>
</body>
</html>

JavaScript Implementation

Please take a look at the JavaScript example, on the right or below if you're on mobile.

JavaScript SDK Implementation

// Initialize the SDK with the PUBLISHABLE key (environment is inferred from the domain serving the SDK)
var sdk = PaymentSDK.init({
    merchantId: '12345678',                 // Replace with your merchant ID
    publishableKey: 'pk_YOUR_PUBLISHABLE_KEY' // The pk_ key. Never the sk_ key.
});

// Create the payment form on the session your server created in Step 1
var paymentForm = sdk.createPaymentForm({
    container: '#payment-form',
    sessionId: 'SESSION_ID_FROM_YOUR_SERVER', // the session_id of Step 1

    // Success handler
    onSuccess: function(result) {
        console.log('Payment successful, transaction', result.transaction_id);
        alert('Payment completed! Transaction ID: ' + result.transaction_id);
        // Redirect to success page
        window.location.href = '/payment-success';
    },

    // Error handler
    onError: function(error) {
        console.error('Payment failed:', error.code, error.message);
        alert('Payment failed: ' + error.message);
    },

    // Pending handler (for async processors)
    onPending: function(context) {
        console.log('Processing payment...');
        // SDK automatically handles status updates via SSE
        // The form will update when payment completes
    }
});

When the customer clicks Pay, the SDK reads the state of the session first and sends the card only when the session is still open: a page reloaded on a paid order shows the outcome and calls onSuccess without sending a card again.

Testing

Sandbox Environment

Browser Console

  1. Open Developer Tools (F12)
  2. Check Console for any errors
  3. Verify SDK initialization message

Common Test Scenarios

Production Checklist

Advanced Features

Debug Logging

Use the optional onLog function to surface SDK internal logs to your console.

Please take a look at the JavaScript example, on the right or below if you're on mobile.

Debug Logging

var sdk = PaymentSDK.init({
    merchantId: '12345678',
    publishableKey: 'pk_YOUR_PUBLISHABLE_KEY',
    onLog: function() {
        // Prefix logs for easy filtering in the console
        try {
            console.log('[PaymentSDK]', Array.prototype.slice.call(arguments));
        } catch (e) {}
    }
});

What gets logged:

Handle Async Payments

Please take a look at the JavaScript example, on the right or below if you're on mobile.

Handle Async Payments

onPending: function(context) {
    // Show custom loading UI
    document.getElementById('loading-message').style.display = 'block';

    // context.session_id names the session: keep it for your own logic, never log it

    // SSE automatically handles updates
    // onSuccess or onError will be called when complete
}

IDEM Club Integration

For merchants with IDEM Club integration enabled (m_idem = 1), the SDK automatically handles:

The mr_idem_user_id field will be automatically set when processing payments for IDEM Club members.

Webhook Integration

Do not rely on JavaScript callbacks alone for fulfillment or accounting. Always implement a backend Webhook listener to receive authoritative status updates even if the browser closes or the network drops.

Error Codes

Code Description User Action
declined Payment was declined by the card processor (counts one of the 3 requests the session may send to the processor) Try different payment method
invalid_request Request refused before the processor (missing or invalid parameter). No attempt consumed Check the parameters and submit again
invalid_customer A mandatory customer field is empty: first name, last name, city, country, or the state for a US customer. No attempt consumed Complete the customer object
invalid_email Customer email address rejected (invalid, or not accepted by the platform). No attempt consumed Correct the email address
amount_out_of_range Amount below the minimum or above the maximum of your account. No attempt consumed Check the amount limits of your account
currency_mismatch Currency differs from your account currency. No attempt consumed Use your account currency
duplicate_reference A payment with this order reference was already received (HTTP 409). No attempt consumed Check the status of that order and payment before retrying; use a new reference only for a genuinely new purchase
order_ref_conflict An open session exists for this order reference with another amount or currency (HTTP 409) Reconcile with the open session (same amount and currency) or let it expire; a new reference is only for a different order
payment_refused Request refused after its creation but before the processor (customer account or card locked, processor unavailable on this channel). No attempt consumed Follow the message
payment_in_progress Another submission of this order is being processed right now (HTTP 409); the SDK reads the order's outcome and follows it Do not resubmit
session_busy Another request is opening the session of this order (HTTP 409) Retry in a moment
session_inactive The session's payment is in flight or already completed (HTTP 409); the SDK reads the outcome and follows it Do not resubmit
payments_unavailable Payments are suspended on this merchant account (HTTP 403) Contact support
forbidden_new_users Your account accepts known customers only, and this email has no account yet (HTTP 403). No attempt consumed Contact support
idem_signup_not_allowed Your account is an IDEM Club account, but it does not allow automatic login or signup (HTTP 422). No attempt consumed Contact support
merchant_not_found The merchant of the server call does not exist (HTTP 404). No attempt consumed Check the merchant_id of your server call
processing_error The platform did not complete the payment (HTTP 500). This response does not say what happened to the card Read the status of the session before you submit again
attempts_exceeded Three requests already reached the processor on this session (the session counts declined, pending and completed requests; it restarts from zero when the platform switches the order to the fallback processor) Wait and try again later
unauthorized No Authorization header (HTTP 401) Pass the publishable key to PaymentSDK.init(); send the secret key on payment/session
secret_key_invalid The key sent to POST /api/sdk/payment/session is not the secret key of this merchant (HTTP 401). A publishable key is refused here too Check the secret key and the merchant_id of your server call
public_key_invalid The key in the page is not the publishable key of the merchant that owns the session (HTTP 401) Check the publishable key passed to PaymentSDK.init(), and that the session was created for the same merchant
secret_key_in_browser A secret key (sk_) was sent from the page (HTTP 403). The platform logs it as a leak Remove the secret key from the page, use the publishable key, and ask for both keys to be regenerated
origin_required A browser endpoint was called without an Origin header (HTTP 403). Browsers send it on cross-origin requests only: the page must be served from one of your allowed origins, not from the platform host Call payment/process, payment/status and payment/stream from the page only; your server calls payment/session
origin_not_configured No allowed origin is configured on your account (HTTP 403) Set the allowed origins in your settings
origin_not_allowed The origin of the page is not in your allowed origins (HTTP 403) Add the exact origin (scheme and host, port if any) to the allowed origins
not_found / method_not_allowed Unknown endpoint, or wrong HTTP method (HTTP 404 / 405) Check the SDK version and the URL
session_expired Payment session expired Refresh page and start over
idem_user_invalid IDEM Club validation failed Check customer information

Troubleshooting

Issue Solution
"Missing Authorization header" Pass the publishable key to PaymentSDK.init(); on payment/session, send Authorization: Bearer sk_…
"Invalid secret key" on payment/session Check the secret key and the merchant_id; sandbox and production keys differ
"A secret key was presented on a browser endpoint" The page holds the secret key: remove it, use the publishable key, ask for both keys to be regenerated
"Origin not allowed" / "No allowed origin is configured" Add the exact origin of your page to the allowed origins in your settings
"Session expired" Payment took too long, refresh page
"SDK disabled" Contact support to enable SDK
Form doesn't appear Check container selector exists
SSE connection fails Ensure CloudFlare or similar is not blocking SSE

Debugging a refused session or payment

If POST /api/sdk/payment/session answers 401 or 403, or if the form shows an error before any card is sent:

  1. Enable logging - Initialize with onLog to capture SDK messages
  2. Verify domain/environment - Ensure correct domain (sandbox: .info, prod: .com); the keys of one environment do not work on the other
  3. Inspect Network tab - Every response carries code, message and correlation_id
  4. Common causes:
    • secret_key_invalid: wrong secret key, or wrong merchant_id in the server call
    • public_key_invalid: wrong publishable key in the page, or a session of another merchant
    • secret_key_in_browser: the secret key ended up in the page
    • sdk_disabled_merchant: the SDK is not enabled on your account
    • origin_not_allowed / origin_not_configured: the exact origin of the page is not in your allowed origins
    • session_not_found / session_expired: the page holds a stale session_id; create a new session
  5. Provide correlation_id to support for faster tracing