An underpaid crypto invoice should not be fulfilled automatically, and an overpaid invoice should not trigger an automatic refund. First verify the transaction’s network, genuine token contract, recipient, status and amount. Then apply a written merchant policy that records the shortfall or excess and produces one explicit resolution.

In GramPayBot, the expected amount is exact. A lower transfer is classified as partial, a higher transfer as overpaid, and neither case silently becomes a normally paid invoice. That protects the merchant from closing the wrong order and protects the buyer from an unsafe refund decision.

Underpaid vs overpaid: quick decision table

Verified resultInvoice decisionTypical next step
Received amount equals the exact expected amountEligible for normal matching after confirmationFulfil when the invoice is paid
Received amount is lowerUnderpaid / partial; keep out of automatic fulfilmentReview the shortfall and instruct the buyer
Received amount is higherOverpaid; keep out of automatic fulfilmentReview whether to accept, credit or refund the excess
Several transfers appear to relate to one invoiceAmbiguous until reconciledVerify every hash and resolve manually
Wrong token, network or recipientNot payment of this invoiceFollow the relevant mismatch or recovery process

For a wrong network, use the wrong-network investigation and recovery guide. If the amount issue involves an expired or replacement invoice, follow the unpaid, late and expired invoice workflow before asking for another payment.

BTCPay Server’s invoice documentation likewise separates partially paid and overpaid states from a normally settled invoice. Outside crypto, Stripe’s partial-payment documentation tracks remaining amounts and overpayments separately. These references do not define your business policy, but they demonstrate why amount exceptions need their own state instead of being hidden inside “paid.”

Why crypto invoices become underpaid

Common causes include:

  • the buyer typed a rounded amount instead of copying the exact value;
  • an exchange or wallet displayed a fee that the buyer misunderstood;
  • the buyer sent a small test payment and assumed it counted automatically;
  • the buyer used old payment instructions or an expired invoice;
  • the transferred token uses decimals that were formatted or parsed incorrectly;
  • two people attempted to pay the same order;
  • the buyer deliberately withheld part of the amount because of a dispute.

Withdrawal-fee behavior varies by provider and asset. Some services show the recipient amount separately; others make the user reason about the withdrawal and network fees. Fees can also change. Binance, for example, tells users that crypto withdrawal fees are dynamic and shown on the withdrawal page. Therefore, do not write a universal rule such as “the network always deducts the fee from the invoice amount.” The buyer must use the provider’s final preview and ensure the merchant receives the exact requested token amount.

Why crypto invoices become overpaid

An overpayment often comes from:

  • copying the fiat price instead of the exact token amount;
  • adding a network fee to the recipient amount even though the wallet charges it separately;
  • paying an invoice twice;
  • sending the intended amount after an earlier test transfer;
  • using a stale invoice and then trying to compensate for uncertainty;
  • manual decimal or unit conversion errors.

USDT and USDC are displayed with decimal fractions, but transfers are represented on-chain in integer base units. Official Circle examples for USDC demonstrate amount handling with six decimal places. A robust payment system converts between display amounts and atomic units deterministically; it should not compare floating-point approximations.

Verify the exception before resolving it

Do not start with the difference between two numbers. Start with the transfer itself:

  1. Open the raw transaction hash in the explorer for the invoice network.
  2. Confirm that the transaction succeeded and is sufficiently confirmed.
  3. Verify the token contract or mint, not only the USDT or USDC symbol.
  4. Compare the full recipient address with the invoice address.
  5. Read the token transfer amount from the transfer event or balance change.
  6. Compare it with the exact displayed invoice amount.
  7. Check whether another transaction has already been assigned to the invoice or order.
  8. Record the invoice expiry and the transfer’s actual block time.

If the token contract is wrong, the payment is not simply underpaid or overpaid: it is the wrong asset. Use the USDT and USDC token contract verification guide before assigning any value to it.

After verification, link every accepted hash to exactly one invoice and order. The payment-to-order matching guide explains how to preserve that relationship without relying on screenshots or chat usernames.

GramPayBot exact-amount behavior

GramPayBot creates the expected network, token, recipient and amount before payment. The current checkout amount uses no more than four digits after the decimal point and may include an identifying fractional suffix, so the buyer must send the whole displayed amount exactly—for example, 180.0134 USDT, not a rounded 180 USDT. A token such as USDT or USDC can use six base-unit decimals on-chain; that token precision does not mean GramPayBot displays a six-digit invoice suffix.

For automatic matching:

  • an exact confirmed transfer can pay the invoice;
  • a lower transfer is classified as partial;
  • a higher transfer is classified as overpaid;
  • multiple plausible or reused transfers are not accepted as a clean exact match.

GramPayBot’s exact matcher does not treat an arbitrary second transfer as an automatic “top-up” that completes the first one. Tell the buyer not to send another transaction until you provide a specific resolution. This avoids turning one underpayment into two ambiguous transfers.

Merchant workflow for an underpayment

1. Calculate the verified shortfall

Use token units, not a screenshot or approximate fiat conversion:

shortfall = exact invoice amount − verified received amount

Record both values at their full displayed precision.

2. Keep fulfilment on hold

Do not mark the order paid merely because most of the amount arrived. This prevents inconsistent staff decisions such as accepting a 1% shortfall for one customer but rejecting it for another.

3. Choose one written resolution

Depending on your terms and the economics of the payment, you can:

  • accept the shortfall manually and record it as a discount or write-off;
  • create a new invoice for the remaining balance;
  • cancel fulfilment and refund the verified amount;
  • hold the case for support or compliance review.

If you request the balance, use a new, explicit invoice rather than telling the buyer to send “a little more” to an address. Link the original payment and the balance invoice in your records. Do not imply that the original GramPayBot invoice will automatically aggregate the two transfers.

4. Confirm the outcome to the buyer

State the amount received, the shortfall, the chosen resolution and the new invoice ID or refund reference. Avoid vague messages such as “payment incomplete” with no actionable next step.

Merchant workflow for an overpayment

1. Check for a duplicate or unrelated transfer

The excess may not be a single typing error. Verify whether there are two transactions, whether one hash belongs to another invoice and whether a previous payment was already fulfilled.

2. Separate the invoice amount from the excess

Record:

excess = verified received amount − exact invoice amount

Do not change the original invoice amount after the fact to make the numbers look equal.

3. Apply one policy

Your terms may allow you to:

  • accept the invoice manually and return the excess;
  • place the excess on an agreed customer credit balance;
  • accept the full amount when it represents an intentional tip or added purchase;
  • refund the entire payment and reissue the invoice.

The decision should be explicit and traceable. Stripe’s partial-payment documentation is a useful non-crypto example of why remaining balances and overpayments need defined reconciliation rules rather than guesses.

4. Verify a refund destination independently

Do not automatically send the excess back to the on-chain sender. A centralized exchange can broadcast withdrawals from a shared wallet that does not credit incoming returns to the buyer.

Authenticate the customer through the original order channel, request a same-network refund address, confirm it, document fee treatment and record the outgoing transaction hash. A refund is a new transfer; it does not reverse the original one.

Policy choices to define before the first exception

Write down:

  • whether any underpayment tolerance exists;
  • whether tolerance is a fixed token amount or percentage;
  • whether balance invoices are allowed;
  • the minimum economical refund amount after network fees;
  • whether customer credits are supported;
  • who approves manual acceptance and refunds;
  • how duplicate transfers are handled;
  • how long exception records are retained.

If you use a tolerance, apply it consistently and keep it outside the automatic exact-payment claim unless your integration explicitly supports the rule. Exact matching is easier to audit than an undocumented judgement made during fulfilment.

Buyer instructions that prevent amount errors

Tell the buyer to:

  1. Open the active invoice rather than paying an address copied from an old message.
  2. Select the exact token and network displayed.
  3. Copy the full amount, including every decimal digit.
  4. Review whether their wallet or exchange subtracts any fee from the recipient amount.
  5. Confirm the recipient amount in the final withdrawal preview.
  6. Send only once and save the transaction hash.
  7. Stop and contact the merchant if they already sent a test amount or the invoice expired.

The complete buyer workflow is in how to pay an invoice with USDT or USDC.

Exception record template

For each underpayment or overpayment, store:

  • invoice and order IDs;
  • expected network, token, recipient and exact amount;
  • every related transaction hash;
  • verified amount per hash and confirmation state;
  • shortfall or excess in token units;
  • invoice expiry and transaction block times;
  • customer-authentication method;
  • resolution, approver and timestamps;
  • balance-invoice, credit or refund reference.

This prevents a transaction from being counted twice and lets another staff member reproduce the decision.

Frequently asked questions

Will a second payment automatically complete an underpaid GramPayBot invoice?

Do not assume it will. The normal matcher expects one exact transfer and does not automatically sum arbitrary partial transfers. Contact the merchant and wait for a new balance invoice or another explicit resolution.

Can I round the amount shown on checkout?

No. Send the complete displayed amount. The fractional digits may help identify and match the invoice.

Is an overpaid invoice automatically paid?

No. A higher amount is an exception that requires review. The merchant must decide how to treat the invoice amount and the excess.

Should the merchant refund to the sender address?

Not automatically. First authenticate the buyer and confirm a refund address, especially when the original transfer came from an exchange.

Does a real USDT transfer prove the order is paid?

Not by itself. The network, token contract, recipient, amount, time window and transaction identity must all match the invoice and the transfer must be confirmed.

Next step

Create a tracked crypto payment link

Issue a USDT or USDC invoice manually, send one hosted checkout and follow its payment status without an API.

Explore payment links →