Add payments to your website in 5 minutes. SDK v5.0
Create an account, then go to your Dashboard to find these keys:
pk_live_xxxxxxxxUse in your frontend / SDK. Safe to expose in browser.
sk_live_xxxxxxxxUse ONLY on your server. Never put this in frontend code.
whsec_xxxxxxxxUse to verify webhook signatures on your server.
When a customer clicks "Buy" on your site, your server creates an order using the Secret Key:
// This runs on YOUR backend — never in the browser
app.post('/api/create-order', async (req, res) => {
const { amount, productName, userId } = req.body;
const response = await fetch('https://YOUR_GATEWAY_URL/api/v1/orders', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer sk_live_YOUR_SECRET_KEY' // Secret key
},
body: JSON.stringify({
amount: amount, // Amount in INR (e.g. 499)
currency: 'INR',
receipt: 'order_' + Date.now(), // Your internal reference
customer: {
name: 'Customer Name',
email: 'customer@email.com',
phone: '9876543210'
}
})
});
const data = await response.json();
// Send order_id back to your frontend
res.json({
order_id: data.data.id, // e.g. "order_abc123"
payment_id: data.data.payment_id
});
});{
"success": true,
"data": {
"id": "order_abc123",
"payment_id": "pay_xyz789",
"amount": 499,
"status": "created"
}
}Add the SDK script tag and open the payment modal. The SDK handles everything — QR code, UPI apps, Razorpay, Binance crypto.
<!-- 1. Add PayGate SDK v5.0 -->
<script src="https://YOUR_GATEWAY_URL/sdk/pay.js"></script>
<!-- 2. Payment button -->
<button onclick="pay()">Pay ₹499</button>
<script>
async function pay() {
// First, create order on YOUR server
const res = await fetch('/api/create-order', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ amount: 499, productName: 'Pro Plan' })
});
const { order_id } = await res.json();
// Then open PayGate checkout
const gateway = new PayGate({
key: 'pk_live_YOUR_PUBLIC_KEY', // Public key (safe for frontend)
order_id: order_id, // From your server
amount: 499,
name: 'My Store', // Shows in modal header
description: 'Pro Plan', // Shows below name
base_url: 'https://YOUR_GATEWAY_URL', // Your gateway URL
customer: {
name: 'John Doe',
email: 'john@example.com'
},
theme: {
color: '#6C5CE7' // Brand color
},
// Called when payment succeeds
handler: function(response) {
console.log('Payment ID:', response.payment_id);
console.log('Order ID:', response.order_id);
console.log('Method:', response.method);
console.log('Ref:', response.upi_ref);
// Verify on your server, then show success to user
verifyPayment(response);
},
// Called when user closes modal without paying
modal: {
ondismiss: function() {
console.log('Payment cancelled');
}
}
});
// Open inline modal
gateway.open();
}
</script>Opens payment page in a new tab while showing a progress-tracking modal in the current page. Perfect for complex checkouts or when you want users to have the full payment page experience.
const gateway = new PayGate({
key: 'pk_live_YOUR_PUBLIC_KEY',
order_id: order_id,
amount: 499,
name: 'My Store',
base_url: 'https://YOUR_GATEWAY_URL',
handler: function(response) {
// Called when payment completes
console.log('Paid via:', response.method);
window.location.href = '/success?order=' + response.order_id;
},
modal: {
ondismiss: function() {
console.log('Modal closed');
}
}
});
// Opens payment in new tab + shows progress modal here
gateway.openHosted();/pay/ORDER_ID in a new browser tab| Method | Code | Best For | User Experience |
|---|---|---|---|
| 📱 Inline Modal | gateway.open() | Quick payments, SPA apps | Popup over your page |
| 🌐 Hosted + Progress | gateway.openHosted() | Complex flows, mobile | New tab + progress tracker |
| ↗️ Full Redirect | window.location.href | Server-rendered sites | Full page redirect |
// For server-rendered sites, just redirect: const payUrl = 'https://YOUR_GATEWAY_URL/pay/' + order_id + '?key=pk_live_xxx'; window.location.href = payUrl; // User pays on hosted page, then redirects to your success_url // (Configure success_url in dashboard or per-order)
After the handler fires, always verify on your server before fulfilling the order:
app.post('/api/verify-payment', async (req, res) => {
const { order_id, payment_id } = req.body;
// Check with PayGate server
const response = await fetch(
'https://YOUR_GATEWAY_URL/api/v1/orders/' + order_id,
{
headers: {
'Authorization': 'Bearer sk_live_YOUR_SECRET_KEY'
}
}
);
const data = await response.json();
if (data.data.status === 'paid') {
// ✅ Payment confirmed!
// - Save to your database
// - Send confirmation email
// - Activate subscription
// - Deliver product
console.log('Paid via:', data.data.payment_method_used);
// UPI: 'upi_qr'
// Gateways: 'razorpay' | 'phonepe' | 'paytm'
// Binance: 'binance_usdt_bep20' | 'binance_btc' | 'binance_eth' | 'binance_bnb'
// Crypto: 'btc' | 'eth' | 'usdt_trc20' | 'sol'
res.json({ verified: true });
} else {
res.json({ verified: false, status: data.data.status });
}
});Set your webhook URL in the Dashboard. We send a POST request when payment succeeds. This is more reliable than the frontend handler alone.
const crypto = require('crypto');
app.post('/api/payment-webhook', (req, res) => {
const body = req.body;
const signature = req.headers['x-gateway-signature'];
const event = req.headers['x-gateway-event'];
// 1. Verify signature
const expected = crypto
.createHmac('sha256', 'whsec_YOUR_WEBHOOK_SECRET')
.update(JSON.stringify(body))
.digest('hex');
if (signature !== expected) {
return res.status(401).json({ error: 'Invalid signature' });
}
// 2. Handle event
if (event === 'payment.success') {
console.log('Order:', body.order_id);
console.log('Amount:', body.amount);
console.log('Method:', body.payment_method);
console.log('Ref:', body.upi_ref || body.binance_tx_hash);
// Fulfill order, send email, etc.
}
res.json({ received: true });
});{
"event": "payment.success",
"order_id": "order_abc123",
"payment_id": "pay_xyz789",
"amount": 499,
"currency": "INR",
"status": "paid",
"payment_method": "binance_usdt_bep20",
"upi_ref": null,
"binance_tx_hash": "0x1234abcd...",
"customer": {
"name": "John Doe",
"email": "john@example.com"
},
"paid_at": 1710856200000
}import { useState } from 'react';
const GATEWAY_URL = 'https://YOUR_GATEWAY_URL';
const PUBLIC_KEY = 'pk_live_YOUR_PUBLIC_KEY';
// Load SDK v5.0
function loadPayGate() {
return new Promise((resolve, reject) => {
if (window.PayGate) return resolve();
const s = document.createElement('script');
s.src = GATEWAY_URL + '/sdk/pay.js';
s.onload = () => window.PayGate ? resolve() : reject('SDK not found');
s.onerror = () => reject('Failed to load SDK');
document.body.appendChild(s);
});
}
export default function PayButton({ plan, user, useHosted = false }) {
const [loading, setLoading] = useState(false);
const handlePay = async () => {
setLoading(true);
try {
// 1. Create order on YOUR server
const res = await fetch('/api/create-order', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
amount: plan.price,
planId: plan.id
})
});
const { order_id } = await res.json();
// 2. Load SDK
await loadPayGate();
// 3. Open checkout
const gw = new window.PayGate({
key: PUBLIC_KEY,
order_id: order_id,
amount: plan.price,
name: 'My App',
description: plan.name + ' Plan',
base_url: GATEWAY_URL,
customer: {
name: user?.name || '',
email: user?.email || ''
},
theme: { color: '#6C5CE7' },
handler: async (response) => {
// 4. Verify on your server
await fetch('/api/verify-payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
order_id: response.order_id,
payment_id: response.payment_id,
method: response.method
})
});
alert('Payment successful! 🎉');
window.location.reload();
},
modal: {
ondismiss: () => setLoading(false)
}
});
// Choose checkout method
if (useHosted) {
gw.openHosted(); // New tab + progress
} else {
gw.open(); // Inline modal
}
} catch (err) {
alert('Error: ' + err.message);
setLoading(false);
}
};
return (
<button onClick={handlePay} disabled={loading}>
{loading ? 'Processing...' : `Pay ₹${plan.price}`}
</button>
);
}| Option | Type | Required | Description |
|---|---|---|---|
| key | string | ✅ | Your public key (pk_live_xxx) |
| order_id | string | ✅ | Order ID from Step 2 |
| amount | number | ✅ | Amount in INR |
| name | string | — | Store name (shows in modal header) |
| description | string | — | Product description |
| base_url | string | — | Gateway URL (auto-detected from script src) |
| customer.name | string | — | Customer name |
| customer.email | string | — | Customer email |
| customer.phone | string | — | Customer phone |
| theme.color | string | — | Brand color (default: #6C5CE7) |
| preferred_method | string | — | Open specific tab: upi_qr, razorpay, binance, crypto |
| handler | function | ✅ | Called on successful payment |
| modal.ondismiss | function | — | Called when user closes modal |
gateway.open()Opens inline modal popupgateway.openHosted()Opens new tab + progress modalv5.0gateway.close()Programmatically close modalWhen payment succeeds, your handler function receives:
| Field | Example | Description |
|---|---|---|
| payment_id | pay_abc123 | Unique payment identifier |
| order_id | order_xyz789 | Your order ID |
| amount | 499 | Amount paid (INR) |
| status | paid | Always "paid" in handler |
| method | upi_qr | Payment method used |
| upi_ref | 345678901234 | UPI reference (UPI payments) |
All methods are enabled/disabled by the gateway admin. Your integration code stays the same regardless of which methods are active.
Accept crypto payments via Binance Pay with Gmail auto-verification. No manual confirmation needed when gateway admin has Gmail integration enabled.
const gateway = new PayGate({
key: 'pk_live_xxx',
order_id: order_id,
amount: 500,
preferred_method: 'binance', // Opens Binance tab first
// ...
});
gateway.open();curl -X POST https://YOUR_GATEWAY_URL/api/v1/orders \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_live_YOUR_SECRET_KEY" \
-d '{"amount":100,"customer":{"name":"Test","email":"test@test.com"}}'Get your API keys and start accepting payments today.