CNPJws
English
English
  • Overview
  • Data Models
    • Countries
    • States
    • Cities
    • Legal Natures
    • Company Sizes
    • Economic Activities
    • Corporate Qualifications
    • Partners
    • Simples Nacional and MEI
    • Establishments
    • State Registrations
    • Suframa
    • Tax Regimes
    • Registration Statuses
    • Error Messages
  • Changelog
  • API Reference
    • API - Commercial
      • Consulting CNPJ in the Commercial API
      • Consulting by CNPJ Root
      • Company Search
      • Consulting Monthly Request Consumption
      • Validating Suframa Registration
    • API - Public
      • Consulting CNPJ in the Public API
      • Validating Suframa Registration in the Public API
      • Limitations
  • BLOG
    • What is CNPJ
    • Consult CNPJ with Java
    • Consult CNPJ for Free with Excel
    • Consult CNPJ with PHP
    • Trigger to Consult CNPJ in Protheus
    • Keep Customer and Supplier Records Updated
    • Consult CNPJ with Javascript and Node.JS
    • Consult CNPJ with ADVPL (Protheus)
    • CNPJ.ws Project
Powered by GitBook
On this page

Was this helpful?

  1. BLOG

Consult CNPJ with ADVPL (Protheus)

Consult CNPJ in Protheus using the CNPJ.ws API with ADVPL

PreviousConsult CNPJ with Javascript and Node.JSNextCNPJ.ws Project

Last updated 4 months ago

Was this helpful?

The Totvs Protheus system is the leading ERP in the Brazilian market and can be easily and simply integrated with the CNPJ.ws API to consult customers or suppliers through the CNPJ.

Protheus uses Totvs' proprietary language, ADVPL (Advanced Protheus Language), which is a standard xBase programming language (Clipper, Visual Objects, and later Fivewin).

For this integration, we will build a generic communication class that can be used in various types of projects. You can also find this project on .

Remember that you can use our free API to consult CNPJ, but with a limitation of 3 queries per minute, or you can purchase one of our commercial plans.

With the integration, we can use the API to query the address, state registration, registration status, CNAE, and many other information that may be important when registering a customer or supplier, a legal entity, through the CNPJ.

Integration of CNPJ.ws with Totvs Protheus ERP

Let's get started, below is the class declaration:

#include 'totvs.ch'
#include 'protheus.ch'

class CNPJws
	data lVerb	  as Logical
	data cURL     as String
	data cToken   as String
	data cErro    as String
	data cRet     as String
	data oRet     as String
	data aHeaders as Array
	data lRet     as Logical

  method new() CONSTRUCTOR
	method consoleLog(cMsg,lErro)
	method setError(oRest)
	method consultarCNPJ(cCNPJ)
	method getResponse()
	method getError()
endClass

We will have 6 methods in our class:

  • new: Responsible for instantiating the class;

  • setError: Internal method for generating errors;

  • consultarCNPJ: Responsible for querying the CNPJ using the CNPJ.ws API;

  • getResponse: Returns the API response in JSON format;

  • getError: Returns the error message;

Now let's develop the new method, which is our constructor method. Note that this method receives the parameter lTest (the default value is false) and yes, we will run tests with our integration class.

Also note that we have a CN_TOKEN parameter, which we must create if we are using the Commercial API (without restrictions) and fill it with the Token that was sent to your email.

method new(lTest) class CNPJws

	default lTest:= .f.

	::cToken  := if(lTest, '', superGetMV('CN_TOKEN',.f.,''))
	::cURL    := if(empty(::cToken),'https://publica.cnpj.ws','https://comercial.cnpj.ws')
	::lVerb   := if(lTest, .t., superGetMV('CN_VERBO',.f.,.t.)) //Indica se ira imprimir todas as msgs no console
	::cErro   := ''
	::cRet    := ''
	::oRet    := nil
	::lRet    := .t.
	::aHeaders:= {"Content-Type: application/json; charset=utf-8"}

	if !empty(::cToken)
		aAdd(::aHeaders,'x_api_token: ' + allTrim(::cToken))
	endif

	::consoleLog('Classe instanciada com sucesso!')

return Self

In the new method we use the consoleLog method, so let's develop it now. This method aims to standardize the messages emitted by the class.

If the CN_VERBO parameter is set to .T., the class will print all messages in the Protheus console.log.

method consoleLog(cMsg,lErro) class CNPJws
	local cLog:= ''
	default cMsg := ''
	default lErro:= .f.

	if ::lVerb .or. lErro
		cLog:= '[' + dtoc(date()) + ']'
		cLog+= '[' + time() + ']'
		cLog+= '[' + ProcName(1) + ']'
		cLog+= '[' + cValToChar(ProcLine(1)) + ']'
		cLog+= '['+allTrim(cMsg)+']'
		if lErro
			::cErro:= cLog
			::lRet := .f.
		endif
		if ::lVerb .or. lErro
			conout(cLog)
		endif
	endif

return

Below is the setError method used by the class to generate error messages:

method setError(oRest,cPath) class CNPJws
	local cLog		:= ''
	local cAux  	:= ''
	local cStatus	:= ''

	default cPath := ''

	::oRet := nil
	::cRet:= oRest:GetResult()

	if valType(::cRet) <> 'C'
		::cRet:= ''
	endif

	if !empty(::cRet)
		::cRet:= FWNoAccent(DecodeUtf8(::cRet))
		if empty(::cRet)
			::cRet:= FWNoAccent(oRest:GetResult())
		endif
	endif

	cAux:= FWNoAccent(DecodeUtf8(oRest:GetLastError()))
	if empty(cAux)
		cAux:= FWNoAccent(oRest:GetLastError())
	endif

	cStatus:= oRest:GetHTTPCode()
	cLog+= 'Host: ' + ::cURL + CRLF
	cLog+= 'Operacao: ' + ProcName(1) + ' ' + cPath + CRLF
	cLog+= 'HTTP Code: ' + cStatus + CRLF
	cLog+= 'Erro: ' + cAux + CRLF
	cLog+= 'Resultado: ' + ::cRet + CRLF

	::consoleLog(cLog,.T.)

return

The method returns a boolean, if everything goes well it will return true, if an error occurs the return will be false, see below:

method consultarCNPJ(cCNPJ) class CNPJws
	local oRest	:= FWRest():New(::cURL)
	local cPath := ''

	::cRet := ''
	::oRet := nil
	::lRet := .t.
	::cErro:= ''

	cPath+=  allTrim(cCNPJ)
	oRest:setPath(cPath)

	if oRest:Get(::aHeaders)
		if !empty(oRest:GetResult())
			::cRet:= FWNoAccent(DecodeUtf8(oRest:GetResult()))
			if empty(::cRet)
				::cRet:= FWNoAccent(oRest:GetResult())
			endif
			::cRet:= strTran(::cRet,'\/','/')
			::cRet:= strtran(::cRet,":null",': " "')
			::cRet:= strtran(::cRet,'"self"','"_self"')
			::oRet:= JsonObject():new()
			::oRet:fromJson(::cRet)
			::lRet := .t.
			::cErro:= ''
		else
			::oRet := nil
			::cErro:= ''
			::lRet := .t.
		endif
		::consoleLog('Sucesso! ' + cPath)
	else
		::setError(oRest,cPath)
	endif

	FreeObj(oRest)

return ::lRet
method getResponse() class CNPJws
return ::oRet

Below we have the method responsible for returning the error message if the query is not successful:

method getError() class CNPJws
return ::cErro

Great, we have built our class, now is a good time to develop a routine to use our class:

user function tstCNPJ()
	local oCNPJ:= nil
	local oJSON:= nil

	RpcSetType(3)
	if !RpcSetEnv('99','01')
		return
	endif

	oCNPJ:= CNPJws():new()//Instancia a classe

	if oCNPJ:consultarCNPJ('40154884000153')
		oJSON:= oCNPJ:getResponse()
	endif

	RPCClearEnv()

return

See you soon!

Now, let's develop the method responsible for communicating with the CNPJ.ws API, the consultarCNPJ method. Here we will use the class to communicate with the API. This method receives the CNPJ as a parameter and performs the query in the API.

Below we have the method responsible for returning the JSON that the API returned in the query:

If you need support to implement this integration in your environment, we recommend , our partner, which has consultants specialized in system integration!

This post is quite long, isn't it? So I will leave a part 2 using TL++ to create a test for the integration class, but the source code is already on if you want to take a look!

To learn more about our plans and payment methods, visit .

GitHub
FWREST
CNPJ.ws
Apply System
GitHub
CNPJ.ws