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) o https://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-Agent claro, por ejemplo AcmeShop-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_currency en GET/account, hoy USD).
  • face_currency es la moneda impresa en la tarjeta. Puede ser distinta a la de tu billetera.
  • Para tus costos, usa siempre merchant_price. Campos como price_label son 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é esEjemploNotas
Merchant IDM00000001Nunca cambia.
ID de SKUS000456Lo usas para cotizar y pedir.
ID de productoP000123El producto al que pertenece un SKU.
ID de pedido de CardVO-00001234Lo usas para consultar un pedido.
Tu número de pedidoSHOP-10001external_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 id numérico. No lo uses. Usa order_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:

HTTP
GET /api/v1/skus?limit=100&offset=200
JSON
{"count": 1234, "limit": 100, "results": ["..."], "filter_options": {}}
  • limit vale 100 por defecto. El máximo es 500. Los valores mayores se reducen a 500.
  • count es el total de resultados. Sigue pidiendo páginas hasta que offset llegue a count.
  • Un limit u offset negativo 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 :00 del 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):

    JSON
    {"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:

JSON
{"detail": "Order not found."}

Los errores de pedidos y cotizaciones indican el campo:

JSON
{"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:

JSON
{"items": [{}, {"quantity": ["Ensure this value is greater than or equal to 1."]}]}
ClaveDóndeQué hacer
detailCualquieraMira el código de estado más abajo.
itemsPOST/ordersCorrige la línea. Si cambió el precio, vuelve a cotizar.
balancePOST/ordersAgrega fondos en el Portal.
riskPOST/ordersLlegaste a un límite de pedidos. Contacta a CardV.
external_order_idPOST/ordersFalta tu número de pedido, es demasiado largo o ya se usó en otro pedido.
walletPOST/ordersNo hay una billetera activa. Contacta a CardV.
quantity, amountCotizaciónFuera de rango o no es un número.
limit, offsetGET/skusNo es un número válido.

Algunos errores no vienen en JSON:

  • Un HTTP 403 con texto plano como error code: 1010 viene de la red perimetral de CardV. Tu solicitud nunca llegó a CardV. Envía a CardV la IP de tu servidor y tu User-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ódigoSignificado¿Reintentar?
200Éxito. En POST/orders: el pedido ya existía.No hace falta
201Se creó un pedido nuevo.No hace falta
400La solicitud fue rechazada. No se cobró nada.Después de corregirla
403Credenciales, firma, IP o un endpoint exclusivo del Portal.Después de corregirlo
404No existe o no está disponible para tu cuenta.No
405Método incorrecto para esta ruta.No
429Demasiadas solicitudes.Después de Retry-After
5xx o tiempo agotadoProblema 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_url y image_url son URLs completas de imágenes alojadas por CardV, o "". Son públicas y se pueden guardar en caché.
  • Los campos del pedido invoice_url y delivery_file_url son 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.