Transferir Saldo
Transferir saldo entre cuentas de usuarios de QvaPay.
POST /transaction/transfer
Transfiere saldo desde tu cuenta hacia otro usuario de QvaPay. La transferencia se ejecuta de forma atómica y notifica a ambas partes por email, push y Telegram.
Autenticación
Bearer Token o Credenciales de App (app-id + app-secret en headers).
Request
curl -X POST "https://api.qvapay.com/transaction/transfer" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"amount": 10.00,
"to": "janedoe",
"pin": "1234",
"description": "Pago por servicio"
}'Parámetros
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
amount | number | string | Si | Monto a transferir (debe ser mayor a 0) |
to | string | Si | Destinatario: UUID, email, username o teléfono |
pin | string | Si | PIN de seguridad del usuario (4 o 6 dígitos) |
description | string | No | Nota o descripción de la transferencia |
idempotency_key | string | No | Clave de idempotencia (8-64 caracteres, [A-Za-z0-9._-]) para reintentos seguros en conexiones inestables. Repetir la misma clave en 24h devuelve la transacción original con duplicate: true en vez de transferir de nuevo |
compliance | object | No | Certificación OFAC (CACR) cuando el destinatario es nacional cubano. Ver Certificación OFAC |
Response
{
"success": true,
"message": "Transferencia completada correctamente",
"transaction": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}Campos de respuesta
| Campo | Tipo | Descripción |
|---|---|---|
success | boolean | Indica si la transferencia fue exitosa |
message | string | Mensaje de confirmación |
transaction | string | UUID de la transacción creada |
Idempotencia
Si se envía idempotency_key y una transferencia ya fue completada con esa misma clave, la respuesta es 200 con la transacción original y el campo adicional "duplicate": true (no se mueve saldo de nuevo). Si la transferencia original aún está en proceso, se responde 409 con "code": "DUPLICATE_REQUEST" — reintenta unos segundos después.
Certificación OFAC (destinatario cubano)
Si el destinatario está identificado como nacional cubano en su verificación de identidad, la transferencia lleva la misma autocertificación CACR (31 CFR Part 515) que un retiro con destino Cuba. El servidor no rechaza la transferencia si falta: la certificación se registra cuando llega un payload válido y el destinatario es efectivamente nacional cubano; en cualquier otro caso se ignora.
Consulta si aplica antes de mostrar el formulario:
curl "https://api.qvapay.com/transaction/transfer/ofac-check?to=janedoe" \
-H "Authorization: Bearer <token>"{ "required": true }La respuesta es solo un booleano; nunca expone la nacionalidad ni otros datos del destinatario. Formato del objeto (códigos válidos P-1, P-2, P-3, P-4; las cuatro casillas en true):
{
"amount": 100,
"to": "janedoe",
"pin": "1234",
"compliance": {
"purposeCode": "P-1",
"attestations": {
"notProhibitedOfficial": true,
"notProhibitedPartyMember": true,
"notRestrictedList": true,
"lawfulPurpose": true
}
}
}Detalle de cada campo en Cumplimiento.
Controles regulatorios
| Control | Umbral | Efecto |
|---|---|---|
| Verificación de identidad (KYC) | Cualquier monto | Una cuenta sin KYC aprobado recibe 403 KYC_REQUIRED. Recibir saldo nunca requiere KYC |
| Travel Rule | Envíos de $3,000 o más | El remitente debe tener nombre y dirección en su ficha (Configuración → Datos de tu cuenta); si no, 403 |
| Sanciones | Cualquier monto | Si alguna de las partes está bloqueada por sanciones, 403 con un mensaje genérico |
Errores
| Código | Descripción |
|---|---|
400 | Datos inválidos (monto, PIN incorrecto, transferencia a tu propia cuenta, balance insuficiente) |
401 | Token de autenticación inválido o ausente |
403 | KYC_REQUIRED, Travel Rule sin datos del remitente, sanciones, o app sin allowed_transfer |
404 | Usuario destino no encontrado |
409 | DUPLICATE_REQUEST: ya hay una transferencia en proceso con la misma idempotency_key |
429 | Demasiadas solicitudes (límite: 1 cada 10 segundos) |
500 | Error interno al procesar la transferencia |