What Goes on a USDC Invoice and How Onchain Reminders Work
See what belongs on a USDC invoice, how to automate reminders for stablecoin payments, and how to reconcile incoming funds onchain for your crypto business.

Invoices in crypto look familiar at first. There is a payer, an amount, a due date and a destination. But the mechanics of stablecoin settlement, onchain visibility and integration with wallets require a few adjustments. Getting these details right saves time and avoids disputes. This post covers the minimum fields for a USDC invoice, how to automate reminders, and the practicalities of reconciling onchain payments.
What to Put on a USDC Invoice
The core of every invoice is the claim: who owes what, to whom, and by when. In stablecoins, the process is explicit and verifiable. Each invoice should state:
- Amount in USDC, with decimal precision. Do not round. If you are billing for $1,234.56, record
1234.56USDC, not1235. - Settlement address. This is the wallet address controlled by the merchant, not a shared or third-party address.
- Chain. Specify which network is accepted: Base, Polygon, or Ethereum. Fees, timing, and supported wallets differ.
- Due date and time. Use UTC in ISO 8601 format. Example:
2024-07-01T17:00:00Z. - Invoice identifier. A unique string, not just a number, for matching settlement.
- Reference or memo. An optional field for purchase order, description or metadata, visible both on the invoice and in the transaction.
A minimal USDC invoice as JSON could look like this:
{
"id": "INV-2024-2301-B2B",
"amount_usdc": "1234.56",
"settlement_address": "0xAbC123...Ef45",
"chain": "base",
"due": "2024-07-01T17:00:00Z",
"memo": "July SaaS subscription"
}
Why Decimal Precision and Chain Matter
USDC is an ERC-20 token with 6 decimals. If your invoice rounds or omits cents, reconciliation will fail. Onchain settlement cannot guess intent. The chain matters because a payment on Ethereum will not appear on Polygon, even for the same address. Listing both chain and address avoids mistakes.
Example: Generating a USDC Invoice
Here is a TypeScript snippet illustrating invoice creation:
function createUsdcInvoice({ id, amount, address, chain, due, memo }: {
id: string,
amount: number,
address: string,
chain: 'base' | 'polygon' | 'ethereum',
due: string,
memo?: string
}) {
return {
id,
amount_usdc: amount.toFixed(6),
settlement_address: address,
chain,
due,
memo: memo || ''
};
}
const invoice = createUsdcInvoice({
id: 'INV-2024-2301-B2B',
amount: 1234.56,
address: '0xAbC123...Ef45',
chain: 'base',
due: '2024-07-01T17:00:00Z',
memo: 'July SaaS subscription'
});
How Reminders Should Work in Crypto Invoicing
In traditional invoicing, reminders are sent by email or SMS. In crypto, settlement is visible to anyone, so reminders can be smarter. But reminders must never assume intent or access to the payer’s wallet.
Triggering Reminders
A reminder is needed if the invoice is unpaid at the due date. The sender can monitor the destination address for an incoming USDC transfer matching the invoice amount, chain, and memo (if used). If no match appears, a reminder is sent. This can be automated via an indexer or a lightweight webhook.
For example:
- Invoice INV-2024-2301-B2B for 1234.56 USDC due on Base at 0xAbC123...Ef45.
- At 2024-07-01T17:00:00Z, check for an incoming USDC transfer.
- If not found, send reminder by preferred channel.
Reminder Content
Include the original invoice details: amount, address, chain, and a direct payment link if supported. Do not include a new address or change the amount. This avoids phishing and reconciliation issues.
Example: Automated Reminder Flow
from web3 import Web3
from usdc_abi import ERC20_ABI # Standard USDC ABI
w3 = Web3(Web3.HTTPProvider('https://mainnet.base.org'))
usdc_contract = w3.eth.contract(address='0xA0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', abi=ERC20_ABI)
INVOICE_AMOUNT = int(1234.56 * 1_000_000) # USDC has 6 decimals
SETTLEMENT_ADDRESS = '0xAbC123...Ef45'
START_BLOCK = 12345678 # Block at invoice creation
# Query for incoming transfers
logs = usdc_contract.events.Transfer.createFilter(
fromBlock=START_BLOCK,
toBlock='latest',
argument_filters={'to': SETTLEMENT_ADDRESS}
).get_all_entries()
paid = any(log['args']['value'] == INVOICE_AMOUNT for log in logs)
if not paid:
# Trigger reminder via email/SMS
send_reminder_to_payer()
Onchain Reconciliation: Matching Payment to Invoice
Onchain reconciliation means matching incoming USDC transfers to outstanding invoices. In stablecoins, the settlement is final once confirmed, but only if the transfer matches the invoice fields.
What to Match
- Amount: Must match, with full decimal precision.
- Chain: Only the specified chain counts.
- Destination address: Must match. Do not accept to a different address.
- Reference: If you support invoice IDs or memos, match against the transaction data field.
Handling Overpayment or Underpayment
If a payer sends less than the invoice, mark as partial. If more, mark as overpaid. Do not automatically refund or reallocate without a workflow. Onchain settlement is final. Any further movement requires a new transaction and a new gas cost.
Example: Reconciling a Payment
Suppose the invoice above is for 1234.56 USDC. At 2024-07-01T16:50:00Z, this transfer is seen on Base:
from:0xPayerWallet...to:0xAbC123...Ef45amount:1234560000(six decimals)hash:0xTxHash...
Your reconciliation code matches amount and to on the correct chain. Mark the invoice as paid, record the transaction hash for audit.
When It Fails
If the payer sends to the wrong address or on the wrong chain, the transfer will not appear. If the amount is off by even a cent, your code should flag it for review. There is no way to reverse the transaction through Reclack or the network. Any refund or correction must be handled as a new transfer.
How We Handle This at Reclack
At Reclack, our hosted invoices specify amount, chain, and destination address up front. We never ask for approvals that exceed the invoice or recurring cap. Our reminder engine monitors the chain for exact matches and triggers notifications only if the invoice is still unpaid at the due time. Onchain reconciliation is strict: only matching, settled USDC transfers to the merchant’s address count. We never hold funds, and we never ask for keys. See how crypto invoicing works in practice at reclack.com.