PAYchat
home
Send a Link
home

Documentation

Part 1: Introduction & Authentication

PAYchat Partner API

Build seamless USDT payments into your app with our simple REST API.

Welcome

PAYchat Partner API lets you:
β€’
Accept payments - Generate payment links and get paid in USDT
β€’
Send money - Instantly transfer USDT to any Telegram user
β€’
Track everything - Real-time webhooks and detailed analytics
Base URL: https://paychat.me/api/partner

Official SDK

Install our Node.js SDK for the easiest integration:
npm install paychat-sdk
Bash
볡사
import PAYchatClient from 'paychat-sdk'; const client = new PAYchatClient('pk_your_api_key'); // Create payment const payment = await client.createPayment({ amount: 10, description: 'Limited Edition T-Shirt' }); console.log(payment.payment.payment_url);
JavaScript
볡사
Full SDK Documentation

Authentication

Every API request requires your API Key in the header.

Your Credentials

Key
Format
Purpose
API Key
pk_xxxx...
Authenticate API requests
Secret Key
sk_xxxx...
Verify webhook signatures

How to Authenticate

Add your API Key to the request header:
X-API-Key: pk_your_api_key_here
Plain Text
볡사

Example Request

curl https://paychat.me/api/partner/balance \ -H "X-API-Key: pk_abc123..."
Bash
볡사

Keep Your Keys Safe

β€’
Never expose keys in client-side code
β€’
Don't commit keys to version control
β€’
Use environment variables
β€’
Regenerate immediately if compromised

Part 2: Plans & Pricing

Plans & Pricing

Plan

Plan
Rate Limit
Founding Member
500/min
One-time payment. Lifetime access.

Volume Discount (Based on Total Holdings)

Your discount rate is based on total holdings:
$$ \text{Total Holdings} = \text{Your Balance} + \text{Referred Users' Balances} $$
The more you hold, the higher your discount rate (up to 100% off).

How It Works

1.
Pay once β†’ Get lifetime API access
2.
API fees deducted from your balance per call
3.
More holdings = Higher discount = Lower fees
4.
Refer users β†’ Their balances count toward your discount!

Part 3: Rate Limits

Rate Limits

Protect your integration and our infrastructure with sensible rate limits.

Limits

Endpoint
Limit
POST /payments
500/min
POST /withdrawals
250/min
All GET requests
1,500/min

Response Headers

Every response includes rate limit info:
Header
Meaning
X-RateLimit-Limit
Max requests per window
X-RateLimit-Remaining
Requests left
X-RateLimit-Reset
Seconds until reset

When You Hit the Limit

{ "success": false, "error": { "code": "RATE_LIMIT_EXCEEDED", "message": "Too many requests. Please retry later." } }
JSON
볡사
Tip: Check the Retry-After header to know when to retry.

Part 4: API Endpoints Overview

API Endpoints

Quick Reference

Method
Endpoint
Description
POST
/payments
Create a payment link
GET
/payments/:id
Check payment status
POST
/withdrawals
Send USDT to a user
GET
/balance
Check your balance
GET
/transactions
List transactions
GET
/deposit-address
Get deposit address
PUT
/webhook
Set webhook URL
POST
/webhook-test
Test your webhook

Public Endpoints (No Auth Required)

Method
Endpoint
Description
GET
/plans
View available plans
GET
/me?telegram_id=
Check partner status
POST
/register
Register as partner

Part 5: Create Payment

Create a Payment

Generate a payment link that customers can use to pay you.
Endpoint: POST /api/partner/payments

Request Body

Field
Type
Required
Description
amount
number
Amount in USDT (min: 0.000001)
description
string
What the payment is for
metadata
object
Your custom data (stored, returned in webhooks)
idempotency_key
string
Prevent duplicate payments

Example Request

curl -X POST https://paychat.me/api/partner/payments \ -H "X-API-Key: pk_your_key" \ -H "Content-Type: application/json" \ -d '{ "amount": 29.99, "description": "Limited Edition T-Shirt", "metadata": { "user_id": "user_123", "item": "tshirt_black_L" } }'
Bash
볡사

Example Response

{ "success": true, "payment": { "id": "pay_abc123xyz", "link_id": "x7k2m9", "amount": 29.99, "currency": "USDT", "description": "Limited Edition T-Shirt", "status": "pending", "payment_url": "https://t.me/paychat_aibot?start=x7k2m9", "expires_at": "2025-01-08T12:00:00.000Z", "metadata": { "user_id": "user_123", "item": "tshirt_black_L" }, "created_at": "2025-01-07T12:00:00.000Z" } }
JSON
볡사

What to Do Next

1.
Redirect your customer to payment_url
2.
They'll complete payment in Telegram
3.
You'll receive a payment.completed webhook
4.
Funds are instantly added to your balance

Check Payment Status

See if a payment has been completed.
Endpoint: GET /api/partner/payments/:id

Example Request

curl https://paychat.me/api/partner/payments/x7k2m9 \ -H "X-API-Key: pk_your_key"
Bash
볡사

Example Response (Completed)

{ "success": true, "payment": { "id": "x7k2m9", "amount": 29.99, "currency": "USDT", "description": "Limited Edition T-Shirt", "status": "completed", "payer": { "telegram_id": "987654321" }, "paid_at": "2025-01-07T12:30:00.000Z", "created_at": "2025-01-07T12:00:00.000Z" } }
JSON
볡사

Payment Status Values

Status
Meaning
pending
Waiting for payment
completed
Payment received

Part 6: Send Withdrawal

Send a Withdrawal

Instantly send USDT to any Telegram user.
Endpoint: POST /api/partner/withdrawals

Request Body

Field
Type
Required
Description
telegram_id
string
Recipient's Telegram ID
amount
number
Amount in USDT (min: 0.000001)
memo
string
Message shown to recipient

Example Request

curl -X POST https://paychat.me/api/partner/withdrawals \ -H "X-API-Key: pk_your_key" \ -H "Content-Type: application/json" \ -d '{ "telegram_id": "123456789", "amount": 10.00, "memo": "Referral bonus - Thanks!" }'
Bash
볡사

Example Response

{ "success": true, "withdrawal": { "id": "wd_xyz789abc", "telegram_id": "123456789", "amount": 10.00, "status": "completed", "created_at": "2025-01-07T12:00:00.000Z" } }
JSON
볡사

Good to Know

Feature
How It Works
Instant delivery
Funds arrive immediately
Auto-registration
New users get a PAYchat account automatically
Notifications
Recipients get a Telegram message
Referral registration
First withdrawal registers the user as your referral

Part 7: Check Balance

Check Your Balance

See how much USDT you have available.
Endpoint: GET /api/partner/balance

Example Response

{ "success": true, "balance": { "available": 1250.50, "currency": "USDT", "total_holdings": 5500.00, "referral_holdings": 2500.00 } }
JSON
볡사
Field
Description
available
USDT you can withdraw or send
total_holdings
Total holdings (your balance + referred users' balances)
referral_holdings
Total balance of your referred users

Get Deposit Address

Get the address to fund your partner account.
Endpoint: GET /api/partner/deposit-address

Example Response

{ "success": true, "deposit": { "address": "TXxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "network": "TRON (TRC20)", "currency": "USDT", "memo": "partner_abc123", "note": "Include the memo when sending to identify your deposit" } }
JSON
볡사
Important: Always include the memo when sending funds so we can credit your account.

Part 8: Transactions & History

List Transactions

View your transaction history with filtering options.
Endpoint: GET /api/partner/transactions

Query Parameters

Parameter
Type
Default
Description
type
string
all
payment or withdraw
status
string
all
Filter by status
from
string
-
Start date (ISO 8601)
to
string
-
End date (ISO 8601)
limit
number
20
Results per page (max 100)
offset
number
0
Pagination offset

Example Request

curl "https://paychat.me/api/partner/transactions?type=payment&limit=10" \ -H "X-API-Key: pk_your_key"
Bash
볡사

Example Response

{ "success": true, "transactions": [ { "id": 1, "type": "payment", "telegram_id": "123456789", "amount": 29.99, "status": "completed", "created_at": "2025-01-07T12:00:00.000Z" }, { "id": 2, "type": "withdraw", "telegram_id": "987654321", "amount": 10.00, "status": "completed", "created_at": "2025-01-07T11:30:00.000Z" } ], "pagination": { "total": 156, "limit": 10, "offset": 0 } }
JSON
볡사

Part 9: Webhooks

Webhooks

Get real-time notifications when events happen.

Available Events

Event
Description
When It Fires
payment.completed
Payment received
Customer completes payment
withdraw.completed
Withdrawal sent
Funds delivered to user
test
Test event
You send a test webhook

Setting Up Webhooks

1. Set your webhook URL:
curl -X PUT https://paychat.me/api/partner/webhook \ -H "X-API-Key: pk_your_key" \ -H "Content-Type: application/json" \ -d '{"webhook_url": "https://your-server.com/webhooks/paychat"}'
Bash
볡사
2. Test it:
curl -X POST https://paychat.me/api/partner/webhook-test \ -H "X-API-Key: pk_your_key"
Bash
볡사

Webhook Headers

Every webhook includes these headers:
Header
Description
Content-Type
application/json
X-PAYchat-Event
Event type
X-PAYchat-Signature
HMAC signature for verification
X-PAYchat-Delivery-ID
Unique delivery ID

Webhook Payload: payment.completed

{ "event": "payment.completed", "data": { "payment_id": "x7k2m9", "amount": 29.99, "payer": { "telegram_id": "987654321" } }, "created_at": "2025-01-07T12:00:00.000Z" }
JSON
볡사

Webhook Payload: withdraw.completed

{ "event": "withdraw.completed", "data": { "withdrawal_id": "wd_xyz789", "telegram_id": "123456789", "amount": 10.00, "memo": "Referral bonus" }, "created_at": "2025-01-07T12:00:00.000Z" }
JSON
볡사

Part 10: Webhook Security & Retries

Verifying Webhooks

Always verify webhook signatures to ensure they're from PAYchat.

How Signatures Work

1.
We create a message: {timestamp}.{payload}
2.
We sign it with your Secret Key using HMAC-SHA256
3.
We send the signature in X-PAYchat-Signature header

Signature Format

X-PAYchat-Signature: t=1704628800,v1=abc123def456...
Plain Text
볡사
Part
Description
t
Unix timestamp
v1
HMAC-SHA256 signature

Verification Code (Node.js)

const crypto = require('crypto'); function verifyWebhook(payload, signatureHeader, secretKey) { // Parse the signature header const [tPart, v1Part] = signatureHeader.split(','); const timestamp = tPart.replace('t=', ''); const signature = v1Part.replace('v1=', ''); // Recreate the signed message const message = `${timestamp}.${JSON.stringify(payload)}`; // Calculate expected signature const expected = crypto .createHmac('sha256', secretKey) .update(message) .digest('hex'); // Compare signatures return signature === expected; } // In your webhook handler app.post('/webhooks/paychat', (req, res) => { const isValid = verifyWebhook( req.body, req.headers['x-paychat-signature'], process.env.PAYCHAT_SECRET_KEY ); if (!isValid) { return res.status(401).send('Invalid signature'); } // Process the webhook... res.status(200).send('OK'); });
JavaScript
볡사

Webhook Retries

If your server doesn't respond with a 2xx status, we'll retry automatically.

Retry Schedule

Attempt
Wait Time
1st
Immediate
2nd
1 minute
3rd
5 minutes
4th
30 minutes
5th
2 hours
Final
Marked as failed

Requirements for Success

Requirement
Details
Status code
Any 2xx (200-299)
Timeout
Respond within 10 seconds
Response body
Not required

Part 11: Error Handling

Error Handling

All errors follow a consistent format.

Error Response Format

{ "success": false, "error": { "code": "ERROR_CODE", "message": "Human readable description" } }
JSON
볡사

HTTP Status Codes

Code
Meaning
200
Success
400
Bad request (check your input)
401
Authentication failed
403
Forbidden (account inactive)
404
Resource not found
429
Rate limit exceeded
500
Server error (retry later)

Common Error Codes

Code
HTTP
Meaning
Solution
INVALID_API_KEY
401
Missing or invalid API Key
Check your X-API-Key header
PARTNER_INACTIVE
403
Account is disabled
Contact support
RATE_LIMIT_EXCEEDED
429
Too many requests
Wait and retry
INVALID_AMOUNT
400
Amount too small
Minimum is 0.000001
INSUFFICIENT_BALANCE
400
Not enough funds
Deposit more USDT
PAYMENT_NOT_FOUND
404
Payment doesn't exist
Check the payment ID
INVALID_WEBHOOK_URL
400
Bad webhook URL
Must start with https://

Error Examples

Authentication Failed
{ "success": false, "error": { "code": "INVALID_API_KEY", "message": "API Key is required" } }
JSON
볡사
Insufficient Balance
{ "success": false, "error": { "code": "INSUFFICIENT_BALANCE", "message": "Insufficient balance" } }
JSON
볡사

Part 12: Code Examples

Using the Official SDK (Recommended)

The easiest way to integrate PAYchat:
npm install paychat-sdk
Bash
볡사
import PAYchatClient from 'paychat-sdk'; const client = new PAYchatClient('pk_your_api_key'); // Create payment const payment = await client.createPayment({ amount: 29.99, description: 'Limited Edition Hoodie', metadata: { user_id: '123' } }); // Send withdrawal const withdrawal = await client.createWithdrawal({ telegramId: '123456789', amount: 5.00, memo: 'Referral bonus' }); // Check balance const balance = await client.getBalance(); // Verify webhook const isValid = PAYchatClient.verifyWebhook(payload, signature, 'sk_your_secret_key');
JavaScript
볡사

Quick Start Examples

Node.js Setup

const axios = require('axios'); const paychat = axios.create({ baseURL: 'https://paychat.me/api/partner', headers: { 'X-API-Key': process.env.PAYCHAT_API_KEY, 'Content-Type': 'application/json' } });
JavaScript
볡사

Create a Payment

async function createPayment(amount, description, metadata = {}) { try { const { data } = await paychat.post('/payments', { amount, description, metadata, idempotency_key: `pay_${Date.now()}_${Math.random()}` }); console.log('Payment URL:', data.payment.payment_url); return data.payment; } catch (error) { console.error('Error:', error.response?.data?.error?.message); throw error; } } // Usage const payment = await createPayment(29.99, 'Limited Edition Hoodie', { user_id: '123' });
JavaScript
볡사

Send Money to a User

async function sendReward(telegramId, amount, memo) { try { const { data } = await paychat.post('/withdrawals', { telegram_id: telegramId, amount, memo }); console.log(`Sent $${amount} to ${telegramId}`); return data.withdrawal; } catch (error) { if (error.response?.data?.error?.code === 'INSUFFICIENT_BALANCE') { console.error('Not enough balance! Please deposit more funds.'); } throw error; } } // Usage await sendReward('123456789', 5.00, 'Thanks for your referral!');
JavaScript
볡사

Handle Webhooks (Express)

const express = require('express'); const crypto = require('crypto'); const app = express(); app.use(express.json()); app.post('/webhooks/paychat', (req, res) => { // Verify signature const signature = req.headers['x-paychat-signature']; if (!verifySignature(req.body, signature)) { return res.status(401).send('Invalid signature'); } // Handle events const event = req.headers['x-paychat-event']; switch (event) { case 'payment.completed': handlePayment(req.body.data); break; case 'withdraw.completed': handleWithdrawal(req.body.data); break; } res.status(200).send('OK'); }); function handlePayment(data) { console.log(`πŸ’° Payment received!`); console.log(` Amount: $${data.amount}`); console.log(` From: ${data.payer.telegram_id}`); // Update your database, send confirmation email, etc. } function handleWithdrawal(data) { console.log(`βœ… Withdrawal completed!`); console.log(` Amount: $${data.amount}`); console.log(` To: ${data.telegram_id}`); } function verifySignature(payload, header) { const [t, v1] = header.split(','); const timestamp = t.replace('t=', ''); const signature = v1.replace('v1=', ''); const message = `${timestamp}.${JSON.stringify(payload)}`; const expected = crypto .createHmac('sha256', process.env.PAYCHAT_SECRET_KEY) .update(message) .digest('hex'); return signature === expected; } app.listen(3000);
JavaScript
볡사

Part 13: FAQ

Frequently Asked Questions

General

Q: What if my balance is too low?
A: Auto-charge triggers if enabled. Otherwise, API returns error.
Q: How do referred users affect my discount?
A: First withdrawal to a user registers them as your referral. Their balance counts toward your total holdings, increasing your discount rate.
Q: What if my API key is exposed?
A: Regenerate it immediately:
curl -X POST https://paychat.me/api/partner/regenerate-key \ -H "X-API-Key: pk_your_current_key"
Bash
볡사
Your old key becomes invalid instantly.

Payments

Q: How long do payment links last?
A: 24 hours. After that, they expire and can't be used.
Q: What currencies are supported?
A: Currently USDT on the TRON network (TRC-20). More options coming soon!
Q: When do I receive funds?
A: Instantly! As soon as a customer completes payment, it's added to your balance.

Withdrawals

Q: What if the recipient doesn't have PAYchat?
A: We automatically create an account for them. They'll receive a Telegram message with instructions to access their funds.
Q: Is there a minimum withdrawal?
A: Yes, 0.000001 USDT (practically any amount).
Q: How fast are withdrawals?
A: Instant! The recipient sees the funds immediately.

Webhooks

Q: What if my webhook endpoint is down?
A: We retry up to 5 times over ~2.5 hours. You can also manually retry failed webhooks later.
Q: Do I need to respond to webhooks?
A: Yes, with any 2xx status code within 10 seconds. The response body doesn't matter.

Security

Q: What's the idempotency_key for?
A: It prevents duplicate transactions if you accidentally send the same request twice. Use a unique value for each transaction.
Q: How do I verify webhooks are really from PAYchat?
A: Check the X-PAYchat-Signature header using your Secret Key. See the Webhook Security section for code examples.

Need Help?

Channel
Contact
Telegram
Email

Changelog

Date
Version
Changes
2025-01-07
1.0.0
Initial release
2025-01-10
2.0.0
Updated to holdings-based discount system