En el presente documento se encuentra la documentación correspondiente a los snippets de código desarrollados en NodeJs v11.15.0, así como también las librerías externas utilizadas para realizar las solicitudes HTTP correspondientes a la API REST del proyecto de Web Service de Timbox.
Para realizar las solicitudes HTTP en node.js se utlizó la version de node 11.15.0 en conjunto con la biblioteca "axios" para realizar las peticiones HTTP
Usando nvm nvm install node
Usando apt
sudo apt install nodejs
npm install axios
node archivo.js
Se requiere una autenticación básica para generar una API-KEY
URL de autenticación:
- Ambiente Producción https://sistema.timbox.com.mx/api/auth
- Ambiente Pruebas https://staging.ws.timbox.com.mx/api/auth
El siguiente codigo hace una solicitud a la API del Web Service de Timbox para generar una API KEY y enviarla en conjunto en cada petición posterior. Esta función necesita como parámetros el usuario y la contraseña proporcionados en la cuenta del dashboard de Timbox.
El formato para enviar las credenciales es el siguiente:
usuario:contraseña
Por esta razón se concatenan los textos y se deben transformar a base 64 para poder enviarlos correctamente.
var axios = require('axios');
var APIKEY;
const init_buscar_acuse = (user, password) => {
// Get API key first
const credentials_64 = Buffer.from(`${user}:${password}`).toString('base64');
const auth = `Basic ${credentials_64}`;
var config = {
method: 'get',
url: 'https://staging.ws.timbox.com.mx/api/auth',
headers: {
'Authorization': auth
},
};
axios(config)
.then(res => {
APIKEY = res.data.api_key;
buscar_acuse_request();})
.catch(err => console.log(err));
}
- Ambiente Producción https://sistema.timbox.com.mx/api/buscar_acuse_recepcion
- Ambiente Pruebas https://staging.ws.timbox.com.mx/api buscar_acuse_recepcion
var axios = require('axios');
var APIKEY;
const init_buscar_acuse = (user, password) => {
// Get API key first
const credentials_64 = Buffer.from(`${user}:${password}`).toString('base64');
const auth = `Basic ${credentials_64}`;
var config = {
method: 'get',
url: 'https://staging.ws.timbox.com.mx/api/auth',
headers: {
'Authorization': auth
},
};
axios(config)
.then(res => {
APIKEY = res.data.api_key;
buscar_acuse_request();
})
.catch(err => console.log(err));
}
const buscar_acuse_request = () => {
// Declare params:
// ** uuid must be array
var payload = JSON.stringify({
"parametros_acuse": {
"uuids": {
"Comprobante": [
{"uuid": "3E30C124-58FB-408B-84D6-C253E8E573F1"}
]
}
}
});
// Params, header, url, method
var config = {
method: 'post',
url: 'https://staging.ws.timbox.com.mx/api/buscar_acuse_recepcion',
headers: {
'x-api-key': APIKEY,
'Content-Type': 'application/json'
},
data: payload
}
axios(config)
.then((res) => {
console.log(JSON.stringify(res.data))
})
.catch((err) => {
console.error('ERROR:', err.response.data.message);
});
}
// Init (User, password)
init_buscar_acuse('user','password');
- Ambiente Producción https://sistema.timbox.com.mx/api/buscar_cfdi
- Ambiente Pruebas https://staging.ws.timbox.com.mx/api/buscar_cfdi
var axios = require('axios');
var APIKEY;
const init_buscar_cfdi = (user, password) => {
// Get API key first
const credentials_64 = Buffer.from(`${user}:${password}`).toString('base64');
const auth = `Basic ${credentials_64}`;
var config = {
method: 'get',
url: 'https://staging.ws.timbox.com.mx/api/auth',
headers: {
'Authorization': auth
},
};
axios(config)
.then(res => {
APIKEY = res.data.api_key;
buscar_cfdi_request();
})
.catch(err => console.log(err));
}
const buscar_cfdi_request = () => {
// Declare params
var payload = JSON.stringify({
"parametros_cfdis": {
"uuid": "3E30C124-58FB-408B-84D6-C253E8E573F1"
}
});
// Params, header, url, method
var config = {
method: 'post',
url: 'https://staging.ws.timbox.com.mx/api/buscar_cfdi',
headers: {
'x-api-key': APIKEY,
'Content-Type': 'application/json'
},
data: payload
}
axios(config)
.then((res) => {
console.log(JSON.stringify(res.data))
})
.catch((err) => {
console.error('ERROR:', err.response.data.message);
});
}
// Init (user, password)
init_buscar_cfdi('user','password');
Para timbrar un XML debe enviarse el archivo cifrado en base 64.
- Ambiente Producción https://sistema.timbox.com.mx/api/timbrar_cfdi_40
- Ambiente Pruebas https://staging.ws.timbox.com.mx/api/timbrar_cfdi_40
var axios = require('axios');
var file64;
var APIKEY;
const cfdiFileHandler = () => {
// File library
const fs = require('fs')
fs.readFile('cfdi_40.xml', 'utf8' , (err, data) => {
if (err) {
console.error(err)
return
}
file64 = Buffer.from(data).toString('base64');
})
}
const init_timbrar_cfdi = (user, password) => {
// read File content and parse to 64
cfdiFileHandler();
// Get API key first
const credentials_64 = Buffer.from(`${user}:${password}`).toString('base64');
const auth = `Basic ${credentials_64}`;
var config = {
method: 'get',
url: 'https://staging.ws.timbox.com.mx/api/auth',
headers: {
'Authorization': auth
},
};
axios(config)
.then(res => {
APIKEY = res.data.api_key;
timbrar_cfdi_request();
})
.catch(err => console.log(err));
}
const timbrar_cfdi_request = () => {
// Declare params
var payload = JSON.stringify({
"sxml": file64
});
// Params, header, url, method
var config = {
method: 'post',
url: 'https://staging.ws.timbox.com.mx/api/timbrar_cfdi_40',
headers: {
'x-api-key': APIKEY,
'Content-Type': 'application/json'
},
data: payload
}
axios(config)
.then((res) => {
console.log(JSON.stringify(res.data))
})
.catch((err) => {
console.error('ERROR:', err.response.data.message);
});
}
// Init (user, password)
init_timbrar_cfdi('user', 'password');
- Ambiente Producción https://sistema.timbox.com.mx/api/obtener_consumo
- Ambiente Pruebas https://staging.ws.timbox.com.mx/api/obtener_consumo
var axios = require('axios');
var APIKEY;
const init_obtener_consumo = (user, password) => {
// Get API key first
const credentials_64 = Buffer.from(`${user}:${password}`).toString('base64');
const auth = `Basic ${credentials_64}`;
var config = {
method: 'get',
url: 'https://staging.ws.timbox.com.mx/api/auth',
headers: {
'Authorization': auth
},
};
axios(config)
.then(res => {
APIKEY = res.data.api_key;
obtener_consumo_request();
})
.catch(err => console.log(err));
}
const obtener_consumo_request = () => {
// Params, header, url, method
var config = {
method: 'get',
url: 'https://staging.ws.timbox.com.mx/api/obtener_consumo',
headers: {
'x-api-key': APIKEY,
'Content-Type': 'application/json'
},
data:''
}
axios(config)
.then((res) => {
console.log(JSON.stringify(res.data))
})
.catch((err) => {
console.error('ERROR:', err.response.data.message);
});
}
// Init (user, password)
init_obtener_consumo('user', 'password');
- Ambiente Producción https://sistema.timbox.com.mx/api/recuperar_comprobante
- Ambiente Pruebas https://staging.ws.timbox.com.mx/api/recuperar_comprobante
var axios = require('axios');
var APIKEY;
const init_recuperar_comprobante = (user, password) => {
// Get API key first
const credentials_64 = Buffer.from(`${user}:${password}`).toString('base64');
const auth = `Basic ${credentials_64}`;
var config = {
method: 'get',
url: 'https://staging.ws.timbox.com.mx/api/auth',
headers: {
'Authorization': auth
},
};
axios(config)
.then(res => {
APIKEY = res.data.api_key;
recuperar_comprobante_request();
})
.catch(err => console.log(err));
}
const recuperar_comprobante_request = () => {
// Declare params
var payload = JSON.stringify({
"uuid":{
"Comprobante":[{ "uuid": "44235C12-0BEF-4919-9B44-7F8BFE44D451"}]
}
})
// Params, header, url, method
var config = {
method: 'post',
url: 'https://staging.ws.timbox.com.mx/api/recuperar_comprobante',
headers: {
'x-api-key': APIKEY,
'Content-Type': 'application/json'
},
data: payload
}
axios(config)
.then((res) => {
console.log(JSON.stringify(res.data))
})
.catch((err) => {
console.error('ERROR:', err.response.data.message);
});
}
// Init (user, password)
init_recuperar_comprobante('usuario', 'password');
A partir del 01 de enero de 2022 el SAT modificó el esquema para la cancelación de CFDI’s. A continuación se muestra toda la información relevante y relacionada al proceso de cancelación.
En el esquema anterior, los campos que debían añadirse a la petición eran los siguientes:
- UUID
- Total
- RFCReceptor
- Certificado en formato PEM
- Llave en formato PEM
- Motivo
- Folio Sustituto
Se requiere el envio de los certificado y llave privada del CSD en .PEM
- Ambiente Producción https://sistema.timbox.com.mx/api/cancelar_cfdi
- Ambiente Pruebas https://staging.ws.timbox.com.mx/api/cancelar_cfdi
var axios = require('axios');
var APIKEY;
const cancelacion = (user, password) => {
// Get API key first
const credentials_64 = Buffer.from(`${user}:${password}`).toString('base64');
const auth = `Basic ${credentials_64}`;
var config = {
method: 'get',
url: 'https://staging.ws.timbox.com.mx/api/auth',
headers: {
'Authorization': auth
},
};
axios(config)
.then(res => {
APIKEY = res.data.api_key;
cancelacion_request();
})
.catch(err => console.log(err));
}
const cancelacion_request = () => {
//Parametros
var emisor = "XIA190128J61"
var uuid = "766428AF-101A-4EF8-B897-799270629076"
var receptor = "XAXX010101000"
var total = "0.0"
var motivo = "02"
var folios_sustituto = ""
var uuids = { 'uuid': uuid, 'rfc_receptor': receptor, 'total': total, 'motivo': motivo, 'folios_sustituto': folios_sustituto }
var folios =[]
folios.push(uuids)
var payload = JSON.stringify({
'rfc_emisor': emisor,
'folios': {
'folio': folios
},
'cert_pem': "-----BEGIN CERTIFICATE-----\
-----END CERTIFICATE-----",
'llave_pem': "-----BEGIN PRIVATE KEY-----\
-----END PRIVATE KEY-----"
});
// Params, header, url, method
var config = {
method: 'post',
url:'https://staging.ws.timbox.com.mx/api/cancelar_cfdi',
headers: {
'x-api-key': APIKEY,
'Content-Type': 'application/json'
},
data: payload
}
axios(config)
.then((res) => {
console.log(JSON.stringify(res.data))
})
.catch((err) => {
console.error('ERROR:', err.response.data.message);
});
}
// Init (user, password)
cancelacion('USER','PASS');
- Ambiente Producción https://sistema.timbox.com.mx/api/consultar_documento_relacionado
- Ambiente Pruebas https://staging.ws.timbox.com.mx/api/consultar_documento_relacionado
var axios = require('axios');
var APIKEY;
const documento_relacionado = (user, password) => {
// Get API key first
const credentials_64 = Buffer.from(`${user}:${password}`).toString('base64');
const auth = `Basic ${credentials_64}`;
var config = {
method: 'get',
url: 'https://staging.ws.timbox.com.mx/api/auth',
headers: {
'Authorization': auth
},
};
axios(config)
.then(res => {
APIKEY = res.data.api_key;
recuperar_comprobante_request();
})
.catch(err => console.log(err));
}
const recuperar_comprobante_request = () => {
// Declare params
var payload = JSON.stringify({
"uuid": "44235C12-0BEF-4919-9B44-7F8BFE44D451",
"rfc_receptor": "XIA190128J61",
"cert_pem": "-----BEGIN CERTIFICATE-----\
-----END CERTIFICATE-----",
"llave_pem": "-----BEGIN PRIVATE KEY-----\
-----END PRIVATE KEY-----"
})
// Params, header, url, method
var config = {
method: 'post',
url: 'https://staging.ws.timbox.com.mx/api/consultar_documento_relacionado',
headers: {
'x-api-key': APIKEY,
'Content-Type': 'application/json'
},
data: payload
}
axios(config)
.then((res) => {
console.log(JSON.stringify(res.data))
})
.catch((err) => {
console.error('ERROR:', err.response.data.message);
});
}
// Init (user, password)
documento_relacionado('USER','PASS');
- Ambiente Producción https://sistema.timbox.com.mx/api/consultar_peticiones_pendientes
- Ambiente Pruebas https://staging.ws.timbox.com.mx/api/consultar_peticiones_pendientes
var axios = require('axios');
var APIKEY;
const peticiones_pendientes = (user, password) => {
// Get API key first
const credentials_64 = Buffer.from(`${user}:${password}`).toString('base64');
const auth = `Basic ${credentials_64}`;
var config = {
method: 'get',
url: 'https://staging.ws.timbox.com.mx/api/auth',
headers: {
'Authorization': auth
},
};
axios(config)
.then(res => {
APIKEY = res.data.api_key;
peticiones_pendientes_request();
})
.catch(err => console.log(err));
}
const peticiones_pendientes_request = () => {
// Declare params
var payload = JSON.stringify({
"rfc_receptor": "XIA190128J61",
'cert_pem':"-----BEGIN CERTIFICATE-----\
-----END CERTIFICATE-----",
'llave_pem':"-----BEGIN PRIVATE KEY-----\
-----END PRIVATE KEY-----"
});
// Params, header, url, method
var config = {
method: 'post',
url:'https://staging.ws.timbox.com.mx/api/consultar_peticiones_pendientes',
headers: {
'x-api-key': APIKEY,
'Content-Type': 'application/json'
},
data: payload
}
axios(config)
.then((res) => {
console.log(JSON.stringify(res.data))
})
.catch((err) => {
console.error('ERROR:', err.response.data.message);
});
}
// Init (user, password)
peticiones_pendientes('USR','PASS');
- Ambiente Producción https://sistema.timbox.com.mx/api/procesar_respuesta
- Ambiente Pruebas https://staging.ws.timbox.com.mx/api/procesar_respuesta
var axios = require('axios');
var APIKEY;
const procesar_respuesta = (user, password) => {
// Get API key first
const credentials_64 = Buffer.from(`${user}:${password}`).toString('base64');
const auth = `Basic ${credentials_64}`;
var config = {
method: 'get',
url: 'https://staging.ws.timbox.com.mx/api/auth',
headers: {
'Authorization': auth
},
};
axios(config)
.then(res => {
APIKEY = res.data.api_key;
procesar_respuesta_request();
})
.catch(err => console.log(err));
}
const procesar_respuesta_request = () => {
var emisor = "XIA190128J61"
var uuid = "766428AF-101A-4EF8-XXXX-799270629076"
var receptor = "XAXX010101000"
var total = "0"
var folio = { 'uuid': uuid, 'rfc_emisor': emisor, 'total': total, respuesta: 'A'}
var folio_resp =[]
folio_resp.push(folio)
//var dato= { 'rfc_receptor': receptor, respuestas: {folios_respuestas:folio}}
// Declare params
var payload = JSON.stringify({
'rfc_receptor': receptor,
'respuestas':{folios_respuestas: folio_resp},
'cert_pem': "-----BEGIN CERTIFICATE-----\
-----END CERTIFICATE-----",
'llave_pem': "-----BEGIN PRIVATE KEY-----\
-----END PRIVATE KEY-----"
})
// Params, header, url, method
var config = {
method: 'post',
url: 'https://staging.ws.timbox.com.mx/api/procesar_respuesta',
headers: {
'x-api-key': APIKEY,
'Content-Type': 'application/json'
},
data: payload
}
axios(config)
.then((res) => {
console.log(JSON.stringify(res.data))
})
.catch((err) => {
console.error('ERROR:', err.response.data.message);
});
}
// Init (user, password)
procesar_respuesta('USER','PASS');
- Ambiente Producción https://sistema.timbox.com.mx/api/consultar_estaus
- Ambiente Pruebas https://staging.ws.timbox.com.mx/api/consultar_estaus
var axios = require('axios');
var APIKEY;
const init_consultar_estatus = (user, password) => {
// Get API key first
const credentials_64 = Buffer.from(`${user}:${password}`).toString('base64');
const auth = `Basic ${credentials_64}`;
var config = {
method: 'get',
url: 'https://staging.ws.timbox.com.mx/api/auth',
headers: {
'Authorization': auth
},
};
axios(config)
.then(res => {
APIKEY = res.data.api_key;
consultar_estatus_request();
})
.catch(err => console.log(err));
}
const consultar_estatus_request = () => {
// Declare params
var payload = JSON.stringify({
"uuid": "3E30C124-XXXX-XXXX-XXXX-C253E8E573F1",
“rfc_emisor”: ‘’
“rfc_receptor”: “”
“total”: “0.0”
});
// Params, header, url, method
var config = {
method: 'get',
url: 'https://staging.ws.timbox.com.mx/api/consultar_estatus',
headers: {
'x-api-key': APIKEY,
'Content-Type': 'application/json'
},
data: payload
}
axios(config)
.then((res) => {
console.log(JSON.stringify(res.data))
})
.catch((err) => {
console.error('ERROR:', err.response.data.message);
});
}
// Init (user, password)
init_buscar_cfdi('USER', 'PASS');