Skip to content

Dynamic Product Catalog

Preview

This API is active and recommended for new integrations. The schema may evolve before general availability.

Overview

The Dynamic Product Catalog introduces a backend-driven product configuration model. Instead of hardcoding product flows in your application, products are defined as purchase forms where fields, validation, options, and checkout mapping are fully configurable from the backend.

Tenant-Specific Catalog

The catalog returned by /v2/catalog is unique to each tenant. Through the IIMMPACT Dashboard, you can:

  • View your costs — See wholesale pricing for each product
  • Set price adjustments — Configure fixed or percentage adjustments per product
  • Customize your catalog — Create custom groups, categories, and product ordering
  • Enable/disable products — Choose which products to offer your users

This means the API returns your personalized catalog with your pricing and structure.

Prerequisites

Before using the Catalog API, ensure you have:

  1. API Credentials - API Key + HMAC-SHA256 signing from API Key Authentication
  2. Base URL - https://api.iimmpact.com for production
  3. Webhook endpoint (optional) - HTTPS endpoint for real-time catalog sync

Environments

EnvironmentBase URLPurpose
Productionhttps://api.iimmpact.comLive transactions
Staginghttps://staging.iimmpact.comTesting with simulated data

Staging Environment

Use the staging environment to test your integration without processing real transactions. Staging returns realistic responses with test data.

Key Benefits

BenefitDescription
No App UpdatesAdd or modify products without client releases
Unified Field ModelInputs, amounts, and selections are all "fields" with consistent handling
Explicit FulfillmentClear declaration of how fields map to payment requests
Multi-Tenant ReadySame schema serves multiple apps with customizable catalogs

Architecture

┌─────────────────────────────────────────────────────────────────────┐
│                         Your Application                            │
├─────────────────────────────────────────────────────────────────────┤
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────────┐   │
│  │ Catalog      │  │ Options      │  │ Dynamic Form Builder     │   │
│  │ Cache        │  │ Fetcher      │  │ (renders fields)         │   │
│  └──────┬───────┘  └──────┬───────┘  └──────────────┬───────────┘   │
│         │                 │                          │              │
│         └─────────────────┴──────────────────────────┘              │
│                              │                                      │
└──────────────────────────────┼──────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────────┐
│                         IIMMPACT API                                │
├─────────────────────────────────────────────────────────────────────┤
│  GET /v2/catalog              │  GET /v2/options                    │
│  - Returns full product       │  - Returns items for select fields  │
│    catalog with fields        │  - Supports reference & dynamic     │
│  - Cached on device           │  - Paginated for large lists        │
└─────────────────────────────────────────────────────────────────────┘

Endpoints

EndpointPurpose
GET /v2/catalogReturns the complete product catalog with hierarchical structure and field configurations
GET /v2/optionsReturns selectable items for select fields (billers, plans, amounts)
GET /v2/reseller/catalog/webhookGet current webhook configuration (URL, enabled status, secret presence)
POST /v2/reseller/catalog/webhookRegister webhook URL and generate secret
PUT /v2/reseller/catalog/webhookEnable or disable webhook delivery
DELETE /v2/reseller/catalog/webhookRemove webhook configuration and disable delivery
POST /v2/reseller/catalog/webhook/rotateRotate webhook secret

Core Concepts

Everything is a Field

The key insight: inputs, amount selection, and option selection are all fields with consistent structure.

However, where the pricing data comes from depends on the field type:

  • select fields require fetching options from /v2/options (fixed amounts, plans, packages)
  • money fields have min/max validation directly in the catalog response (flexible amounts)
json
{
  "id": "phone",
  "type": "text",
  "input_mode": "tel",
  "label": "Phone Number",
  "placeholder": "e.g. 0123456789",
  "required": true,
  "role": "account",
  "validation": {
    "pattern": "^01[0-9]{8,9}$",
    "message": "Enter valid Malaysian phone number"
  }
}

Field Types

TypeDescriptionCommon input_modeExample
textFree-form text inputtext, tel, numericPhone, NRIC, reference numbers
numberNumeric inputnumericPlayer ID, quantities
selectSelection from listPlans, billers, denominations
moneyCurrency amount with decimalsdecimalFlexible payment amounts

Where Pricing Data Lives

A common question: "Do I need to call the Options API for this product?"

Pricing ModelField TypeWhere Data LivesExample Products
Fixed amountsselectOptions API (/v2/options)Digi Prepaid (RM 5, 10, 30)
Flexible rangemoneyCatalog (validation.min/max)TNB, JomPAY (RM 1 - RM 30,000)
Dynamic plansselectOptions API (with account_number)Hotlink Internet, PTPTN

Decision rule: If the pricing field is type: "select", call /v2/options. If it's type: "money", use validation.min/max from the catalog directly.

Field Roles

Fields have roles that determine how they map to the payment request:

RolePurposeMaps To
accountIdentifies the recipientaccount
pricingDetermines payment amountamount
noneAdditional dataextras.*

Data Sources

Select fields can have different data sources:

TypeWhen to UseCaching
referenceStatic lists (amounts, billers, game packages)Cache locally
dynamicUser-specific (plans, accounts)Fetch after dependencies filled

Pricing Structure

Each product includes pricing information with three fields:

  1. Cost — Your wholesale cost (what IIMMPACT charges you)
  2. Price Adjustment — Reseller-specific fixed/percentage adjustment
  3. Loss Risk Flag — Indicates if current adjustment can produce negative margin
json
{
  "pricing": {
    "cost": {
      "model": "percentage_discount",
      "percentage_rate": 0.98
    },
    "price_adjustment": {
      "type": "fixed",
      "value": 0.50,
      "currency": "MYR"
    },
    "has_loss_risk": false
  }
}

Cost Models

ModelExampleCalculation
percentage_discountCB (2% off)cost = price × rate (e.g. 0.98)
fixed_discountTNB (RM 0.50 off)cost = price - abs(fixed_amount)

Price Adjustment Models (Dashboard Configurable)

TypeExampleCalculation
fixed+0.50user_pays = price + value
percentage0.98user_pays = price × value

Pricing Example

TNB electricity bill payment for RM 100 with cost.fixed_amount=-0.50 and price_adjustment.fixed=+0.50:

Price:                RM 100.00
Your Cost:            RM  99.50  (fixed_discount: -RM 0.50)
Price Adjustment:     RM   0.50  (fixed: +RM 0.50)
────────────────────────────────
User Pays:            RM 100.50
Your Margin:          RM   1.00

B2B Data

Cost and price_adjustment information is for your backend only. Do not expose wholesale pricing to end users.

Fulfillment Mapping

Each product declares how its fields map to the payment request:

json
{
  "fulfillment": {
    "account": { "from_field": "phone" },
    "amount": { "from_field": "plan", "path": "price.amount" },
    "extras": {
      "subproduct_code": { "from_field": "plan", "path": "code" }
    }
  }
}

Quick Start

1. Fetch the Catalog

bash
curl -X GET "https://api.iimmpact.com/v2/catalog" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "X-Timestamp: 1704067200" \
  -H "X-Nonce: req-1704067200-a1b2c3d4e5f6" \
  -H "X-Signature: v1=BASE64_HMAC_SIGNATURE"

2. Render Dynamic Form

For each product, iterate through fields and render appropriate inputs based on type.

3. Fetch Options for Select Fields

When a user interacts with a select field:

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

4. Build Payment Request

Use the product's fulfillment mapping to populate product, account, amount, and extras, then add your own refid for idempotency (see Make Payment).

Complete Flow Examples

Fixed Denominations (e.g., Digi Prepaid)

Products with predefined amounts use select fields that require the Options API:

1. GET /v2/catalog
   → Product "D" has a `select` field with role "pricing"

2. GET /v2/options?product_code=D&field_id=amount
   → Returns [RM 5, RM 10, RM 30, RM 50, RM 100]

3. User selects RM 30

4. POST /v2/topup
   → { product: "D", account: "0123456789", amount: "30.00" }

Flexible Amounts (e.g., TNB, JomPAY)

Products with amount ranges use money fields with validation in the catalog:

1. GET /v2/catalog
   → Product "TNB" has a `money` field with validation: { min: 10, max: 60000 }

2. No Options API call needed for the amount field

3. User enters RM 150.00 (validated against min/max)

4. POST /v2/topup
   → { product: "TNB", account: "123456789012", amount: "150.00" }

Products with user-specific options use select fields with dependencies:

1. GET /v2/catalog
   → Product "HI" has a `select` field with data_source.depends_on: ["phone"]

2. User enters phone number: 0178855286

3. GET /v2/options?product_code=HI&field_id=plan&account_number=0178855286
   → Returns plans available for this specific number

4. User selects "Unlimited Weekly Pass RM12"

5. POST /v2/topup
   → { product: "HI", account: "0178855286", amount: "12.00", extras: { subproduct_code: "..." } }

What's Next

What Backend Can Change (No App Update)

  • Add/remove/reorder groups and categories
  • Add new products using existing field types
  • Modify field labels, placeholders, validation
  • Change denomination options (fixed amounts, min/max)
  • Update biller lists, payment codes
  • Enable/disable products

What Requires App Update

  • New field types (e.g., image_upload, signature)
  • Breaking schema changes

Webhooks

Register a webhook to receive real-time push notifications when the catalog changes — products, options, categories, and groups. Each HTTP request contains one event (product.updated, option.created, etc.) signed with HMAC-SHA256.

FeatureDetail
Events12 event types across products, options, categories, groups
DeliveryOne event per POST request to your HTTPS endpoint
SecurityHMAC-SHA256 signature in X-Webhook-Signature header
RetriesUp to 5 attempts with exponential backoff

See the Catalog Webhooks page for the full event table, payload format, signature verification code, retry policy, and endpoint reference.

Dashboard Configuration

The IIMMPACT Dashboard allows you to customize your catalog before it's served via the API.

Pricing Configuration

SettingDescription
View CostSee your wholesale cost for each product
Price AdjustmentConfigure fixed or percentage price_adjustment values
Per-ProductSet different adjustment rules by product

Catalog Organization

SettingDescription
Custom GroupsCreate your own top-level groups (e.g., "Popular", "Promos")
Custom CategoriesOrganize products into categories within groups
Product OrderingDrag-and-drop to reorder products within categories
Enable/DisableToggle products on or off for your catalog

Product Visibility

SettingDescription
Active ProductsUse is_active=true to return enabled only
Hidden ProductsHidden products are excluded unless include_hidden=true
New ProductsNewly added products are disabled by default

Instant Updates

Changes made in the dashboard are reflected in your /v2/catalog response. If you've registered a webhook, you'll receive per-resource events (for example product.updated).

Need Help?

ResourceLink
Technical Supportsupport@iimmpact.com
API Statushttps://status.iimmpact.com
Dashboardhttps://dashboard.iimmpact.com

IIMMPACT API Documentation