Electronic Billing

Implemented — deployment and functional validation pending

As of October 13, 2026, these additions are implemented in the feature branch and are not announced as available in dev or production. Existing contact endpoints remain separate from their pending fiscal-field extensions. Examples are for integration planning.

The live API reference still uses the published OpenAPI contract. Wait for availability confirmation before calling the new operations.

Operations and account access

Send X-Api-Key. Electronic billing operations derive the account from that key, check the order and mode ownership, and do not accept a caller-selected account in another header or body.

Implemented additions pending deployment
OperationScopeAddition
POST /v1/contactscontacts:writeOptional fiscal fields added to the existing contact request.
GET /v1/contactscontacts:readOptional fiscal fields in the existing contact list response.
GET /v1/billing/operation-modesorders:readStored modes for the account’s companies.
GET /v1/billing/resolutionsorders:readStored resolutions for the account’s companies.
POST /v1/orders/{id}/electronic-document/emitorders:writeElectronic invoice for an existing sale.
GET /v1/orders/{id}/electronic-documentorders:readStored fiscal result and available files.

Fiscal contact details

Contact creation still requires account_id and first_name, and returns the resource with HTTP 201. These new fields are optional strings, returned when available in creation and list responses; new null fiscal fields are omitted:

  • legal_name
  • address
  • city_id
  • type_document_identification_id
  • verification_number
  • type_person_id
  • type_regime_id
  • type_liability_id
  • merchant_registration

Use Wahio identifiers; the extension does not automatically convert DIAN/DANE codes or certify fiscal readiness. legal_name supports up to 250 characters. identification_type keeps its existing meaning and does not replace the fiscal document type identifier.

Configuration and emission

Catalogs return direct arrays of stored configuration, or [] if none exists. A mode identifies its company, document type, environment, default resolution, and credit-note resolution. Resolution records include their prefix, authorization number, date/range limits, and informational next_number; reading it does not reserve a number. Historical or expired entries may be present. Credentials and technical keys are excluded.

Emission requires an existing Sale order and an enabled, configured invoice mode (document_id = 1). Wahio retrieves the customer, lines, taxes, and payments from Orders. The request only selects operation_mode_id; it does not create the sale or a commercial invoice.

curl --request POST 'https://api.wahio.com/api/v1/orders/WAHIO_ORDER_ID/electronic-document/emit' \
  --header 'X-Api-Key: YOUR_API_KEY' \
  --header 'Idempotency-Key: #W-123' \
  --header 'Content-Type: application/json' \
  --data '{"operation_mode_id":"WAHIO_OPERATION_MODE_ID"}'

The invoice is emitted synchronously. Email and fiscal updates follow the existing flow; no public email opt-out is provided. No new commercial action or direct inventory movement is requested, but derived effects still require validation before claiming full inventory independence.

Retry without issuing another invoice

Provide one stable Idempotency-Key with 1–128 visible ASCII characters and no spaces, such as #W-123. Keep the same account, order, key, and mode for every retry. Completed attempts return the saved fiscal result without another emission or email, including rejected or undefined validity.

  • 409 / idempotency_conflict: a key was used for another order, or this order was requested with a different key or mode. Do not change the key to force an emission.
  • 409 / emission_in_progress_or_uncertain: the attempt is still running or has no saved outcome. Read the order result and reconcile.
  • 409 / already_issued: a fiscal document exists or the order is marked as issued.

Uncertain attempts do not expire or unlock automatically. A timeout may happen before or after provider processing. Correcting a rejection or recovering an uncertain attempt requires operational reconciliation; no public unlock operation exists. Failed attempts can leave a number reserved. This control does not deduplicate sale creation or coordinate historical emitters/manual numbering changes.

Read fiscal results and files

REST results are direct resources in snake_case. is_valid preserves true, false, or undefined validity; null fields can be omitted. HTTP 200 alone does not confirm DIAN acceptance. Read available status_code, status_description, status_message, and errors_messages. Individual error codes are not invented from text.

uuid is the stored fiscal identifier. In a document result, resolution_number is the consecutive number; in the resolution catalog, it is the authorization number. PDF/QR/XML links may be absent. attached_document_xml_url refers to AttachedDocument; the legacy xml_url is not certified as valid DIAN invoice XML.

GET selects the document Wahio currently stores for the order rather than listing every related note/document. A rejected attempt can be replayed even if GET has no document. HTTP 404 does not prove that emission never happened.

HTTP 400 indicates invalid input/key, 401 invalid authentication, 403 missing scope, 404 a missing/foreign resource, and 422 an ineligible sale or mode. Rate limit or 5xx/timeout responses do not change the retry key or justify a second emission.

Fiscal notifications awaiting deployment

electronic-billing.updated reports saved fiscal results with account, order, validity, messages/errors, and available files. Rejected results from the new emission can be notified without creating an accepted document. Attempts without saved results still require reconciliation.

Verify the Base64 signature and deduplicate by the stable eventId; duplicate and out-of-order delivery are possible. Notification recovery never calls DIAN again. The fiscal webhook guide explains the camelCase payload and redelivery policy. Availability is pending messaging infrastructure, rollout, activation, and validation.

Still outside this release

Public POS/support-document/credit-note emission, test sets, batches, payment/municipality catalogs, and reconciliation by date or external sale number remain pending. General events such as order.updated do not provide a complete fiscal-status contract.

Browse the published API reference for the contracts currently served by your environment.