Polygon Payments Integration: Developer Guide
How to integrate payments on Polygon: choose the network and token, manage wallets, send and verify transfers, handle webhooks, and test before launch.
Reviewed by Maurice Sobiera

A Polygon payments integration is the set of components that lets your application accept and send tokens on the Polygon PoS network: wallets, transfers, verification and notifications. You can build each component against raw nodes, or call a REST API that provides wallets, transfers and webhooks. This guide covers both paths.
TL;DR
- Polygon PoS has chain ID 137 and uses POL for gas. The Amoy testnet has chain ID 80002.
- A payment is only done when you have checked the transaction status, recipient, amount and token contract. A hash alone is not proof.
- Use webhooks, not polling, to track payments. Verify the signature and make your handler idempotent.
- Chaingateway webhooks are not retried automatically, so reconcile against the notification list.
- Plan for legal scope, key custody, nonce conflicts and gas swings before launch, not after.
Table of Contents
- What does a Polygon payment integration include?
- Which network and token should I choose?
- How do I set up wallets and protect the keys?
- How do I send a token payment on Polygon?
- How do I verify that a payment arrived?
- How do I get notifications with webhooks?
- How should I design the backend?
- What should I check before launch?
- FAQ
- Sources
What does a Polygon payment integration include?
A payment integration is more than sending tokens. A working gateway manages user wallets, tracks each transaction’s state through webhooks, and reconciles balances in a database. The chain only tells you what happened. Your backend decides what it means for an order, an invoice or a balance.
In practice, you build five components:
- Wallet layer: addresses to receive funds and keys to send them.
- Transfer layer: code that builds, signs and broadcasts token transfers.
- Verification layer: checks that a transfer really happened as expected.
- Notification layer: webhooks that tell your app about status changes.
- Ledger: your own database record of what is owed, paid and settled.
The first four are chain plumbing. The fifth is your product. The less time you spend on the plumbing, the sooner you ship the part customers see.
Do I need a license?
Work out where you operate and which rules apply before you write code. In the EU, the Markets in Crypto-Assets Regulation (MiCA) regulates crypto-asset service providers, as described on the ESMA MiCA page. In the US, FinCEN’s guidance on virtual currencies describes when administering or exchanging virtual currency makes you a money transmitter.
Whether your model triggers any rule depends on whether you hold or move funds for others. That question is for a lawyer who knows payments, not for a code review. Ask it before launch, because the answer can change whether you custody funds at all.
Which network and token should I choose?
Choose Polygon PoS with a stablecoin such as USDC or USDT for most payment products. The Polygon documentation lists chain ID 137 and POL as the gas token for mainnet, and chain ID 80002 for the Amoy testnet. Hard-code the chain ID in your signing code, so that a transaction can never be broadcast to the wrong network.
Fees are the reason teams pick Polygon, but they move with congestion and the POL price. Design your fee handling around ranges and read the current gas price at send time. With Chaingateway, GET /api/v2/polygon/gasprice returns it.
Ethereum is the alternative for customers who prefer its liquidity and settlement. If you need both, one API across chains means you write the payment flow once. See the Ethereum API for the other side of that setup.
Your sending wallets need POL for gas, even when the asset being sent is a stablecoin. When you fund a wallet from a trading venue, pick Polygon as the withdrawal network and check the network label before you confirm. A withdrawal on the wrong network is a common way to lose funds during setup.
| Decision | Typical choice for payments | Why |
|---|---|---|
| Network | Polygon PoS (chain ID 137) | Low fees |
| Payment token | USDC or USDT (ERC-20) | Stable value, familiar to customers |
| Gas token | POL | Required for every transaction |
| Notifications | Webhooks | No polling |
How do I set up wallets and protect the keys?
There are two common patterns:
- One address per customer or invoice. Each payment gets its own deposit address. Matching an incoming transfer to an order is then trivial, because the recipient address identifies it. The cost is more addresses to manage and, later, sweeping funds to a treasury wallet.
- One shared address with references. This is simpler to operate, but a plain token transfer carries no reference field. You end up matching on amount and timing, which breaks when two customers pay the same amount.
For most commerce flows, per-order addresses are the cleaner design. Whatever you choose, keep these habits:
- Never keep private keys in source control, logs or client-side code.
- Separate receiving wallets from the treasury that holds your balance, so that a compromise of one does not expose the other.
- Limit who and what can trigger an outgoing transfer, and log every request.
- Back up key material in a way that survives the loss of one person or one server.
Chaingateway is non-custodial. POST /api/v2/polygon/addresses creates a wallet. If you send a password, the private key is stored encrypted with it, and you use the password instead of the key when you send a transaction. Chaingateway does not store the password and cannot restore a wallet if you lose it. See create a crypto wallet with an API for the call flow.
How do I send a token payment on Polygon?
Polygon PoS is EVM-compatible, so token transfers follow the ERC-20 standard. The ERC-20 specification defines two payment patterns:
- Direct payment: the payer calls
transfer(recipient, amount), which emits aTransferevent. - Contract-mediated pull payment: the payer first calls
approve(spender, amount), then the authorized contract callstransferFrom(sender, recipient, amount).
For a simple checkout, a direct transfer is enough. Approvals matter when a smart contract collects the money, as in subscriptions or escrow. Keep approvals narrow: approve the amount you need, not an unlimited allowance.
How do I send with raw node code?
Sending directly means you build the transaction, estimate gas, set the nonce, sign, broadcast, and watch for inclusion. That is manageable for a prototype. In production, you also need a reliable RPC provider, retry logic and a way to replace stuck transactions. Our guide on sending ERC-20 tokens compares the wallet, code and API methods.
How do I send with one REST call?
With Chaingateway, a token transfer is one authenticated request. It names the sender, the token contract, the recipient and the amount. The gas fields are optional. The OpenAPI definition marks from, contractaddress, to and amount as required.
curl -X POST https://app.chaingateway.io/api/v2/polygon/transactions/erc20 \ -H "Authorization: Bearer $CHAINGATEWAY_TOKEN" \ -H "X-Network: testnet" \ -H "Content-Type: application/json" \ -d '{ "from": "0xSenderAddress", "contractaddress": "0xTokenContract", "to": "0xRecipientAddress", "amount": 25.5, "password": "wallet-password" }'X-Network: testnet runs the request on Amoy. Leave the header out for mainnet. The same pattern works on the other EVM chains, so adding a second chain later changes the path, not the flow. See the Polygon API page and the OpenAPI file for the full list of endpoints.
How do I verify that a payment arrived?
A transaction hash only proves that a transaction was submitted. Before you mark an order paid, check the transaction status, the recipient, the token transfer amount and the token contract. ERC-20 transfers are recorded in Transfer event logs, as defined in the ERC-20 specification, so the log is where you read the real transfer.
The contract check is the one teams forget. Anyone can deploy a token named “USDC” that is worthless. Compare the contract address in the log with the address you whitelisted. Your verification routine should confirm all of these:
- The transaction succeeded, not just that it was mined.
- The
Transferevent came from your expected token contract. - The recipient matches the address you issued for this order.
- The amount is at least what you invoiced, in the token’s smallest unit.
- Enough blocks have passed for your risk tolerance before you release goods.
Reading raw logs means decoding topics and data by hand. Our explainer on the ERC-20 Transfer event shows the structure. Chaingateway also returns decoded transactions with GET /api/v2/polygon/transactions/{txid}/decoded.
How do I get notifications with webhooks?
Polling an address every few seconds wastes requests and still lags. With a webhook, the service calls your endpoint when a matching transaction is detected. Create one with POST /api/v2/polygon/webhooks. The url field is required, and you filter by to, from or contractaddress. See Polygon webhooks for the mechanics.
How do I build the receiver safely?
These rules apply to any provider:
- Verify the signature. Chaingateway adds an
X-Signatureheader once you set a personal secret. It is a Base64-encoded HMAC-SHA256 of the transaction ID, keyed with your secret. See Verify webhook signatures. - Compare in constant time. Use your language’s secure compare function, not
==. - Answer fast. Return a 2xx status immediately and do the heavy work in a queue.
- Expect duplicates. You can receive the same event twice, for example after you re-send a notification. Store a transaction ID and ignore repeats.
- Expect missed events. Chaingateway does not retry failed notifications automatically. List them with
GET /api/v2/polygon/webhooks/notifications/failedand re-send each withPOST /api/v2/polygon/webhooks/notifications/{id}/retry.
Which payment states should I store?
Keep payment states small and explicit: awaiting_payment, pending, confirmed, failed, expired. Each webhook maps to at most one transition. If a failed event arrives for a payment that is already confirmed, log it and alert a human instead of overwriting the state.
How should I design the backend?
Keep chain-specific code at the edges. Put an internal interface in front of the chain, with methods such as createDepositAddress, sendPayment and getPaymentStatus, and keep your order logic on the other side of it. Adding a chain then means adding an implementation of that interface, not rewriting the core.
The ledger should be yours. Never treat the chain or a provider dashboard as your book of record. Store every expected payment, every observed transfer and the link between them, so that you can reconcile at the end of the day and explain any gap.
What should I check before launch?
Test three things in particular: failed transactions, nonce conflicts and gas price changes.
Before launch
- Run the whole flow on the Amoy testnet: create an address, pay it, receive the webhook, mark the order paid.
- Replay each webhook twice and confirm that the second delivery changes nothing.
- Send a payment in the wrong token, with the wrong amount (under and over) and to an expired order. Decide and test what happens in each case.
- Break your endpoint on purpose with a 500 error and a timeout, then list the failed notifications and re-send them.
- Fire two transfers from the same wallet at once to expose nonce conflicts.
At launch
- Start with low limits and one token.
- Alert on any transfer that stays pending beyond your threshold.
- Watch the gas wallet balance, because an empty POL balance stops every outgoing payment.
- Rotate your personal secret on a schedule and update your receiver at the same time.
Common mistakes
- Trusting the hash instead of the event log.
- Trusting a webhook before verifying the signature.
- Hard-coding a gas price.
- Skipping the token contract check.
- Keeping hot-wallet keys and treasury keys together.
Plans start at €49 per month (€490 per year) with a 7-day free trial that needs no card. See the pricing page.
Sources
- Polygon documentation: RPC endpoints and chain IDs
- ERC-20: Token Standard
- ESMA: Markets in Crypto-Assets Regulation (MiCA)
- FinCEN: guidance on persons administering, exchanging or using virtual currencies
Recommended
Frequently asked questions
Most payment products accept a stablecoin such as USDC or USDT, because the price does not swing between invoice and payment. You still need a small POL balance on any wallet that sends transactions, since POL pays the gas. Whitelist the exact token contract addresses you accept and reject everything else.
No. You can use a hosted RPC provider or a blockchain API that handles node access for you. Running your own node makes sense only if you have specific latency, privacy or compliance needs and the team to maintain it.
Store a unique transaction ID for every payment you process, and check it before you change any order state. An idempotent handler turns a repeated event into a harmless no-op.
It depends on what you value. Polygon PoS usually costs less per transaction than Ethereum mainnet. Ethereum has the larger base of users and liquidity. Many teams support both and let the customer pick.
Ready to build this yourself? Get your API key — 7-day trial, no card required — or see the Polygon API for the full endpoint reference.