Ventas y facturación electrónica

Dos módulos que se contratan por separado y encajan uno detrás del otro: Ventas lleva el catálogo y los pedidos; Facturación electrónica convierte un pedido en factura ante la DIAN y se la manda al cliente por su misma conversación de WhatsApp. Puedes usar Ventas sin facturar; facturar sin un pedido, no.

Antes de empezar: qué tienes contratado

GET /sales/entitlement responde qué está activo. Cada módulo puede venir en el plan o activarse como add-on con PUT /sales/addons. Si intentas facturar sin el add-on de facturación, la llamada falla aunque Ventas funcione.

El camino completo

  1. CatálogoPOST /sales/products.
  2. PedidoPOST /sales/orders, con sus líneas. Se puede atar a un contacto y a una conversación, que es lo que permite responder dentro del mismo chat.
  3. Perfil de facturación POST /sales/billing-profiles: los datos fiscales del cliente (documento, razón social, régimen). Sin esto no hay factura.
  4. FacturaPOST /sales/einvoicing/invoices sobre el pedido. Es opcional: un pedido puede quedarse sin facturar.
  5. Enviarla POST /sales/einvoicing/invoices/:invoiceId/send se la manda al cliente por WhatsApp, en su conversación.

Configurar el emisor (una vez)

  • PUT /sales/einvoicing/config — conecta el proveedor con su token. Requiere sales:config, un permiso más restrictivo que el de operar.
  • POST /sales/einvoicing/validate — comprueba el token y trae la numeración vigente. Vale la pena llamarlo antes de la primera factura: es donde se detecta una resolución vencida.
  • GET /sales/einvoicing/companies — una organización puede facturar con varias empresas emisoras; la predeterminada viene primero. Solo se puede borrar una que no haya emitido documentos.
  • POST /sales/einvoicing/customers/import — trae los clientes ya registrados en el proveedor y los convierte en perfiles de facturación, para no rehacerlos a mano.

Ejemplo: pedido, factura y envío

# 1. Pedido con dos líneas, atado a la conversación
curl -X POST "https://api.mosend.dev/organizations/${ORG_ID}/sales/orders" \
  -H "X-Api-Key: ${API_KEY}" -H "Content-Type: application/json" \
  -d '{
    "contactId": "'"${CONTACT_ID}"'",
    "conversationId": "'"${CONVERSATION_ID}"'",
    "items": [
      { "productId": "'"${PRODUCT_ID}"'", "quantity": 2 },
      { "description": "Instalación", "quantity": 1, "unitPriceCents": 15000000 }
    ]
  }'

# 2. ¿Ya está registrado en la DIAN? Búscalo por documento y evita retecleo
curl "https://api.mosend.dev/organizations/${ORG_ID}/sales/einvoicing/customer-lookup?document=900123456" \
  -H "X-Api-Key: ${API_KEY}"

# 3. Emitir la factura del pedido
curl -X POST "https://api.mosend.dev/organizations/${ORG_ID}/sales/einvoicing/invoices" \
  -H "X-Api-Key: ${API_KEY}" -H "Content-Type: application/json" \
  -d '{ "orderId": "'"${ORDER_ID}"'", "billingProfileId": "'"${PROFILE_ID}"'" }'

# 4. Mandársela por WhatsApp
curl -X POST "https://api.mosend.dev/organizations/${ORG_ID}/sales/einvoicing/invoices/${INVOICE_ID}/send" \
  -H "X-Api-Key: ${API_KEY}"

Anular: nota crédito

Una factura emitida no se borra. Para anularla se emite una nota crédito total con POST /sales/einvoicing/credit-notes, que es lo que reconoce la DIAN. La nota se envía al cliente igual que la factura.

Detalles que evitan sorpresas

  • Dos permisos distintos. sales:write opera (productos, pedidos, facturas); sales:config toca la configuración fiscal y las empresas emisoras. Un asesor factura, pero no reconfigura el emisor ni rota el token.
  • Solo se puede borrar un pedido en borrador o cancelado. Uno facturado se queda.
  • El PDF se obtiene en base64 con GET /sales/einvoicing/invoices/:id/pdf, o por una URL pública con token (/sales/invoice-pdf/:token) pensada para mandársela a alguien sin darle acceso a la API.
  • Si vendes licencias digitales y el cliente pide factura, POST /sales/einvoicing/license-orders/invoice factura esa venta sin duplicar el pedido. Ver licencias digitales.

Referencia completa en API · sales.