Skip to content

Create Bill Presentment SDK Session

Create a new SDK session for a user. Returns a session_token that your frontend passes to the SDK.

Use this token directly as Authorization: Bearer {session_token} for Bill Presentment SDK API calls.

This is a server-to-server call from your backend.

INFO

For the full integration flow, see Bill Presentment SDK Quickstart and Bill Presentment SDK Authentication.

API Endpoint

http
POST https://api.iimmpact.com/v2/sdk/sessions

Authentication

Use API Key + HMAC headers:

HeaderRequiredDescription
X-Api-KeyYesYour API key
X-TimestampYesUnix timestamp in seconds
X-NonceYesUnique request nonce (UUID recommended)
X-SignatureYesHMAC signature in format v1=<base64>

Compute the signature using the canonical HMAC flow documented in API Key Authentication.

DANGER

Never generate these headers in client-side code (web/mobile). API key and HMAC secret must stay on your backend.

Request Body

FieldTypeRequiredDescription
ic_numberstringYesMalaysian IC number (12 digits, no dashes)
json
{
  "ic_number": "901234567890"
}

Response 200

FieldTypeDescription
session_tokenstringSession token for SDK/API auth (bp_sess_xxxx)
expires_atstringISO 8601 expiry time (15 minutes from creation)
json
{
  "session_token": "bp_sess_xxxx",
  "expires_at": "2026-03-11T10:15:00Z"
}

Session Lifetime

  • Initial expiry is 15 minutes from creation.
  • TTL is sliding: each successful SDK API call extends expiry by 15 minutes.
  • Absolute maximum lifetime is 1 hour from session creation.

Error Responses

401 Unauthorized

Returned when API key authentication fails.

Common causes:

  • Invalid or revoked X-Api-Key
  • Missing/invalid HMAC headers (X-Timestamp, X-Nonce, X-Signature)
  • Signature mismatch (X-Signature does not verify)

400 Bad Request

Returned when request validation fails.

Validation rules:

  • ic_number is required
  • ic_number must be exactly 12 digits (numeric only, no dashes/spaces)

Example

curl

bash
TIMESTAMP=$(date +%s)
NONCE=$(uuidgen | tr '[:upper:]' '[:lower:]')
SIGNATURE="v1=BASE64_HMAC_SIGNATURE"

curl -X POST https://api.iimmpact.com/v2/sdk/sessions \
  -H "X-Api-Key: ${API_KEY}" \
  -H "X-Timestamp: ${TIMESTAMP}" \
  -H "X-Nonce: ${NONCE}" \
  -H "X-Signature: ${SIGNATURE}" \
  -H "Content-Type: application/json" \
  -d '{"ic_number":"901234567890"}'

Use API Key Authentication to compute SIGNATURE from the canonical string.

Node.js

typescript
import crypto from "node:crypto";

const API_KEY = process.env.API_KEY!;
const HMAC_SECRET = process.env.HMAC_SECRET!; // Base64-encoded

const url = "https://api.iimmpact.com/v2/sdk/sessions";
const method = "POST";
const body = {
  ic_number: "901234567890",
};
const bodyJson = JSON.stringify(body);

const timestamp = Math.floor(Date.now() / 1000).toString();
const nonce = crypto.randomUUID().toLowerCase();
const query = ""; // No query string
const bodyHash = crypto.createHash("sha256").update(bodyJson).digest("base64");
const canonical = `v1:${timestamp}:${nonce}:${method}:${query}:${bodyHash}`;

const signatureBase64 = crypto
  .createHmac("sha256", Buffer.from(HMAC_SECRET, "base64"))
  .update(canonical)
  .digest("base64");

const response = await fetch(url, {
  method,
  headers: {
    "X-Api-Key": API_KEY,
    "X-Timestamp": timestamp,
    "X-Nonce": nonce,
    "X-Signature": `v1=${signatureBase64}`,
    "Content-Type": "application/json",
  },
  body: bodyJson,
});

const { session_token, expires_at } = await response.json();
// Pass session_token to the SDK client

Security Notes

  • IC plaintext may exist briefly in Redis for active session processing, then expires automatically.
  • IC is hashed (HMAC-SHA256) before persistence in PostgreSQL.
  • Session token is scoped to a single user's IC and intended for one SDK flow; create a new session for each launch.
  • Keep API key and HMAC secret strictly server-side.

IIMMPACT API Documentation