Skip to content

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.

FieldTypeRequiredDescription
X-Api-KeystringYesYour API key; keep it on your backend.
X-TimestampstringYesCurrent Unix time in seconds; within five minutes of server time.
X-NoncestringYesFresh identifier for every request, including retries.
X-SignaturestringYesv1= 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 ​

FieldTypeRequiredDescription
order_idstringYesOrder 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.

Order detail includes one item per purchased unit, using the same result fields as order webhook data. No separate per-unit detail request is needed. A webhook is a snapshot at its event time; a fresh GET can show later order or refund progress.

FieldTypeDescription
order_idstringOrder identifier.
external_referencestringYour order reference.
statusstringpayment_pending, payment_processing, transaction_processing, completed, or expired.
currencystringMYR.
items_subtotalstringFrozen item sale subtotal.
itemsarrayOne row per unit purchased; see item fields below.
refundsarrayRefund summaries for this order. Each entry contains payment_id, status, and the total amount for that payment and status; empty when none exist.
metadataobject or nullnull unless supplied on order creation.
created_atstringUTC order creation time.
updated_atstringUTC time of the latest public change, including fulfillment/refund changes.
expires_atstringUTC cutoff for admitting new payments, 24 hours after order creation. Existing attempts, settlement, fulfillment, and refunds continue afterward.

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.

A successful or failed unit does not change afterward. Order results omit unit_price; this does not change the frozen sale subtotal, payment total or refund amounts.

FieldTypeDescription
productstringProduct code.
product_namestringProduct display name.
accountstringRecipient's account number or identifier; may be "" for an account-optional product.
amountstringRequested topup face value for this unit.
statusstringawaiting_payment, accepted, processing, successful, or failed.
refidstring or nullFulfillment reference; null until dispatch.
status_codeintegerTransaction result code, such as 20 for success; present after dispatch.
snstringSerial number, when the product returns one.
pinstringRedemption PIN, when the product returns one.
expirystringProvider expiry text, when the product returns one; not necessarily RFC3339.
coststringRecorded wholesale cost, when available. Preserves up to four decimal places; never substitute the requested face value or sale price.
remarksstringResult text, when the provider returns it.
notestringInstructions, when the product returns them.
voucherlinkstringRedemption URL, when the product returns one.
timestampstringUTC time this unit's recorded state/result last changed. Not the supplier's transaction-entry time. Reads and retries do not advance it.

Unavailable result strings normally use "". Where a definitive rejection has no downstream transaction, downstream details may be null. An unknown result code or cost is not reported as zero. Hosted checkout responses omit serial numbers, PINs, voucher links and wholesale cost.

Order detail has no payer identity, payment fees, or redirect destination. Authorize customer access before exposing it.

Response example — 200 ​

json
{
  "data": {
    "order_id": "ord_example",
    "external_reference": "ORD-00042",
    "status": "completed",
    "currency": "MYR",
    "items_subtotal": "100.00",
    "items": [
      {
        "product": "TNB",
        "product_name": "Tenaga Nasional Berhad",
        "account": "220012345679",
        "amount": "60.00",
        "status": "successful",
        "status_code": 20,
        "refid": "ORD-00042-1",
        "cost": "58.1234",
        "timestamp": "2026-09-14T02:10:43.000Z"
      },
      {
        "product": "TNB",
        "product_name": "Tenaga Nasional Berhad",
        "account": "220012345678",
        "amount": "40.00",
        "status": "failed",
        "status_code": 52,
        "refid": "ORD-00042-2",
        "cost": "39.1250",
        "remarks": "Invalid Account No",
        "timestamp": "2026-09-14T02:10:44.000Z"
      }
    ],
    "refunds": [
      {
        "payment_id": "pay_example",
        "amount": "40.00",
        "status": "successful"
      }
    ],
    "metadata": null,
    "created_at": "2026-09-14T02:00:00.000Z",
    "updated_at": "2026-09-14T02:18:00.000Z",
    "expires_at": "2026-09-15T02:00:00.000Z"
  }
}

Errors ​

HTTPCodeAction
404order_not_foundCheck the order ID; foreign orders also return 404.

See shared errors.

Order states ​

StatusMeaning
payment_pendingUnpaid and awaiting payment before the order's expires_at cutoff.
payment_processingCollection or cancellation is unresolved.
transaction_processingWinning collection verified; fulfillment is in progress.
completedAll units have final results, including any failures. Refunds may still be pending.
expiredNew-payment cutoff passed with no winner or unresolved attempt. Continue reconciliation of known late verified collections.

Get payment detail ​

http
GET https://api.iimmpact.com/v2/payments/{payment_id}

Path fields ​

FieldTypeRequiredDescription
payment_idstringYesPayment 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",
    "transaction_refids": [],
    "status": "processing",
    "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",
      "method": "GET"
    },
    "created_at": "2026-09-14T02:05:00.000Z",
    "updated_at": "2026-09-14T02:05:00.000Z",
    "expires_at": "2026-09-14T02:35:00.000Z"
  }
}

For a failed payment, action is omitted and a failure object appears inside data (excerpt):

json
{
  "status": "failed",
  "failure": {
    "code": "AUTHENTICATION_FAILED"
  },
  "updated_at": "2026-09-14T02:06:00.000Z"
}

Errors ​

HTTPCodeAction
404payment_not_foundCheck the payment ID; foreign payments also return 404.

See shared errors.

Payment failure codes ​

failure.code preserves the provider or system code. Examples include:

CodeMeaning
AUTHENTICATION_FAILEDCustomer authentication failed.
provider_validation_errorThe provider rejected the submitted details.
TIMEOUT_ERROR, PARTNER_TIMEOUT_ERRORProvider-reported timeout on a confirmed failed payment request.
SERVER_ERROR, ISSUER_UNAVAILABLE, CHANNEL_UNAVAILABLEProvider-reported service or channel failure on a confirmed failed payment request.
payment_expiredThe payment was finalized as expired.
payment_preparation_interruptedPayment preparation was finalized without submitting a collection.

This is not an exhaustive provider-code list. Use the payment's status to decide whether an attempt is final, not a code alone. An HTTP timeout, malformed response or uncertain outcome does not prove failure. Once confirmed failed, the attempt stops status reconciliation; an eligible replacement requires a new key and payment ID on the same order.

Fulfillment is separate: an accepted or processing unit keeps its existing reference while being checked. A confirmed successful or failed unit stops requerying. Retry exhaustion does not manufacture a failed unit or refund.

List orders ​

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

Query fields ​

FieldTypeRequiredDescription
external_referencestringNoExact order reference.
statusstringNoOne order state.
created_fromstringNoInclusive RFC3339 start.
created_tostringNoExclusive RFC3339 end, later than start.
limitintegerNo1–100; defaults to 20.
cursorstringNoOpaque token; send data.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. A cursor is bound to the request's filters: keep them unchanged when paging, though limit may differ. 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 ​

FieldTypeDescription
data.itemsarrayOrder summaries; empty when none match. This list does not contain per-unit fulfillment results.
items[].order_idstringOrder identifier.
items[].external_referencestringYour order reference.
items[].statusstringCurrent order state.
items[].items_subtotalstringFrozen item sale subtotal.
items[].created_atstringRFC3339 creation time.
items[].updated_atstringRFC3339 latest public order change.
data.next_cursorstring or nullNext page cursor; null on the final page.

Response example — 200 ​

json
{
  "data": {
    "items": [
      {
        "order_id": "ord_example",
        "external_reference": "ORD-00042",
        "status": "completed",
        "items_subtotal": "100.00",
        "created_at": "2026-09-14T02:00:00.000Z",
        "updated_at": "2026-09-14T02:18:00.000Z"
      }
    ],
    "next_cursor": null
  }
}

Errors ​

HTTPCodeAction
400validation_errorCorrect filters or date bounds; see validation details.
400invalid_cursorThe cursor does not match these filters; restart pagination without it.

See shared errors. Retry reads with bounded backoff and fresh HMAC headers; routine polling is not required.

Pine Labs API Documentation