MPChatMPChat/Docs

Orders

Orders can be paid on-chain or inside the MP client. Use /v1/orders for a blockchain address and hosted payment_url, or /v1/mp/orders for an MP app-only payment_uri.

The Order object

FieldTypeDescription
idstringUnique order ID (UUID)
order_numberstringHuman-readable ID with ord_ prefix
payment_railstringMP_INTERNAL for MP app-only orders; omitted from legacy on-chain responses
amount_modestringFIXED or CUSTOM for MP app-only orders
statusstringPENDING · OPEN · PENDING_CONFIRM · CONFIRMING · PAID · EXPIRED · EXPIRED_PAID · UNDERPAID · FROZEN
order_amountstringRequested payment amount in USDT
received_amountstringAmount received on-chain
credited_amountstringAmount credited to your balance after fees
currencystringAlways USDT
networkstringTRC20 or ERC20
payment_urlstringHosted checkout page URL — redirect your customer here
payment_uristringPrivate mppay:// URI returned only for MP app-only orders
expire_atstringISO 8601 timestamp when the order expires
paid_atstringISO 8601 timestamp when payment was confirmed (null if unpaid)
metadataobjectArbitrary key-value data you attached when creating the order
created_atstringISO 8601 creation timestamp

Create an on-chain order

POST
/v1/orders

Create a new payment order and receive a hosted checkout URL

💡Redirect the customer to payment_url immediately after creation. The order expires in 30 minutes by default.

Body parameters

amountstringrequired

Payment amount in USDT as a decimal string. Must be greater than 10. Example: "99.99".

currencystringrequired

Must be "USDT".One of: USDT

networkstringrequired

Blockchain network. TRC20 (TRON) has lower fees.One of: TRC20, ERC20

descriptionstringoptional

Human-readable description shown on the hosted checkout page.

metadataobjectoptional

Arbitrary key-value pairs (JSON object). Returned in webhook events.

return_urlstringoptional

HTTPS URL to redirect the customer after payment. Never use this as payment proof — verify server-side.

webhook_urlstringoptional

HTTPS URL to receive payment event POSTs for this order. Overrides your default webhook.

idempotency_keystringoptional

Unique key for safe retries. Passing the same key returns the original order without creating a duplicate. Scoped per merchant, expires after 24h.

tolerance_percentnumberoptionaldefault: 0.01

Acceptable underpayment as a decimal (0.01 = 1%). Orders paid within this tolerance are marked PAID.

Returns Returns the Order object with a payment_url. Redirect your customer to this URL.

Request

bash
curl -X POST https://call.mp.net/merchant/v1/orders \
  -H "Authorization: Bearer mk_live_abc:{ts}:{sig}" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "99.99",
    "currency": "USDT",
    "network": "TRC20",
    "description": "Pro Plan - 1 month",
    "metadata": {"customer_id": "cust_123"},
    "return_url": "https://acme.com/payment/return",
    "webhook_url": "https://acme.com/webhooks/mp",
    "idempotency_key": "checkout_session_xyz"
  }'

Response 201

JSON
{
  "id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
  "merchant_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "order_number": "ord_6f8a2b",
  "status": "OPEN",
  "order_amount": "99.99",
  "received_amount": "0.00",
  "credited_amount": "0.00",
  "currency": "USDT",
  "network": "TRC20",
  "description": "Pro Plan - 1 month",
  "metadata": {"customer_id": "cust_123"},
  "payment_url": "https://pay.mpchat.com/pay/ord_6f8a2b",
  "return_url": "https://acme.com/payment/return",
  "webhook_url": "https://acme.com/webhooks/mp",
  "expire_at": "2024-01-15T10:31:00Z",
  "paid_at": null,
  "environment": "live",
  "tolerance_percent": "0.01",
  "created_at": "2024-01-15T10:01:00Z",
  "updated_at": "2024-01-15T10:01:00Z"
}

Create an MP app-only order

POST
/v1/mp/orders

Create an order that can only be paid inside the MP client

⚠️ MP client only

Pass payment_uri to the MP client exactly as returned. Do not open it as a Web checkout URL or append an amount, network, address, or signature. For a CUSTOM order, send only amount_mode=CUSTOM and currency=USDT plus any optional business fields, without amount. The server sets inclusive limits (default 0.01–200000 USDT) and fixes CUSTOM precision at 2 decimal places. Legacy range and precision fields are ignored. Configuration changes affect only new orders; historical orders retain their stored rules.

Body parameters

amount_modestringrequired

FIXED requires amount; CUSTOM uses server-defined limits and precision.One of: FIXED, CUSTOM

amountstringoptional

Required for FIXED and forbidden for CUSTOM. Must be within the server-configured inclusive limits (default 0.01–200000 USDT), with at most 8 decimal places.

min_amountanyoptional

Optional legacy field. Any supplied value or type is ignored; new CUSTOM orders use the configured minimum, default 0.01.

max_amountanyoptional

Optional legacy field. Any supplied value or type is ignored; new CUSTOM orders use the configured maximum, default 200000.

scaleanyoptional

Optional legacy field. Any supplied value or type is ignored; new CUSTOM orders use 2.

currencystringrequired

Must be "USDT".One of: USDT

descriptionstringoptional

Merchant-facing payment description.

metadataobjectoptional

Arbitrary merchant-defined JSON object.

return_urlstringoptional

Merchant return URL retained with the order; it is not a Web payment fallback.

webhook_urlstringoptional

HTTPS URL for signed payment events.

Returns Returns an MP_INTERNAL order with a private payment_uri and no network, address_id, or payment_url.

Request

bash
curl -X POST https://call.mp.net/merchant/v1/mp/orders \
  -H "Authorization: Bearer mk_live_abc:{ts}:{sig}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: bot_payment_1042" \
  -d '{
    "amount_mode": "FIXED",
    "amount": "25.00",
    "currency": "USDT",
    "description": "Bot order #1042",
    "metadata": {"merchant_order_id": "M-1042"}
  }'

Response 201

JSON
{
  "id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
  "order_number": "ord_9591c681698d11da271f372dd4ba7a33",
  "payment_rail": "MP_INTERNAL",
  "amount_mode": "FIXED",
  "amount": "25.00",
  "scale": 8,
  "currency": "USDT",
  "status": "OPEN",
  "payment_uri": "mppay://ord_9591c681698d11da271f372dd4ba7a33",
  "expire_at": "2026-09-03T13:30:00Z",
  "created_at": "2026-09-03T13:00:00Z",
  "updated_at": "2026-09-03T13:00:00Z"
}

List orders

GET
/v1/orders

Return a paginated list of orders for your merchant account

Query parameters

limitintegeroptionaldefault: 20

Maximum number of orders to return. Max 100.

offsetintegeroptionaldefault: 0

Number of orders to skip (for pagination).

Returns Returns an object with an orders array and total count.

Request

bash
curl "https://call.mp.net/merchant/v1/orders?limit=20&offset=0" \
  -H "Authorization: Bearer mk_live_abc:{ts}:{sig}"

Response 200

JSON
{
  "orders": [
    {
      "id": "c3d4e5f6-...",
      "order_number": "ord_6f8a2b",
      "status": "PAID",
      "order_amount": "99.99",
      "currency": "USDT",
      "network": "TRC20",
      "payment_url": "https://pay.mpchat.com/pay/ord_6f8a2b",
      "paid_at": "2024-01-15T10:05:00Z",
      "created_at": "2024-01-15T10:01:00Z"
    }
  ],
  "total": 42
}

Retrieve an order

GET
/v1/orders/{id}

Retrieve a single order by its ID

ℹ️ MPChat App payment note

When a customer pays with the MPChat App and adds a note, remark contains that note (up to 128 characters). The Dashboard order detail page displays the same value. It isnull when no note was provided and is available only from this single-order detail endpoint.

Path parameters

idstringrequired

The order UUID (e.g. c3d4e5f6-a7b8-...).

Returns Returns the Order object plus the nullable customer payment note. Returns 404 if not found or belongs to another merchant.

Request

bash
curl https://call.mp.net/merchant/v1/orders/c3d4e5f6-a7b8-9012-cdef-123456789012 \
  -H "Authorization: Bearer mk_live_abc:{ts}:{sig}"

Response 200

JSON
{
  "id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
  "order_number": "ord_6f8a2b",
  "status": "PAID",
  "order_amount": "99.99",
  "received_amount": "99.99",
  "credited_amount": "98.99",
  "currency": "USDT",
  "network": "TRC20",
  "payment_url": "https://pay.mpchat.com/pay/ord_6f8a2b",
  "remark": null,
  "expire_at": "2024-01-15T10:31:00Z",
  "paid_at": "2024-01-15T10:05:12Z",
  "environment": "live",
  "created_at": "2024-01-15T10:01:00Z",
  "updated_at": "2024-01-15T10:05:12Z"
}

Stream order events (SSE)

GET
/v1/orders/{id}/events

Subscribe to real-time status updates via Server-Sent Events

💡Use SSE instead of polling for a better customer experience. The first event sent contains the current order state so you don't need a separate GET request.

Path parameters

idstringrequired

The order UUID to subscribe to.

Returns Returns a text/event-stream. The connection closes automatically when the order reaches a terminal state (PAID, EXPIRED, UNDERPAID, FROZEN).

Subscribe (JavaScript)

JavaScript
const es = new EventSource(
  `https://call.mp.net/merchant/v1/orders/${orderId}/events`,
  { headers: { Authorization: `Bearer ${buildAuthHeader()}` } }
);

es.onmessage = (event) => {
  const order = JSON.parse(event.data);
  console.log('Status:', order.status);

  // Close on terminal states
  if (['PAID', 'EXPIRED', 'UNDERPAID', 'FROZEN'].includes(order.status)) {
    es.close();
  }
};

Response

JSON
// First event: current order state
data: {"id":"c3d4e5f6-...","status":"OPEN","order_amount":"99.99",...}

// Subsequent events: pushed on each status change
data: {"id":"c3d4e5f6-...","status":"CONFIRMING",...}

data: {"id":"c3d4e5f6-...","status":"PAID","paid_at":"2024-01-15T10:05:12Z",...}

Next: Webhooks API