Ethereum Payments Integration for Developers
How to integrate Ethereum payments: choose ETH or tokens, create payment requests, detect and confirm transactions, handle gas, secure keys and test.
Reviewed by Maurice Sobiera

Ethereum payments integration is the work of accepting ETH or tokens in your own application: giving each customer a unique address, detecting the transaction when it lands, deciding when it counts as final, and reconciling it with the order. You can build it on nodes and JSON-RPC, or call an API that handles wallets and notifications.
This guide covers both paths so you can choose with the trade-offs in view.
TL;DR
- An Ethereum payment is a signed transaction that moves ETH or tokens. Submitting it is not the same as confirming it: you must check the receipt.
- Decide first: ETH only, stablecoins and ERC-20 tokens, or your own token. That choice drives your event handling and your gas strategy.
- Use one deposit address per order or user, and listen for events through webhooks instead of polling.
- Treat private keys, webhook signatures and contract code as the three main security surfaces.
- An API such as Chaingateway replaces the node and the block scanner, with plans from €49 per month. Gas settings and the confirmation policy stay your decisions.
What is an Ethereum payment?
An Ethereum payment is a cryptographically signed instruction from an account that updates the state of the network, for example by transferring ETH or tokens. According to ethereum.org’s transaction documentation, a validator then checks the transaction and includes it in a block. Only after that does the money exist at the recipient’s address.
For your application this has a practical consequence. The customer does not pay you. They broadcast a transaction to the network, and your system has to notice it. Everything in an integration is a variation on that observation problem.
There are two kinds of payment you will meet:
- Native ETH transfers. The transaction itself carries a recipient and a value. Simple, and visible directly in the transaction and its receipt.
- Token transfers (ERC-20 and similar). The transaction goes to the token’s contract, which updates balances internally. The standard defines a
Transferevent for this, as laid out in the ERC-20 specification on ethereum.org. Your system learns about the payment from that event log, not from the transaction’s own value field.
Most stablecoin checkouts are the second kind. If you only watch for ETH arriving at an address, you will miss them.
What should you decide before you write code?
Which assets will you accept?
Start with the narrowest set that serves your customers. ETH alone is the easiest to implement. Adding a stablecoin removes price volatility from the equation, which matters for invoices and subscriptions. If you issue your own token, you also need to know its decimals, its contract address and whether it behaves like a standard ERC-20.
Every extra asset adds a contract address to monitor, a decimals value to apply, and a pricing rule. Keep a small allowlist and reject anything else on purpose.
Hosted checkout, payment links or an API?
There are three integration shapes, and they trade control for speed:
| Approach | Best for | You control | You give up |
|---|---|---|---|
| Hosted checkout or payment link | Fast launch, low volume | Almost nothing about the flow | Branding, custody, custom logic |
| Wallet-connect in your own front end | Dapps where users already hold ETH | The user experience | Detection and reconciliation are still yours |
| Backend API with wallets and webhooks | Apps, marketplaces, SaaS billing | Addresses, amounts, order logic | Operating your own infrastructure |
If you are a developer building payments into a product, the third row is usually where you end up. A useful checklist for any provider: does it offer a sandbox, clear error formats, documented rate limits and webhooks that fit your stack?
Custody and compliance
Who holds the keys? If your platform generates deposit wallets for customers, you are handling funds, and depending on your jurisdiction and business model that can carry licensing or reporting obligations. Ask a lawyer who knows your market before launch, not after. This guide is about the engineering, not legal advice.
How does the payment flow work, step by step?
Here is the sequence that holds up in production, whether you build it or buy it.
1. Create a payment request
When the customer reaches checkout, create an order record with an amount, an asset and an expiry. Then assign a unique receiving address to that order. A unique address per order lets you match an incoming transfer to the right customer without asking them to paste a memo or reference.
Price the order in a stable unit, lock an ETH amount for a short window if you accept volatile assets, and store both numbers.
2. The customer signs and submits
If the customer pays from a browser wallet, your front end asks for permission to use their account, builds a transaction object and submits it. MetaMask’s eth_sendTransaction reference describes this order: get account permission, submit the transaction, keep the returned hash. If the customer instead sends from an exchange or a mobile wallet to your displayed address, you never see this step. You only see the result on-chain.
Either way, a transaction hash is the receipt number of the payment. Store it.
3. Detect the transaction
You have three options for noticing a payment:
- Polling. Ask a node for the receipt or the address balance every few seconds. Simple, but wasteful, and fragile at scale.
- Subscriptions. Open a WebSocket to a node and subscribe to new blocks or contract logs. The go-ethereum documentation on real-time events describes
eth_subscribefor exactly this. You must handle dropped connections and replay missed blocks yourself. - Webhooks. A service watches the chain and calls your server when something relevant happens. This is the lowest-maintenance option and the one most teams choose.
For tokens, you are watching event logs. The Ethereum documentation notes that applications can listen for contract events through the JSON-RPC API and act on the logs they emit.
4. Confirm the result
Submission is not confirmation. The MetaMask send-transaction guide shows the pattern: poll for the receipt by hash; no receipt means the transaction is still pending, a status of 0x1 means success, and 0x0 means it failed. The eth_getTransactionReceipt reference adds that the receipt carries the block number, gas used and logs.
Your order state machine should reflect this explicitly:
awaiting_payment: address issued, nothing seen.pending: a matching transaction is visible but not yet in a block.confirmed: receipt found, status successful, amount and asset match.final: enough additional blocks have passed for your risk tolerance.failed,underpaid,overpaidorexpired: the cases that need a rule, not a shrug.
How many blocks to wait before releasing goods is a business decision. Digital goods under a few dollars can ship on the first confirmation. High-value orders deserve a longer wait, because a block can occasionally be reorganized before the network settles on it.
5. Reconcile
Compare, every day, the sum of confirmed payments in your database against what the chain says arrived at your addresses. Any difference is a bug, a missed webhook or a customer who paid the wrong asset. The data and analytics section of ethereum.org lists indexers that serve historical event logs, which can reduce how much of this you maintain yourself.
How do gas, failed transactions and refunds work?
Gas is where many first integrations get surprised. Every transaction pays a fee made of a base fee and a priority fee, and the sender pays it, as the transactions documentation explains. Three consequences follow for you.
- Customers can underpay or stall. If they set a fee too low, the transaction sits pending. Your order should not expire while a valid transaction is in flight.
- Failed transactions still cost gas. A reverted token transfer produces a receipt with a failed status, and the customer’s funds do not move. Do not mark the order paid because you saw a hash.
- Sending from your side costs you. Refunds, sweeps from deposit addresses to a treasury wallet and payouts all require gas, and token addresses need ETH to move tokens. Estimate the fee before sending, and budget for it.
In the Chaingateway API, gas, gasprice, maxFeePerGas and maxPriorityFeePerGas are optional fields of the ERC-20 and ETH transaction endpoints, and GET /api/v2/ethereum/gasprice returns the current gas price. Our guide on how to estimate gas fees on Ethereum and other chains walks through the estimation methods.
If you want customers to pay without holding ETH at all, account abstraction lets developers sponsor transactions, as described in the ethereum.org tutorial on sponsoring gas fees. It adds contract complexity, so reserve it for products where the gas friction really costs you conversions.
For refunds, decide the policy up front. Refund to the sending address only after checking that it is not an exchange deposit address you cannot control, or ask the customer for a refund address. Subtract the network fee openly, or absorb it, but write the rule down.

How do you secure keys, signatures and contracts?
Private keys
Whoever holds the key controls the funds. Generate keys inside a hardened environment, never log them, never commit them, and separate hot wallets (small balances, used for payouts) from cold storage (most of the funds). Sweep deposit addresses to the cold side on a schedule.
Webhook authenticity
A webhook endpoint is a public URL that can mark orders as paid, so anyone who finds it can post a fake event. Protect it in four ways:
- Verify a signature on every request. HMAC signing is the common approach. Where the scheme includes a timestamp, reject stale ones.
- Make the handler idempotent, so that a duplicate delivery does not credit an order twice.
- Confirm amount and recipient with a direct lookup before you release goods.
- Chaingateway’s
X-Signatureheader covers only the transaction ID, as the signature verification article explains, so the lookup matters.
Smart contract code
If you write your own payment contracts, the risk moves to the code. Ethereum’s own security report notes that audits, tested libraries, formal verification and static analysis all improve contract security, and that custom code for advanced controls can increase vulnerability risk. The practical rule: do not deploy a custom contract when a plain address and standard token events are enough for your use case.
Should you build it yourself or use an API?
The do-it-yourself path means running or renting nodes and writing an address generator. You also build the log decoder for every token you accept, estimate gas, handle reorgs and keep all of it running. It is a reasonable path for a team whose product is the payment infrastructure.
For everyone else, the cost is time and ongoing maintenance. The architecture question is whether to receive events as they happen or to reconcile in batches later. For payments, events as they happen are the better default.
Our comparison of blockchain API types and when to use each lays out the categories. The Ethereum overview explains ETH, gas and ERC-20 tokens for teams new to the chain.
How does Chaingateway fit an Ethereum integration?
The Ethereum API lets you send ERC-20 tokens over REST, without web3.js. Three endpoints cover most of a payment flow:
| Step | Endpoint |
|---|---|
| Create a deposit address | POST /api/v2/ethereum/addresses |
| Watch it for incoming ETH or tokens | POST /api/v2/ethereum/webhooks with to, url and type (ETH, ERC20 or ERC721) |
| Send ETH or an ERC-20 token onward | POST /api/v2/ethereum/transactions or .../transactions/erc20 |
An ERC-20 payout needs the sender, recipient, contractaddress and amount, plus the wallet password for wallets that the API created with one. The 422 error for an empty fee balance is insufficient funds for gas * price + value. Test it first on Sepolia by adding the header X-Network: testnet. The Chaingateway Webhooks page and the Blockchain API cover the other supported networks with the same calls.
Failed webhook notifications are not retried automatically. List them with GET /api/v2/ethereum/webhooks/notifications/failed and resend each one.
Plans are billed by usage and features: Plus is €49 per month, Pro €99, Premium €249 and Enterprise €499, or €490, €990, €2,490 and €4,990 per year on annual billing. Every plan starts with a 7-day free trial without a card or KYC. See the pricing page for what each plan includes.

How do you test and monitor an Ethereum payment integration?
A payment integration is not done when the demo works. Run through this list on a test network first, then again with small real amounts:
- Exact payment, underpayment and overpayment of both ETH and each accepted token.
- Late payment after the order expired, and duplicate payment to the same address.
- A failed transaction with a low gas limit, so you see a failed receipt and confirm the order does not complete.
- Duplicate and out-of-order webhooks, replayed deliberately.
- Your own downtime: stop your server for ten minutes, send a payment, restart, and verify that nothing is lost.
- Wallet flows in the front end. QA teams can regression-test them without holding private keys, using tools such as the one listed on ethereum.org’s Impersonator.xyz page.
After launch, alert on three signals: orders stuck in pending longer than a threshold, a gap between database totals and on-chain totals, and webhook delivery failures. The first catches fee problems, the second catches missed events, the third catches your own outages.
Sources
- Transactions, ethereum.org
- ERC-20 Token Standard, ethereum.org
- eth_sendTransaction, MetaMask documentation
- eth_getTransactionReceipt, MetaMask documentation
- Send transactions, MetaMask documentation
- Real-time Events, go-ethereum
- Logging data from smart contracts with events, ethereum.org
- Sponsoring gas fees, ethereum.org
- Security Challenges Overview, ethereum.org
- Data and analytics, ethereum.org
- Impersonator.xyz, ethereum.org
Recommended
Frequently asked questions
No. A node gives you direct access to the chain, but you also inherit its maintenance, syncing and monitoring. Most teams use a provider API or a service that watches the chain for them and calls a webhook when a payment arrives.
Watch the token contract’s Transfer event for your receiving address. The ERC-20 standard defines that event, and a token transfer does not show up as an ETH value on the transaction. A Chaingateway webhook notification carries the sender, recipient, contract address and amount directly.
There is no single correct number. It depends on the order value and your tolerance for the rare chain reorganization. Low-value digital goods can be released early, while high-value orders should wait longer. Write the thresholds into your order logic so support does not decide case by case.
The sender pays it, so customers cover the fee on their own payments and you cover it when you send refunds, sweeps or payouts. Sponsored gas through account abstraction can shift that cost to you for specific flows.
It can if you choose an interface that is not tied to one chain. With Chaingateway, supporting Polygon or Arbitrum later reuses the same wallet, transfer and webhook calls under a different chain name in the path. Tron uses a similar pattern with its own fee model.
Ready to build this yourself? Get your API key — 7-day trial, no card required — or see the Ethereum API for the full endpoint reference.