Skip to main content

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.

note

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

HeaderTypeRequiredDescriptionExample
X-Api-KeystringYesGateway API key. Keep it server-side only.<your-api-key>
Content-TypestringYesMust be application/json.application/json

Path parameters

ParameterTypeRequiredDescriptionExample
idstring (UUID)YesThe payment UUID from create payment. Must belong to your gateway.0d9f3a64-4f0c-4b6e-9f6e-2f4f4c1b8a21

Request body

FieldTypeRequiredDescriptionExample
txHashstringYesThe on-chain transaction hash your customer reports. Accepted with or without the 0x prefix.0xabc123…
offerIdstring (UUID)NoRestricts 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"
}
}
FieldTypeNullableDescriptionExample
resultCodestring (enum)NoThe verdict. See the table below.ok
reasonstringYesHuman-readable detail. Present on most non-ok verdicts.transaction not found…
creditedPaymentIdstring (UUID)YesSet on ok / tx_already_processed — the payment now being credited.0d9f3a64-…
attemptsRemainingintegerNoAttempts left on this payment for your account (see Limits). Always present, including 0.4
resolvedRecipientstringYesThe recipient address we read from the chain. Useful for diagnosing wrong_recipient.0x1234…
resolvedAssetstringYesThe token contract we read from the chain; empty for a native transfer. Diagnoses wrong_asset.0x55d3…
resolvedAmountstring (decimal)YesThe on-chain amount. Decimal string — never a number, to preserve precision.51.42

Result codes

Handle these explicitly:

resultCodeMeaningWhat to doCosts an attempt
okMatched. The payment is being credited.Poll verify for the outcome.No
tx_already_processedWe had already detected this transaction.Poll verify; no action needed.No
tx_not_foundNot found on any network this payment can be paid on.Re-check the hash with your customer.Yes
tx_unconfirmedOn chain, but not yet final.Wait and retry in a few minutes.No
tx_revertedThe transaction reverted — no funds moved.Ask the customer to pay again.Yes
tx_belongs_to_another_paymentThis hash is already bound to a different payment.Re-check the hash; it isn't for this payment.Yes
wrong_recipientSent 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_assetThe asset sent isn't one this payment accepts. Compare resolvedAsset.Customer sent the wrong coin — handle as a support case.Yes
deposit_below_minimumGenuinely ours, but worth less than the minimum we can credit.Not creditable; treat as a dust transfer.No
no_offer_selectedNo deposit address has been assigned yet.The customer never selected an asset/network — nothing was payable.No
inquiry_limit_exceededYou've used your attempts on this payment.Stop retrying; contact support.No
sandbox_paymentSandbox payments don't accept inquiries.Use the sandbox simulation controls instead.No
payment_terminal_not_expiredThe 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_exceeded without 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 gets 403 with 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 statusError codeMeaningHow to fix
401auth_api_key_invalidBad or missing API key.Send a valid X-Api-Key from a verified gateway.
403forbiddenYour server's IP isn't on the gateway allowlist. The message echoes the IP we observed.Add that IP to your gateway's allowlist.
404not_foundUnknown ID, or the payment belongs to another gateway.Check the payment ID — it must belong to your gateway.
422validation_errortxHash missing or the body isn't valid JSON.Send {"txHash":"…"} with Content-Type: application/json.
429rate_limit_exceededToo many requests from your IP on this endpoint.Honor Retry-After before retrying — see rate limits.