Recent Payments Received
My Smart Contracts
Each store has its dedicated contract on Polygon/Arbitrum/Base (USDT ERC-20).
Manage Your On-Chain Contract
Connect your wallet and paste the contract in the search box
Create Your Cryptocurrency
Connect your wallet and fill in the data below to create your ERC-20 token
Token will be created with 18 decimals • You will be the initial owner
Paynch Quick Payment Button
Paste the code below on any page of your website to add the crypto checkout button in 1 line. It handles wallet connection, USDT payment, and automatic verification.
See Button Example (click to load with your data)
Ready to copy code (updates when editing above):
<!-- Click "See example" or edit fields above to generate -->
⚙️ Integrations & API
🚀 100% on-chain and frontend-only system.
There is no Paynch backend, API keys, or centralized webhook.
All execution happens directly in the client's browser via Web3.js.
📦 Choose your integration type
⚙️ Manual Integration (Advanced)
Full control over UI/UX and payment flow. For developers who need complete customization.
- ✅ 100% customizable UI
- ✅ Integration with complex systems
- ✅ Advanced tracking and analytics
- ✅ Personalized checkout flows
⚙️ Manual Integration - Complete Documentation
1. Required libraries
Paste the scripts below before closing the </body> tag of your checkout:
<!-- Process polyfill for Web3 v4 -->
<script type="module">
window.process = { browser: true, env: { ENVIRONMENT: 'BROWSER' } };
</script>
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<!-- Web3.js v4 -->
<script src="https://unpkg.com/web3@4.0.1/dist/web3.min.js"></script>
<!-- Paynch Script (paynch-connect-pt.js para português, paynch-connect-en for english and paynch-connect-es.js para español ) -->
<script type="module" src="https://pay.paynch.io/js/paynch-connect.js"></script>
2. Required URL parameters
The checkout page MUST contain these parameters via GET:
https://yourstore.com/checkout.php?shop=0xE5fF9d546278a7CE0DF261EB85945Df2F0Dcc3c6&orderId=ORD_1738368123_a1b2c3&amount=15.00
| Parameter | Type | Description | Example |
|---|---|---|---|
shop |
String | Store contract address (42 chars) | 0xE5fF...c3c6 |
orderId |
String | Unique order ID (8-20 alphanumeric chars) | ORD_1738368123 |
amount |
Number | Amount in USDT (use decimal point) | 15.00 |
💡 Tip: Add parameters automatically with JavaScript:
<script>
const url = new URL(window.location);
const params = {
shop: '<?= $contract ?>',
orderId: '<?= $orderId ?>',
amount: '<?= $amount ?>'
};
Object.keys(params).forEach(key => {
if (!url.searchParams.has(key)) {
url.searchParams.set(key, params[key]);
}
});
history.replaceState(null, '', url.toString());
</script>
3. Required HTML Elements
The Paynch script depends on these specific IDs. Do not change them!
<!-- Action buttons --> <button id="connect-wallet">🔌 Connect Wallet</button> <button id="pay-button">🚀 Pay <?= $valor ?> USDT</button> <!-- Payment status --> <div id="pay-status"> 💳 Connect your wallet to continue </div>
❌ DO NOT change these IDs:
connect-wallet,
pay-button,
pay-status,
amount-input,
order-id-input,
contract-input
4. Payment Verification API
After the user pays, use this API to verify whether the transaction has been confirmed on the blockchain:
Endpoint:
GET https://api.paynch.io/paynch.php
📋 Request Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
contract |
string | ✅ Yes | Store smart contract address |
orderId |
string | ✅ Yes | Unique order ID |
📤 Call example:
GET https://api.paynch.io/paynch.php?contract=0xE5fF9d546278a7CE0DF261EB85945Df2F0Dcc3c6&orderId=ORD_123456
📥 JSON response:
When the payment was NOT detected:
{
"success": true,
"count": 0,
"payments": []
}
When the payment WAS confirmed:
{
"success": true,
"count": 1,
"payments": [
{
"customer": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"amount": "15000000",
"amountHuman": "15.00",
"code": "0xa1b2c3d4e5f6...",
"orderId": "ORD_123456",
"timestamp": 1738368000,
"timestampFormatted": "2026-01-31 15:30:00"
}
]
}
🔍 Response fields:
| Field | Type | Description |
|---|---|---|
success |
boolean | Query status (always true on success) |
count |
integer | Number of confirmed payments (0 = pending) |
payments |
array | List of payments (empty if count = 0) |
customer |
string | Wallet address that made the payment |
amount |
string | Amount in wei (6 decimals for USDT) |
amountHuman |
string | Formatted amount in USDT (e.g. "15.00") |
code |
string | Blockchain transaction hash |
orderId |
string | Order ID (same as sent in the request) |
timestamp |
integer | Unix confirmation timestamp |
timestampFormatted |
string | Formatted date (YYYY-MM-DD HH:MM:SS) |
5. 💻 Code Examples
🔹 PHP (Backend) - Server-side validation:
<?php
// Configuration
$contract = '0xE5fF9d546278a7CE0DF261EB85945Df2F0Dcc3c6';
$orderId = $_GET['orderId'] ?? 'ORD_123456';
// Query Paynch API via cURL (recommended)
$url = "https://api.paynch.io/paynch.php?" . http_build_query([
'contract' => $contract,
'orderId' => $orderId
]);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
die('Error querying API');
}
$data = json_decode($response, true);
// Full validation
if ($data['success'] && $data['count'] > 0) {
$payment = $data['payments'][0];
// Get expected amount from database
$expectedAmount = 15.00; // Fetch from database
$receivedAmount = floatval($payment['amountHuman']);
// 1.2% tolerance (platform fees)
$tolerance = $expectedAmount * 0.012;
if ($receivedAmount >= ($expectedAmount - $tolerance)) {
// ✅ PAYMENT CONFIRMED!
echo "✅ Payment confirmed!
";
echo "Amount: " . $payment['amountHuman'] . " USDT
";
echo "Customer: " . $payment['customer'] . "
";
echo "TX Hash: " . $payment['code'] . "
";
// RELEASE THE PRODUCT HERE
releaseProduct($orderId);
} else {
echo "❌ Insufficient amount. Expected: {$expectedAmount}, Received: {$receivedAmount}";
}
} else {
echo "⏳ Payment pending...";
}
?>
🔹 JavaScript (Frontend) - Automatic verification:
// Configuration
const CONFIG = {
CONTRACT: '0xE5fF9d546278a7CE0DF261EB85945Df2F0Dcc3c6',
ORDER_ID: 'ORD_123456',
EXPECTED_AMOUNT: 15.00,
MAX_ATTEMPTS: 20,
INTERVAL_MS: 5000 // 5 seconds
};
let attempts = 0;
// Verification function
async function verifyPayment() {
attempts++;
const url = `https://api.paynch.io/paynch.php?contract=${CONFIG.CONTRACT}&orderId=${CONFIG.ORDER_ID}`;
try {
const response = await fetch(url);
const data = await response.json();
if (data.success && data.count > 0) {
const payment = data.payments[0];
const receivedAmount = parseFloat(payment.amountHuman);
const tolerance = CONFIG.EXPECTED_AMOUNT * 0.012; // 1.2%
if (receivedAmount >= (CONFIG.EXPECTED_AMOUNT - tolerance)) {
console.log('✅ Payment confirmed!');
console.log('Amount:', payment.amountHuman, 'USDT');
console.log('TX:', payment.code);
// Redirect to success page
window.location.href = 'success.php?orderId=' + CONFIG.ORDER_ID;
return true;
}
} else {
console.log(`⏳ Waiting for confirmation... (${attempts}/${CONFIG.MAX_ATTEMPTS})`);
}
return false;
} catch (error) {
console.error('Error while verifying:', error);
return false;
}
}
// Start automatic verification after clicking "Pay"
document.getElementById('pay-button')?.addEventListener('click', () => {
setTimeout(() => {
const interval = setInterval(async () => {
const confirmed = await verifyPayment();
if (confirmed || attempts >= CONFIG.MAX_ATTEMPTS) {
clearInterval(interval);
if (!confirmed) {
alert('Time limit reached. Please verify manually.');
}
}
}, CONFIG.INTERVAL_MS);
}, 3000); // Wait 3s before starting
});
6. 🛡️ Mandatory Security Validations
⚠️ CRITICAL: Always validate on the backend before releasing products!
- ✅ Check if
data.success === true - ✅ Check if
data.count > 0 - ✅ Compare
amountHumanwith the expected amount - ✅ Implement a 1.2% tolerance for fees
- ✅ Validate that
orderIdexists in the database - ✅ Avoid processing the same
orderIdmultiple times - ✅ Log all validations
Example of secure validation with tolerance:
<?php
// Values
$expectedAmount = 15.00; // From the database
$receivedAmount = 14.82; // From the API (after fees)
// 1.2% tolerance (covers platform fees)
$tolerance = $expectedAmount * 0.012; // 0.18 USDT
$minimumAmount = $expectedAmount - $tolerance; // 14.82 USDT
if ($receivedAmount >= $minimumAmount) {
// ✅ Valid payment (within tolerance)
$pdo->prepare("UPDATE orders SET status = 'confirmed' WHERE order_id = ?")
->execute([$orderId]);
releaseProduct($orderId);
sendEmail($customer);
} else {
// ❌ Insufficient amount
logError("Insufficient amount: expected {$expectedAmount}, received {$receivedAmount}");
}
?>
7. 💡 Best Practices
⚡ Automatic Verification
- Check every 3–5 seconds
- Maximum of 20 attempts (100s)
- Wait 3s after payment before starting
- Stop after confirmation or timeout
🔐 Security
- Generate unique and unpredictable Order IDs
- Use database transactions (BEGIN/COMMIT)
- Implement rate limiting
- Always validate on the backend
📊 Logs & Audit
- Log all API queries
- Log confirmations and failures
- Store TX hash in the database
- Notify duplicate payments
🎯 UX
- Show a loading spinner during verification
- Display the number of attempts
- Automatically redirect after confirmation
- Provide a manual verification button
8. 🔄 Complete Integration Flow
URL contains: shop, orderId, amount
MetaMask/Trust Wallet connects to BSC
USDT transaction submitted to the blockchain
Frontend queries the API every 5 seconds
API returns count > 0 with transaction data
PHP verifies amount, tolerance, and marks as "confirmed"
Email sent, product delivered, order completed
User sees confirmation and purchase details