MPChatMPChat/Docs

Quick Start

Go from zero to accepting USDT payments in under 5 minutes. This guide walks through registering a merchant account, generating an API key, creating a payment order, and receiving a webhook notification.

1

Register as a merchant

Create a merchant account by posting to /v1/merchants. You'll receive a merchant_id that identifies your account in all subsequent requests.

Register merchant
curl -X POST https://api.mpchat.com/v1/merchants \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Store",
    "email": "[email protected]"
  }'
Response
{
  "id": "mer_01HQ...",
  "name": "Acme Store",
  "email": "[email protected]",
  "status": "PENDING_KYB",
  "tier": "BASIC",
  "environment": "test",
  "created_at": "2024-01-15T10:00:00Z"
}

⚠️ KYB Required for Live Payments

New accounts start in PENDING_KYB status. You can test with sandbox keys immediately, but live payments require KYB verification. Contact support to start the process.
2

Generate an API key

Generate your first API key. The response includes both key_id (public) and secret (private). Store the secret safely — it is only shown once.

Create API key
curl -X POST https://api.mpchat.com/v1/merchants/api-keys \
  -H "Authorization: Bearer {session_token}" \
  -H "Content-Type: application/json" \
  -d '{"name": "Production Key", "environment": "live"}'
Response
{
  "key_id": "mk_live_01HQ...",
  "secret": "sk_live_a1b2c3d4e5f6...",
  "name": "Production Key",
  "environment": "live",
  "created_at": "2024-01-15T10:01:00Z"
}

🚨 Save your secret immediately

The secret value is shown only once and cannot be retrieved again. Store it in an environment variable or secrets manager before closing this response.

Use mk_test_ prefix keys for sandbox testing — they behave identically but don't require real blockchain transactions.

3

Create a payment order

Create an order specifying the amount in USDT and the preferred network. The API returns a payment_url — redirect your customer there.

Create order
curl -X POST https://api.mpchat.com/v1/orders \
  -H "Authorization: Bearer mk_live_01HQ...:{timestamp}:{signature}" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "99.99",
    "currency": "USDT",
    "network": "TRC20",
    "description": "Pro Plan - Monthly",
    "return_url": "https://acme.com/payment/return",
    "webhook_url": "https://acme.com/webhooks/mpchat"
  }'
Response
{
  "id": "ord_01HQ...",
  "order_number": "ord_a1b2c3",
  "status": "OPEN",
  "order_amount": "99.99",
  "received_amount": "0.00",
  "currency": "USDT",
  "network": "TRC20",
  "payment_url": "https://pay.mpchat.com/pay/ord_01HQ...",
  "expire_at": "2024-01-15T10:31:00Z",
  "created_at": "2024-01-15T10:01:00Z"
}
4

Redirect the customer

Redirect your customer to the payment_url. MPChat hosts the entire checkout experience — displaying the USDT address, QR code, amount, and countdown timer.

Web redirect
// After creating the order:
window.location.href = order.payment_url;

💡 Mobile & bot integration

For mobile apps and chat bots, see the Payment Integration guide for deep links and embedded flows.
5

Handle the webhook

When the customer pays, MPChat sends a payment.confirmed event to yourwebhook_url. Verify the signature before processing.

Express.js webhook handler
const crypto = require('crypto');

app.post('/webhooks/mpchat', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.headers['x-merchant-signature'];
  const [tPart, v1Part] = sig.split(',');
  const timestamp = tPart.replace('t=', '');
  const receivedHash = v1Part.replace('v1=', '');

  const payload = `${timestamp}.${req.body.toString()}`;
  const expected = crypto
    .createHmac('sha256', process.env.WEBHOOK_SECRET)
    .update(payload)
    .digest('hex');

  if (expected !== receivedHash) {
    return res.status(401).send('Invalid signature');
  }

  const event = JSON.parse(req.body);
  if (event.event === 'payment.confirmed') {
    // Fulfill the order: event.data.order_id
    console.log('Payment confirmed:', event.data.order_id);
  }

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

Poll order status (alternative)

If you prefer polling over webhooks, check order status with a GET request. Poll at most every 5 seconds.

Get order status
curl https://api.mpchat.com/v1/orders/ord_01HQ... \
  -H "Authorization: Bearer mk_live_01HQ...:{timestamp}:{signature}"

Order statuses

StatusDescription
PENDINGOrder created, address not yet assigned
OPENAddress assigned, awaiting payment
CONFIRMINGTransaction detected, waiting for confirmations
PAIDPayment confirmed — fulfill the order
EXPIREDOrder expired with no payment received
EXPIRED_PAIDPayment received after expiry — contact support
UNDERPAIDPayment received but amount is insufficient
FROZENOrder flagged for compliance review
💡For real-time updates without polling, use the SSE stream atGET /v1/orders/{id}/events. See the Payment Integration guide.

Next steps