QvaPay API
P2P

Puesto promocionado

Comprar o pujar por el puesto destacado de una moneda en el mercado P2P.

Cada moneda del mercado P2P tiene dos puestos promocionados, uno por tipo de oferta:

offer_typePestaña donde saleQué ofertas promociona
sellComprarTus ofertas de venta de QUSD
buyVenderTus ofertas de compra de QUSD

Quien tiene el puesto sale arriba del listado de esa moneda y tipo con su mejor oferta abierta (la de mejor tasa para quien la toma), con borde amarillo y la etiqueta «Promocionado». La misma oferta lleva el borde también en su posición normal. El orden del mercado por mejor tasa no cambia. Si el titular no tiene ninguna oferta abierta de ese par, no sale nada.

Cómo funciona

  • Puesto libre: se compra al instante a precio de salida ($10) y queda bloqueado 30 días. Nadie lo quita en ese tiempo.
  • Puesto ocupado: se puja por el periodo siguiente. Para superar la puja líder hay que ofrecer un 10 % más, con un mínimo de +$1. La primera puja empieza en el precio de salida.
  • La puja se cobra del saldo al hacerla y queda retenida. Si alguien la supera, se devuelve íntegra al instante. Solo paga quien gana el periodo.
  • Al vencer el periodo, la puja más alta empieza el suyo justo donde terminó el anterior. Si nadie pujó, el puesto vuelve a estar libre.
  • No puedes subir tu propia puja mientras vas ganando. El titular actual sí puede pujar por el periodo siguiente.
  • Te avisamos por push y Telegram cuando te superan, cuando ganas un periodo, cuando termina y 3 días antes de que venza.

GET /p2p/promo

Estado de los dos puestos de una moneda.

Autenticación

Bearer Token (Authorization: Bearer <token> en headers).

Request

curl -X GET "https://api.qvapay.com/p2p/promo?coin=BANK_CUP" \
  -H "Authorization: Bearer <token>"
ParámetroTipoRequeridoDescripción
coinstringSíTick de la moneda (ej: BANK_CUP)

Response (200)

{
  "data": {
    "coin": "BANK_CUP",
    "enabled": true,
    "slots": [
      {
        "coin": "BANK_CUP",
        "offer_type": "sell",
        "state": "held",
        "holder": { "uuid": "9a1b…", "username": "comerciante" },
        "starts_at": "2026-10-16T12:00:00.000Z",
        "ends_at": "2026-11-15T12:00:00.000Z",
        "leading_amount": 25,
        "min_bid": 27.5,
        "start_price": 10,
        "period_days": 30
      },
      {
        "coin": "BANK_CUP",
        "offer_type": "buy",
        "state": "free",
        "holder": null,
        "starts_at": null,
        "ends_at": null,
        "leading_amount": null,
        "min_bid": 10,
        "start_price": 10,
        "period_days": 30
      }
    ]
  }
}
CampoDescripción
statefree (se compra a start_price), held (se puja por el periodo siguiente) o rotating (el periodo acaba de vencer y se está asignando, reintenta en unos minutos)
holderTitular del periodo vigente, o null
ends_atFin del periodo vigente
leading_amountPuja más alta por el periodo siguiente, o null si no hay. Quién la hizo no se publica
min_bidLo mínimo que hay que mandar como amount ahora mismo

Con la función apagada, enabled es false y slots viene vacío.

POST /p2p/promo

Compra el puesto (si está libre) o puja por el periodo siguiente (si está ocupado). El servidor decide cuál de las dos según el estado del puesto en ese instante.

Requisitos de la cuenta: KYC aprobado y P2P activo.

Request

curl -X POST "https://api.qvapay.com/p2p/promo" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "coin": "BANK_CUP", "offer_type": "sell", "amount": 27.5, "idempotency_key": "promo-7f3c9a1e" }'

Body

CampoTipoRequeridoDescripción
coinstringSíTick de la moneda
offer_typestringSísell (pestaña Comprar) o buy (pestaña Vender)
amountnumberSíPuesto libre: exactamente start_price. Puesto ocupado: tu puja, igual o mayor que min_bid (máximo $5000)
idempotency_keystringSí8–64 caracteres [A-Za-z0-9._-]. Repetir la misma clave nunca cobra dos veces

Response (201)

{
  "data": {
    "uuid": "3f2a…",
    "coin": "BANK_CUP",
    "offer_type": "sell",
    "kind": "bid",
    "status": "held",
    "amount": 27.5,
    "period_starts_at": null,
    "period_ends_at": null,
    "created_at": "2026-10-20T09:15:00.000Z"
  },
  "action": "bid",
  "slot": { "coin": "BANK_CUP", "offer_type": "sell", "state": "held", "leading_amount": 27.5, "min_bid": 30.25 },
  "balance": 412.7
}

action es purchase cuando compraste un puesto libre (kind: "purchase", status: "won", con su periodo) o bid cuando pujaste (status: "held" mientras vas ganando). Repetir una idempotency_key ya usada responde 200 con la misma operación y duplicate: true.

Errores

StatuscodeCuándo
400INVALID_BODY / INVALID_COIN / INVALID_AMOUNTDatos inválidos o moneda sin P2P
400INSUFFICIENT_BALANCENo tienes saldo para el monto
400BID_TOO_HIGHLa puja supera el máximo (max)
403P2P_NOT_ENABLEDLa cuenta no tiene KYC o P2P activo
403SECURITY_HOLDLa cuenta tiene una retención de seguridad vigente
409PROMO_PRICE_CHANGEDEl estado cambió (alguien pujó o el puesto se liberó): min trae el nuevo mínimo y no se cobró nada
409ALREADY_LEADINGYa tienes la puja más alta por el periodo siguiente
409PROMO_RETRYEl puesto se está actualizando; reintenta en unos segundos
409DUPLICATE_REQUESTHay una operación con la misma clave en curso
429RATE_LIMITEDMás de 5 operaciones por minuto
503PROMO_DISABLEDLa función no está disponible

Todos los errores de negocio traen slot con el estado actual del puesto.

En el listado

GET /p2p con coin y type devuelve el campo promoted con la oferta promocionada de ese par, lista para pintar arriba del resto.