QvaPay API
Store

Vouchers / Gift Cards

Catálogo global de vouchers y gift cards. Listar países, marcas, ofertas y comprar.

Catálogo de vouchers y gift cards distribuido por país y marca. Es el flujo único para tarjetas de regalo (Amazon, Apple, Spotify, Steam, etc.) — los productos se descubren navegando por país y marca.


GET /store/voucher-catalog

Endpoint multimodo. El modo se determina por los query params presentes.

Autenticación

No requiere autenticación (endpoint público). Rate limit: 30 req/min por IP.

Modos

ModoQueryDevuelve
Destacados?featuredTop 12 marcas globales por cantidad de ofertas
Países?countriesLista de países con vouchers disponibles
Marcas?country=XXMarcas disponibles para un país (acepta &q=... para búsqueda)
Ofertas?country=XX&brand=NombreOfertas de una marca en un país

Modo destacados

curl -X GET "https://api.qvapay.com/store/voucher-catalog?featured"
{
  "featured": [
    {
      "brand": "Amazon",
      "slug": "amazon",
      "country": "US",
      "logo_url": "https://...",
      "offer_count": 12,
      "country_meta": { "name": "Estados Unidos", "flag": "🇺🇸" }
    }
  ]
}

Modo países

curl -X GET "https://api.qvapay.com/store/voucher-catalog?countries"
{
  "countries": [
    { "code": "US", "offer_count": 230, "name": "Estados Unidos", "flag": "🇺🇸" },
    { "code": "ES", "offer_count": 45, "name": "España", "flag": "🇪🇸" }
  ]
}

Modo marcas (por país)

curl -X GET "https://api.qvapay.com/store/voucher-catalog?country=US&q=amazon"
ParámetroTipoRequeridoDescripción
countrystring (ISO-2)SíCódigo de país
qstringNoBúsqueda parcial por nombre de marca
{
  "country": { "name": "Estados Unidos", "flag": "🇺🇸" },
  "brands": [
    {
      "brand": "Amazon",
      "slug": "amazon",
      "country": "US",
      "logo_url": "https://...",
      "bg_color": "#FF9900",
      "offer_count": 5,
      "sample_price": 10.00
    }
  ]
}

Modo ofertas

curl -X GET "https://api.qvapay.com/store/voucher-catalog?country=US&brand=Amazon"
ParámetroTipoRequeridoDescripción
countrystring (ISO-2)SíCódigo de país
brandstringSíNombre de marca (URL-encoded)
{
  "country": { "name": "Estados Unidos", "flag": "🇺🇸" },
  "brand": "Amazon",
  "brand_logo_url": "https://...",
  "offers": [
    {
      "source": "global",
      "offer_id": "OFFER_ABC123",
      "name": "Amazon Gift Card $10",
      "notes": "Amazon Gift Card $10",
      "sent_benefits": "Código digital",
      "send": { "currency": "USD", "value": 10.00 },
      "sub_type": "DIGITAL",
      "price_type": "FIXED",
      "price": 10.50
    },
    {
      "source": "global",
      "offer_id": "OFFER_XYZ789",
      "name": "Amazon Gift Card (variable)",
      "notes": null,
      "sent_benefits": "Código digital",
      "sub_type": "DIGITAL",
      "price_type": "RANGE",
      "price_min": 5.00,
      "price_max": 500.00,
      "service_fee_pct": 5.0
    }
  ]
}

Notas

  • Para ofertas FIXED, el campo price ya incluye impuestos. No se expone base_price ni tax_pct.
  • Para ofertas RANGE, se expone service_fee_pct para que el cliente pueda calcular el total: total = amount + (amount * service_fee_pct / 100).
  • El offer_id es el identificador requerido por el endpoint de compra.
  • sent_benefits describe lo que el destinatario recibe (ej: "60 UC", "12,000 UC + 4,200 Free"). Puede ser null si la oferta no provee descripción específica.
  • send contiene el valor monetario que se entrega al destinatario ({ currency, value }). Útil cuando sent_benefits viene vacío y el voucher representa un monto fijo en USD/etc. — el cliente puede mostrar ese valor al usuario para transparencia.

POST /store/voucher/purchase

Compra un voucher. El monto total (base + impuesto) se descuenta del balance del usuario autenticado.

Autenticación

Bearer Token (header Authorization: Bearer <token>). Rate limit: 1 req/10s por usuario.

Request

curl -X POST https://api.qvapay.com/store/voucher/purchase \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "offer_id": "OFFER_ABC123",
    "country": "US",
    "brand": "Amazon",
    "amount": 25
  }'

Parámetros (body)

ParámetroTipoRequeridoDescripción
offer_idstringSíID de la oferta obtenido del catálogo
countrystring (ISO-2)SíCódigo de país de la oferta
brandstringSíNombre de la marca. Se acepta por compatibilidad, pero la marca que se registra es la de la oferta en el catálogo
amountintegerCondicionalMonto deseado en USD, entero (sin decimales). Requerido solo para ofertas con price_type: "RANGE"

Response

{
  "message": "Tarjeta solicitada",
  "transaction_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "buyedService_id": "123"
}

Recuperar el código del voucher

La compra queda en pending hasta que se procesa la entrega. Para obtener el código/PIN/URL de canje una vez procesada, consulta GET /store/my/{buyedService_id} usando el buyedService_id devuelto aquí — el código vive en data.service_data.receipt. Ver Mis Compras.

Notas

  • La compra valida la oferta contra el catálogo en vivo (el precio puede haber cambiado entre la consulta del catálogo y la compra).
  • El impuesto se aplica según el override de la oferta o el tax/tax_gold (si el usuario es golden) del service GIFT_CARD configurado para la marca.
  • La compra queda en estado pending hasta que se procesa la entrega.
  • Para ofertas RANGE, amount debe ser un entero (sin decimales) dentro del rango [price_min, price_max] retornado por el catálogo.

Errores

CódigoDescripción
400Request inválido (faltan campos o formato incorrecto)
400country no coincide con la oferta
400Categoría de oferta inválida (no es VOUCHER)
400Precio de oferta inválido
400amount requerido para ofertas RANGE
400amount fuera del rango permitido o con decimales
400Saldo insuficiente
401No autorizado
403code: "PREPAID_LIMIT": límite de acceso prepagado alcanzado (por compra o acumulado en 30 días)
403code: "GIFTCARD_LIMIT": límite diario de compras de tarjetas de la cuenta (las cuentas recientes tienen un límite menor durante sus primeros días)
404Oferta no disponible o deshabilitada
429Rate limit excedido
500Error al procesar la compra
503code: "GIFTCARD_PAUSED": compras de tarjetas pausadas temporalmente por volumen anómalo. Reintenta más tarde

Los límites no se publican: la respuesta solo indica que se alcanzaron. Un 403/503 con estos códigos no cobra nada.