openapi: 3.0.0
info:
description: '# Introducción
Documentación del API de Contalink
# Autenticación
El método de autenticación para el api de contalink es mediante un api key el cual está relacionado forzosamente a un usuario dentro del sistema, por lo cual, todas las peticiones utilizando ese api key quedarán registradas como peticiones del usuario relacionado.
'
title: API Contalink Balanza de comprobación Cargar un documento fiscal API
version: 1.0.4
x-logo:
altText: Contalink
url: http://apidocs.contalink.com/logocontalinknew.svg
servers:
- description: prod
url: https://794lol2h95.execute-api.us-east-1.amazonaws.com/prod
tags:
- description: Carga un documento fiscal al sistema
name: Cargar un documento fiscal
paths:
/invoices/upload/:
post:
description: Endpoint para subir documentos fiscales a Contalink. Es importante señalar que la subida de documentos al sistema es asíncrona. La respuesta de este endpoint contiene una URL de Google Firebase donde se puede consultar el status de la carga.
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UploadXML'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/UploadXMLResult'
description: 0 indica error, 1 indica éxito
security:
- APIKey: []
summary: Sube un documento a Contalink
tags:
- Cargar un documento fiscal
x-codeSamples:
- lang: C
source: "CURL *curl;\nCURLcode res;\ncurl = curl_easy_init();\nif(curl) {\n curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, \"POST\");\n curl_easy_setopt(curl, CURLOPT_URL, \"%7B%7BbaseUrl%7D%7D/invoices/upload/\");\n curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);\n curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, \"https\");\n struct curl_slist *headers = NULL;\n headers = curl_slist_append(headers, \"Content-Type: application/json\");\n headers = curl_slist_append(headers, \"Accept: application/json\");\n headers = curl_slist_append(headers, \"Content-Length: \");\n curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);\n const char *data = \"{\\n \\\"xml\\\": \\\"\\\",\\n \\\"name\\\": \\\"\\\"\\n}\";\n curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);\n res = curl_easy_perform(curl);\n}\ncurl_easy_cleanup(curl);\n"
- lang: C#
source: 'var client = new RestClient("{{baseUrl}}/invoices/upload/");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/json");
var body = @"{" + "\n" +
@" ""xml"": """"," + "\n" +
@" ""name"": """"" + "\n" +
@"}";
request.AddParameter("application/json", body, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);'
- lang: Curl
source: "curl --location -g --request POST '{{baseUrl}}/invoices/upload/' \\\n--header 'Content-Type: application/json' \\\n--header 'Accept: application/json' \\\n--data-raw '{\n \"xml\": \"\",\n \"name\": \"\"\n}'"
- lang: Dart
source: "var headers = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n};\nvar request = http.Request('POST', Uri.parse('{{baseUrl}}/invoices/upload/'));\nrequest.body = json.encode({\n \"xml\": \"\",\n \"name\": \"\"\n});\nrequest.headers.addAll(headers);\n\nhttp.StreamedResponse response = await request.send();\n\nif (response.statusCode == 200) {\n print(await response.stream.bytesToString());\n}\nelse {\n print(response.reasonPhrase);\n}\n"
- lang: Go
source: "package main\n\nimport (\n \"fmt\"\n \"strings\"\n \"net/http\"\n \"io/ioutil\"\n)\n\nfunc main() {\n\n url := \"%7B%7BbaseUrl%7D%7D/invoices/upload/\"\n method := \"POST\"\n\n payload := strings.NewReader(`{\n \"xml\": \"\",\n \"name\": \"\"\n}`)\n\n client := &http.Client {\n }\n req, err := http.NewRequest(method, url, payload)\n\n if err != nil {\n fmt.Println(err)\n return\n }\n req.Header.Add(\"Content-Type\", \"application/json\")\n req.Header.Add(\"Accept\", \"application/json\")\n\n res, err := client.Do(req)\n if err != nil {\n fmt.Println(err)\n return\n }\n defer res.Body.Close()\n\n body, err := ioutil.ReadAll(res.Body)\n if err != nil {\n fmt.Println(err)\n return\n }\n fmt.Println(string(body))\n}"
- lang: Http
source: "POST /invoices/upload/ HTTP/1.1\nHost: {{baseUrl}}\nContent-Type: application/json\nAccept: application/json\nContent-Length: 45\n\n{\n \"xml\": \"\",\n \"name\": \"\"\n}"
- lang: Java
source: "OkHttpClient client = new OkHttpClient().newBuilder()\n .build();\nMediaType mediaType = MediaType.parse(\"application/json\");\nRequestBody body = RequestBody.create(mediaType, \"{\\n \\\"xml\\\": \\\"\\\",\\n \\\"name\\\": \\\"\\\"\\n}\");\nRequest request = new Request.Builder()\n .url(\"{{baseUrl}}/invoices/upload/\")\n .method(\"POST\", body)\n .addHeader(\"Content-Type\", \"application/json\")\n .addHeader(\"Accept\", \"application/json\")\n .addHeader(\"Content-Length\", \"\")\n .build();\nResponse response = client.newCall(request).execute();"
- lang: Java
source: "Unirest.setTimeouts(0, 0);\nHttpResponse response = Unirest.post(\"{{baseUrl}}/invoices/upload/\")\n .header(\"Content-Type\", \"application/json\")\n .header(\"Accept\", \"application/json\")\n .header(\"Content-Length\", \"\")\n .body(\"{\\n \\\"xml\\\": \\\"\\\",\\n \\\"name\\\": \\\"\\\"\\n}\")\n .asString();\n"
- lang: JavaScript
source: "var myHeaders = new Headers();\nmyHeaders.append(\"Content-Type\", \"application/json\");\nmyHeaders.append(\"Accept\", \"application/json\");\nmyHeaders.append(\"Content-Length\", \"\");\n\nvar raw = JSON.stringify({\n \"xml\": \"\",\n \"name\": \"\"\n});\n\nvar requestOptions = {\n method: 'POST',\n headers: myHeaders,\n body: raw,\n redirect: 'follow'\n};\n\nfetch(\"{{baseUrl}}/invoices/upload/\", requestOptions)\n .then(response => response.text())\n .then(result => console.log(result))\n .catch(error => console.log('error', error));"
- lang: JavaScript
source: "var data = JSON.stringify({\n \"xml\": \"\",\n \"name\": \"\"\n});\n\nvar xhr = new XMLHttpRequest();\nxhr.withCredentials = true;\n\nxhr.addEventListener(\"readystatechange\", function() {\n if(this.readyState === 4) {\n console.log(this.responseText);\n }\n});\n\nxhr.open(\"POST\", \"%7B%7BbaseUrl%7D%7D/invoices/upload/\");\nxhr.setRequestHeader(\"Content-Type\", \"application/json\");\nxhr.setRequestHeader(\"Accept\", \"application/json\");\nxhr.setRequestHeader(\"Content-Length\", \"\");\n\nxhr.send(data);"
- lang: JavaScript
source: "var settings = {\n \"url\": \"{{baseUrl}}/invoices/upload/\",\n \"method\": \"POST\",\n \"timeout\": 0,\n \"headers\": {\n \"Content-Type\": \"application/json\",\n \"Accept\": \"application/json\",\n \"Content-Length\": \"\"\n },\n \"data\": JSON.stringify({\n \"xml\": \"\",\n \"name\": \"\"\n }),\n};\n\n$.ajax(settings).done(function (response) {\n console.log(response);\n});"
- lang: NodeJS
source: "var axios = require('axios');\nvar data = JSON.stringify({\n \"xml\": \"\",\n \"name\": \"\"\n});\n\nvar config = {\n method: 'post',\n url: '{{baseUrl}}/invoices/upload/',\n headers: { \n 'Content-Type': 'application/json', \n 'Accept': 'application/json', \n 'Content-Length': ''\n },\n data : data\n};\n\naxios(config)\n.then(function (response) {\n console.log(JSON.stringify(response.data));\n})\n.catch(function (error) {\n console.log(error);\n});\n"
- lang: NodeJS
source: "var https = require('follow-redirects').https;\nvar fs = require('fs');\n\nvar options = {\n 'method': 'POST',\n 'hostname': '{{baseUrl}}',\n 'path': '/invoices/upload/',\n 'headers': {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Content-Length': ''\n },\n 'maxRedirects': 20\n};\n\nvar req = https.request(options, function (res) {\n var chunks = [];\n\n res.on(\"data\", function (chunk) {\n chunks.push(chunk);\n });\n\n res.on(\"end\", function (chunk) {\n var body = Buffer.concat(chunks);\n console.log(body.toString());\n });\n\n res.on(\"error\", function (error) {\n console.error(error);\n });\n});\n\nvar postData = JSON.stringify({\n \"xml\": \"\",\n \"name\": \"\"\n});\n\nreq.write(postData);\n\nreq.end();"
- lang: NodeJS
source: "var request = require('request');\nvar options = {\n 'method': 'POST',\n 'url': '{{baseUrl}}/invoices/upload/',\n 'headers': {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Content-Length': ''\n },\n body: JSON.stringify({\n \"xml\": \"\",\n \"name\": \"\"\n })\n\n};\nrequest(options, function (error, response) {\n if (error) throw new Error(error);\n console.log(response.body);\n});\n"
- lang: NodeJS
source: "var unirest = require('unirest');\nvar req = unirest('POST', '{{baseUrl}}/invoices/upload/')\n .headers({\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Content-Length': ''\n })\n .send(JSON.stringify({\n \"xml\": \"\",\n \"name\": \"\"\n }))\n .end(function (res) { \n if (res.error) throw new Error(res.error); \n console.log(res.raw_body);\n });\n"
- lang: Objective-C
source: "#import \n\ndispatch_semaphore_t sema = dispatch_semaphore_create(0);\n\nNSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@\"%7B%7BbaseUrl%7D%7D/invoices/upload/\"]\n cachePolicy:NSURLRequestUseProtocolCachePolicy\n timeoutInterval:10.0];\nNSDictionary *headers = @{\n @\"Content-Type\": @\"application/json\",\n @\"Accept\": @\"application/json\",\n @\"Content-Length\": @\"\"\n};\n\n[request setAllHTTPHeaderFields:headers];\nNSData *postData = [[NSData alloc] initWithData:[@\"{\\n \\\"xml\\\": \\\"\\\",\\n \\\"name\\\": \\\"\\\"\\n}\" dataUsingEncoding:NSUTF8StringEncoding]];\n[request setHTTPBody:postData];\n\n[request setHTTPMethod:@\"POST\"];\n\nNSURLSession *session = [NSURLSession sharedSession];\nNSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request\ncompletionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {\n if (error) {\n NSLog(@\"%@\", error);\n dispatch_semaphore_signal(sema);\n } else {\n NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;\n NSError *parseError = nil;\n NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];\n NSLog(@\"%@\",responseDictionary);\n dispatch_semaphore_signal(sema);\n }\n}];\n[dataTask resume];\ndispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);"
- lang: OcaML
source: "open Lwt\nopen Cohttp\nopen Cohttp_lwt_unix\n\nlet postData = ref \"{\\n \\\"xml\\\": \\\"\\\",\\n \\\"name\\\": \\\"\\\"\\n}\";;\n\nlet reqBody = \n let uri = Uri.of_string \"%7B%7BbaseUrl%7D%7D/invoices/upload/\" in\n let headers = Header.init ()\n |> fun h -> Header.add h \"Content-Type\" \"application/json\"\n |> fun h -> Header.add h \"Accept\" \"application/json\"\n |> fun h -> Header.add h \"Content-Length\" \"\"\n in\n let body = Cohttp_lwt.Body.of_string !postData in\n\n Client.call ~headers ~body `POST uri >>= fun (_resp, body) ->\n body |> Cohttp_lwt.Body.to_string >|= fun body -> body\n\nlet () =\n let respBody = Lwt_main.run reqBody in\n print_endline (respBody)"
- lang: PHP
source: "setUrl('{{baseUrl}}/invoices/upload/');\n$request->setMethod(HTTP_Request2::METHOD_POST);\n$request->setConfig(array(\n 'follow_redirects' => TRUE\n));\n$request->setHeader(array(\n 'Content-Type' => 'application/json',\n 'Accept' => 'application/json',\n 'Content-Length' => ''\n));\n$request->setBody('{\\n \"xml\": \"\",\\n \"name\": \"\"\\n}');\ntry {\n $response = $request->send();\n if ($response->getStatus() == 200) {\n echo $response->getBody();\n }\n else {\n echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .\n $response->getReasonPhrase();\n }\n}\ncatch(HTTP_Request2_Exception $e) {\n echo 'Error: ' . $e->getMessage();\n}"
- lang: PHP
source: " '%7B%7BbaseUrl%7D%7D/invoices/upload/',\n CURLOPT_RETURNTRANSFER => true,\n CURLOPT_ENCODING => '',\n CURLOPT_MAXREDIRS => 10,\n CURLOPT_TIMEOUT => 0,\n CURLOPT_FOLLOWLOCATION => true,\n CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n CURLOPT_CUSTOMREQUEST => 'POST',\n CURLOPT_POSTFIELDS =>'{\n \"xml\": \"\",\n \"name\": \"\"\n}',\n CURLOPT_HTTPHEADER => array(\n 'Content-Type: application/json',\n 'Accept: application/json',\n 'Content-Length: '\n ),\n));\n\n$response = curl_exec($curl);\n\ncurl_close($curl);\necho $response;\n"
- lang: PHP
source: "setRequestUrl('{{baseUrl}}/invoices/upload/');\n$request->setRequestMethod('POST');\n$body = new http\\Message\\Body;\n$body->append('{\n \"xml\": \"\",\n \"name\": \"\"\n}');\n$request->setBody($body);\n$request->setOptions(array());\n$request->setHeaders(array(\n 'Content-Type' => 'application/json',\n 'Accept' => 'application/json',\n 'Content-Length' => ''\n));\n$client->enqueue($request)->send();\n$response = $client->getResponse();\necho $response->getBody();\n"
- lang: PowerShell
source: '$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-Type", "application/json")
$headers.Add("Accept", "application/json")
$headers.Add("Content-Length", "")
$body = "{`n `"xml`": `"`",`n `"name`": `"`"`n}"
$response = Invoke-RestMethod ''{{baseUrl}}/invoices/upload/'' -Method ''POST'' -Headers $headers -Body $body
$response | ConvertTo-Json'
- lang: Python
source: "import requests\nimport json\n\nurl = \"{{baseUrl}}/invoices/upload/\"\n\npayload = json.dumps({\n \"xml\": \"\",\n \"name\": \"\"\n})\nheaders = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Content-Length': ''\n}\n\nresponse = requests.request(\"POST\", url, headers=headers, data=payload)\n\nprint(response.text)\n"
- lang: Python
source: "import http.client\nimport json\n\nconn = http.client.HTTPSConnection(\"{{baseUrl}}\")\npayload = json.dumps({\n \"xml\": \"\",\n \"name\": \"\"\n})\nheaders = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Content-Length': ''\n}\nconn.request(\"POST\", \"/invoices/upload/\", payload, headers)\nres = conn.getresponse()\ndata = res.read()\nprint(data.decode(\"utf-8\"))"
- lang: Ruby
source: "require \"uri\"\nrequire \"json\"\nrequire \"net/http\"\n\nurl = URI(\"{{baseUrl}}/invoices/upload/\")\n\nhttp = Net::HTTP.new(url.host, url.port);\nrequest = Net::HTTP::Post.new(url)\nrequest[\"Content-Type\"] = \"application/json\"\nrequest[\"Accept\"] = \"application/json\"\nrequest[\"Content-Length\"] = \"\"\nrequest.body = JSON.dump({\n \"xml\": \"\",\n \"name\": \"\"\n})\n\nresponse = http.request(request)\nputs response.read_body\n"
- lang: Shell
source: "printf '{\n \"xml\": \"\",\n \"name\": \"\"\n}'| http --follow --timeout 3600 POST '{{baseUrl}}/invoices/upload/' \\\n Content-Type:'application/json' \\\n Accept:'application/json' \\\n Content-Length:"
- lang: Shell
source: "wget --no-check-certificate --quiet \\\n --method POST \\\n --timeout=0 \\\n --header 'Content-Type: application/json' \\\n --header 'Accept: application/json' \\\n --header 'Content-Length: ' \\\n --body-data '{\n \"xml\": \"\",\n \"name\": \"\"\n}' \\\n '{{baseUrl}}/invoices/upload/'"
- lang: Swift
source: "import Foundation\n#if canImport(FoundationNetworking)\nimport FoundationNetworking\n#endif\n\nvar semaphore = DispatchSemaphore (value: 0)\n\nlet parameters = \"{\\n \\\"xml\\\": \\\"\\\",\\n \\\"name\\\": \\\"\\\"\\n}\"\nlet postData = parameters.data(using: .utf8)\n\nvar request = URLRequest(url: URL(string: \"{{baseUrl}}/invoices/upload/\")!,timeoutInterval: Double.infinity)\nrequest.addValue(\"application/json\", forHTTPHeaderField: \"Content-Type\")\nrequest.addValue(\"application/json\", forHTTPHeaderField: \"Accept\")\nrequest.addValue(\"\", forHTTPHeaderField: \"Content-Length\")\n\nrequest.httpMethod = \"POST\"\nrequest.httpBody = postData\n\nlet task = URLSession.shared.dataTask(with: request) { data, response, error in \n guard let data = data else {\n print(String(describing: error))\n semaphore.signal()\n return\n }\n print(String(data: data, encoding: .utf8)!)\n semaphore.signal()\n}\n\ntask.resume()\nsemaphore.wait()\n"
components:
schemas:
UploadXML:
properties:
name:
description: Valor opcional, en caso de no existir, se coloca el UUID.
title: Nombre del archivo
type: string
xml:
description: El XML en base 64
title: XML
type: string
required:
- xml
title: UploadXML
type: object
UploadXMLResult:
properties:
message:
description: Mensaje de éxito o de error que acompaña al status
type: string
result:
description: Contiene la información del endpoint donde se puede consultar el status de la carga
properties:
url:
description: URL de Firebase donde se puede consultar el status de la carga
type: string
type: object
status:
description: Indica el status de la llamada, 1.- Éxito, 0.- Error
type: number
type: object
securitySchemes:
APIKey:
description: Llave de API relacionada al usuario que hace la petición.
in: header
name: Authorization
type: apiKey
x-tagGroups:
- name: Conciliación
tags:
- Conciliación
- name: Tesorería
tags:
- Movimientos bancarios
- name: Documentos fiscales
tags:
- Listado de documentos fiscales
- Cargar un documento fiscal
- Status de documentos fiscales
- name: Contabilidad
tags:
- Balanza de comprobación
- Pólizas manuales
- Saldo de una cuenta