Skip to content

Options API

The Options API returns selectable items for select fields. This is a unified endpoint that replaces the legacy Sub Products endpoint, providing consistent structure for all product types.

Migrating from /v2/subproducts?

See the Migration Guide for endpoint mapping and a migration checklist. Key field changes:

Old field (/v2/subproducts)New field (/v2/options)Notes
subproduct_codecodeRenamed
display_namelabelRenamed
min / max (string)min_amount / max_amount (Money object)Structured with amount + currency
denomination / face_value (number)price (Money object)Structured with amount + currency
links.next (URL path)meta object with current_page, last_page, per_page, totalRicher pagination

Endpoint

http
GET https://api.iimmpact.com/v2/options

Request Headers

HeaderDescriptionRequired
X-Api-KeyYour API keyYes
X-TimestampCurrent Unix timestamp in secondsYes
X-NonceUnique nonce for replay protectionYes
X-SignatureHMAC signature in format v1=<base64>Yes

See API Key Authentication for canonical-string rules and signature generation.

Query Parameters

ParameterTypeRequiredDescription
product_codestringYesProduct code (e.g., D, HI, JOMPAY)
field_idstringYesField identifier from catalog (e.g., amount, plan, biller)
account_numberstringConditionalRequired by many dynamic fields (phone number, NRIC, etc.)
biller_codestringNoFilter by specific biller code (JomPAY only)
limitnumberNoItems per page (default: 100, max: 1000)
per_pagenumberNoAlias for limit
pagenumberNoPage number for pagination (default: 1)
is_activebooleanNoFilter active status (applies to static options)
include_hiddenbooleanNoInclude hidden products when resolving options
include_inactivebooleanNoInclude inactive products when resolving options

Example Request with Pagination

bash
curl -X GET "https://api.iimmpact.com/v2/options?product_code=JOMPAY&field_id=biller&limit=50&page=2" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "X-Timestamp: 1704067200" \
  -H "X-Nonce: req-1704067200-a1b2c3d4e5f6" \
  -H "X-Signature: v1=BASE64_HMAC_SIGNATURE"

Response Structure

json
{
  "product_code": "HI",
  "field_id": "plan",
  "items": [
    {
      "code": "HI_UNL_30_3M",
      "label": "Unlimited 30 Days (3Mbps)",
      "description": "Unlimited data with hotspot and calls",
      "price": { "amount": "40.00", "currency": "MYR" }
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 1,
    "per_page": 100,
    "total": 5
  }
}
FieldTypeDescription
product_codestringEchoed product code
field_idstringEchoed field identifier
itemsarrayList of selectable items
metaobjectPagination metadata

Item Schema

Items follow a consistent structure with optional fields based on product type:

json
{
  "code": "string",
  "label": "string",
  "description": "string",

  "price": { "amount": "23.00", "currency": "MYR" },
  "cost": { "amount": "19.50", "currency": "MYR" },
  "rrp": { "amount": "25.00", "currency": "MYR" },

  "account_number": "12345678",

  "min_amount": { "amount": "1.00", "currency": "MYR" },
  "max_amount": { "amount": "30000.00", "currency": "MYR" }
}
FieldTypeDescriptionUsed By
codestringStable identifier for fulfillmentAll products
labelstringDisplay textAll products
descriptionstringAdditional detailsOptional
priceobjectEffective selling price after reseller adjustmentsAll priced options
costobjectYour wholesale costAll priced options
rrpobjectRecommended retail priceAll priced options
account_numberstringMaps to account fieldPTPTN accounts
min_amountobjectMinimum payment amountJomPAY billers
max_amountobjectMaximum payment amountJomPAY billers

Pricing Fields

The API returns three pricing fields to support flexible pricing strategies:

  • cost — Your wholesale cost (what you pay us)
  • rrp — Recommended retail price (our suggested selling price)
  • price — Effective selling price after reseller adjustment rules are applied

B2B Data

The cost field is for your backend only. Do not expose this to end users.


Product-Specific Examples

Digi Prepaid — Fixed Amounts

Static denomination list with pricing.

Request:

bash
curl -X GET "https://api.iimmpact.com/v2/options?product_code=D&field_id=amount" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "X-Timestamp: 1704067200" \
  -H "X-Nonce: req-1704067200-a1b2c3d4e5f6" \
  -H "X-Signature: v1=BASE64_HMAC_SIGNATURE"

Response:

json
{
  "product_code": "D",
  "field_id": "amount",
  "items": [
    {
      "code": "5",
      "label": "RM 5",
      "price": { "amount": "5.00", "currency": "MYR" }
    },
    {
      "code": "10",
      "label": "RM 10",
      "price": { "amount": "10.00", "currency": "MYR" }
    },
    {
      "code": "30",
      "label": "RM 30",
      "price": { "amount": "30.00", "currency": "MYR" }
    },
    {
      "code": "50",
      "label": "RM 50",
      "price": { "amount": "50.00", "currency": "MYR" }
    },
    {
      "code": "100",
      "label": "RM 100",
      "price": { "amount": "100.00", "currency": "MYR" }
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 1,
    "per_page": 100,
    "total": 5
  }
}

Plans tailored to the specific phone number.

Request:

bash
curl -X GET "https://api.iimmpact.com/v2/options?product_code=HI&field_id=plan&account_number=0178855286" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "X-Timestamp: 1704067200" \
  -H "X-Nonce: req-1704067200-a1b2c3d4e5f6" \
  -H "X-Signature: v1=BASE64_HMAC_SIGNATURE"

Response:

json
{
  "product_code": "HI",
  "field_id": "plan",
  "items": [
    {
      "code": "Everything Unlimited with Unlimited Weekly Pass RM12",
      "label": "Unlimited Weekly Pass",
      "description": "Everything Unlimited with Unlimited Weekly Pass RM12",
      "price": { "amount": "12.00", "currency": "MYR" }
    },
    {
      "code": "Unlimited data with hotspot and calls 30-days (3Mbps) H",
      "label": "Unlimited 30 Days (3Mbps)",
      "description": "Unlimited data with hotspot and calls",
      "price": { "amount": "40.00", "currency": "MYR" }
    },
    {
      "code": "Unlimited data with hotspot and calls 30-days (6Mbps) H",
      "label": "Unlimited 30 Days (6Mbps)",
      "description": "Unlimited data with hotspot and calls",
      "price": { "amount": "50.00", "currency": "MYR" }
    },
    {
      "code": "Unlimited RM55 12Mbps with 5G (100GB) 30D",
      "label": "Unlimited 5G (12Mbps)",
      "description": "100GB 5G data included",
      "price": { "amount": "55.00", "currency": "MYR" }
    },
    {
      "code": "Unlimited data with hotspot and calls 30-days (18Mbps) H",
      "label": "Unlimited 30 Days (18Mbps)",
      "description": "Unlimited data with hotspot and calls",
      "price": { "amount": "60.00", "currency": "MYR" }
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 1,
    "per_page": 100,
    "total": 5
  }
}

Dynamic Plans

Plans are uniquely tailored to individual phone numbers based on user eligibility. Always pass the account_number parameter for dynamic fields.


PTPTN — Loan Accounts

Returns accounts linked to the NRIC, with account numbers for payment.

Request:

bash
curl -X GET "https://api.iimmpact.com/v2/options?product_code=PTPTN&field_id=loan_account&account_number=941123045001" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "X-Timestamp: 1704067200" \
  -H "X-Nonce: req-1704067200-a1b2c3d4e5f6" \
  -H "X-Signature: v1=BASE64_HMAC_SIGNATURE"

Response:

json
{
  "product_code": "PTPTN",
  "field_id": "loan_account",
  "items": [
    {
      "code": "S",
      "label": "KELVIN LEE WEI SERN",
      "description": "SSPN Prime",
      "account_number": "009411230450014"
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 1,
    "per_page": 100,
    "total": 1
  }
}

Account Number Mapping

For PTPTN, the account_number in the item response is used as the account field in the payment request, not the NRIC.


JomPAY — Biller List

Large reference list (21,000+ billers) with dynamic validation limits.

Request (paginated):

bash
curl -X GET "https://api.iimmpact.com/v2/options?product_code=JOMPAY&field_id=biller&limit=3" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "X-Timestamp: 1704067200" \
  -H "X-Nonce: req-1704067200-a1b2c3d4e5f6" \
  -H "X-Signature: v1=BASE64_HMAC_SIGNATURE"

Response:

json
{
  "product_code": "JOMPAY",
  "field_id": "biller",
  "items": [
    {
      "code": "818625",
      "label": "TADIKA DIDIKAN SOLEH PLT.",
      "min_amount": { "amount": "1.00", "currency": "MYR" },
      "max_amount": { "amount": "30000.00", "currency": "MYR" }
    },
    {
      "code": "779264",
      "label": "RIM PRO AUTOMOTIVE.",
      "min_amount": { "amount": "1.00", "currency": "MYR" },
      "max_amount": { "amount": "30000.00", "currency": "MYR" }
    },
    {
      "code": "249722",
      "label": "ALANG MILA ENTERPRISE",
      "min_amount": { "amount": "1.00", "currency": "MYR" },
      "max_amount": { "amount": "30000.00", "currency": "MYR" }
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 7096,
    "per_page": 3,
    "total": 21287
  }
}

Filter by Biller Code:

bash
curl -X GET "https://api.iimmpact.com/v2/options?product_code=JOMPAY&field_id=biller&biller_code=818625" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "X-Timestamp: 1704067200" \
  -H "X-Nonce: req-1704067200-a1b2c3d4e5f6" \
  -H "X-Signature: v1=BASE64_HMAC_SIGNATURE"
json
{
  "product_code": "JOMPAY",
  "field_id": "biller",
  "items": [
    {
      "code": "818625",
      "label": "TADIKA DIDIKAN SOLEH PLT.",
      "min_amount": { "amount": "1.00", "currency": "MYR" },
      "max_amount": { "amount": "30000.00", "currency": "MYR" }
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 1,
    "per_page": 100,
    "total": 1
  }
}

Dynamic Validation for JomPAY

When user selects a biller, use that biller's min_amount and max_amount to validate the payment amount field. These override the static min/max values in the catalog, which serve as fallbacks before a biller is selected.

Caching Recommendation

For large lists like JomPAY billers, we recommend caching the full list in your database and refreshing periodically (e.g., daily). This provides faster lookups and reduces API calls.


PUBG Mobile — Game Packages

Game packages with all three pricing fields.

Request:

bash
curl -X GET "https://api.iimmpact.com/v2/options?product_code=PUBG&field_id=package" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "X-Timestamp: 1704067200" \
  -H "X-Nonce: req-1704067200-a1b2c3d4e5f6" \
  -H "X-Signature: v1=BASE64_HMAC_SIGNATURE"

Response:

json
{
  "product_code": "PUBG",
  "field_id": "package",
  "items": [
    {
      "code": "60",
      "label": "60 UC",
      "price": { "amount": "5.00", "currency": "MYR" },
      "cost": { "amount": "4.50", "currency": "MYR" },
      "rrp": { "amount": "5.50", "currency": "MYR" }
    },
    {
      "code": "325",
      "label": "325 UC",
      "price": { "amount": "23.00", "currency": "MYR" },
      "cost": { "amount": "19.50", "currency": "MYR" },
      "rrp": { "amount": "25.00", "currency": "MYR" }
    },
    {
      "code": "660",
      "label": "660 UC",
      "price": { "amount": "50.00", "currency": "MYR" },
      "cost": { "amount": "42.00", "currency": "MYR" },
      "rrp": { "amount": "55.00", "currency": "MYR" }
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 1,
    "per_page": 100,
    "total": 3
  }
}

Pagination

For large lists (like JomPAY billers with 21,000+ items), use page-based pagination:

javascript
async function fetchAllBillers() {
  const billers = [];
  let page = 1;
  let lastPage = 1;

  do {
    const params = new URLSearchParams({
      product_code: "JOMPAY",
      field_id: "biller",
      limit: "100",
      page: String(page),
    });

    // Generate fresh auth headers for each request
    // (timestamp, nonce, and signature must be unique per request)
    const headers = generateHmacHeaders("GET", params.toString());

    const response = await fetch(
      `https://api.iimmpact.com/v2/options?${params}`,
      { headers },
    );

    const data = await response.json();
    billers.push(...data.items);
    lastPage = data.meta.last_page;
    page++;
  } while (page <= lastPage);

  return billers;
}

Caching Strategy

Data TypeRecommendation
referenceCache in database, refresh daily
dynamicCache per input value, short TTL (5-10 mins)

For large reference lists like JomPAY billers:

  1. Initial sync: Fetch all pages and store in your database
  2. Daily refresh: Re-sync the full list overnight
  3. Lookup: Query your local database for fast biller search

For dynamic options (mobile plans, PTPTN accounts):

  1. Cache per account: Store results keyed by product_code:account_number
  2. Short TTL: Refresh every 5-10 minutes as plans may change

Error Responses

Validation and not-found responses typically use this envelope:

json
{
  "message": "The given data was invalid.",
  "errors": {
    "field_name": ["Validation message"]
  }
}

400 Bad Request

Missing required parameters:

json
{
  "message": "The given data was invalid.",
  "errors": {
    "product_code": ["The product_code field is required."],
    "field_id": ["The field_id field is required."]
  }
}

400 Bad Request — Missing Account Number

Dynamic field requires account number:

json
{
  "message": "The given data was invalid.",
  "errors": {
    "account_number": [
      "This field depends on phone and requires account_number parameter."
    ]
  }
}

404 Not Found

Invalid product or field:

json
{
  "message": "Options not found for INVALID/amount",
  "errors": {}
}

IIMMPACT API Documentation