Skip to content

Step 5: Make Payment

This is the central step in your integration — processing transactions via a single unified endpoint (POST /v2/topup) that handles all product types, including JomPAY, mobile recharge, gift cards, vouchers, eSIM purchases, and more.

API Reference

For the full endpoint specification (headers, request body, response schema, and examples), see Make Payment API Reference.

How It Works

  1. Initiate payment — Call POST /v2/topup with a unique refid, the product code, account number, and amount.
  2. Handle the response — Check the HTTP status code first, then data.status:
    • HTTP 400 + Failed — Validation error (invalid amount, insufficient balance, etc.). No transaction was created. Fix the input and retry with the same refid.
    • HTTP 200 + Accepted — Transaction accepted, processing will begin.
    • HTTP 200 + Processing — Transaction still in progress. Re-query with the same refid and parameters.
    • HTTP 200 + Succesful — Transaction completed. Display the result to the user.
    • HTTP 200 + Failed — Transaction was created but failed at the provider. Use a new refid for the next attempt.
  3. Check final status — If the response was Processing or you encountered a network error, re-call the same endpoint with the identical refid and parameters.

Spelling Note

The success status value is spelled Succesful (single 's'), not Successful. This is a legacy quirk that cannot be changed. Match this exact string in your code.

StageHTTPStatusTransaction Created?Retry?
Validation fails (invalid amount, account, denomination, insufficient balance, etc.)400FailedNoYes — same refid, fix input
Request accepted, pending processing200AcceptedYesRe-query same refid
Still processing200ProcessingYesRe-query same refid
Transaction completed200SuccesfulYesNo
Transaction failed at provider (via re-query/callback)200FailedYesNo — use new refid
Transaction voided200RefundYesNo

Retries and refid Reuse

The API is idempotent: calling POST /v2/topup with the same refid will return the existing transaction, never create a duplicate. Always reuse the original refid and parameters when retrying — generating a new refid on retry will create a duplicate charge. Only generate a new refid for a genuinely new transaction.

When to reuse the same refid vs. generate a new one:

  • HTTP 400 + Failed — No transaction was created, refid not consumed. Fix the input and retry with the same refid.
  • HTTP 200 + Processing / network error — Transaction may be in progress. Re-query with the same refid.
  • HTTP 200 + Failed — Transaction was created and failed at the provider level. This is final — use a new refid.

Recommended Polling Strategy

When a transaction returns Processing, poll every 5-10 seconds by re-querying with the same refid. Most transactions resolve within 30 seconds. Always combine polling with callbacks — polling provides immediate UX feedback, while callbacks are the reliable final status delivery mechanism.

Extras Parameters by Product

The extras object in the request body has different requirements depending on the product:

ParameterJomPAYPTPTNMobile DataOthers
subproduct_code-MandatoryMandatory-
ic_numberMandatory (payee IC)Mandatory (recipient IC)--
biller_codeMandatory---
ref2Conditional---

ref2 is required by some JomPAY billers. The ref2 value is typically printed on the user's JomPAY bill. Use bill presentment to validate. The API returns an error if ref2 is required but not provided.

AMLA Compliance — JomPAY

DANGER

Due to AMLA (Anti-Money Laundering Act 2001) requirements, it is mandatory to perform eKYC on your end-users for all JomPAY transactions. Pass the verified IC number (Malaysians) or Passport number (non-Malaysians) via the ic_number field. Failure to comply, or providing fictitious/invalid numbers, may lead to account suspension.

Success UX

After a successful transaction, display the following fields to the user:

FieldDescription
snSerial number or identifier generated by the provider/operator. Include a Copy button.
pinPIN for vouchers, gift cards, and similar products. Include a Copy button.
voucherlinkA URL to open in a web view for voucher redemption.
Share buttonAllow the user to share the transaction via WhatsApp, email, SMS, etc.

DANGER

If a field (sn, pin, expiry, voucherlink) is not returned by the API, do not display that label or field to the user.

Successful transaction screen showing PIN and Serial Number fields

Failure UX

After a failed transaction, display the failure reason so the user understands what went wrong:

FieldDescription
remarksThe failure reason returned by the API.

Failed transaction screen showing remarks field with failure reason

Error Handling

Error codes for failed transactions can be found in the Payment Errors reference.

WARNING

Staging server statuses and failure reasons might not match production due to limited validation.

IIMMPACT API Documentation