Merchant API

Poll payment intent status

GET /payment_intents/:id while waiting for processing or a provider callback.

If your integration cannot host a webhook endpoint, poll for status. Webhooks are still preferable in production.

Endpoint

GET /payment_intents/:id

Scoped to the authenticating merchant and the key's stamped environment. An intent from another merchant or environment returns 404 not_found.

Request

curl -s "$API_BASE/payment_intents/dord_01HZX..." \
  -u "$API_PUBLIC_KEY:$API_SECRET_KEY"
const auth =
  "Basic " +
  Buffer.from(`${process.env.API_PUBLIC_KEY}:${process.env.API_SECRET_KEY}`).toString("base64");

async function getPaymentIntent(id: string) {
  const res = await fetch(`${process.env.API_BASE}/payment_intents/${id}`, {
    headers: { Authorization: auth },
  });
  if (res.status === 404) return null;
  if (!res.ok) {
    const { error } = (await res.json()) as { error: { code: string; message: string } };
    throw new Error(`${error.code}: ${error.message}`);
  }
  return res.json();
}

Success

{
  "object": "payment_intent",
  "id": "dord_01HZX...",
  "amount": "10000",
  "currency": "MYR",
  "country": "MY",
  "environment": "test",
  "status": "succeeded",
  "merchant_reference": "order_12345",
  "payment_method": "MY_FPX",
  "next_action": null,
  "failure_code": null,
  "failure_message": null,
  "created_at": "2026-05-09T12:00:00.000Z",
  "updated_at": "2026-05-09T12:01:00.000Z"
}

Statuses are processing, requires_action, succeeded, failed, and expired.

Polling pattern

async function waitForTerminal(id: string, deadlineMs = 60_000) {
  const start = Date.now();
  let delayMs = 500;
  while (Date.now() - start < deadlineMs) {
    const intent = await getPaymentIntent(id);
    if (!intent) return null;
    if (!["processing", "requires_action"].includes(intent.status)) return intent;
    await new Promise((resolve) => setTimeout(resolve, delayMs));
    delayMs = Math.min(delayMs * 2, 5_000);
  }
  return null;
}

Cap polling. Past 60 seconds the right answer is usually to wait for a webhook or inspect the intent in the dashboard.

On this page