Skip to main content

Payment Statuses

A payment starts PENDING and ends in exactly one terminal status:

StatusTerminalMeaningMerchant action
PENDINGNoAwaiting payment — the customer has not completed an on-chain transfer yet.Do not fulfil yet.
SUCCESSYesPaid — the received amount matches the expected amount.Fulfil after verify.
ACCEPTABLEYesPaid with a small deviation that is within the tolerance you configured.Fulfil after verify.
MISMATCHYesPaid, but under- or over-paid outside your tolerance.Hold for manual review.
EXPIREDAlmostThe payment window elapsed with no payment.Do not fulfil — but see below.

SUCCESS, ACCEPTABLE and MISMATCH are final: a payment never leaves them, and never changes into another one.

EXPIRED has one exception, described next.

An EXPIRED payment can still be paid​

A customer who sends the transfer after the payment window has closed is still paid into the address Finomesh gave them — the blockchain does not know the window elapsed. Rather than lose those funds, Finomesh keeps watching that address for a grace period after expiry. If the money arrives inside it, the payment reopens and resolves to SUCCESS, ACCEPTABLE or MISMATCH exactly as a timely payment would.

This means:

  • An EXPIRED payment can change status days later, with no action by you or the customer.
  • You receive a second webhook for that payment, carrying the new status. If you cancelled the order on the EXPIRED notification, treat this one as a genuine late payment, not a duplicate — webhooks are delivered once per status change.
  • The amount is judged against the price quoted when the payment was created, not the price on the day it arrived. For a stablecoin that makes no difference. For a volatile asset, a deposit that lands days late may resolve ACCEPTABLE or MISMATCH where a fresh quote would have said SUCCESS.
  • Verify still decides. Call verify as usual; depositPath on the response tells you why a payment resolved after expiring (see below).

A payment that expired and was never paid stays EXPIRED forever — which is the overwhelming majority of them.

depositPath — how the deposit reached us​

Verify returns depositPath once a payment has a recorded deposit:

ValueMeaning
scannerThe ordinary case: paid inside the payment window.
late_confirmationPaid inside the window, but the blockchain confirmation reached us after it closed. The customer was on time.
late_capturePaid after the window closed, and credited anyway through the grace period described above.
manual_inquiryMatched to the payment from a transaction hash submitted after the fact.

You do not need to branch on it to fulfil correctly — status remains the decision. It exists so a payment that resolved days after it expired can be explained rather than guessed at.

How SUCCESS / ACCEPTABLE / MISMATCH is decided​

Finomesh compares the USD value of what arrived on-chain (minus any fees the customer covers) against the USD value of what was expected:

  • Exact match → SUCCESS
  • Deviation within your configured tolerance (overAcceptableDiff / underAcceptableDiff, as flat USD or a percentage) → ACCEPTABLE
  • Anything else → MISMATCH

You configure the tolerance per payment at creation (or inherit your gateway's defaults). Setting checkAmountDeviation: false disables the check entirely — any paid amount resolves to SUCCESS.

Fulfil only on the verified status

SUCCESS and ACCEPTABLE are the only statuses you should fulfil on, and only after a server-side verify call — never from the callback or webhook alone.