KriptoGo API Documentation
Add USDT (TRC-20) and TRX payments to your site with two endpoints and one webhook. Average integration time is under 30 minutes.
Overview
KriptoGo reserves a dedicated TRON address for every payment, watches the chain continuously and sends a signed notification to your server the moment funds arrive. You write nothing for wallet management, address generation, payment matching or balance collection.
| Field | Value |
|---|---|
| Base URL | https://kriptogo.com |
| OpenAPI schema | /openapi.json (3.1) · /llms.txt for AI tools |
| Protocol | REST over HTTPS, JSON request and response bodies |
| Network | TRON (TRC-20) |
| Supported assets | USDT (TRC-20) and TRX |
| Invoice currency | Denominated in USDT; the customer may also pay in TRX |
| Authentication | Server-to-server apiKey; Bearer token for the dashboard |
Quick start
Get your keys
Copy the apiKey and Secret Key from the Overview page of the dashboard.
Create an invoice
Send the amount from your server; you get a payment address and a hosted checkout link back.
Catch the notification
When the payment is confirmed a webhook hits your URL. Confirm the order there.
The single command below creates a working invoice. Replace YOUR_API_KEY with your own key.
curl -X POST https://kriptogo.com/api/create-invoice \
-H "Content-Type: application/json" \
-d '{"apiKey":"YOUR_API_KEY","amount":49.90,"callbackUrl":"https://yoursite.com/kriptogo-webhook"}'
{
"invoice_id": "7c2f1a90-4d3e-4b1c-9a55-0f8e6d2b1c34",
"address": "TQ5nX8w2fVv3kM1pR7bYc9dLzA4eH6uJt2",
"amount": 49.9,
"network": "TRON",
"status": "PENDING",
"checkout_url": "https://kriptogo.com/checkout.html?id=7c2f1a90-..."
}
Just redirect your customer to checkout_url. A mobile-friendly checkout page with a QR code and countdown is included; you do not need to build your own payment screen.
API keys
| Key | Where it is used |
|---|---|
| apiKey | Sent in the request body when creating an invoice. Identifies your account. |
| secretKey | Never sent anywhere. Used to compute the signature that proves an incoming webhook really came from KriptoGo. |
Store both as environment variables. Do not hard-code them or commit them to version control.
KRIPTOGO_API_KEY=pk_... KRIPTOGO_SECRET_KEY=... KRIPTOGO_BASE_URL=https://kriptogo.com
Payment flow
- The customer clicks Pay with crypto on your site.
- Your server calls
POST /api/create-invoiceand stores theinvoice_idagainst the order in your database. - The customer is redirected to
checkout_urland pays to the address shown. - KriptoGo scans the chain every 30 seconds. When the payment is seen the invoice becomes
PAID. - A signed notification is sent to your webhook URL. You confirm the order.
- The amount is added to your dashboard balance; withdraw it to your own wallet whenever you like.
GET /api/status/:id every few seconds instead.Create invoice
Opens a new payment request and reserves a customer-specific TRON address.
Request body
| Field | Type | Description |
|---|---|---|
| apiKey | string required | Your API key from the dashboard. |
| amount | number required | Amount to collect, in USDT. Must be greater than zero. |
| callbackUrl | string optional | Webhook URL for this invoice. If omitted, the default webhook URL from the dashboard is used. Only public https URLs are accepted; local or private network addresses are rejected. |
| returnUrl | string optional | Where the customer is redirected once the payment completes. If omitted, the project URL saved in the dashboard is used. |
Response fields
| Field | Description |
|---|---|
| invoice_id | Unique id of the invoice. Store it to match against your order. |
| address | TRON address the customer pays to. |
| amount | Expected amount (USDT). |
| network | Always TRON. |
| status | PENDING on creation. |
| expires_at | Payment deadline (ISO 8601, 10 minutes after creation). |
| checkout_url | Link to the hosted checkout page. |
const res = await fetch('https://kriptogo.com/api/create-invoice', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ apiKey: process.env.KRIPTOGO_API_KEY, amount: 49.90, callbackUrl: 'https://yoursite.com/kriptogo-webhook' }) }); const invoice = await res.json(); // redirect to invoice.checkout_url
<?php $body = json_encode([ 'apiKey' => getenv('KRIPTOGO_API_KEY'), 'amount' => 49.90, 'callbackUrl' => 'https://yoursite.com/kriptogo-webhook', ]); $ch = curl_init('https://kriptogo.com/api/create-invoice'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => $body, CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_RETURNTRANSFER => true, ]); $invoice = json_decode(curl_exec($ch), true); curl_close($ch); header('Location: ' . $invoice['checkout_url']);
import os, requests r = requests.post( "https://kriptogo.com/api/create-invoice", json={ "apiKey": os.environ["KRIPTOGO_API_KEY"], "amount": 49.90, "callbackUrl": "https://yoursite.com/kriptogo-webhook", }, timeout=15, ) invoice = r.json() # redirect to invoice["checkout_url"]
Invoice status
Returns the current state of an invoice. The checkout page polls this endpoint every few seconds; you can use it instead of, or in addition to, webhooks.
{
"id": "7c2f1a90-4d3e-4b1c-9a55-0f8e6d2b1c34",
"amount": 49.9,
"address": "TQ5nX8w2fVv3kM1pR7bYc9dLzA4eH6uJt2",
"currency": "USDT",
"status": "PAID",
"txHash": "9f1c...e3a",
"paidAmount": 49.9,
"expiresAt": "2026-09-05T10:34:11.000Z",
"createdAt": "2026-09-05T10:24:11.000Z",
"trxPrice": 0.331732,
"trxAmount": 150.42
}
trxAmount is the amount required if the customer chooses to pay in TRX, calculated at the current rate. This endpoint is public and needs no API key, so you can call it from the frontend too.
Webhook
When a payment is confirmed KriptoGo sends a JSON POST request to the invoice's callbackUrl (or the default URL saved in the dashboard). On failure it retries after 1 and 2 seconds, three attempts in total.
{
"event": "payment.confirmed",
"invoice_id": "7c2f1a90-4d3e-4b1c-9a55-0f8e6d2b1c34",
"amount": "49.9",
"paid_amount": "49.9",
"currency": "USDT",
"address": "TQ5nX8w2fVv3kM1pR7bYc9dLzA4eH6uJt2",
"tx_hash": "9f1c...e3a",
"status": "PAID",
"timestamp": "2026-09-05T10:31:02.415Z"
}
amount is the invoice amount; paid_amount is what was actually received on-chain (USDT equivalent). Your balance is credited with paid_amount. The two may differ slightly (default tolerance 2%); compare paid_amount with your own amount before confirming the order.Headers sent
| Header | Description |
|---|---|
| X-Kriptogo-Signature | HMAC-SHA256 signature of the body computed with your secret key (hex). |
| X-Kriptogo-Signature-256 | The same signature with the sha256= prefix. |
| User-Agent | Kriptogo-Webhook/1.0 |
200 within 10 seconds. Do slow work (sending email, updating stock) in the background after responding.Signature verification
Never confirm an order without verifying that the request really came from KriptoGo. The signature is computed over the raw body text; if you parse the body into an object and serialize it again, the signature may not match.
const express = require('express'); const crypto = require('crypto'); const app = express(); // Keep the raw body; the signature is computed over it app.use('/kriptogo-webhook', express.json({ verify: (req, res, buf) => { req.rawBody = buf.toString('utf8'); } })); app.post('/kriptogo-webhook', (req, res) => { const expected = crypto .createHmac('sha256', process.env.KRIPTOGO_SECRET_KEY) .update(req.rawBody) .digest('hex'); const received = req.get('X-Kriptogo-Signature') || ''; const ok = received.length === expected.length && crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected)); if (!ok) return res.status(401).send('invalid signature'); const { invoice_id, status, amount, tx_hash } = req.body; if (status === 'PAID') { // Confirm the order here. Ignore a repeated invoice_id. } res.sendStatus(200); });
<?php $raw = file_get_contents('php://input'); $received = $_SERVER['HTTP_X_KRIPTOGO_SIGNATURE'] ?? ''; $expected = hash_hmac('sha256', $raw, getenv('KRIPTOGO_SECRET_KEY')); if (!hash_equals($expected, $received)) { http_response_code(401); exit('invalid signature'); } $data = json_decode($raw, true); if (($data['status'] ?? '') === 'PAID') { // Confirm the order: $data['invoice_id'], $data['amount'], $data['tx_hash'] } http_response_code(200); echo 'ok';
import hmac, hashlib, os from flask import Flask, request app = Flask(__name__) @app.post("/kriptogo-webhook") def webhook(): raw = request.get_data() expected = hmac.new( os.environ["KRIPTOGO_SECRET_KEY"].encode(), raw, hashlib.sha256 ).hexdigest() if not hmac.compare_digest(expected, request.headers.get("X-Kriptogo-Signature", "")): return "invalid signature", 401 data = request.get_json() if data.get("status") == "PAID": pass # Confirm the order return "ok", 200
invoice_id can arrive again. Check whether it was already processed before confirming the order.Invoice statuses
| Status | Meaning |
|---|---|
| PENDING | Invoice open, awaiting payment. |
| PAID | Payment seen on-chain and confirmed. You can deliver the order. |
| EXPIRED | Expired without payment. Late payments are still tracked for 30 more minutes. |
Error codes
Failed requests return a body of the form { "error": "description" }. Validation errors also include a detail field naming the invalid field.
| Code | Meaning | What to do |
|---|---|---|
| 400 | Missing or invalid field | Check that amount is a number above zero and that apiKey was sent. |
| 403 | Account not approved | Submit your project details in the dashboard and wait for approval. Unapproved accounts cannot create invoices. |
| 404 | Key or invoice not found | Copy the key again from the dashboard and make sure no whitespace remains. |
| 409 | Address conflict | Retry the request after a few seconds. |
| 429 | Too many open invoices or requests | The concurrent open-invoice limit was reached (default 10). Retry once invoices close. |
| 503 | All pool addresses in use | Wait briefly and retry. Addresses free up as open invoices close. |
| 500 | Server error | Retry; contact support if it persists. |
Limits and timing
| Item | Value |
|---|---|
| Invoice lifetime | 10 minutes |
| Late payment tracking | 30 more minutes after expiry |
| Chain scan | Every 30 seconds |
| Webhook attempts | 3 attempts, 10-second timeout |
| Concurrent invoices | Up to the size of the address pool. Returns 503 when the pool is full. |
Node.js / Express full example
Starting a payment and receiving the webhook together. Drop this file into your project and fill in the environment variables.
const express = require('express'); const crypto = require('crypto'); const app = express(); const BASE = 'https://kriptogo.com'; const KEY = process.env.KRIPTOGO_API_KEY; const SECRET = process.env.KRIPTOGO_SECRET_KEY; // 1) Start a payment app.post('/start-payment', express.json(), async (req, res) => { const { orderId, amount } = req.body; const r = await fetch(BASE + '/api/create-invoice', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ apiKey: KEY, amount: Number(amount), callbackUrl: 'https://yoursite.com/kriptogo-webhook' }) }); const inv = await r.json(); if (!r.ok) return res.status(400).json({ error: inv.error }); // store the invoice_id -> orderId mapping in your database await db.orders.update(orderId, { invoiceId: inv.invoice_id, status: 'awaiting_payment' }); res.json({ checkoutUrl: inv.checkout_url }); }); // 2) Payment notification app.use('/kriptogo-webhook', express.json({ verify: (req, _res, buf) => { req.rawBody = buf.toString('utf8'); } })); app.post('/kriptogo-webhook', async (req, res) => { const expected = crypto.createHmac('sha256', SECRET).update(req.rawBody).digest('hex'); const got = req.get('X-Kriptogo-Signature') || ''; if (got !== expected) return res.status(401).send('bad signature'); res.sendStatus(200); // Respond first const { invoice_id, status, amount, tx_hash } = req.body; if (status !== 'PAID') return; const order = await db.orders.findByInvoice(invoice_id); if (!order || order.status === 'paid') return; // Ignore a repeated notification await db.orders.update(order.id, { status: 'paid', txHash: tx_hash, paidAmount: amount }); // Deliver the product, send a confirmation email... }); app.listen(3000);
PHP full example
<?php // Read the cart total, create the invoice, send the customer to the checkout page $amount = (float) $_POST['amount']; $ch = curl_init('https://kriptogo.com/api/create-invoice'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_POSTFIELDS => json_encode([ 'apiKey' => getenv('KRIPTOGO_API_KEY'), 'amount' => $amount, 'callbackUrl' => 'https://yoursite.com/kriptogo-webhook.php', ]), CURLOPT_TIMEOUT => 15, ]); $invoice = json_decode(curl_exec($ch), true); curl_close($ch); if (empty($invoice['checkout_url'])) { die('Could not create invoice: ' . ($invoice['error'] ?? 'unknown error')); } // match invoice_id with your order, then redirect $_SESSION['invoice_id'] = $invoice['invoice_id']; header('Location: ' . $invoice['checkout_url']);
Python (Flask) full example
import os, hmac, hashlib, requests from flask import Flask, request, jsonify, redirect app = Flask(__name__) BASE = "https://kriptogo.com" @app.post("/start-payment") def start_payment(): amount = float(request.form["amount"]) r = requests.post(f"{BASE}/api/create-invoice", json={ "apiKey": os.environ["KRIPTOGO_API_KEY"], "amount": amount, "callbackUrl": "https://yoursite.com/kriptogo-webhook", }, timeout=15) inv = r.json() if not r.ok: return jsonify(error=inv.get("error")), 400 # match inv["invoice_id"] with your order return redirect(inv["checkout_url"]) @app.post("/kriptogo-webhook") def webhook(): raw = request.get_data() expected = hmac.new(os.environ["KRIPTOGO_SECRET_KEY"].encode(), raw, hashlib.sha256).hexdigest() if not hmac.compare_digest(expected, request.headers.get("X-Kriptogo-Signature", "")): return "bad signature", 401 data = request.get_json() if data.get("status") == "PAID": pass # Confirm the order (ignore a repeated invoice_id) return "ok", 200
Frontend: payment button
The frontend never calls KriptoGo directly; it calls the endpoint on your own server and redirects to the link it returns.
<button id="payBtn">Pay with crypto (49.90 USDT)</button> <script> document.getElementById('payBtn').onclick = async () => { const r = await fetch('/start-payment', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ orderId: 'ORD-1042', amount: 49.90 }) }); const d = await r.json(); if (d.checkoutUrl) window.location.href = d.checkoutUrl; }; </script>
Building your site with AI?
If you build with tools like Lovable, v0, Bolt, Cursor, ChatGPT or Claude, you do not need to code the integration yourself. The Setup prompt section of the dashboard generates a ready-made instruction pre-filled with your own API key. Copy it and paste it into your AI tool.
Frequently asked questions
Is there a test environment?
KriptoGo runs on TRON mainnet. Test your integration with a small live amount; contact support if you need help.
What if the customer underpays?
The invoice does not become PAID unless the expected amount is met (within a small tolerance). It is still good practice to compare paid_amount in the webhook with your own order amount.
Is the same address given to another customer?
While an invoice is open its address is locked and not assigned to any other invoice. When the invoice closes the address returns to the pool.
Can the customer pay in TRX?
Yes. The checkout page also shows the TRX equivalent at the current rate. Both assets are detected automatically.
When can I withdraw my money?
Confirmed payments are credited to your dashboard balance. Enter your own TRON address in the Withdraw section of the dashboard to request a withdrawal at any time.
How is the commission calculated?
Commission is deducted only from successful payments and the net amount is credited to your balance. There is no fixed monthly fee.
