refactor: separate standalone and managed room configs

- 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
This commit is contained in:
buenosairesam
2026-01-02 17:09:58 -03:00
parent 46dc78db0e
commit 9e5cbbad1f
57 changed files with 1788 additions and 150 deletions

View File

@@ -0,0 +1,263 @@
# 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
```bash
# 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:
```bash
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)
```bash
# 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)
```bash
# 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
```bash
# 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
```bash
# 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:
```json
{
"id": 123456789,
"status": "approved",
"transaction_amount": 95000,
"_mock": "MercadoPago"
}
```
## Testing Scenarios
### Test Payment Link Creation
```python
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
```python
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
```python
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
```python
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:
```python
# 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