API mocks

On this page

DIAN-compatible electronic invoicing (Colombia)

A mock of DIAN's electronic invoicing web service (WcfDianCustomerServices), with the semantics of the habilitación test environment. It covers:

  • sending UBL 2.1 invoices, credit notes and debit notes;
  • the test set;
  • status queries;
  • the numbering range.

Every document is validated on the rules DIAN's verdicts hinge on, and answered with DIAN's DianResponse and a signed ApplicationResponse. It is provider-neutral: it stands in for DIAN itself, so your own software or any technology provider's can send to it.

Test environment only: documents must carry ProfileExecutionID 2, and nothing is reported to DIAN. Testlie is not affiliated with DIAN. "DIAN" is used only to describe API compatibility.

Connect

Create a DIAN-compatible e-invoicing system under ERP, then point your client at it:

  • Endpoint: use <base URL>/WcfDianCustomerServices.svc in place of https://vpfe-hab.dian.gov.co/WcfDianCustomerServices.svc.
  • WSDL: <base URL>/WcfDianCustomerServices.svc?wsdl.
  • Protocol: SOAP 1.2 (Content-Type: application/soap+xml), with the operation as the body's element in the http://wcf.dian.colombia namespace.
Credential Environment variable Use
Issuer NIT DIAN_NIT AccountingSupplierParty CompanyID; GetNumberingRange accountCode
Software id DIAN_SOFTWARE_ID sts:SoftwareID; GetNumberingRange softwareCode
Software PIN DIAN_SOFTWARE_PIN SoftwareSecurityCode, and the CUDE of notes
Test set id DIAN_TEST_SET_ID SendTestSetAsync testSetId
Technical key DIAN_TECHNICAL_KEY The CUFE of invoices; the sample endpoint's bearer token
Numbering authorization, prefix DIAN_INVOICE_AUTHORIZATION, DIAN_INVOICE_PREFIX sts:InvoiceControl; invoices are numbered SETP990000000 to SETP995000000
ApplicationResponse certificate DIAN_MOCK_SIGNING_CERT Verifies the mock's signed ApplicationResponse

WS-Security: every request needs a wsse:Security header with an unexpired wsu:Timestamp and an X.509 BinarySecurityToken. Any test certificate works, and no certificate authority is checked. If the header has a ds:Signature, it must verify with that certificate and sign wsa:To, the wsu:Timestamp or the soap:Body (any of them, as WS-Security policies differ); a signature over none of them is refused. Otherwise the answer is the WCF fault "An error occurred when verifying security for the message.", and the call doesn't count against your plan.

Operations

Operation Parameters Answer
SendBillSync fileName, contentFile (a base64 ZIP with one XML) DianResponse
SendBillAsync fileName, contentFile (up to 50 XMLs) UploadDocumentResponse with a ZipKey
SendTestSetAsync fileName, contentFile, testSetId UploadDocumentResponse; an unknown test set is reported in ErrorMessageList
GetStatus trackId: the CUFE or CUDE DianResponse
GetStatusZip trackId: the ZipKey One DianResponse per document
GetNumberingRange accountCode, accountCodeT, softwareCode OperationCode 100 with the range, resolution and technical key; 301 when the NIT or software is not the mock's

A DianResponse has these fields:

  • IsValid;
  • StatusCode and StatusDescription:
    • 00 processed correctly;
    • 99 errors in mandatory fields;
    • 98 still being validated;
    • 66 unknown track id;
  • StatusMessage, e.g. "La Factura electrónica SETP990000001, ha sido autorizada.";
  • ErrorMessage, a list of Regla: <code>, Rechazo: <message> or Regla: <code>, Notificación: <message>;
  • XmlDocumentKey (the CUFE or CUDE) and XmlFileName;
  • XmlBase64Bytes: a UBL ApplicationResponse that references the document. Its ResponseCode is 02 when the document is validated and 04 when it is rejected, with one LineResponse per rule. Its sender is DIAN (NIT 800197268, check digit 4), as in DIAN's own answers. It is signed XAdES-EPES (enveloped, RSA-SHA256, DIAN's política de firma v2, role third party) with the mock's test certificate, not DIAN's.

Asynchronous sends are validated straight away. GetStatusZip, and GetStatus for their documents, answer 98 until the mock's async delay has passed. With the Outcome scenario "requires action" they stay in process.

What is validated

Rule Rejection
ZB01 The XML is not a well-formed UBL 2.1 Invoice, CreditNote or DebitNote, or ID, UUID, IssueDate or IssueTime is missing
FAD02 / CAD02 / DAD02 ProfileExecutionID is not 2: production documents are refused
FAJ21 … The issuer NIT is not the mock's
FAB19, FAB27 … sts:SoftwareID is not the mock's, or SoftwareSecurityCode is not SHA-384(SoftwareID + PIN + document number)
FAB07, FAB05 (Invoices) wrong numbering authorization, or a prefix or number outside the range
FAD06 / CAD06 / DAD06 The CUFE or CUDE in UUID is not computed correctly
FAU04, FAU14 … LineExtensionAmount is not the sum of the lines; PayableAmount is not TaxInclusiveAmount − allowances + charges − prepaid
FAS07 … The tax subtotals don't add up to their TaxTotal
ZE02 The document's enveloped signature is missing or does not verify with its own X509Certificate. For a XAdES-EPES signature, also when its SignedProperties aren't signed or SigningCertificate doesn't name that certificate. The certificate chain is not checked.
90 A document with this CUFE or CUDE was validated before; the first validation stands

Notifications, which don't reject:

  • CBG03 / DBG03: a note's BillingReference that this mock hasn't validated;
  • TL-ZE01: the signature is plain XML-DSig, without XAdES-EPES qualifying properties. DIAN requires XAdES-EPES under its política de firma v2, so expect a real rejection;
  • TL-ZE02: a XAdES signature without SigningTime;
  • TL-ZE03: a XAdES signature whose SigPolicyId is not https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicadefirmav2.pdf.

The first letter of a code follows the document type: F invoice, C credit note, D debit note. ZB01, ZE02, FAD06 and 90 are DIAN's own codes. Every other code is the mock's: those following DIAN's naming, and the TL- ones, which have no DIAN counterpart. Their messages end with "[regla del mock de Testlie; no es un código oficial de la DIAN]". Check them against the Anexo Técnico before your code depends on an exact code.

CUFE (invoices) and CUDE (notes) are computed as in the Anexo Técnico: SHA-384 of ID + IssueDate + IssueTime + LineExtensionAmount + 01 + IVA + 04 + INC + 03 + ICA + PayableAmount + issuer NIT + customer CompanyID + key + ProfileExecutionID. Amounts have two decimals, and taxes come from the document-level TaxTotal by TaxScheme/ID. The key is the technical key for the CUFE and the software PIN for the CUDE.

The Outcome scenario "decline" rejects every otherwise valid document with the chosen rule (FAD06, ZE02, FAB05, FAJ21 or FAB27).

Sample documents

POST <base URL>/__testlie/sample-document with Authorization: Bearer <technical key> and { "kind": "Invoice" | "CreditNote" | "DebitNote", "number"?, "referencedCufe"?, "lineAmount"? } returns:

  • xml: a complete UBL 2.1 document for this mock's software, signed XAdES-EPES as DIAN requires, with the right CUFE or CUDE, security code, range and totals;
  • contentFile: the same document as a base64 ZIP;
  • cufe;
  • soapEnvelope: a ready SendBillSync request with a signed WS-Security header.

Use them to try the service, or as a reference for your own documents:

sh
curl -s -X POST <base URL>/__testlie/sample-document -H "Authorization: Bearer $DIAN_TECHNICAL_KEY" \
  -H 'Content-Type: application/json' -d '{"kind":"Invoice"}' > sample.json
jq -r .soapEnvelope sample.json | curl -s -X POST <base URL>/WcfDianCustomerServices.svc \
  -H 'Content-Type: application/soap+xml; charset=utf-8' --data-binary @-

Not implemented:

  • GetXmlByDocumentKey;
  • SendEventUpdateStatus and the RADIAN events;
  • payroll (nómina) and support documents;
  • the DIAN catalogue of every rule;
  • certificate authority checks.