check_payment_status

Check the status of an in-flight UPI payment for a Dineout booking (one status read). The confirmation widget polls automatically and auto-confirms on success, so you rarely need to call this yourself.

Check the status of an in-flight UPI payment for a Dineout booking — a single read of the live payment status. The payment confirmation widget polls this automatically on a fixed cadence and auto-finalizes it on any terminal outcome — confirms on success, and finalizes-to-failed on failed/timeout, so in normal flows you do NOT need to call it at all. It's a long-poll (the server holds ~19s, returning early on a status change; fast only on a transient cache miss), so never tight-loop it — hammering it stresses the payment cache. For an ad-hoc user question (“did my payment go through?”), call it at most once and report the result. A self-driven headless client that owns the flow instead follows the bounded polling procedure below — poll until data.terminal, re-poll gently on pending, capped — never a tight loop.

See check_payment_status in actionComing soon

Example

const result = await client.callTool({
  name: "check_payment_status",
  arguments: {
    paasId: "PAAS_TXN_12345",
    orderId: "224511744004217",
  },
});

Parameters

ParameterTypeRequiredDescription
paasIdstringyesThe payment TRANSACTION id from the book_table response (field paasId). NOT a payment-method name — never pass "PayWithQR", "UPI", "UPIIntent", or an app package id here. If you don't have a real paasId, re-read the book_table response instead of calling this tool.
orderIdstringcond.orderId from the book_table response — optional for a bare status read, but pass it so the widget can auto-confirm on SUCCESS (else a paid booking can stay pending).
finalizebooleannoINTERNAL — set by the widget at the polling cap to finalize the booking. Do NOT set this yourself.

Session credentials (user identity, access token) are supplied automatically by the authenticated MCP session - you do not pass them in the tool call. See Authenticate.

Response

For any resolved status read, check_payment_status returns success: true — a terminal payment failure is still a successful status read. Read the outcome off data.status, not the top-level success. (A transport/tool error — e.g. a missing/bad paasId — returns the standard success: false failure envelope instead.)

A terminal read (here, a refund):

{
  "success": true,
  "data": {
    "paasId": "PAAS_TXN_12345",
    "status": "refund-initiated",
    "terminal": true,
    "isTerminalSuccess": false,
    "isTerminalFailure": true
  },
  "message": "↩️ REFUND-INITIATED — a refund has been initiated for this payment."
}

A confirmed success also carries confirmed: true + orderStatus (the booking was finalized server-side, so you do NOT call confirm_order):

{
  "success": true,
  "data": {
    "paasId": "PAAS_TXN_12345",
    "status": "success",
    "terminal": true,
    "isTerminalSuccess": true,
    "isTerminalFailure": false,
    "confirmed": true,
    "orderStatus": "CONFIRMED"
  },
  "message": "✅ Payment SUCCESS — booking CONFIRMED automatically."
}

How your client integrates

On a widget host you don't call this at all — the picker polls and auto-confirms for you. Only if you self-drive (headless): poll until data.terminal === true, then branch on data.status:

data.statusTerminalMeaningWhat your client does
success / paidsuccessPayment done; booking auto-confirmed (data.confirmed: true, data.orderStatus).Show "booking confirmed". Do NOT call confirm_order.
failedfailurePayment didn't go through; any debit is refunded (~4 days).Offer retry → get_payment_options.
refund-initiatedfailureMoney was debited but a refund has already been started; booking not placed.Tell the user a refund is on its way. Do NOT retry.
cancelledfailureBooking cancelled; refund if already paid.Tell the user it was cancelled.
cart_changedfailureBooking cart changed → booking NOT placed (not a payment failure).Ask the user to review and book again.
pending / ""not terminalStill processing.Keep polling; don't act yet.

So a client knows a refund was initiated when data.status === "refund-initiated" (with data.isTerminalFailure === true). The human-readable message mirrors the same outcome for chat surfaces.

Cap your polling — don't loop forever. A pending result (including a transient cache miss) means "not resolved yet," not "poll harder." Honor the window the book_table response gives you (maxTimeToPollForInMs; roughly ~1 min for a UPI-app intent, ~5 min for scan-QR) and re-poll gently on pending — the status read is a long-poll, so space your calls rather than tight-looping. If you reach your cap while still pending, call confirm_order once to finalize — the backend marks the booking failed if the payment is still non-terminal, and a late success is reconciled server-side. Then tell the user it timed out and offer a retry. (On a widget host the picker does all of this for you.)

On a transport/tool error (missing or bad paasId, network failure) you get the standard failure envelope instead:

{
  "success": false,
  "error": { "message": "description of what went wrong" }
}

See Error codes for the full catalogue.

Details

FieldValue
Namecheck_payment_status
MCP ServerDineout
EndpointPOST mcp.swiggy.com/dineout
StagePayment
Behaviourread-only

Agent guidance

How Swiggy agents and orchestration logic use this tool. Surface these expectations in your prompts or tool-selection policies.

⚠️ THE PAYMENT WIDGET POLLS AUTOMATICALLY. After book_table, the confirmation widget polls this and auto-finalizes on any terminal outcome (confirms on success; finalizes-to-failed on failed/timeout), server-side. You normally do NOT need to call this at all. Do NOT tight-loop it — it's a long-poll, and hammering it stresses the payment cache.

WHEN TO CALL (at most ONCE per user request):

  • The user explicitly asks "did my payment go through?" / "check status" → call ONCE and report the result. Do NOT immediately re-call on PENDING.
  • Terminal SUCCESS / PAID → normally already confirmed for you server-side (data.confirmed); only call confirm_order yourself if the result says auto-confirm couldn't run (missing args).
  • Terminal FAILED → do NOT confirm; tell the user it failed and offer get_payment_options to retry.
  • Terminal REFUND-INITIATED → do NOT confirm; tell the user a refund was initiated.
  • PENDING → tell the user it's still processing and will update automatically. Do NOT loop.

Next in this journey →

On terminal SUCCESS the prebook is already confirmed for you server-side (data.confirmed: true) — do not call confirm_order yourself. Continue to tracking: get_booking_status. (Only call confirm_order in the rare case where you hit your own polling cap while still pending.)