Saltar al contenido principal

Order Lifecycle

A complete walkthrough of the C2C order flow from ad creation to trade completion. Each state transition maps to specific API endpoints and error conditions.

State Flow


  ┌──────────────────────────────────────────────────────────────────────────────┐
  │                        Binance C2C Order Lifecycle                          │
  └──────────────────────────────────────────────────────────────────────────────┘

  [Ad Posted]
       │
       │  EP-7: update price       EP-8: toggle online/offline
       │  ─────────────────        ────────────────────────────
       ▼
  ╔══════════╗
  ║ AD LIVE  ║  ◀── EP-4 list your ads    EP-0 searcher sees your ad
  ╚══════════╝
       │
       │  Buyer places order (EP-18, buyer side)
       │  EP-11: checkIfCanPlaceOrder (buyer pre-check)
       ▼
  ╔══════════════════╗
  ║ PENDING_PAYMENT  ║  ─── EP-13: get order detail
  ╚══════════════════╝      EP-15: list orders
       │
       │  Buyer marks as paid (EP-17, buyer side)
       │  Chat: buyer sends payment proof (EP-34 retrieve, EP-31 mark read)
       ▼
  ╔═══════════════════╗
  ║ PAID / PROCESSING ║  ─── Verify payment in bank / payment app
  ╚═══════════════════╝      EP-12: checkIfCanReleaseCoin
       │
       │  Seller releases coin (EP-20, your side)
       ▼
  ╔══════════════╗
  ║   COMPLETE   ║  ─── EP-16: appears in order history
  ╚══════════════╝

  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ Error Paths ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─

  PENDING_PAYMENT ─── Buyer cancels ──────────────────▶ [CANCELLED]
                       EP-10: checkIfAllowedCancelOrder
                       EP-9: cancelOrder (buyer side)

  PAID ─────────────── Dispute raised ─────────────────▶ [IN APPEAL]
                        Binance mediation process
                        (no dedicated SAPI endpoint)

  ANY STATE ──────────── EP-21: verifyAdditionalKyc ───▶ KYC gate
                          Buyer needs additional KYC
                          before trade can proceed

Step-by-Step Breakdown

1

Ad Posted

EP-5 (create) / EP-4 (list)

Create your ad via Binance UI or EP-5 (requires 2FA). Once live, EP-4 lists your ads. Your bot uses EP-0 to see how your ad ranks against competitors.

# Check your ad ranking
sellers = await fetch_order_book("USDT", "USD", "BUY")
my_ads = await list_my_ads(client, api_key, api_secret)
for ad in my_ads:
    rank = next((i for i, s in enumerate(sellers)
                 if s["advNo"] == ad["advNo"]), None)
    print(f"Ad {ad['advNo']} rank: {rank}")
2

Order Placed

EP-13, EP-15

A buyer places an order against your ad. Your bot detects it via EP-15 (list orders) or via WebSocket events. Use EP-13 to fetch full order details including buyer info, fiat amount, and payment method.

Note: When a new order arrives, your ad's surplusAmount decreases automatically. This is why sending surplusAmount in EP-7 price updates causes error 187049 — the cached value may already be stale.
3

Payment Marked

EP-17 (buyer), EP-31, EP-34

The buyer marks the order as paid (EP-17) and typically sends payment proof via chat. Your bot reads chat messages via EP-34 and marks them as read via EP-31. The order enters a payment verification window.

# Poll for new chat messages after order placed
messages = await get_chat_messages(client, api_key, api_secret, order_no)
for msg in messages:
    if msg.get("msgType") == "image":
        # Buyer sent payment proof image
        print(f"Payment proof received: {msg['content']}")
4

Coin Released

EP-12, EP-20

After verifying payment, call EP-12 to confirm coin release is allowed, then EP-20 to release. Most P2P bots do this manually — release only after independently confirming payment in your bank or payment app.

Warning: Never automate coin release without independent payment verification. Scammers exploit bots that release on payment proof images alone.
5

Complete

EP-16

The order reaches COMPLETE status. It appears in EP-16 (order history). Your ad'ssurplusAmount is permanently reduced. If the ad has been fully traded out, it goes offline automatically.

Error Scenarios and Recovery

Ad Live → Reprice

187049

Cause: surplusAmount included in EP-7 body

Recovery: Remove surplusAmount. Send only advNo + price.

Ad Live → Reprice

187055

Cause: Price outside allowed range for the currency

Recovery: Binary search within allowed range. EP-3 (getReferencePrice) can help find bounds.

Ad Live → Reprice

83229 / 83230

Cause: Ad was taken offline by Binance risk system

Recovery: Mark ad as paused. Inspect via EP-2. Do not reprice until status is confirmed.

Any HMAC call

-1021 / -1022

Cause: Clock drift — timestamp outside 1000ms window

Recovery: Sync time via /api/v3/time (UTIL-1), recompute offset, rebuild query and retry.

Order placed

EP-13 returns 401

Cause: Adaptive auth: unsigned attempt rejected

Recovery: Retry with full HMAC signature. Expected behavior — not an error.

Order history

EP-16 returns -1104

Cause: GET not accepted by this environment

Recovery: Retry as POST with identical params. Three-fallback chain handles this automatically.