- veins → shunts rename - add cfg/standalone/ and cfg/<room>/ structure - remove old data/*.json (moved to cfg/<room>/data/) - update build.py and ctrl scripts
5.6 KiB
5.6 KiB
MercadoPago (MOCK) Vein
Mock MercadoPago API for testing - simulates payment processing without hitting the real MercadoPago API.
Purpose
Enables testing of MercadoPago integration without:
- Creating real payments
- Connecting real MercadoPago accounts
- Exposing credentials
- Consuming API quotas
Quick Start
# Install dependencies
pip install -r requirements.txt
# Start the mock server
python run.py
# API docs: http://localhost:8006/docs
# Health check: http://localhost:8006/health
Configuration
Copy .env.example to .env and adjust:
API_PORT=8006 # Server port
ENABLE_RANDOM_DELAYS=true # Add realistic delays
MIN_DELAY_MS=200 # Minimum delay
MAX_DELAY_MS=800 # Maximum delay
ERROR_RATE=0.0 # Error rate (0.0 to 1.0)
DEFAULT_PAYMENT_STATUS=approved # approved, pending, rejected
API Endpoints
Checkout Pro (Preferences)
# Create payment link
POST /v1/preferences
{
"items": [
{
"title": "Visita a domicilio",
"quantity": 1,
"unit_price": 95000,
"currency_id": "ARS"
}
],
"external_reference": "SR-12345",
"back_urls": {
"success": "https://backoffice.amarmascotas.ar/pagos/success/",
"pending": "https://backoffice.amarmascotas.ar/pagos/pending/",
"failure": "https://backoffice.amarmascotas.ar/pagos/failure/"
},
"notification_url": "https://backoffice.amarmascotas.ar/payments/mp/webhook/"
}
# Get preference
GET /v1/preferences/{preference_id}
Checkout API (Payments)
# Create payment
POST /v1/payments
Headers:
X-Idempotency-Key: unique-key-123
Body:
{
"transaction_amount": 95000,
"description": "Visita a domicilio",
"payment_method_id": "visa",
"payer": {
"email": "test@example.com",
"identification": {
"type": "DNI",
"number": "12345678"
}
},
"application_fee": 45000
}
# Get payment details
GET /v1/payments/{payment_id}
OAuth
# Exchange authorization code for tokens
POST /oauth/token
{
"grant_type": "authorization_code",
"client_id": "APP_ID",
"client_secret": "APP_SECRET",
"code": "AUTH_CODE"
}
# Refresh access token
POST /oauth/token
{
"grant_type": "refresh_token",
"client_id": "APP_ID",
"client_secret": "APP_SECRET",
"refresh_token": "REFRESH_TOKEN"
}
Mock Control
# Get mock database stats
GET /mock/stats
# Reset mock database
GET /mock/reset
# Update mock configuration
POST /mock/config
{
"default_payment_status": "approved",
"error_rate": 0.1
}
# Simulate webhook notification
POST /mock/webhook?topic=payment&resource_id=12345
Response Format
All responses include _mock: "MercadoPago" to identify mock data:
{
"id": 123456789,
"status": "approved",
"transaction_amount": 95000,
"_mock": "MercadoPago"
}
Testing Scenarios
Test Payment Link Creation
import requests
BASE_URL = "http://localhost:8006"
# Create preference
pref_resp = requests.post(f"{BASE_URL}/v1/preferences", json={
"items": [{
"title": "Visita a domicilio",
"quantity": 1,
"unit_price": 95000,
"currency_id": "ARS"
}],
"external_reference": "SR-12345"
})
pref = pref_resp.json()
print(f"Payment link: {pref['init_point']}")
Test Direct Payment with Split
import requests
BASE_URL = "http://localhost:8006"
# Create payment with application fee (split)
payment_resp = requests.post(
f"{BASE_URL}/v1/payments",
headers={"X-Idempotency-Key": "unique-123"},
json={
"transaction_amount": 95000,
"description": "Visita a domicilio",
"payment_method_id": "visa",
"payer": {
"email": "test@example.com",
"identification": {"type": "DNI", "number": "12345678"}
},
"application_fee": 45000 # Platform fee
}
)
payment = payment_resp.json()
print(f"Payment status: {payment['status']}")
print(f"Net amount (for vet): ${payment['net_amount']}")
Test Different Payment Statuses
import requests
BASE_URL = "http://localhost:8006"
# Configure mock to return rejected payments
requests.post(f"{BASE_URL}/mock/config", json={
"default_payment_status": "rejected"
})
# Now all payments will be rejected
payment_resp = requests.post(f"{BASE_URL}/v1/payments", json={...})
print(payment_resp.json()["status"]) # "rejected"
# Reset to approved
requests.post(f"{BASE_URL}/mock/config", json={
"default_payment_status": "approved"
})
Test Error Scenarios
import requests
BASE_URL = "http://localhost:8006"
# Configure 50% error rate
requests.post(f"{BASE_URL}/mock/config", json={
"error_rate": 0.5
})
# Half of requests will now fail with 500 error
for i in range(10):
try:
resp = requests.post(f"{BASE_URL}/v1/payments", json={...})
print(f"Request {i}: Success")
except:
print(f"Request {i}: Failed")
Data Generator
This vein uses the independent datagen tool from ward/tools/datagen/mercadopago.py.
See ward/tools/datagen/README.md for data generation details.
Integration with Amar Backend
Point your Amar backend to the mock MercadoPago API:
# settings.py or .env
MP_PLATFORM_ACCESS_TOKEN = "mock_token" # Any value works
MP_API_BASE_URL = "http://localhost:8006" # Point to mock
Notes
- Mock database is in-memory (resets on server restart)
- All payment IDs are randomly generated
- Payment status can be configured via
/mock/config - Webhook notifications can be simulated via
/mock/webhook - OAuth tokens are generated but not validated