Desarrolladores/Primeros pasos
Convenciones
Reglas que se aplican a los siete endpoints.
Ver también: Autenticación · Catálogo y pedidos · README
#Solicitudes
- URL base:
https://b2b.cardv.net/api/v1(Live) ohttps://sandbox.cardv.net/api/v1(Sandbox). - Las rutas no llevan barra al final. Usa
/api/v1/orders, no/api/v1/orders/. - Envía los cuerpos JSON en UTF-8 con
Content-Type: application/json. - Envía los montos como texto, por ejemplo
"9.2500". Así evitas errores de redondeo. - Usa un
User-Agentclaro, por ejemploAcmeShop-CardV/1.4.
#Montos y fechas
- Los montos son texto con 4 decimales, por ejemplo
"merchant_price": "9.2500". - Léelos con un tipo decimal, nunca con un número de punto flotante.
- Pagas en la moneda de tu billetera (
default_currencyenGET/account, hoy USD). face_currencyes la moneda impresa en la tarjeta. Puede ser distinta a la de tu billetera.- Para tus costos, usa siempre
merchant_price. Campos comoprice_labelson solo para mostrar. - Todas las fechas y horas están en UTC, en formato ISO 8601, por ejemplo
2026-09-29T08:15:30.123456Z. - Usa un parser de ISO 8601 de verdad. La cantidad de decimales en los segundos puede variar.
X-Timestamp, que se usa para firmar, es la hora Unix en segundos.
#Identificadores
| Qué es | Ejemplo | Notas |
|---|---|---|
| Merchant ID | M00000001 | Nunca cambia. |
| ID de SKU | S000456 | Lo usas para cotizar y pedir. |
| ID de producto | P000123 | El producto al que pertenece un SKU. |
| ID de pedido de CardV | O-00001234 | Lo usas para consultar un pedido. |
| Tu número de pedido | SHOP-10001 | external_order_id, de 1 a 120 caracteres, único. |
- Guarda los IDs como texto. No intentes interpretarlos. Pueden volverse más largos.
- Los pedidos también tienen un
idnumérico. No lo uses. Usaorder_id. - En tu número de pedido, usa solo
A–Z a–z 0–9 - _ ..
#Paginación
Solo GET/skus está paginado. Envía limit y offset:
GET /api/v1/skus?limit=100&offset=200{"count": 1234, "limit": 100, "results": ["..."], "filter_options": {}}limitvale 100 por defecto. El máximo es 500. Los valores mayores se reducen a 500.countes el total de resultados. Sigue pidiendo páginas hasta queoffsetllegue acount.- Un
limituoffsetnegativo o que no sea un número devuelve HTTP 400. - Un valor de filtro desconocido devuelve una lista vacía, no un error.
#Límite de solicitudes
El límite por defecto es de 60 solicitudes por minuto para toda tu cuenta. Lo comparten todas tus claves y los usuarios del Portal. Tu nivel de cuenta puede tener otro límite.
El minuto empieza en
:00del reloj. Las solicitudes rechazadas también cuentan.Si te pasas del límite, recibes HTTP 429 y un encabezado
Retry-After(segundos que debes esperar):{"detail": "Merchant API rate limit exceeded. Expected available in 23 seconds."}Para no pasarte: guarda en caché la lista de SKUs, usa webhooks en vez de consultar a cada rato y espera un poco más después de cada 429.
#Errores
Revisa siempre primero el código HTTP. Después lee el cuerpo JSON. La clave del cuerpo te dice qué salió mal. No dependas del texto del mensaje.
Los errores de autenticación, permisos, recurso no encontrado y límite de solicitudes usan detail:
{"detail": "Order not found."}Los errores de pedidos y cotizaciones indican el campo:
{"balance": "Insufficient available balance."}Si una línea del pedido está mal formada, el error se indica por línea, en la misma posición que en tu items:
{"items": [{}, {"quantity": ["Ensure this value is greater than or equal to 1."]}]}| Clave | Dónde | Qué hacer |
|---|---|---|
detail | Cualquiera | Mira el código de estado más abajo. |
items | POST/orders | Corrige la línea. Si cambió el precio, vuelve a cotizar. |
balance | POST/orders | Agrega fondos en el Portal. |
risk | POST/orders | Llegaste a un límite de pedidos. Contacta a CardV. |
external_order_id | POST/orders | Falta tu número de pedido, es demasiado largo o ya se usó en otro pedido. |
wallet | POST/orders | No hay una billetera activa. Contacta a CardV. |
quantity, amount | Cotización | Fuera de rango o no es un número. |
limit, offset | GET/skus | No es un número válido. |
Algunos errores no vienen en JSON:
- Un HTTP 403 con texto plano como
error code: 1010viene de la red perimetral de CardV. Tu solicitud nunca llegó a CardV. Envía a CardV la IP de tu servidor y tuUser-Agent. - Una ruta desconocida (404) o un error de proxy (5xx) pueden devolver HTML.
Cuando registres errores en tus logs, nunca incluyas claves de API, firmas ni códigos.
#Códigos de estado HTTP
| Código | Significado | ¿Reintentar? |
|---|---|---|
| 200 | Éxito. En POST/orders: el pedido ya existía. | No hace falta |
| 201 | Se creó un pedido nuevo. | No hace falta |
| 400 | La solicitud fue rechazada. No se cobró nada. | Después de corregirla |
| 403 | Credenciales, firma, IP o un endpoint exclusivo del Portal. | Después de corregirlo |
| 404 | No existe o no está disponible para tu cuenta. | No |
| 405 | Método incorrecto para esta ruta. | No |
| 429 | Demasiadas solicitudes. | Después de Retry-After |
| 5xx o tiempo agotado | Problema del servidor o de la red. El pedido puede existir. | Sí, ver abajo |
En POST/orders, reintenta solo con el mismo cuerpo y el mismo número de pedido.
Consulta cómo reintentar sin riesgo.
#Respuestas
brand_logo_urlyimage_urlson URLs completas de imágenes alojadas por CardV, o"". Son públicas y se pueden guardar en caché.- Los campos del pedido
invoice_urlydelivery_file_urlson rutas como/orders/O-00001234/invoice, o""si todavía no hay nada. Solo funcionan en el Portal: con una clave de API devuelven HTTP 403. Abre las facturas y los archivos CSV de códigos en el Portal.
#Compatibilidad
- Ignora los campos que no conozcas. CardV agrega campos sin publicar una nueva versión de la API.
- Pueden aparecer nuevos valores de estado. Trata un estado desconocido como "todavía no terminado".
- No dependas del orden de las claves JSON ni del texto de los mensajes.
¿Dudas sobre tu integración? Escribe a [email protected] con tu Merchant ID y el ID del pedido o de la solicitud.