Appearance
Migration Guide
This guide helps you migrate from the existing /v2/product-list and /v2/subproducts endpoints to the new Dynamic Product Catalog API.
Why Migrate?
| Current Approach | New Approach |
|---|---|
| Hardcoded product flows per product type | Single dynamic form renderer for all products |
| Scattered validation logic | Backend-driven validation rules |
Implicit extras requirements | Explicit fulfillment mapping |
| Multiple endpoints for subproducts | Unified /v2/options endpoint |
| App releases for new products | Backend configuration only |
| No wholesale pricing info | B2B pricing with costs and margins |
| Manual sync for catalog updates | Webhook notifications for real-time sync |
API Versioning & Deprecation
Both the old endpoints (/v2/product-list, /v2/subproducts) and new endpoints (/v2/catalog, /v2/options) are currently supported.
| Endpoint | Status | Deprecation Date | Sunset Date |
|---|---|---|---|
/v2/product-list | Deprecated | TBA | TBA |
/v2/subproducts | Deprecated | TBA | TBA |
/v2/catalog | Active | - | - |
/v2/options | Active | - | - |
Migration Timeline
We recommend migrating to the new Catalog API as soon as possible. Deprecation notices will be announced at least 6 months before the old endpoints are sunset. Subscribe to our changelog for updates.
Endpoint Mapping
| Old Endpoint | New Endpoint | Notes |
|---|---|---|
GET /v2/product-list | GET /v2/catalog | Returns products with field configurations |
GET /v2/subproducts?product_code=JOMPAY | GET /v2/options?product_code=JOMPAY&field_id=biller | JomPAY billers |
GET /v2/subproducts?product_code=HI&account_number=... | GET /v2/options?product_code=HI&field_id=plan&account_number=... | Mobile data plans |
GET /v2/subproducts?product_code=PTPTN&account_number=... | GET /v2/options?product_code=PTPTN&field_id=loan_account&account_number=... | PTPTN accounts |
Response Changes
Product List → Catalog
The biggest structural change. Instead of a flat array of products with implicit field requirements, the Catalog API returns a hierarchical tree for navigation and a products map with explicit field configurations, validation rules, and fulfillment mapping.
Key field changes:
denomination: "5,10,30,50,100"→fields[].data_sourcepointing to/v2/optionsaccount_label+keyboard_type→fields[].type: "text"+input_modewithlabelandvalidationhas_subproduct→fields[].data_source.type: "dynamic"- Implicit extras → Explicit
fulfillmentmapping - No pricing info →
pricingobject with cost model and optional price adjustment
See the Catalog API Reference for the full product schema and complete product examples.
Denomination Mapping
This table shows how old denomination formats map to the new Catalog API:
| Old API Field | Old Value | New Field Type | New Location |
|---|---|---|---|
denomination | "5,10,30,50,100" | select | /v2/options returns available amounts |
denomination | "1-30000" | money | validation.min/max in catalog |
denomination_data_type | Integer | money | input_mode: "numeric" |
denomination_data_type | Decimal | money | input_mode: "decimal" |
has_subproduct: true | — | select | data_source.type: "dynamic" |
Subproducts → Options
All subproduct endpoints migrate to the unified /v2/options endpoint. The key field renames are consistent across all product types:
subproduct_code→codedisplay_name→labelmin/max(string) →min_amount/max_amount(structured Money objects withamount+currency)denomination/face_value(number) →price(structured Money object)links.next→metaobject withcurrent_page,last_page,per_page,total
See the Options API Reference for the full response schema and per-product examples, including the complete field mapping table for migrating developers.
Pricing (New)
The old API provided no wholesale pricing info. The Catalog API includes a pricing object on each product with your cost model and optional price adjustments configured via Dashboard. See the Catalog API Reference for cost models, adjustment types, and calculation examples.
| Model | Use Case | Your Cost Calculation |
|---|---|---|
percentage_discount | Mobile reloads, postpaid | price × percentage_rate |
fixed_discount | Utility bills (TNB, water) | price - abs(fixed_amount) |
For game products, per-item price / cost / rrp values are returned directly in /v2/options responses. See the Options API Reference for details.
B2B Data
The cost and pricing fields are for your backend only. Do not expose wholesale pricing to end users.
What to Change in Your Code
The migration involves four key refactors. The pattern for each is the same: replace product-specific logic with generic, configuration-driven code that reads from the catalog.
1. Payment Request Builder
Replace product-specific switch statements for building /v2/topup requests with a generic function that reads the product's fulfillment mapping. The fulfillment object declares exactly how each field maps to account, amount, and extras — no product-specific branching needed. See the Catalog API Reference for the mapping spec.
2. Form Rendering
Replace per-product form views (e.g., PhoneInputWithAmounts, BillerSearchWithRefs) with a single dynamic form builder that iterates over product.fields and renders inputs based on type (text, number, select, money). Use input_mode for keyboard hints and data_source to know when to call /v2/options.
3. Validation
Replace scattered validation functions with a generic validator that reads field.validation. Pattern validation uses validation.pattern + validation.message. Min/max validation for money/number fields uses validation.min and validation.max.
4. Catalog Sync
Replace periodic polling of /v2/product-list with Catalog Webhooks for real-time push notifications. Webhook events cover products, options, categories, and groups.
| Event Prefix | Trigger | Payload |
|---|---|---|
product.* | Product changes | Single product payload |
option.* | Option changes | Single option payload |
category.* | Category changes | Single category payload |
group.* | Group changes | Single group payload |
During migration, both APIs can run in parallel — try the new catalog first, fall back to the old product-list if needed.
Migration Checklist
- [ ] Update API client to support both
/v2/catalogand/v2/options - [ ] Create generic field components for each
type - [ ] Implement fulfillment mapping builder
- [ ] Migrate validation logic to use field configurations
- [ ] Update caching strategy for catalog using
last_updatedcomparison - [ ] Handle
data_source.depends_onfor dynamic fields - [ ] Implement cost calculation for each pricing model
- [ ] Register webhook for real-time catalog sync
- [ ] Handle resource webhook events (
product.*,option.*,category.*,group.*) - [ ] Test all product types with new endpoints
- [ ] Remove product-specific hardcoded logic
- [ ] Update error handling for new response formats
