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
- Catálogo —
POST /sales/products. - Pedido —
POST /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. - Perfil de facturación —
POST /sales/billing-profiles: los datos fiscales del cliente (documento, razón social, régimen). Sin esto no hay factura. - Factura —
POST /sales/einvoicing/invoicessobre el pedido. Es opcional: un pedido puede quedarse sin facturar. - Enviarla —
POST /sales/einvoicing/invoices/:invoiceId/sendse 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. Requieresales: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:writeopera (productos, pedidos, facturas);sales:configtoca 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/invoicefactura esa venta sin duplicar el pedido. Ver licencias digitales.
Referencia completa en API · sales.