Appearance
Step 5: Track Results
Use webhooks for updates and these reads for browser returns, missing notifications, or on-demand checks.
Request headers
All three GET endpoints use these headers. Sign an empty body.
| Field | Type | Required | Description |
|---|---|---|---|
X-Api-Key | string | Yes | Your API key; keep it on your backend. |
X-Timestamp | string | Yes | Current Unix time in seconds; within five minutes of server time. |
X-Nonce | string | Yes | Fresh identifier for every request, including retries. |
X-Signature | string | Yes | v1= followed by the request's HMAC signature. |
Follow API Key Authentication. Sign the exact body, or an empty body for bodyless requests, and the sorted query when present.
Get order detail
http
GET https://api.iimmpact.com/v2/orders/{order_id}Path fields
| Field | Type | Required | Description |
|---|---|---|---|
order_id | string | Yes | Order ID from creation. No query fields. |
Request example
bash
curl "https://api.iimmpact.com/v2/orders/$ORDER_ID" \
--header "X-Api-Key: $API_KEY" \
--header "X-Timestamp: $TIMESTAMP" \
--header "X-Nonce: $NONCE" \
--header "X-Signature: v1=$SIGNATURE"Response fields
Fields below are inside data.
| Field | Type | Description |
|---|---|---|
order_id | string | Order identifier. |
external_reference | string | Your order reference. |
status | string | payment_pending, payment_processing, transaction_processing, or completed. |
currency | string | MYR. |
items_subtotal | string | Frozen item sale subtotal. |
items | array | One row per unit purchased; see item fields below. |
latest_payment_id | string or null | Payment ID of the most recent collection attempt; null when no payment has been created. Use it to resolve a 409 conflict or read the current payment without a stored ID. |
refunds | array | Order-level refunds; empty when none exist. |
metadata | object | Returned when supplied on order creation; omitted otherwise. |
created_at | string | RFC3339 order creation time. |
updated_at | string | RFC3339 time of the latest public change, including fulfillment/refund changes. |
Item fields
Each item is one unit of a purchased product. An order with quantity: 3 produces three rows. Rows exist from order creation; fulfillment fields appear once dispatch starts.
| Field | Type | Description |
|---|---|---|
product | string | Product code. |
product_name | string | Product display name. |
account | string | Recipient's account number or identifier. |
amount | string | Requested topup face value for this unit. |
unit_price | string | Two-place sale price; may differ from face value. |
status | string | awaiting_payment, accepted, processing, successful, or failed. |
refid | string or null | Fulfillment reference; null until dispatch. |
status_code | integer | Transaction result code, such as 20 for success; present after dispatch. |
sn | string | Serial number, when the product returns one. |
pin | string | Redemption PIN, when the product returns one. |
expiry | string | Provider expiry text, when the product returns one; not necessarily RFC3339. |
cost | string | Merchant-only wholesale cost with original decimal precision, after dispatch. |
remarks | string | Result text, when the provider returns it. |
note | string | Instructions, when the product returns them. |
voucherlink | string | Redemption URL, when the product returns one. |
timestamp | string | RFC3339 fulfillment-entry time, after dispatch. |
Order detail has no payer identity, payment fees, or redirect destination. Authorize customer access, exclude wholesale cost from customer responses, and redact PINs and voucher links from logs.
Response example — 200
json
{
"data": {
"order_id": "ord_example",
"external_reference": "ORD-00042",
"status": "completed",
"currency": "MYR",
"items_subtotal": "100.00",
"latest_payment_id": "pay_example",
"items": [
{
"product": "TNB",
"product_name": "Tenaga Nasional Berhad",
"account": "220012345679",
"amount": "60.00",
"unit_price": "60.00",
"status": "successful",
"status_code": 20,
"refid": "ORD-00042-1",
"cost": "58.1234",
"timestamp": "2026-09-14T10:10:43+08:00"
},
{
"product": "TNB",
"product_name": "Tenaga Nasional Berhad",
"account": "220012345678",
"amount": "40.00",
"unit_price": "40.00",
"status": "failed",
"status_code": 52,
"refid": "ORD-00042-2",
"cost": "39.1250",
"remarks": "Invalid Account No",
"timestamp": "2026-09-14T10:10:44+08:00"
}
],
"refunds": [
{
"refund_id": "ref_example",
"order_id": "ord_example",
"payment_id": "pay_example",
"external_reference": "ORD-00042",
"currency": "MYR",
"amount": "40.00",
"reason": "failed_fulfillment",
"status": "successful",
"review_reason": null,
"created_at": "2026-09-14T10:15:20+08:00",
"updated_at": "2026-09-14T10:18:00+08:00"
}
],
"created_at": "2026-09-14T10:00:00+08:00",
"updated_at": "2026-09-14T10:18:00+08:00"
}
}Order states
| Status | Meaning |
|---|---|
payment_pending | Unpaid and awaiting payment; no order-age cutoff. |
payment_processing | Collection or cancellation is unresolved. |
transaction_processing | Winning collection verified; fulfillment is in progress. |
completed | All units have final results, including any failures. Refunds may still be pending. |
Get payment detail
http
GET https://api.iimmpact.com/v2/payments/{payment_id}Path fields
| Field | Type | Required | Description |
|---|---|---|---|
payment_id | string | Yes | Payment ID retained from creation, browser return, or events. No query fields. |
Request example
bash
curl "https://api.iimmpact.com/v2/payments/$PAYMENT_ID" \
--header "X-Api-Key: $API_KEY" \
--header "X-Timestamp: $TIMESTAMP" \
--header "X-Nonce: $NONCE" \
--header "X-Signature: v1=$SIGNATURE"Response fields
Returns the payment schema inside data, with current status and action. Refunds are read from the order. A failed payment still returns HTTP 200.
Response example — 200
json
{
"data": {
"payment_id": "pay_example",
"order_id": "ord_example",
"external_reference": "ORD-00042",
"customer_external_id": "CUS-1042",
"status": "pending",
"currency": "MYR",
"payment_method_code": "CARD",
"customer_fee_percent": "50.00",
"fee": {
"type": "percentage",
"value": "1.70"
},
"totals": {
"items_subtotal": "100.00",
"fee": {
"total": "1.70",
"customer": "0.85",
"merchant": "0.85"
},
"payment_total": "100.85"
},
"action": {
"type": "redirect",
"url": "https://payments.example/checkout/session"
},
"created_at": "2026-09-14T10:05:00+08:00",
"updated_at": "2026-09-14T10:05:00+08:00"
}
}For a failed payment, action is null and the following fields change or appear inside data (excerpt):
json
{
"status": "failed",
"action": null,
"failure": {
"code": "collection_failed",
"message": "Payment collection failed."
},
"updated_at": "2026-09-14T10:06:00+08:00"
}List orders
http
GET https://api.iimmpact.com/v2/ordersQuery fields
| Field | Type | Required | Description |
|---|---|---|---|
external_reference | string | No | Exact order reference. |
status | string | No | One order state. |
created_from | string | No | Inclusive RFC3339 start. |
created_to | string | No | Exclusive RFC3339 end, later than start. |
limit | integer | No | 1–100; defaults to 20. |
cursor | string | No | Use next_cursor from the previous response to get the next page. |
Date ranges are at most 90 days; one bound implies a 90-day range. With neither bound, all dates are eligible. Results are newest first by creation time then order ID. Keep filters and limit unchanged when paging; percent-encode values, including + in timezone offsets.
Unfiltered history includes all orders in your account. Keep customer-to-order ownership in your backend and authorize customer-facing reads; the payer on a payment does not establish order ownership.
Request example
bash
curl 'https://api.iimmpact.com/v2/orders?external_reference=ORD-00042&limit=20' \
--header "X-Api-Key: $API_KEY" \
--header "X-Timestamp: $TIMESTAMP" \
--header "X-Nonce: $NONCE" \
--header "X-Signature: v1=$SIGNATURE"Response fields
| Field | Type | Description |
|---|---|---|
data.orders | array | Order summaries; empty when none match. |
orders[].order_id | string | Order identifier. |
orders[].external_reference | string | Your order reference. |
orders[].status | string | Current order state. |
orders[].currency | string | MYR. |
orders[].items_subtotal | string | Frozen item sale subtotal. |
orders[].successful_payment_total | string or null | Winning collection total; null until paid, unchanged by refunds. |
orders[].created_at | string | RFC3339 creation time. |
orders[].updated_at | string | RFC3339 latest public order change. |
data.next_cursor | string or null | Next page cursor; null on the final page. |
Response example — 200
json
{
"data": {
"orders": [
{
"order_id": "ord_example",
"external_reference": "ORD-00042",
"status": "completed",
"currency": "MYR",
"items_subtotal": "100.00",
"successful_payment_total": "100.85",
"created_at": "2026-09-14T10:00:00+08:00",
"updated_at": "2026-09-14T10:18:00+08:00"
}
],
"next_cursor": null
}
}Read errors
| HTTP | Code | Action |
|---|---|---|
| 400 | invalid_cursor | Restart pagination with valid filters. |
| 404 | order_not_found, payment_not_found | Check the resource ID; foreign resources also return 404. |
| 422 | validation_error | Correct IDs, filters, or date bounds. |
See shared errors. Retry reads with bounded backoff and fresh HMAC headers; routine polling is not required.
