Appearance
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/sessionsAuthentication
Use API Key + HMAC headers:
| Header | Required | Description |
|---|---|---|
X-Api-Key | Yes | Your API key |
X-Timestamp | Yes | Unix timestamp in seconds |
X-Nonce | Yes | Unique request nonce (UUID recommended) |
X-Signature | Yes | HMAC 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
| Field | Type | Required | Description |
|---|---|---|---|
ic_number | string | Yes | Malaysian IC number (12 digits, no dashes) |
json
{
"ic_number": "901234567890"
}Response 200
| Field | Type | Description |
|---|---|---|
session_token | string | Session token for SDK/API auth (bp_sess_xxxx) |
expires_at | string | ISO 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-Signaturedoes not verify)
400 Bad Request
Returned when request validation fails.
Validation rules:
ic_numberis requiredic_numbermust 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 clientSecurity 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.
