Files
soleprint/artery/shunts/mercadopago/README.md
buenosairesam 9e5cbbad1f 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
2026-01-02 17:09:58 -03:00

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

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