bling.emit-nfse
Multi-step emission of an NFS-e (Brazilian services electronic invoice). Validates input, submits via Bling /nfse, polls until the municipality returns AUTHORIZED or REJECTED, and persists the result. The load-bearing piece of the Stripe → NF flow.
Emit an NFS-e at Bling and wait for municipal authorization.
Overview
| Property | Value |
|---|---|
| Workflow type | Linear |
| Library | App-bling |
| Version | 1.0 |
Input Schema
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
organization_uuid | uuid | Yes | — | — |
connection_uuid | uuid | Yes | — | — |
customer_external_ref | string | Yes | — | Bling-side contact id of the service recipient |
items | json | Yes | — | List of service line items. Each item is a dict with at least {service_code, description, unit_price} and optionally {quantity, discount, iss_rate}. |
competence_date | string | No | — | ISO date — mês de competência. Defaults to today. |
issue_date | string | No | — | ISO date — dataEmissao. Defaults to today. |
series | string | No | — | — |
rps_number | string | No | — | Pre-issued RPS number; some municipalities require it |
order_external_ref | string | No | — | Bling-side order id if this NFS-e is emitted off an order |
max_poll_attempts | integer | No | — | Polling cap. Default 30 (≈3 min at 6s). |
poll_interval_seconds | integer | No | — | Seconds between polls. Default 6. |
idempotency_key | string | No | — | Caller-provided key to dedupe retries. Stored in extra. |
actor | string | No | — | — |
Output Schema
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
organization_uuid | uuid | Yes | — | — |
connection_uuid | uuid | Yes | — | — |
customer_external_ref | string | Yes | — | Bling-side contact id of the service recipient |
items | json | Yes | — | List of service line items. Each item is a dict with at least {service_code, description, unit_price} and optionally {quantity, discount, iss_rate}. |
competence_date | string | No | — | ISO date — mês de competência. Defaults to today. |
issue_date | string | No | — | ISO date — dataEmissao. Defaults to today. |
series | string | No | — | — |
rps_number | string | No | — | Pre-issued RPS number; some municipalities require it |
order_external_ref | string | No | — | Bling-side order id if this NFS-e is emitted off an order |
max_poll_attempts | integer | No | — | Polling cap. Default 30 (≈3 min at 6s). |
poll_interval_seconds | integer | No | — | Seconds between polls. Default 6. |
idempotency_key | string | No | — | Caller-provided key to dedupe retries. Stored in extra. |
actor | string | No | — | — |
submitted_external_ref | string | No | — | Bling NFS-e id returned after POST /nfse |
submitted_at | string | No | — | — |
poll_attempts | integer | No | — | — |
provider_status | string | No | — | Last status seen during polling (universal enum string) |
rejection_reason | string | No | — | — |
access_key | string | No | — | Municipal access key when status=AUTHORIZED |
pdf_url | string | No | — | — |
xml_url | string | No | — | — |
nfse_number | string | No | — | — |
nfse_series | string | No | — | — |
commerce_entity_uuid | uuid | No | — | UUID of the persisted commerce_entity row |
authorized_at | string | No | — | — |
completed_at | string | No | — | — |
failure_reason | string | No | — | — |
failed_at | string | No | — | — |
_last_contract_dump | json | No | — | — |
failure_type | string | No | — | — |
failed_action | string | No | — | — |
failed_at_state | string | No | — | — |
failed_step | json | No | — | — |
failed_layer | json | No | — | — |
error | string | No | — | — |
error_type | string | No | — | — |
States
| State | Initial | Terminal | Success | Auto-advance | Description |
|---|---|---|---|---|---|
initiated | Yes | No | — | validate | Emission requested |
polling | No | No | — | record | Polling for municipal authorization |
submitting | No | No | — | poll | POSTing NFS-e to Bling |
validating | No | No | — | submit | Validating items + customer |
completed | No | Yes | Yes | — | NFS-e authorized + persisted |
failed | No | Yes | No | — | NFS-e emission failed |
State Diagram
Transitions
| From | Action | To | Description |
|---|---|---|---|
initiated | validate | validating | — |
validating | submit | submitting | — |
submitting | poll | polling | — |
polling | record | completed | — |
initiated | fail | failed | — |
validating | fail | failed | — |
submitting | fail | failed | — |
polling | fail | failed | — |
Business Errors
| Code | Message Template |
|---|---|
BLING_CONNECTION_NOT_FOUND | Bling connection {connection_uuid} not found in organization |
BLING_CONNECTION_WRONG_PROVIDER | Connection {connection_uuid} is not a Bling connection |
BLING_NFSE_MISSING_ITEMS | At least one service line item is required to emit an NFS-e |
BLING_NFSE_INCOMPLETE_ITEM | Item {index}: {missing_field} is required |
BLING_NFSE_MISSING_CUSTOMER | customer_external_ref is required to emit an NFS-e |
BLING_NFSE_SUBMIT_FAILED | Bling rejected NFS-e submission: |
BLING_NFSE_REJECTED | NFS-e rejected by municipality: |
BLING_NFSE_TIMEOUT | NFS-e {external_id} still {status} after {attempts} poll attempts |
BLING_NFSE_PERSIST_FAILED | data.commerce.entity.persist failed for emitted NFS-e: |
API Usage
bash
POST /api/workflows/start
Content-Type: application/json
{
"workflow_type": "bling.emit-nfse",
"initial_data": {
"organization_uuid": "value",
"connection_uuid": "value",
"customer_external_ref": "value",
"items": "value"
}
}