POST /payments/{id}/inquiry
Submits a customer's transaction hash against a payment that hasn't updated on its own — the recovery path for "my customer says they paid, but the payment is still PENDING".
We verify the hash on-chain against every deposit address the payment holds. On a match the payment enters the normal crediting pipeline, exactly as if our scanner had detected it: your webhook fires and verify reports the outcome.
This endpoint triggers crediting; it is not the outcome. A resultCode of ok means the transaction matched and is being credited — always fulfil from verify, never from this response.
curl -X POST https://api.finomesh.com/api/v1/payments/0d9f3a64-4f0c-4b6e-9f6e-2f4f4c1b8a21/inquiry \
-H "X-Api-Key: $FINOMESH_API_KEY" \
-H "Content-Type: application/json" \
-d '{"txHash":"0xabc123…"}'
Headers
| Header | Type | Required | Description | Example |
|---|---|---|---|---|
X-Api-Key | string | Yes | Gateway API key. Keep it server-side only. | <your-api-key> |
Content-Type | string | Yes | Must be application/json. | application/json |
Path parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
id | string (UUID) | Yes | The payment UUID from create payment. Must belong to your gateway. | 0d9f3a64-4f0c-4b6e-9f6e-2f4f4c1b8a21 |
Request body
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
txHash | string | Yes | The on-chain transaction hash your customer reports. Accepted with or without the 0x prefix. | 0xabc123… |
offerId | string (UUID) | No | Restricts the check to one offer's deposit address. Omit it unless you know which network the customer actually paid on — without it we check every address the payment holds, which is almost always what you want. | 4b1e… |
A payment offering several networks holds one deposit address per network. We check all of them, so you do not need to know the customer's chain. offerId only narrows the search to a single chain lookup when you do know.
Response — 200 OK
Verdicts return 200 — including rejections like wrong_recipient. Read resultCode, not the HTTP status.
{
"success": true,
"data": {
"resultCode": "ok",
"creditedPaymentId": "0d9f3a64-4f0c-4b6e-9f6e-2f4f4c1b8a21",
"attemptsRemaining": 4,
"resolvedRecipient": "0x1234…",
"resolvedAsset": "0x55d3…",
"resolvedAmount": "51.42"
}
}
| Field | Type | Nullable | Description | Example |
|---|---|---|---|---|
resultCode | string (enum) | No | The verdict. See the table below. | ok |
reason | string | Yes | Human-readable detail. Present on most non-ok verdicts. | transaction not found… |
creditedPaymentId | string (UUID) | Yes | Set on ok / tx_already_processed — the payment now being credited. | 0d9f3a64-… |
attemptsRemaining | integer | No | Attempts left on this payment for your account (see Limits). Always present, including 0. | 4 |
resolvedRecipient | string | Yes | The recipient address we read from the chain. Useful for diagnosing wrong_recipient. | 0x1234… |
resolvedAsset | string | Yes | The token contract we read from the chain; empty for a native transfer. Diagnoses wrong_asset. | 0x55d3… |
resolvedAmount | string (decimal) | Yes | The on-chain amount. Decimal string — never a number, to preserve precision. | 51.42 |
Result codes
Handle these explicitly:
resultCode | Meaning | What to do | Costs an attempt |
|---|---|---|---|
ok | Matched. The payment is being credited. | Poll verify for the outcome. | No |
tx_already_processed | We had already detected this transaction. | Poll verify; no action needed. | No |
tx_not_found | Not found on any network this payment can be paid on. | Re-check the hash with your customer. | Yes |
tx_unconfirmed | On chain, but not yet final. | Wait and retry in a few minutes. | No |
tx_reverted | The transaction reverted — no funds moved. | Ask the customer to pay again. | Yes |
tx_belongs_to_another_payment | This hash is already bound to a different payment. | Re-check the hash; it isn't for this payment. | Yes |
wrong_recipient | Sent to an address that isn't one of this payment's. Compare resolvedRecipient. | Customer paid the wrong address — handle as a support case. | Yes |
wrong_asset | The asset sent isn't one this payment accepts. Compare resolvedAsset. | Customer sent the wrong coin — handle as a support case. | Yes |
deposit_below_minimum | Genuinely ours, but worth less than the minimum we can credit. | Not creditable; treat as a dust transfer. | No |
no_offer_selected | No deposit address has been assigned yet. | The customer never selected an asset/network — nothing was payable. | No |
inquiry_limit_exceeded | You've used your attempts on this payment. | Stop retrying; contact support. | No |
sandbox_payment | Sandbox payments don't accept inquiries. | Use the sandbox simulation controls instead. | No |
payment_terminal_not_expired | The payment is already finalised. | Read verify for the outcome. | No |
Any other value is transient or configuration-side on our end — safe to retry later, and it never costs you an attempt. Treat unrecognised codes as retryable rather than failing hard, so a future code can't break your integration.
Limits
- 5 attempts per payment, shared with inquiries your team submits from the merchant dashboard. Only the verdicts marked Yes above consume one — transient results don't.
- 20 total requests per payment across everyone, as an absolute ceiling. Past it, every request returns
inquiry_limit_exceededwithout touching the chain. - Standard rate limits apply on top.
Attempts are deliberately scarce: each one drives live blockchain lookups. Retry loops will exhaust the budget and leave your support team none.
Requirements
- IP allowlist — for payments created with
checkoutMode: "API", your server's IP must be on the gateway allowlist, the same requirement as create payment. A non-allowlisted address gets403with the observed IP echoed back so you can add it. Hosted-checkout payments are not IP-gated. - Availability — this endpoint exists only when transaction inquiry is enabled for your deployment. If it isn't, requests return
404.
Errors
| HTTP status | Error code | Meaning | How to fix |
|---|---|---|---|
| 401 | auth_api_key_invalid | Bad or missing API key. | Send a valid X-Api-Key from a verified gateway. |
| 403 | forbidden | Your server's IP isn't on the gateway allowlist. The message echoes the IP we observed. | Add that IP to your gateway's allowlist. |
| 404 | not_found | Unknown ID, or the payment belongs to another gateway. | Check the payment ID — it must belong to your gateway. |
| 422 | validation_error | txHash missing or the body isn't valid JSON. | Send {"txHash":"…"} with Content-Type: application/json. |
| 429 | rate_limit_exceeded | Too many requests from your IP on this endpoint. | Honor Retry-After before retrying — see rate limits. |