PAYchat

For Developers

Stop building payment systems from scratch.


Sound familiar?

  • Blockchain payment integration is way too complicated
  • Wallet connection UX is clunky and users drop off
  • Can't verify payment completion on your server
  • Want to monetize but don't know where to start with payments
  • Sending rewards to users requires manual work

PAYchat API solves it all.


Build It Yourself vs PAYchat

Build YourselfPAYchat
Development time2–4 weeks5 minutes
Wallet integrationBuild it yourselfNot needed
Payment verificationBuild it yourselfWebhooks included
Withdrawal featureBuild it yourself1 API call
EscrowBuild it yourself1 API call
Blockchain knowledgeRequiredNot needed
MaintenanceOngoingNone

Finish in 5 minutes what would take 2 weeks.


Perfect for apps like these

  • 🛒 Physical goods & merch sales
  • 🎫 Event tickets & reservations
  • 🎁 Creator tips & donations
  • 💰 Rewards & cashback
  • 🏆 Contest & event prizes
  • 🌍 Cross-border payments

How It Works

Accepting Payments

code
User clicks "Buy"
  → PAYchat payment screen opens
  → User enters PIN to pay
  → Webhook notifies your server
  → Order confirmed & shipped

Sending Rewards

code
User completes a mission
  → Your server calls the withdrawal API
  → USDT deposited to user's wallet
  → Telegram notification sent automatically

Settlement is instant. Funds hit your balance the moment payment completes.


Integration Steps

1. Register as a Partner (1 min)

Select a plan on the Partner page in the mini app → API Key issued instantly

2. Set Up Webhooks (1 min)

Partner page → Webhooks tab → enter your public HTTPS URL

json
POST /api/partner/payments

{
  "amount": 5.00,
  "description": "Limited Edition T-Shirt",
  "metadata": {
    "user_id": "user_123",
    "item": "tshirt_black_L"
  },
  "idempotency_key": "order_5521"
}

Show the payment_url from the response to your user. That's it.

The response also returns payment.id — a 6-character link_id. Store it: this is how you look the payment up later.


Webhook Data

When a payment completes, your server receives this:

json
{
  "event": "payment.completed",
  "data": {
    "payment_id": "x7k2m9",
    "status": "completed",
    "transaction_id": "x7k2m9",
    "amount": 5.00,
    "fee": 0.0004,
    "net_amount": 4.9996,
    "metadata": {
      "user_id": "user_123",
      "item": "tshirt_black_L"
    },
    "payer": {
      "telegram_id": "123456789"
    }
  },
  "created_at": "2026-08-13T12:00:00.000Z"
}

Matching the payment to your order

Whatever you put in metadata comes right back in the webhook. No lookup, no order matching headaches.

javascript
app.post('/webhooks/paychat', (req, res) => {
  const { payment_id, amount, metadata } = req.body.data;

  fulfillOrder(metadata.order_id, metadata.user_id, amount);

  res.status(200).send('OK');
});

payment_id is also the 6-character link_id from the create response, so you can match on that instead if you prefer storing IDs over metadata.

The same applies to qr.paid, escrow.created, escrow.paid, escrow.released, and escrow.cancelled. withdraw.completed carries memo instead of metadata.


Ready to get started?

→ Open the Partner page in the PAYchat mini app


For Contest & Tournament Organizers

Stop managing payments manually.

Sound familiar?

  • Collecting entry fees via wallet transfers is chaotic
  • Can't tell who actually paid until you check manually
  • Sending prize money to 50+ winners takes hours
  • Disputes over "I paid but didn't get registered"
  • Spreadsheet hell for tracking payments

PAYchat solves all of this with a single API.

The Problem with Manual Methods

Manual TransfersPAYchat
Entry fee tracking❌ Spreadsheets✅ Automatic
Registration confirmation❌ Manual check✅ Webhooks
Prize distribution❌ One by one, by hand✅ Scripted — loop the API
Duplicate paymentsCommon✅ Blocked by idempotency_key
Participant disputesManyAlmost none
Payment records❌ Scattered✅ Dashboard + GET /transactions

A transfer is just "sending money." A payment is "completing a registration."

How It Works

Entry Fee Collection

code
Player clicks "Join Tournament"
  → Enters PIN in PAYchat
  → Payment complete
  → Webhook notifies your server
  → Player registered automatically

Prize Distribution

code
Tournament ends
  → Your server loops the withdrawal API over the winner list
  → USDT sent to each winner
  → Telegram notifications sent automatically
javascript
for (const winner of winners) {
  await client.createWithdrawal({
    telegramId: winner.telegramId,
    amount: winner.prize,
    memo: 'Tournament prize',
    idempotencyKey: `prize_${tournamentId}_${winner.telegramId}`
  });
}

The idempotencyKey means a crashed or re-run script never pays anyone twice.

At the Founding Member rate limit, 250 withdrawals per minute — 50 winners paid in under 15 seconds.

Entry fees that need holding

For tournaments where entry fees are refundable until the bracket is locked, use escrow instead: funds are held, then released to you or refunded to the player in full.