- 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
264 lines
5.6 KiB
Markdown
264 lines
5.6 KiB
Markdown
# 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
|