DEV Community

Milton Altenwerth
Milton Altenwerth

Posted on

How to Reconcile Monero Deposits Before a Swap Payout

Verify an XMR deposit in your wallet before releasing the destination asset. Your backend needs to match the received amount to an order, check that the transaction is confirmed, and keep monitoring for changes until the payout is safe to make.

When the source leg is XMR and the destination is on another chain, a Monero bridge handles the cross-chain route; an integrator still needs a reliable deposit record before releasing value. Monero conceals amounts and recipient details on-chain, so a block explorer cannot independently show that a customer paid a particular order.

How should the backend identify a payment?

Assign each order a unique Monero subaddress and watch for incoming transfers to it. A subaddress is a receiving address tied to your wallet; the wallet can identify payments to it even though observers cannot link the visible blockchain data to your customer or order.

  1. Create and store the deposit mapping. Generate a subaddress for the order and save its wallet account and subaddress indices alongside the expected amount, asset, destination chain, and expiry. Reuse neither the address nor the mapping for another order: a late payment to an expired address must remain attributable to the original order.
  2. Scan with a Monero wallet. Use a wallet connected to a synchronized daemon, and query its incoming transfers, such as through the wallet RPC method get_transfers. Match the returned subaddress index to your order record, then compare the received amount in atomic units: 1 XMR equals 1,000,000,000,000 atomic units. Do not try to infer the amount from public transaction data.

Use a wallet with only the access it needs to detect deposits; keep spending keys outside the order-processing service. A view-only wallet can scan incoming funds, while a separate, controlled signing process handles outgoing transfers.

How many confirmations justify payout?

Wait for the confirmation threshold in your payout policy, then recheck the wallet record before releasing the destination asset. Monero targets a block about every two minutes, and wallets commonly require 10 confirmations before a received output is unlocked, so that wait is roughly 20 minutes on average. Treat that as a useful baseline, not a guarantee of settlement time or a universal bridge rule.

  1. Set a risk-based threshold. Choose a minimum confirmation count for each payout tier, accounting for the amount at risk and the cost of a reorganization, where a block is replaced by a competing chain. The wallet’s confirmation count tells you how many blocks have followed the one containing the transfer; the output’s locked status tells you whether it is spendable. Neither field alone determines your business risk policy.
  2. Gate the payout on fresh state. Before sending on the destination chain, verify the node is synchronized and the transfer still appears in the wallet with the expected amount and subaddress. Check that it is confirmed, not only in the transaction pool, and that double_spend_seen is false. A transaction seen but not mined is not a confirmed deposit.

What should happen when a payment is ambiguous?

Keep the order pending when the payment does not satisfy the recorded terms; do not silently treat a mismatch as a full payment. For example, if an order expects 0.50 XMR and the wallet reports 0.47 XMR to its subaddress, record the partial amount and apply your stated underpayment policy. If the customer sends the remainder later, reconcile that incoming transfer against the same order before deciding whether the total qualifies.

  1. Handle late, split, or duplicate observations idempotently. Key each observed transfer by transaction ID and subaddress index so repeated scans do not create duplicate credit. Keep expired orders searchable, and route deposits received after expiry to a review or refund policy rather than assigning them to a new customer.
  2. Recheck after a chain change. If a previously confirmed transfer disappears from the wallet’s confirmed results, suspend an unreleased payout and rescan from a safe earlier height. If destination funds have already been sent, mark the case for reconciliation; a source-chain reorganization cannot automatically reverse a finalized destination transaction.

Keep the deposit record, confirmation count, and payout decision together for audit and recovery. As a practical tip, test the complete flow on a non-production network first, including a partial payment and a delayed deposit, so your order state handles both before real funds are at risk.

Top comments (0)