Cobros
Cobra facturas de tu App con el saldo QvaPay del usuario sin que salga de tu mini-app.
Flujo
-
Tu servidor crea la factura con
POST /v2/create_invoice, usando las credenciales de la App de tu mini-app. Guarda eltransaction_uuidjunto a tu pedido (remote_id). -
Tu frontend pide el pago:
const { status, transaction_uuid } = await QvaPay.payments.payInvoice(invoiceUuid)La app muestra la hoja de pago nativa con el importe y el nombre de tu App; el usuario confirma con su PIN (o código 2FA).
-
Tu servidor confirma el pago con el webhook de la factura (o el
callbackde la App), o consultando/v2/transactions/:uuid. Solo entonces entregas el producto.
La promesa de payInvoice sirve para la interfaz (mostrar "¡Pagado!"), no para entregar nada. Un frontend se puede manipular: confía únicamente en el webhook firmado (x-qvapay-signature) o en el estado de la factura consultado desde tu servidor.
Reglas
- La factura debe pertenecer a la misma App que la mini-app, si no:
INVOICE_APP_MISMATCH. - Debe estar
pendingy sin caducar (expire_at). - El usuario no puede pagar una factura propia y necesita saldo suficiente.
- Pagar no requiere que el usuario haya compartido su identidad: puedes cobrar sin
requestLogin. - Las facturas de sandbox (
is_test) no se pueden pagar desde una mini-app. - La app protege el pago con una clave de idempotencia: un doble toque o un reintento por red caída nunca cobran dos veces.
- Solo cobra una mini-app cuyo dueño tiene la verificación de identidad aprobada. Si deja de cumplirlo, el pago se rechaza con
MINIAPP_UNAVAILABLE. - Hay un máximo por pago y un máximo por usuario en 24 horas para los pagos desde mini-apps (
MINIAPP_LIMIT_PER_PAYMENT,MINIAPP_LIMIT_DAILY). Diseña tus importes por debajo; si necesitas más, habla con QvaPay. - El pago pasa los mismos controles que una transferencia entre usuarios (sanciones, Travel Rule y, si tu App es de un nacional cubano, la certificación OFAC del pagador). Un rechazo por estos motivos llega a tu frontend como
FAILED.
Webhook
Cuando la factura se paga, QvaPay envía un POST al webhook de la factura (o al callback de la App) con:
{
"transaction_uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"remote_id": "order-12345",
"status": "paid",
"amount": "5.00",
"signed": 0,
"created_at": "2026-10-05T12:00:00.000Z",
"updated_at": "2026-10-05T12:00:30.000Z"
}Con las cabeceras x-qvapay-signature: sha256=<hex> (HMAC-SHA256 del cuerpo con tu app-secret) y x-qvapay-timestamp. Verifica la firma antes de marcar el pedido como pagado.