Proof verification

How JoPay verifies on-chain payments and handles mismatches.

How verification works

When a customer pays a merchant, JoPay needs to confirm that the on-chain transfer actually matches the payment request. This is called proof verification. There are two ways proof can be submitted:

  • Automatic (Trails) — JoPay's verification engine watches supported chains for incoming USDC transfers to the merchant's wallet. When a matching transfer is detected, proof is attached and verified automatically. This is the default for most payments.
  • Manual (TX hash) — If automatic detection does not find the transfer (e.g. the customer paid on a different chain or from an unexpected wallet), the customer or merchant can manually submit the transaction hash. JoPay then looks up the transaction on-chain and verifies it.
Automatic verification via Trails is the most common path. Manual TX hash submission is a fallback for edge cases.

Verification statuses

Every payment request has a proof status that progresses through these states:

None

No proof has been submitted yet. The payment is waiting for the customer to send USDC. The payment may still be in Pending state (active, waiting for payment) or Expired (the window closed).

Attached

A transaction hash has been submitted (either automatically by Trails or manually by the customer/merchant), but verification has not yet finished. JoPay is looking up the transaction on-chain and checking it against the payment request.

This is usually a brief intermediate state. The status will move to either Verified or Mismatch shortly.

Verified

The on-chain transfer has been verified and matches the payment request on all criteria:

  • Correct amount of USDC.
  • Correct asset (USDC, not another token).
  • Correct recipient (the merchant's wallet address).
  • Correct chain (one of the supported chains).

A verified payment is final. Revenue is counted in the merchant's dashboard and the customer can view a receipt.

Mismatch

The transaction was found on-chain, but one or more fields do not match the payment request. JoPay flags exactly what is wrong so you can take action.

Mismatch reasons

When a mismatch occurs, JoPay reports which field(s) did not match:

  • Amount mismatch — The customer sent a different amount of USDC than requested. This can happen if the customer manually typed the amount instead of using the payment page, or if they sent a partial payment.
  • Asset mismatch — The customer sent a different token (e.g. USDT instead of USDC). JoPay only accepts USDC.
  • Recipient mismatch — The transfer went to a different wallet address than the merchant's. This typically means the customer sent to the wrong address.
  • Chain mismatch — The transaction was on an unsupported chain or a different chain than expected. The transfer must be on a chain that JoPay monitors (Polygon, Base, Ethereum, Optimism, or Arbitrum).
A mismatch does not mean the funds are lost. The on-chain transfer still happened. The mismatch simply means JoPay cannot automatically confirm it as a valid payment for this specific request. The merchant and customer should coordinate to resolve the issue.

Conflict resolution

If a payment shows a mismatch, here is how to resolve it:

  • Amount mismatch — Verify the actual amount sent on a block explorer. If the customer underpaid, they can send the remainder in a new payment. If they overpaid, coordinate a return directly (JoPay does not handle returns).
  • Asset mismatch — The customer sent the wrong token. They need to send USDC specifically. The original token transfer is a separate transaction unrelated to JoPay.
  • Recipient mismatch — The customer sent to the wrong address. This is outside JoPay's control. The customer should contact the wallet they sent to.
  • Chain mismatch — If the customer paid on an unsupported chain, the funds are at the same address on that chain. The merchant may need to import that chain in their wallet to access the funds.

Automatic vs manual verification

FeatureAutomatic (Trails)Manual (TX hash)
How it triggersTrails detects incoming USDC transferCustomer or merchant pastes TX hash
SpeedNear real-time after on-chain verificationSeconds after hash submission
When to useDefault for all paymentsFallback when auto-detection misses
Action neededNone (fully automatic)Paste valid transaction hash

Next steps