Licencias digitales

Vende llaves de licencia —software, cuentas, códigos— por la misma conversación de WhatsApp. Cargas un pool de llaves, el cliente paga, y Mosend le entrega una llave del pool sin que nadie tenga que copiarla a mano. Una llave entregada queda ligada a su orden: se puede reenviar, revocar o reembolsar, pero no se recicla en silencio.

Montarlo una vez

  1. Habilitar el móduloPUT /license-delivery/settings. Necesita que el plan lo incluya, o activarlo como add-on de tarifa fija con PUT /license-delivery/settings/addon.
  2. Crear el productoPOST /license-delivery/products. Si son muchos, POST /products/import acepta Excel o CSV: crea los nuevos y salta los que ya existen.
  3. Cargar las llaves POST /products/:productId/keys. Normaliza el formato y omite las duplicadas, así que puedes reenviar el mismo lote sin miedo.
  4. Comprobar que se puede vender GET /license-delivery/selling-readiness dice si falta algo: el módulo activo, la pasarela conectada o productos con stock.

Cómo se entrega una venta

Según quién dispara la venta y si hay cobro de por medio:

  • Con cobro automático POST /products/:productId/checkout crea la orden y lanza el cobro push por Nequi (vía Wompi). Al confirmarse el pago, la licencia sale sola.
  • Desde el chat, cobrando POST /conversations/:conversationId/sell. Lo usa el asesor dentro de la conversación: cobra y entrega al contacto de ese chat.
  • Desde el chat, sin cobrar POST /conversations/:conversationId/dispatch. Entrega una licencia sin pasar por caja: cortesías, reposiciones, garantías.
  • FiadoentregarYa: true en la venta por transferencia entrega la licencia de una vez y deja el cobro pendiente; POST /orders/:orderId/marcar-pagada lo salda después. La venta a mano (POST /conversations/:conversationId/venta-manual) separa las dos cosas desde el principio.
  • Entrega asistida POST /orders/:orderId/completar-entrega la cierra cuando la hizo una persona. Con llaves registra las que entregó a mano (una por línea de la venta) y las manda con la plantilla e instrucciones del producto; notificar: false las registra sin escribirle al cliente.

Cada orden lleva un orderNumber: un consecutivo corto por organización que aparece en los mensajes al cliente y sirve para referirse a la compra sin leerle un identificador entero.

Precios: variantes, listas y cupones

  • Variantes (/products/:id/variants) — el mismo producto con precios distintos: mensual, anual, 5 puestos. Cada variante tiene su precio propio y comparte el pool.
  • Listas de precios (/price-lists) — precios por etiqueta de cliente: mayoristas, proveedores, distribuidores. Se fija producto a producto con PUT /price-lists/:id/items; mandar priceCents: null quita el precio especial y vuelve al de lista.
  • Cupones (/coupons) — descuentos puntuales.

A dónde paga el cliente

Además de la pasarela, una organización puede recibir por transferencia a varias cuentas y en cripto. Las cuentas se administran en /license-delivery/transfer-accounts (GET, POST, PATCH /transfer-accounts/:accountId, DELETE /transfer-accounts/:accountId) y POST /transfer-accounts/reorder fija el orden en que las ve el cliente.

  • Cada cuenta declara currency (ISO 4217). Vacío significa cualquiera; con un valor, solo se le ofrece a quien paga en esa moneda.
  • La llave Bre-B / Nequi del ajuste transferKey es colombiana: solo recibe COP. Para un producto en otra moneda hace falta una cuenta con esa currency.
  • Al vender, transferAccountId elige el destino. Si se omite, el cobro va a la llave — que con un producto que no está en COP no sirve.

GET /license-delivery/selling-readiness es lo que hay que consultar antes de pintar los medios de pago: dice si la pasarela y la llave están configuradas, trae cuentas con su moneda y binanceConfigured.

Para cripto, los ajustes binanceEnabled, binancePayId, binanceAsset, binanceExpiryHours y binanceMode (OFF · SUGGEST · AUTO) habilitan el método BINANCE al vender. La clave de API de Binance debe ser de solo lectura: se guarda cifrada y nunca se devuelve.

Comprobantes y la bandeja de pagos

Cuando el cliente transfiere y manda la foto del comprobante, esa imagen se archiva contra el pedido. El ajuste receiptMode decide qué pasa después: MANUAL lo deja esperando a una persona y AUTO entrega si el monto cuadra.

  • GET /license-delivery/receipts — los pendientes de revisar; GET /orders/:orderId/receipts los de un pedido concreto.
  • POST /receipts/:receiptId/approve confirma el pago y entrega la licencia. POST /receipts/:receiptId/reject lo rechaza con un motivo.
  • GET /license-delivery/payments-inbox junta en una sola lista los avisos leídos del correo del banco y los comprobantes del chat. POST /payments-inbox/discard descarta varios de una vez; aprobar sigue siendo de a uno.

Cuando algo sale mal

  • No le llegóPOST /orders/:orderId/resend reenvía la misma licencia por WhatsApp y correo. No consume una llave nueva. El ajuste resendLimitPerDay limita cuántos reenvíos puede hacer el bot al mismo cliente en un día (0 = solo una persona).
  • No pagóPOST /orders/:orderId/cancel cancela la orden pendiente y devuelve las llaves al pool.
  • Contracargo o fraude POST /orders/:orderId/refund registra el reembolso y revoca las llaves de esa orden. Para una llave suelta, POST /products/:id/keys/:keyId/revoke.

Detalles que evitan sorpresas

  • Las llaves entregadas no se borran. DELETE /products/:id/keys/:keyId solo acepta llaves libres. Lo contrario dejaría ventas sin rastro de qué se entregó.
  • Borrar una variante con ventas tampoco se permite; si no las tiene, sus llaves libres vuelven al pool del producto.
  • Los pagos por Daviplata piden un OTP: POST /orders/:orderId/otp lo valida y /otp/resend lo reenvía. Hasta que se valide, la orden sigue pendiente y la llave sigue reservada.
  • La imagen del producto se sirve pública en /license-delivery/img/:productId — pensada para incrustarla en el mensaje de entrega, sin token.

Ejemplo: producto, llaves y venta

# 1. Producto
curl -X POST "https://api.mosend.dev/organizations/${ORG_ID}/license-delivery/products" \
  -H "X-Api-Key: ${API_KEY}" -H "Content-Type: application/json" \
  -d '{ "name": "Antivirus Pro 1 año", "priceCents": 4500000, "currency": "COP" }'

# 2. Llaves al pool (las duplicadas se omiten solas)
curl -X POST "https://api.mosend.dev/organizations/${ORG_ID}/license-delivery/products/${PRODUCT_ID}/keys" \
  -H "X-Api-Key: ${API_KEY}" -H "Content-Type: application/json" \
  -d '{ "keys": ["AAAA-BBBB-CCCC", "DDDD-EEEE-FFFF"] }'

# 3. Cobrar y entregar
curl -X POST "https://api.mosend.dev/organizations/${ORG_ID}/license-delivery/products/${PRODUCT_ID}/checkout" \
  -H "X-Api-Key: ${API_KEY}" -H "Content-Type: application/json" \
  -d '{ "contactId": "'"${CONTACT_ID}"'", "phone": "573001234567" }'

# 4. Seguir la orden hasta que se entregue
curl "https://api.mosend.dev/organizations/${ORG_ID}/license-delivery/orders/${ORDER_ID}" \
  -H "X-Api-Key: ${API_KEY}"

En vez de consultar la orden en bucle, escucha el webhook saliente correspondiente: llega cuando el pago se confirma y la licencia sale.

Referencia completa en API · license-delivery. Para el cobro, ver cobros.