How It Works
Architecture, trade flow, glossary, and KYC models for the MexicoP2P Partner API.
The two worlds
The MexicoP2P Partner API sits between your server and a blockchain marketplace. Understanding the boundary is key:
| Your API calls (REST) | Marketplace (automatic) |
|---|---|
| Register users | Escrow deposit on Starknet |
| Create quotes & orders | Buyer discovery & locking |
| Track order status | SPEI payment & CEP verification |
| Receive webhooks | Crypto release on-chain |
You create orders. The marketplace settles them. After you call POST /orders, everything else happens without further API calls from you.
Glossary
| Term | Definition |
|---|---|
| CLABE | 18-digit standardized bank account number used in Mexico for SPEI transfers (like an IBAN) |
| SPEI | Mexico's real-time interbank transfer system operated by Banxico (the central bank) |
| CEP | Comprobante Electrónico de Pago — a digitally signed XML receipt issued by Banxico that proves a SPEI transfer happened |
| Escrow | A smart contract on Starknet that holds the seller's crypto until the trade completes or is refunded |
| Starknet | An Ethereum Layer 2 blockchain where the escrow contracts live. Partners never interact with it directly |
| Spread | The difference between the exchange rate at order creation and the seller's asking price, expressed as a percentage |
Your 5 API calls
The entire partner integration uses just 5 endpoints:
GET /health— Verify your API key and check your tierPOST /users— Register a user (once per user)GET /exchange-rate— Get the current USD/MXN ratePOST /quotes— Lock a rate for 5 minutesPOST /orders— Create an escrow order from a quote
That's it. Everything after step 5 is handled by the marketplace.
What happens after you create an order
YOUR SERVER MEXICOP2P STARKNET BUYER
│ │ │ │
│ POST /orders │ │ │
│ ─────────────────────────► │ │ │
│ ◄── { status: PENDING } │ │ │
│ │ │ │
│ │ Seller deposits crypto │ │
│ │ ────────────────────────►│ │
│ ◄── webhook: ACTIVE │ │ │
│ │ │ │
│ │ Buyer locks order │
│ │ ◄───────────────────────────────────│
│ ◄── webhook: LOCKED │ │ │
│ │ │ │
│ │ │ Buyer sends MXN │
│ │ │ via SPEI │
│ │ │ │
│ │ CEP verified │ │
│ │ ────────────────────────►│ Release crypto │
│ ◄── webhook: COMPLETED │ │ ────────────────────►│
│ │ │ │Key takeaway: After POST /orders, you just listen for webhooks. You don't need to call any more endpoints to complete the trade.
Order statuses
| Status | What happened | What you should do |
|---|---|---|
PENDING_DEPOSIT | Order created, waiting for seller to deposit crypto into escrow | Wait for order.deposit_confirmed webhook |
ACTIVE | Crypto is in escrow, order visible to buyers on marketplace | Wait for order.locked webhook |
LOCKED | A buyer committed to purchase, has 24h to send MXN via SPEI | Wait for order.payment_verified or order.lock_expired webhook |
PENDING_RELEASE | SPEI payment verified via CEP, crypto being released on-chain | Wait for order.completed webhook |
COMPLETED | Trade finished — buyer got crypto, seller got MXN | Update your UI. Terminal state |
EXPIRED | No deposit or no buyer before timeout | Clean up. Terminal state |
REFUNDED | Crypto returned to seller (lock expired, cancelled, or dispute) | Clean up. Terminal state |
DISPUTED | Either party opened a dispute on the escrow contract | Wait for order.dispute_resolved webhook |
Status flow diagram
Happy path
----------
PENDING_DEPOSIT ---> ACTIVE ---> LOCKED ---> PENDING_RELEASE ---> COMPLETED
Unhappy paths
-------------
PENDING_DEPOSIT ---> EXPIRED (no deposit before timeout)
ACTIVE -----------> EXPIRED (no buyer before timeout)
LOCKED -----------> REFUNDED (lock expired, no payment)
LOCKED -----------> DISPUTED ------> COMPLETED (resolved for buyer)
|--> REFUNDED (resolved for seller)
|--> LOCKED (no-fault, retry with new 24h timer)KYC: Two models
MexicoP2P supports two approaches to Know Your Customer verification. Your model is chosen when your partner account is created — it applies to all your users.
Option A: Partner-managed
You already verify identities on your side (e.g., you're a regulated fintech). When registering users, you attest to their KYC level:
curl -X POST \
-H "X-API-Key: mp2p_test_xxx" \
-H "Content-Type: application/json" \
-d '{
"partnerUserRef": "user_12345",
"kycAttestation": {
"level": "BASIC",
"verifiedAt": "2025-06-01T00:00:00Z"
}
}' \
https://mexicop2p.org/api/v1/usersYou're responsible for verifying the user meets the requirements for the level you attest to. With this model, POST /users/:ref/kyc returns KYC_NOT_AVAILABLE since verification happens on your side.
Option B: MexicoP2P-provided
We handle identity verification through our provider (Didit). You redirect users to a verification URL when they need to level up:
# 1. Register the user (no attestation needed)
curl -X POST \
-H "X-API-Key: mp2p_test_xxx" \
-H "Content-Type: application/json" \
-d '{"partnerUserRef": "user_12345"}' \
https://mexicop2p.org/api/v1/users
# 2. Start a KYC session when the user needs to verify
curl -X POST \
-H "X-API-Key: mp2p_test_xxx" \
-H "Content-Type: application/json" \
-d '{
"level": "BASIC",
"returnUrl": "https://your-app.com/kyc/complete"
}' \
https://mexicop2p.org/api/v1/users/user_12345/kycThe response contains a sessionUrl — redirect the user there. When they finish, they're sent back to your returnUrl. Each verification session costs $1.00 (BASIC) or $2.50 (FULL), billed to the partner. Free and Growth tiers include a monthly allocation before overages apply.
BASIC vs FULL verification
| BASIC | FULL | |
|---|---|---|
| What's checked | Government-issued ID (INE/passport) + selfie liveness check | Everything in BASIC + proof of address (utility bill, bank statement) + enhanced screening |
| Volume limit | Up to 50,000 MXN/month | Unlimited |
| Typical use | Most users | High-volume traders |
When is KYC required?
KYC is not required to start trading. New users can trade immediately. Verification is only triggered when a user's cumulative volume hits a threshold:
| Cumulative volume | Required KYC | What happens |
|---|---|---|
| Under 10,000 MXN/month | None | User trades freely |
| 10,000 – 50,000 MXN/month | BASIC | Next POST /orders returns KYC_REQUIRED until BASIC is completed |
| Over 50,000 MXN/month | FULL | Next POST /orders returns KYC_REQUIRED until FULL is completed |
When a user hits a threshold, their next order creation fails with KYC_REQUIRED. You then either submit a kycAttestation (partner-managed) or start a KYC session (MexicoP2P-provided) to unlock further trading.
Dispute resolution
Disputes can happen during LOCKED status — for example, the buyer claims they sent payment but the seller says they didn't receive it, or the CEP can't be verified due to a Banxico outage.
How disputes work
- Either party opens a dispute on the Starknet escrow contract. The order moves to
DISPUTEDstatus. You receive anorder.disputedwebhook. - A MexicoP2P admin reviews the evidence — CEP records, transaction history, user reputation, and fraud scoring.
- The admin resolves the dispute. You receive an
order.dispute_resolvedwebhook with the outcome.
Three possible outcomes
| Outcome | What happens to the crypto | What happens to reputation | When this applies |
|---|---|---|---|
| Resolved for buyer | Released to buyer | Seller loses 50 points | Buyer paid but seller denies receiving it; CEP proves payment |
| Resolved for seller | Refunded to seller | Buyer loses 50 points | Buyer never paid or submitted a fraudulent CEP |
| No-fault | Depends on sub-outcome (see below) | No penalty for either party | External issue — neither party is at fault |
No-fault sub-outcomes
When a dispute is nobody's fault (e.g., Banxico was down, a network error prevented the CEP from being verified), the admin chooses one of these:
- Release to buyer — Buyer actually paid (has a valid receipt outside the system). Crypto released to buyer. Order →
COMPLETED. - Refund to seller — Buyer couldn't complete payment due to the external issue. Crypto returned to seller. Order →
REFUNDED. - Retry — Temporary issue is resolved. Order returns to
LOCKEDwith a fresh 24-hour timer so the buyer can try again.
What you need to do
Nothing. Disputes are handled entirely by the marketplace. Just listen for the order.dispute_resolved webhook and update your UI based on the final order status (COMPLETED, REFUNDED, or back to LOCKED).
Pricing
MexicoP2P does not charge fees to end users. There is no platform fee on trades.
Your fee, your choice
As a partner, you decide whether to charge your users a fee on each trade. When creating a quote, you can pass feePercent (0–10%) and feeRecipient to add a markup:
Exchange rate (from Banxico): 17.25 MXN/USD
100 USDC at that rate: 1,725.00 MXN
Your fee (e.g., 1.5%): − 25.88 MXN
Net to user: 1,699.12 MXNIf you don't pass feePercent, it defaults to 0 — the user gets the raw exchange rate with no markup.
Revenue share
MexicoP2P takes a percentage of the fees you collect, based on your tier:
| Tier | MexicoP2P's share of your fees |
|---|---|
| Free | 30% |
| Growth | 20% |
| Enterprise | Custom (negotiated) |
If you charge no fees (feePercent: 0), there's nothing to share — you pay nothing.
Where to see your revenue
- Partner Dashboard — Your total fees collected and MexicoP2P's revenue share are shown in the Revenue tab.
- Admin Dashboard — Platform-wide revenue across all partners is visible under Partners > Revenue.
Quote response fields
| Field | Description |
|---|---|
exchangeRate | Base USD/MXN rate from Banxico |
grossAmountMxn | Total MXN before your fee |
feePercent | Your fee percentage (0 if not set) |
feeAmountMxn | Your fee in MXN |
feeRecipient | "PARTNER", "USER", or "NONE" |
netAmountMxn | MXN amount after your fee |