Skip to main content

P2P Exchange

The P2P (peer-to-peer) exchange allows users to buy and sell USDT for RUB directly with each other. It operates through an ad-based system with built-in escrow, integrated chat, and a rating system.

Core Concepts​

Ads​

An ad is a standing offer to buy or sell USDT for fiat currency. Each ad specifies:

  • Type -- "sell" (offering USDT for RUB) or "buy" (offering RUB for USDT)
  • Fiat currency -- typically "RUB"
  • Exchange rate -- for RUB, defaults to 1:1 (balance is RUB-denominated)
  • Min/max amount -- range in kopecks
  • Payment methods -- accepted methods (e.g., "card", "bank_transfer")
  • Payment details -- the ad maker's payment information
  • Instructions -- optional text instructions for the counterparty

Orders​

An order is created when a user responds to an ad. The order locks in the amount, payment method, and triggers the escrow mechanism.

Escrow​

When an order is created against a sell ad (someone is buying USDT), the seller's USDT balance is frozen (held in escrow). This guarantees the buyer that the USDT is available and will be released upon successful fiat payment. The frozen amount is deducted from the seller's available balance but not yet transferred.

When an order is created against a buy ad (someone is selling USDT), the taker's (seller's) USDT balance is frozen in escrow, and the buyer (ad maker) pays fiat.

Depositing via P2P (Buying USDT)​

To deposit funds via P2P, you respond to a sell ad -- someone offering to sell their USDT for your RUB.

1. Browse Sell Ads​

GET /api/v1/p2p/ads?type=sell&fiat_currency=RUB&limit=20&offset=0

Optional filters:

  • amount -- filter ads that accept this amount (in kopecks)
  • payment_method -- filter by accepted payment method (e.g., card)
  • sort_by -- rating (default, descending), orders_count (descending), or best_price (ascending)

2. Create an Order​

POST /api/v1/p2p/orders

Request body:

{
"ad_id": 15,
"usdt_amount": 500000,
"payment_method": "card"
}
  • ad_id -- the sell ad you are responding to
  • usdt_amount -- amount in kopecks (500000 = 5,000 RUB worth of USDT)
  • payment_method -- one of the ad's accepted payment methods

At this point, the seller's USDT is frozen in escrow.

3. Pay the Seller​

Transfer RUB to the seller using the payment details provided in the ad. The seller's card number or bank details are visible in the order.

4. Confirm Payment​

Once you have sent the fiat payment:

POST /api/v1/p2p/orders/{id}/confirm-paid

This moves the order status from pending to paid_by_buyer, notifying the seller.

5. Seller Confirms Receipt​

The seller checks their bank account and confirms they received the fiat:

POST /api/v1/p2p/orders/{id}/confirm-received

This completes the order. The escrowed USDT is released and credited to your (the buyer's) platform balance.

Order Lifecycle​

pending  -->  paid_by_buyer  -->  completed
| |
+--> cancelled +--> disputed (call operator)
StatusDescription
pendingOrder created, seller's USDT frozen. Buyer should send fiat payment.
paid_by_buyerBuyer confirmed fiat payment. Seller should verify receipt.
completedSeller confirmed receipt. USDT released to buyer.
cancelledOrder cancelled. Escrowed USDT returned to seller.

Managing Ads​

Create an Ad​

POST /api/v1/p2p/ads
{
"type": "sell",
"fiat_currency": "RUB",
"exchange_rate": 100,
"min_amount": 100000,
"max_amount": 5000000,
"payment_methods": ["card", "bank_transfer"],
"payment_details": {
"card_number": "2200..."
},
"instructions": "Please include order ID in the transfer comment."
}
  • exchange_rate -- in kopecks per unit; for RUB this is typically 100 (1:1)
  • min_amount / max_amount -- in kopecks
  • You can have only one active ad per type (one sell, one buy)

View Your Ads​

GET /api/v1/p2p/ads/my

Update an Ad​

PUT /api/v1/p2p/ads/{id}

Delete an Ad​

DELETE /api/v1/p2p/ads/{id}

Integrated Chat​

Every P2P order has a built-in chat for communication between buyer and seller.

Send a message:

POST /api/v1/p2p/orders/{id}/messages
{
"message": "Payment sent, please check."
}

Read messages:

GET /api/v1/p2p/orders/{id}/messages?limit=50&offset=0

View all chat sessions:

GET /api/v1/p2p/sessions

Returns your P2P orders along with the last message and counterparty info, suitable for rendering a chat list UI.

Rating System​

After an order is completed, both parties can rate each other on a 1 to 5 star scale:

POST /api/v1/p2p/orders/{id}/rate
{
"rating": 5
}

Ratings affect the seller's/buyer's reputation and are visible on their ads. The sort_by=rating filter on the ads listing uses this aggregate rating.

Dispute Resolution​

If a dispute arises (e.g., buyer claims payment sent but seller denies receipt), either party can call a platform operator:

POST /api/v1/p2p/orders/{id}/call-operator

The operator reviews chat history, payment evidence, and resolves the dispute manually.

Cancelling an Order​

Either party can cancel an order while it is in pending status:

POST /api/v1/p2p/orders/{id}/cancel

Cancellation releases the escrowed USDT back to the seller's available balance.

Error Codes​

CodeDescription
AD_NOT_ACTIVEThe ad is no longer active
OWN_ADYou cannot create an order for your own ad
AMOUNT_TOO_LOWAmount is below the ad's minimum
AMOUNT_TOO_HIGHAmount exceeds the ad's maximum
AMOUNT_EXCEEDS_AVAILABLEAmount exceeds the remaining available amount on the ad
INVALID_PAYMENT_METHODSelected payment method is not accepted by this ad
SELLER_INSUFFICIENT_BALANCEThe seller does not have enough balance to cover escrow
DUPLICATE_AD_TYPEYou already have an active ad of this type
ACTIVE_DEPOSIT_ORDER_EXISTSYou already have an active deposit order
ACTIVE_WITHDRAW_ORDER_EXISTSYou already have an active withdrawal order
MIN_DEPOSIT_REQUIREDMinimum 1,000 RUB deposit required before P2P withdrawal
WAGERING_REQUIREMENT_NOT_METWagering requirement not met for withdrawal