Toda la integración cabe en tres endpoints REST. Lo demás (sandbox/live, rate limit, webhook events, error codes, retries) lo maneja la plataforma. Spec OpenAPI 3.1 completa disponible.
Una sola base URL para ambos entornos. El prefix de tu API key decide si vas a sandbox o live.
https://getcwallet.app/api/v1
Header Authorization: Bearer <tu_api_key>. La key viene del dashboard de comercios. Cada merchant tiene 2 keys:
cwt_test_… → sandbox (no mueve plata real, simulación pura)cwt_live_… → producción (USDT TRC20 mainnet, settlements reales)| Method | Path | Auth |
|---|---|---|
| POST | /create-payment-intent | Bearer cwt_test_… | cwt_live_… |
| GET | /intent-status?id=<uuid> | ninguno |
| POST | /demo-create-intent | ninguno |
Crea un payment intent en el terminal asociado a la API key.
Request
POST /create-payment-intent
Authorization: Bearer cwt_test_XXXXXXXX
Content-Type: application/json
{
"amount_usdt": 25.50
}Response 200
{
"success": true,
"message": "...",
"terminal": "Caja principal",
"environment": "sandbox",
"livemode": false,
"intent": {
"id": "11111111-2222-...",
"amount_usdt": 25.50,
"status": "pending",
"expires_at": "2026-05-20T15:30:00Z",
"environment": "sandbox",
"checkout_uri": "cwallet:pay?intent=11111111-..."
}
}intent.createdDevuelve el estado actual de un intent. Endpoint público (no requiere auth) porque lo usan widgets de browser para polling.
Request
GET /intent-status?id=<uuid> Accept: application/json
Response 200
{
"id": "11111111-...",
"amount_usdt": 25.50,
"status": "paid",
"environment": "live",
"livemode": true,
"expires_at": "2026-05-20T15:30:00Z"
}Status values: pending, paid, expired, cancelled. Pollealo cada 2 segundos hasta que cambie de pending.
Usado por el widget demo en /developers. Crea un intent sandbox en el merchant demo y auto-simula el pago a los 6 segundos. Rate limit: 5 req/min por IP.
Response 200
{
"intent_id": "abc...",
"amount_usdt": 47.32,
"environment": "sandbox",
"expires_at": "2026-05-20T15:35:00Z",
"auto_completes_in_ms": 6000
}Todos los errores devuelven JSON con shape { error: string, code?: string }. Usá el código para branchear en tu código, no el mensaje.
| HTTP | Code | Cuándo |
|---|---|---|
| 400 | invalid_amount | amount_usdt missing or ≤ 0 |
| 400 | invalid_url_scheme | Webhook URL must start with http:// or https:// |
| 400 | http_in_live | Live mode requires HTTPS webhooks |
| 400 | private_ip_in_live | Live mode rejects localhost / RFC1918 IPs |
| 401 | missing_api_key | No Authorization header |
| 401 | invalid_api_key | API key not found in our records |
| 401 | environment_mismatch | Key prefix doesn't match its stored environment |
| 401 | signature_verification_failed | HMAC signature didn't match (webhooks only) |
| 404 | not_found | Intent / terminal / merchant not found |
| 429 | rate_limited | Demo endpoint: 5 requests / minute per IP |
| 500 | api_error | Unexpected server error — retry with backoff |