Comprobante de Crédito Fiscal (03)
El CCF (tipo 03) se emite entre contribuyentes IVA. El receptor debe tener NRC asignado por el MH. A diferencia de la Factura (01), el CCF desglosa explícitamente el IVA del 13% en el documento y permite al receptor deducirlo en su declaración.
Cuándo usar CCF
Cuando el receptor:
- Tiene NRC asignado (está inscrito como contribuyente IVA).
- Requiere el crédito fiscal para su contabilidad.
- Es persona jurídica o natural con actividad económica formal.
Si el receptor no tiene NRC, emite Factura (01) en lugar de CCF.
Detalles técnicos
| Método | POST |
| URL | https://ocote.io/api/connect/invoice (mismo endpoint, doc_type: "03") |
| Content-Type | application/json |
| Autenticación | Header Authorization: Bearer odt_... |
Request
El request es idéntico al de Factura (01) en estructura, con tres diferencias críticas:
doc_typedebe ser"03".customeres obligatorio y requiere campos específicos.customer.type_contributordetermina si se aplica retención IVA automática.
Campos obligatorios del cliente en CCF
| Campo | Requerido | Descripción |
|---|---|---|
name | Sí | Razón social del contribuyente. |
nit | Sí | NIT del contribuyente receptor. |
nrc | Sí | NRC del contribuyente. |
type_contributor | Sí | 1=Pequeño, 2=Mediano, 3=Grande, 4=Gobierno. |
Los demás campos (activity_code, department, municipality, email, etc.) son opcionales pero recomendados — ver tabla completa en Factura (01) > Cliente.
Cuando type_contributor es 3 (Grande) o 4 (Gobierno) y amount_taxable >= 100.00, el API aplica automáticamente una retención IVA del 1% sobre la base gravable. No envías ningún campo extra ni haces cálculos. Ver Wildcard items > Retención IVA 1%.
Response
Response idéntico a Factura 01 en estructura. En CCF los campos de montos son especialmente relevantes:
| Campo | Cálculo |
|---|---|
amount_taxable | Base gravable = suma de (quantity × unit_price × (1 − discount)) quitando el 13% IVA. |
amount_vat | IVA 13% = amount_taxable × 0.13. |
amount_gross | Total con IVA = amount_taxable + amount_vat. |
amount_retention | amount_taxable × 0.01 si type_contributor ∈ 4 y amount_taxable >= 100; sino 0. |
amount_total | Total neto = amount_gross − amount_retention. |
Ejemplo: CCF a Gran Contribuyente
curl -X POST https://ocote.io/api/connect/invoice \
-H "Authorization: Bearer odt_xxx" \
-H "Content-Type: application/json" \
-d '{
"doc_type": "03",
"external_ref": "CCF-2026-0042",
"customer": {
"name": "EMPRESA GRANDE, S.A. DE C.V.",
"nit": "06140710141035",
"nrc": "2360090",
"type_contributor": 3,
"activity_code": "86902",
"department": "06",
"municipality": "14",
"address": "Boulevard Los Héroes, San Salvador",
"email": "contabilidad@empresagrande.com"
},
"lines": [
{
"description": "Desarrollo de software a la medida - Abril 2026",
"quantity": 1,
"unit_price": 5000.00
}
],
"payment_method": "05",
"transaction_condition": 2,
"deadline": 30
}'
const { data } = await axios.post(
'https://ocote.io/api/connect/invoice',
{
doc_type: '03',
external_ref: 'CCF-2026-0042',
customer: {
name: 'EMPRESA GRANDE, S.A. DE C.V.',
nit: '06140710141035',
nrc: '2360090',
type_contributor: 3,
activity_code: '86902',
department: '06',
municipality: '14',
address: 'Boulevard Los Héroes, San Salvador',
email: 'contabilidad@empresagrande.com',
},
lines: [
{ description: 'Desarrollo de software a la medida - Abril 2026',
quantity: 1, unit_price: 5000.00 },
],
payment_method: '05',
transaction_condition: 2,
deadline: 30,
},
{ headers: { Authorization: `Bearer ${process.env.OCOTE_API_KEY}` } }
);
r = requests.post(
"https://ocote.io/api/connect/invoice",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"doc_type": "03",
"external_ref": "CCF-2026-0042",
"customer": {
"name": "EMPRESA GRANDE, S.A. DE C.V.",
"nit": "06140710141035",
"nrc": "2360090",
"type_contributor": 3,
"activity_code": "86902",
"department": "06",
"municipality": "14",
"address": "Boulevard Los Héroes, San Salvador",
"email": "contabilidad@empresagrande.com",
},
"lines": [
{
"description": "Desarrollo de software a la medida - Abril 2026",
"quantity": 1,
"unit_price": 5000.00,
},
],
"payment_method": "05",
"transaction_condition": 2,
"deadline": 30,
},
)
$response = $client->post('invoice', [
'headers' => ['Authorization' => 'Bearer ' . getenv('OCOTE_API_KEY')],
'json' => [
'doc_type' => '03',
'external_ref' => 'CCF-2026-0042',
'customer' => [
'name' => 'EMPRESA GRANDE, S.A. DE C.V.',
'nit' => '06140710141035',
'nrc' => '2360090',
'type_contributor' => 3,
'activity_code' => '86902',
'department' => '06',
'municipality' => '14',
'address' => 'Boulevard Los Héroes, San Salvador',
'email' => 'contabilidad@empresagrande.com',
],
'lines' => [
[
'description' => 'Desarrollo de software a la medida - Abril 2026',
'quantity' => 1,
'unit_price' => 5000.00,
],
],
'payment_method' => '05',
'transaction_condition' => 2,
'deadline' => 30,
],
]);
Respuesta exitosa con retención
{
"success": true,
"dte_success": true,
"contingency": false,
"rejected": false,
"posted": true,
"is_duplicate": false,
"document_id": "a1b2c3d4-1234-5678-9abc-def012345678",
"external_ref": "CCF-2026-0042",
"control_number": "DTE-03-M001P001-000000000000042",
"generation_code": "A1B2C3D4-1234-5678-9ABC-DEF012345678",
"reception_stamp": "20260421154532...",
"amount_taxable": 4424.78,
"amount_vat": 575.22,
"amount_gross": 5000.00,
"amount_retention": 44.25,
"amount_total": 4955.75,
"ticket_url": "",
"json_url": "https://ocote.io/api/connect/file/a1b2c3d4-1234-5678-9abc-def012345678?type=json&key=odt_xxx"
}
Observa:
- Enviaste
unit_price: 5000.00con IVA incluido. El API extrajo el IVA: base gravable4424.78, IVA575.22, suma5000.00. - Como el receptor es
type_contributor: 3(Gran Contribuyente) y la base supera $100, se aplicó retención IVA:4424.78 × 0.01 = 44.25. - El total neto que el receptor debe pagar es
5000.00 − 44.25 = 4955.75. ticket_urles vacío — los CCF no generan ticket térmico; se usa eljson_urlo el PDF accesible desde la plataforma Ocote.
Errores de validación específicos del CCF
Además de los errores generales de /invoice, el CCF valida:
| Mensaje | Causa |
|---|---|
Crédito Fiscal requiere datos del cliente | No enviaste customer. |
NIT es requerido para Crédito Fiscal | customer.nit vacío. |
NRC es requerido para Crédito Fiscal | customer.nrc vacío. |
Nombre del cliente es requerido para Crédito Fiscal | customer.name vacío. |
Tipo de contribuyente es requerido para Crédito Fiscal | customer.type_contributor no enviado. |
Consultar y modificar después
- Consultar estado:
GET /status/CCF-2026-0042 - Anular:
POST /invalidate/CCF-2026-0042. Si el CCF tiene más de 3 meses, el API automáticamente genera una Nota de Crédito (05) que lo ajusta — ver Nota de Crédito. - Emitir NC sobre este CCF:
POST /credit-memocondocument_idapuntando al CCF — ver Nota de Crédito.
Ver también
- Factura (01) — para consumidor final sin NRC.
- Nota de Crédito — para ajustar un CCF emitido.
- Anular DTE — comportamiento de anulación en CCF.
- Wildcard items > Retención IVA 1% — detalle del cálculo automático.
- Catálogos MH — códigos de actividad económica, departamento y municipio.