CoinGate Integration
CoinGate is a payment processor that takes on the complexity of working with many blockchains: accepting BTC, ETH, LTC, USDT and ~70 other coins, converting to EUR/USD, payouts to bank account or crypto wallet. You don't manage keys and monitor blockchains — CoinGate does it for you in exchange for a fee (1% of transaction).
Integration is technically simple, but there are several places where it's easy to go wrong.
API Integration
CoinGate provides REST API v2. Authentication — Bearer token in header. Test environment: https://api-sandbox.coingate.com, production: https://api.coingate.com.
Creating an Order
const axios = require('axios')
const COINGATE_TOKEN = process.env.COINGATE_API_TOKEN
async function createCryptoOrder(params) {
const { orderId, amount, currency, callbackUrl, successUrl, cancelUrl } = params
const response = await axios.post(
'https://api.coingate.com/v2/orders',
{
order_id: orderId, // your internal ID
price_amount: amount, // amount in price_currency
price_currency: currency, // EUR, USD, BTC, etc.
receive_currency: 'EUR', // currency to receive payment in
callback_url: callbackUrl, // webhook for notifications
success_url: successUrl, // redirect after payment
cancel_url: cancelUrl,
title: `Order #${orderId}`,
description: 'Payment for services'
},
{
headers: {
'Authorization': `Token ${COINGATE_TOKEN}`,
'Content-Type': 'application/json'
}
}
)
return {
coingate_id: response.data.id,
payment_url: response.data.payment_url, // URL to redirect user to
status: response.data.status
}
}
The order_id field is your internal identifier, it will be returned in the callback. This is the key field for reconciliation.
Processing Callback (Webhook)
CoinGate sends a POST request to callback_url whenever order status changes. Webhook authenticity verification is mandatory:
app.post('/webhooks/coingate', express.urlencoded({ extended: true }), async (req, res) => {
// CoinGate sends form-encoded data, not JSON
const {
id, // CoinGate order ID
order_id, // your internal ID
status, // pending, confirming, paid, invalid, expired, canceled, refunded
price_amount,
price_currency,
receive_currency,
receive_amount,
pay_amount, // how much crypto received
pay_currency // which coin paid with
} = req.body
// Verification via re-requesting API (CoinGate has no signature in standard API)
const verified = await verifyCoinGateOrder(id, order_id)
if (!verified) {
return res.status(400).send('Verification failed')
}
switch (status) {
case 'paid':
await markOrderPaid(order_id, { pay_currency, pay_amount })
break
case 'invalid':
// wrong amount or other issue — requires manual handling
await flagOrderForReview(order_id)
break
case 'expired':
await cancelOrder(order_id)
break
}
res.sendStatus(200) // always respond 200, else CoinGate will retry
})
async function verifyCoinGateOrder(coingateId, internalOrderId) {
const response = await axios.get(
`https://api.coingate.com/v2/orders/${coingateId}`,
{ headers: { 'Authorization': `Token ${COINGATE_TOKEN}` } }
)
return response.data.order_id === internalOrderId
}
Important: CoinGate does not add HMAC signature to callback by default. Verification via additional GET request to API — standard practice.
Order Statuses
| Status | Meaning | Action |
|---|---|---|
new |
Created, awaiting payment | Show user payment_url |
pending |
Transaction in mempool | Inform user |
confirming |
Transaction in blockchain, awaiting confirmations | Show progress |
paid |
Confirmed, funds received | Execute order |
invalid |
Problem with amount or transaction | Manual handling |
expired |
Payment deadline passed (default: 20 minutes) | Offer to reorder |
canceled |
Cancelled | Release goods/service |
Typical Issues
Underpayment: user paid less due to transfer fees. CoinGate moves order to invalid. Solution: in CoinGate settings you can enable tolerance margin (usually 1–2%).
Callback delay: CoinGate sometimes delays callback under load. Recommended: additionally poll order status every 30–60 seconds for orders in confirming state.
Testing: in sandbox environment use test keys and test coins. Sandbox simulates real confirmation delays — tests with instant paid should be done via direct API call to sandbox with forced status.
What's Included
- CoinGate account registration and configuration (receive currency setup, KYC documentation)
- API client implementation with order creation
- Webhook endpoint with verification and status handling
- Integration with existing order system
- Testing via sandbox environment







