Custom Cryptocurrency Payment Widget Development
We often get requests: "We want to accept crypto on the site, like PayPal, but for USDT." In practice, this means solving several non-trivial tasks simultaneously: generating unique addresses for each payment, detecting incoming transactions, handling different networks and tokens, and correctly dealing with confirmations and reorgs. Ready-made solutions like Coinbase Commerce or NOWPayments charge 0.5–1% fees and have limited customization. A custom widget is justified when turnover exceeds $10,000 per month—savings on fees can reach $100–$500 monthly. Our experience: 10+ years in blockchain development and over 50 deployed payment solutions. We guarantee complete control over transactions and no hidden fees. A basic widget costs from $5,000, saving you up to $500 monthly on fees.
Why a Custom Widget?
| Criteria | Ready-made gateways (Coinbase Commerce, NOWPayments) | Custom widget |
|---|---|---|
| Fee | 0.5–1% + possible hidden charges — custom widget is 100% cheaper (0% fee) | Only gas and infrastructure costs |
| Customization | Only color and logo selection — custom widget offers unlimited UI/UX control | Full control: UI/UX, currencies, callbacks |
| Integration | Closed API, limited webhooks — custom widget gives direct DB writes and custom events | Custom webhook events, direct DB writes |
| Security | Keys on provider side — custom widget keeps your keys, your infrastructure | Your keys, your infrastructure |
| Supported networks | Limited list — custom widget supports any EVM networks, Bitcoin, Tron, Solana | Any EVM networks, Bitcoin, Tron, Solana |
Architecture
The widget is only the UI part. The real work happens on the backend:
Frontend Widget │ create order / show address and QR
▼
Backend API │ address generation → DB write → polling/webhook
▼
Blockchain Monitoring Service │ monitors transactions on addresses
▼
Payment Processor │ confirmation → callback to application Integration
- Place the JavaScript widget script on the page and initialize it with an API key.
- Call
createPayment({orderId, amount, currency})—the widget generates an address and QR code. - Handle the
onPaymentConfirmed(paymentData)callback in your application to update the order status.
Technical Implementation
HD Wallet Address Generation
Each payment needs a unique address—otherwise it's impossible to match an incoming payment to a specific order. The standard approach is BIP-44 HD Wallet (see BIP-44): "BIP-44 defines hierarchical deterministic wallets" (Wikipedia).
import { ethers } from 'ethers';
const masterWallet = ethers.HDNodeWallet.fromMnemonic(
ethers.Mnemonic.fromPhrase(process.env.PAYMENT_MNEMONIC!)
);
function derivePaymentAddress(orderId: number): string {
const child = masterWallet.derivePath(`m/44'/60'/0'/0/${orderId}`);
return child.address;
}The mnemonic is stored in HSM or Vault; private keys are never materialized on the server. For multi-currency, different coin types are used according to BIP-44 (60 for Ethereum/EVM, 0 for Bitcoin, 195 for Tron). For EVM networks with identical addresses, one address works across all networks—but each network must be monitored separately.
Transaction Monitoring
Two approaches: polling RPC and webhook subscriptions. Polling is simpler but creates load:
async function pollAddress(address: string, network: string) {
const provider = getProvider(network);
const usdtContract = new ethers.Contract(USDT_ADDRESS, ERC20_ABI, provider);
const filter = usdtContract.filters.Transfer(null, address);
const latestBlock = await provider.getBlockNumber();
const events = await usdtContract.queryFilter(filter, latestBlock - 10, latestBlock);
for (const event of events) {
await processIncomingPayment({
txHash: event.transactionHash,
amount: event.args.value,
token: 'USDT',
network,
});
}
}Webhooks—via Alchemy, QuickNode, or Moralis. Subscribe to address events, receive push on each transaction:
const webhook = await alchemy.notify.createWebhook(
'https://your-api.com/webhook/payment',
WebhookType.ADDRESS_ACTIVITY,
{ addresses: [paymentAddress] }
); Private Key Security
The key risk is compromise of the master mnemonic. We apply multi-layer protection:
- Mnemonic is stored in HashiCorp Vault with on-the-fly encryption and access policies.
- Never use .env files in production.
- Private keys for each address are derived via BIP-44 and never materialized in the application.
- All wallet operations are logged, alerting is set up for suspicious activity.
For particularly sensitive projects, we use a hardware security module (HSM)—for example, AWS CloudHSM or YubiHSM. Multi-signature for withdrawals is also configured: transactions over $10,000 require a second key confirmation.
Confirmations and Double-Spend Protection
Different assets require different numbers of confirmations:
| Asset/network | Recommended confirmations | Time |
|---|---|---|
| ETH / ERC-20 (Ethereum) | 12–20 blocks | ~3–4 min |
| BNB Chain | 15–20 blocks | ~1 min |
| Polygon | 100–150 blocks | ~4–6 min |
| TRON TRC-20 | 20 blocks | ~1 min |
| Bitcoin | 3–6 blocks | ~30–60 min |
Polygon requires more confirmations due to higher reorg probability. Do not mark a payment as final until the required threshold is reached.
For stablecoins: additionally verify that the token contract is official. A user could send a fake token named "USDT". A contract address whitelist is mandatory.
UI/UX and Edge Cases
Widget UI Components
Minimal set for conversion:
┌─────────────────────────────────────┐
│ Pay: 47.50 USDT │
│ │
│ Network: [Ethereum ▼] [BNB Chain ▼] │
│ │
│ [QR code] 0x7f3a...b2c4 │
│ [Copy] │
│ │
│ ⏱ Awaiting payment: 14:32 │
│ ● Waiting for transaction... │
└─────────────────────────────────────┘Critical: session timer (usually 15–30 minutes) after which the address is released and the exchange rate is recalculated. Status updates via WebSocket or SSE—polling every 5 seconds is annoying and creates load.
Fiat-to-crypto conversion: use Chainlink Price Feeds or CoinGecko API with caching. Add a 1–2% buffer to the rate to account for volatility during the waiting period.
Handling Underpayment and Overpayment
Real users often pay an imprecise amount:
- Underpayment (sent less): either block the order pending a top-up, or accept with a "partial payment" flag—depends on business logic.
- Overpayment (sent more): credit the user or automatically return the difference.
- Network fee: for native coins (ETH, BNB) the user must have it in their wallet separately—this UX point must be explained.
What's Included and Project Estimation
- API documentation for integrating the widget with your site.
- A test environment in one of the networks (Goerli/Sepolia) for acceptance.
- Source code with deployment instructions (Docker, CI/CD).
- Integration with your CRM or ERP via webhook callbacks.
- Training your team on the admin panel and monitoring.
- Warranty support for 3 months (included in the price).
Order development of a payment widget for your business—we will evaluate the project in 1-2 days and propose the optimal architecture. Get a consultation: discuss requirements, timeline, and budget. Full control over crypto payments without intermediaries.







