Antom Payment Gateway
Use this skill for Antom (Ant International) merchant payment integration work in Malaysia.
Source
Read references/antom-api.md first. It holds environments, domains, headers, the signature method, idempotency, amount rules, the full endpoint catalogue, and the index of the other reference files.
Read references/antom-checkout.md for pay, createPaymentSession, and consult field tables and the integration modes (Checkout Page, Element, API-only).
Read references/antom-payment-ops.md for inquiryPayment, capture, cancel, refund, and inquiryRefund fields and rules.
Read references/antom-notifications.md for notifyPayment, notifyCapture, notifyRefund fields, verification, the acknowledgement body, and retries.
Read references/antom-errors.md for result and error codes per API, and references/antom-codes.md for payment method enums, FPX bank codes, card brands, statuses, and Malaysian method limits.
Read references/account-setup.md for onboarding, keys, sandbox, go-live, settlement, and pricing location. Read references/source-map.md to pick the right official page.
Core Workflow
- Identify environment: sandbox (client ID starts with
SANDBOX_, path/ams/sandbox/api/...) or live (/ams/api/...). - Identify integration mode: hosted Checkout Page, embedded Checkout Page, Payment Element, or API-only (
paywith apaymentMethodType). - Confirm Dashboard setup: client ID, gateway domain, merchant key pair, Antom public key, notification URL, enabled payment methods, settlement currency.
- Create a local pending order with your own
paymentRequestIdbefore calling Antom. - Sign every request with your private key (RSA256) and verify every response signature with the Antom public key.
- Call
createPaymentSession(Checkout Page or Element) orpay(API-only) server-side. Redirect tonormalUrl/applinkUrl/schemeUrl, or passpaymentSessionDatato the client SDK. - Treat
paymentRedirectUrlas display only. Never mark paid from a browser return. - Verify the
notifyPaymentsignature over the raw body, then reply with the fixed SUCCESS acknowledgement. - Settle idempotently after checking
paymentRequestId,paymentId, amount, currency, andresult.resultStatus. For cards, Apple Pay, and Google Pay, ship only after capture succeeds. - Fall back to
inquiryPaymentwhen a notification is late or missing.
Core Facts
- All APIs are
POSTwith JSON bodies, versionv1, pathhttps://<domain>/ams/api/v1/.... - Asia domain:
https://open-sea-global.alipay.com(alsohttps://open-sea.alipay.com). Use the domain shown in your Dashboard. - Sandbox online-payment path is
/ams/sandbox/api/<endpoint>. The official SDKs rewrite/ams/apito/ams/sandbox/apiwhen the client ID starts withSANDBOX_. - Required request headers:
client-id,request-time,signature.Content-Type: application/json; charset=UTF-8is optional. - Sign
POST <http-uri>\n<client-id>.<request-time>.<request-body>with SHA256withRSA, then base64, then URL-encode. - Signature header:
algorithm=RSA256, keyVersion=1, signature=<urlencoded-signature>. - Verify responses with
<client-id>.<response-time>.<raw-response-body>, and notifications with<client-id>.<request-time>.<raw-notify-body>. - Amounts are strings in the smallest unit. MYR has 2 decimals, so RM13.14 is
"1314". - One-time Payments use
productCodeCASHIER_PAYMENT.productSceneisCHECKOUT_PAYMENTorELEMENT_PAYMENTfor sessions. - Malaysian enums:
ONLINEBANKING_FPX,TNG,BOOST,GRABPAY_MY,SHOPEEPAY_MY,CARD. - Default payment timeout is 14 minutes. A payment session defaults to 1 hour.
- Notification acknowledgement body is fixed:
{"result":{"resultCode":"SUCCESS","resultStatus":"S","resultMessage":"success"}}. Do not sign it. - Notification retries run for up to 24 hours at 0s, 2m, 10m, 10m, 1h, 2h, 6h, 15h.
- A notification URL set in the API overrides the Dashboard value, except for capture notifications, where the Dashboard value wins.
- Manual capture must happen within 7 days of authorization. Only full capture is supported.
- Refunds are asynchronous. Card refunds never return
Ssynchronously. FPX refund window is 180 days; TNG, Boost, GrabPay MY, ShopeePay MY are 365 days. - Fees are not published in the docs. They are shown in Antom Dashboard > Payments > Payment methods > Price.
Critical Rules
- Keep the merchant private key and client ID server-side. Use placeholders like
<CLIENT_ID>,<MERCHANT_PRIVATE_KEY>,<ANTOM_PUBLIC_KEY>. - Test and live use different keys, client IDs, and URLs. Never mix them.
- Verify signatures over the raw body bytes. Do not parse and re-serialize JSON first.
- Sign the exact
request-timestring you send in the header. result.resultStatusUis not a failure. HandlePAYMENT_IN_PROCESSby redirecting, otherUby inquiry or a newpaymentRequestIdas the docs say.- Never reuse a
paymentRequestIdwith a changed amount, currency, or method (REPEAT_REQ_INCONSISTENT). - Use the
paymentIdfromnotifyPaymentfor refunds. Card retries on Antom pages can create a newpaymentId. - Do not retry a refund that returned
REFUND_IN_PROCESS. Query withinquiryRefund. - Make notification handling idempotent. Record processed notifications and ignore duplicates.
- Confirm live method availability, acquirer entity, limits, settlement period, and pricing with Antom before claiming production certainty.
Completion Criteria
An Antom integration is done only when:
- Requests are signed server-side and every response signature is verified (or the unsigned F/U case is handled).
paymentRequestIdis unique per attempt and stored with the expected amount and currency before calling Antom.- The notification endpoint verifies the signature over the raw body, settles idempotently, and returns the fixed acknowledgement.
- Settlement checks
paymentRequestId,paymentId, amount, currency, and status. Card flows wait forCAPTURE_RESULTS. inquiryPaymentfallback exists for missing or delayed notifications and forUresults.- Refund and cancel flows handle
U,F, and the asynchronousnotifyRefund. - Tests cover bad signature, duplicate notification, wrong amount,
Uresults, timeout (USER_NOT_SUBMITTED,ORDER_NOT_EXIST), and sandbox-to-live switch. - Deployment docs name
<CLIENT_ID>,<MERCHANT_PRIVATE_KEY>,<ANTOM_PUBLIC_KEY>, gateway domain, notification URL, and redirect URL per environment.
Loophole Review Loop
When asked whether an Antom strategy is "100% confident", run this loop until no factual gaps remain:
- List trust boundaries: browser redirect, client SDK, backend signer, Antom API, notification receiver, raw-body parser, database, capture job, refund job, Dashboard settings.
- Check bypasses: fake redirect success, forged notification, signature over parsed JSON, wrong public key, sandbox key on live, reused
paymentRequestId, wrong amount or currency, shipping on authorization instead of capture, missed notification, duplicate notification, refund retried while in process, refund against a stalepaymentId. - Add fixes: server-side signing and verification, raw-body checks, strict amount and ID matching, durable notification log, idempotent settlement,
inquiryPaymentpolling fallback, capture-based shipping for cards, environment-separated config. - Re-read the relevant section of
references/antom-api.mdand the topic file for any gap. - State remaining uncertainty that depends on the merchant's contract: acquirer entity (AntomMY or other), enabled methods, settlement currency and period, pricing, and whether the sandbox path or the
/ams/apipath applies to the account.


