Página 1 de 1

Gerar Qrcode com para Pagamento de PIX

Enviado: 16 Ago 2023 11:29
por informais
Estou gerando o qrcode de Pix 

se Fizer a Leitura  no APP 

mercado pago               (ok lê de boa)
nubank                           Diz que o Qrcoe é inválido
Sicob                              Diz que o Qr Code está Expirado



Será que está Faltando Algum parametro

Código: Selecionar todos

FUNCTION  Gerar_Qrcode_Pix(v_Documento)
	Local oDlg_Pix, oBmp1
	
	Local nValor 		:= 0 					&&& 1200.75 //Valor do PIX
	Local cPIX_CHAVE 	:= space(30)  		&&& chave pix
	Local cPIX_NOME 	:= space(30)     	&&& Nome do Proprietario do PIX
	Local cPIX_cidade := space(15)     	&&& Nome da Cidade do proprietario do PIX
	Local cMsg 			:= space(10)      &&& Campo de Msg Opcional Para Pix (exemplo Pedido xxx)
   LOCAL nResp
   LOCAL qrDLL
	*------------------------------------------------------------------------------------
	* Coloquei Aqui para Gerar Valores com Base na Hora/m/sg Apenas para testar
	*------------------------------------------------------------------------------------
	nValor 				:=  val(  substr(time(),04,2) + '.' + substr(time(),07,2)  )
	*----------------------------------------------------------------------------
	* Pego os Dados da Chave Cadastrada no Banco de Dados 
	*-----------------------------------------------------------------------------	
	IF SELECT("pix_empresa") != 0
		pix_empresa->(DbCloseArea())
	ENDIF		
	cQuery:='select * from empresa where CODIGO =  ' + TRANSFORMA_SQL(1,'N',06,0) + ' Limit 1'   
	use sql cQuery alias "pix_empresa" new via 'MYSQL'
	pix_empresa->( DbGoTop())
	cPIX_CHAVE 		:= IF(empresa->TIPO_CHAVE_PIX	 =4,'+55','') + (pix_empresa->CHAVE_PIX)  	&& chave pix
	cPIX_NOME 		:= alltrim(pix_empresa->NOME_CHAVE_PIX	)        									&& Nome do Proprietario do PIX
	cPIX_cidade 	:= alltrim(pix_empresa->CIDEMP)     													&& Nome da Cidade do proprietario do PIX
	cMsg 				:= IF(!EMPTY(v_Documento),v_Documento,'Nao Inf.')   
	IF SELECT("pix_empresa") != 0
		pix_empresa->(DbCloseArea())
	ENDIF		

 	*----------------------------------------------------------------------------	
	* Passando Dados Para Gerar o Qrcod_pix
 	*----------------------------------------------------------------------------	
	cMsg      := '05'+ strzero(len(alltrim(left(alltrim(cMsg),21))),2) + left(alltrim(cMsg),21)  //Reference label até 25 caracteres.
	*----------------------------------------------------------------------------
	nTamChave := 22 + len(alltrim(cPIX_CHAVE))  //Tamanho da chave para ser colocado no registro 26
	*----------------------------------------------------------------------------
	cString 	 := '000201'  //Inicio do código para gerar o Qr-Code
	cString 	 += '26'+strzero(nTamChave,2)+'0014BR.GOV.BCB.PIX01'+ strzero(len(alltrim(cPIX_CHAVE)),2) + alltrim(cPIX_CHAVE)
	cString   += '52040000'
	cString   += '5303986'
	cString   += '54' + strzero(len(alltrim(str(nValor))),2) + alltrim(str(nValor))
	cString   += '5802BR'
	cString   += '59' + strzero(len(alltrim(cPIX_NOME)),2) + alltrim(cPIX_NOME) //Merchant Name até 25 caracteres.
	cString   += '60' + strzero(len(left(alltrim(cPIX_cidade),15)),2) + alltrim(left(cPIX_cidade,15)) //City Name até 15 caracteres.
	cString   += '62' + strzero(len(cMsg),2) + cMsg
	cString   += '6304'
	cString   += GERA_CRC(cString)

	*----------------------------------------------------------------------------           
	PASTA_QRCOD						:= CurDrive() +':\'+ CurDir() +'\QRCODPIX\'
   IF !lIsDir(PASTA_QRCOD)
   	lMkDir(PASTA_QRCOD)                                                              
   ENDIF
 	*----------------------------------------------------------------------------
   hBmp := FW_BarCodeBmp( alltrim(cString), "QRCODE", 200, 200 )
   hBmp := bmp2alpha( hBmp )           
   FW_SaveImage( hBmp, (CurDrive() +':\'+ CurDir() +'\QRCODPIX\' +  ALLTRIM('A_CHAVE_PIX') + ".png")  )
 	cFile := (CurDrive() +':\'+ CurDir() +'\QRCODPIX\' +  ALLTRIM('A_CHAVE_PIX') + ".png")
  	*----------------------------------------------------------------------------
  	XIMAGE_zoom( cFile, 'Qrcode Pagamento Valor ' +M->cSimb+' '+  ALLTRIM(TRANSFORM(nValor,"@ZE 999,999,999.99")) + ' Valores de Teste' , (.T.), 60 )
  	*----------------------------------------------------------------------------
   
Return nil

*-------------------------------------------------------------------------------
FUNCTION bmp2alpha( hBmp1 )
   local hBmp, oBmp
   oBmp  := GdiBmp():New()
   oBmp:CreateFromRes( hBmp1, 0 )
   oBmp:Conver24to32Alpha( .f. )
   hBmp  := oBmp:GetGDIHbitmap()
   oBmp:Destroy()
   DeleteObject( hBmp1 )
return hBmp
*-------------------------------------------------------------------------------
*
*-------------------------------------------------------------------------------
Func GERA_CRC(ctxt)
	local i,n,a:={}
	local polinomio:=0x1021
	local resultado:=0xFFFF
	
	for i=1 to len(ctxt) 
		resultado := nXor(hb_bitShift(asc(substr(ctxt,i,1)),8),resultado)
		for n=1 to 8
		    resultado := hb_bitShift(resultado,1)
		    if nand(resultado, 0x10000)<>0
		       resultado:=nXor(resultado,polinomio)
		    end
		    resultado:=nAnd(resultado,0xFFFF)
		next
	next   
return(DecToHex(resultado))
o Qrcode é esse 
Imagem

Gerar Qrcode com para Pagamento de PIX

Enviado: 16 Ago 2023 17:36
por Fernando queiroz

Código: Selecionar todos

**************************************************************************************************************************************************************************
METHOD Pix_String( ) CLASS PIXClass
**********************************************************************************************************************************************************************************
LOCAL cString

    cString := ""
    cString += get_p_value('00', '01')
//   cString += get_p_value('01', '11')
    cString += get_p_account_information(::cPIX_KEY, ::cPIX_RECEIVER, ::pix_url)
    cString += get_p_value('52', '0000')
    cString += get_p_value('53', '986')
    cString += get_p_value('54', ::nPIX_AMOUNT)
    cString += get_p_value('58', 'BR')
    cString += get_p_value('59', SUBSTR(::cPIX_DESCRIPTION,1,25))
    cString += get_p_value('60', ::cPIX_CITY)
    ** cString += get_p_value('61', '')
    cString += get_p_additional_data_field(::cPIX_IDENTIFICATION)
    cString += "6304"
    cString += hb_numtohex(hb_crcct(cString, 0xFFFF, 0x11021))

    ::qrcode := cString

return Nil
**********************************************************************************************************************************************************************************
STATIC function get_p_value(identify, value)
**********************************************************************************************************************************************************************************

return trim(identify + strzero(len(alltrim(value)), 2) + value)
**********************************************************************************************************************************************************************************
STATIC function get_p_account_information(key, description, url)
**********************************************************************************************************************************************************************************
Local base_pix := get_p_value('00', 'br.gov.bcb.pix')
Local info_string := ''

    if key != Nil
        info_string += get_p_value('01', key)
    elseif url != Nil
        info_string += get_p_value('25', url)
    endif

    info_string += get_p_value('02', description)

return get_p_value('26', base_pix + info_string)
**********************************************************************************************************************************************************************************
STATIC function get_p_additional_data_field(identification)
**********************************************************************************************************************************************************************************

    if identification != Nil
        return get_p_value('62', get_p_value('05', identification))
    endif

return get_p_value('62', get_p_value('05', '***'))
ESSE TA FUNCIONANDO CERTINHO

Gerar Qrcode com para Pagamento de PIX

Enviado: 16 Ago 2023 19:46
por Itamar M. Lins Jr.
Olá!
Fernando, ta tudo ai ? precisa de mais coisa para chamar ?

Saudações,
Itamar M. Lins Jr.

Gerar Qrcode com para Pagamento de PIX

Enviado: 16 Ago 2023 20:41
por JoséQuintas
Que eu saiba, não pode gerar chave à vontade, o código precisa estar previamente cadastrado.
A mensagem de vencido, na verdade é porque não vale, e o banco supõe que isso seja por ter perdido validade.
Não é igual boleto, que dá pra criar o código.
Isso se entendi direito o que está fazendo.

Gerar Qrcode com para Pagamento de PIX

Enviado: 16 Ago 2023 20:59
por JoséQuintas
Fernando, tem erro na sua rotina, acho que ainda não ocorreu o problema mas pode ocorrer.

Em Get_P_Value()
Usa AllTrim() pra pegar o tamanho, e adiciona o valor.
Quem garante que o tamanho vai ficar igual?
Coloque AllTrim() no valor também.

Melhor ainda: primeiro AllTrim() no valor, e depois o resto, vai ser menos fonte.

Código: Selecionar todos

STATIC function get_p_value(identify, value)

Value := AllTrim( Value )
return identify + StrZero( Len( value ), 2 ) + value
Apenas sugestão, sei lá se ajuda:

Código: Selecionar todos

cString += "00" + LenAndValue( "01" )
...

FUNCTION LenAndValue( cTxt )

   cTxt := AllTrim( cTxt )

   RETURN StrZero( Len( cTxt ), 2 ) + cTxt
Apenas ao ver LenAndValue já sugere que é tamanho e valor, economiza tempo pra olhar a função, e como a outra não faz diferença, nem precisa ir pra função, também economiza um tempinho. Estou falando de economizar tempo de cérebro, e não economizar tempo do computador, o computador que se lasque... kkkk

Gerar Qrcode com para Pagamento de PIX

Enviado: 17 Ago 2023 08:40
por Fernando queiroz
Itamar M. Lins Jr. escreveu:Olá!
Fernando, ta tudo ai ? precisa de mais coisa para chamar ?

Saudações,
Itamar M. Lins Jr.
segue a rotina completa

Código: Selecionar todos

/*
TITULO     : SISTEMA DE GEST¦O DE COMERCIO
DATA       : 06-06-2023
PROGRAMA   : CLASS_PIX.PRG
COMENTARIO : ROTINA DE INTEGRACAO DE PIX GENERICO

*** como utilizar a class ***
oPIX := PIXClass( ):New( )
oPIX:Setup(sBanco, nEnviroment, sCertificado, sClient_Id, sClient_Secret, sPIX_Key, sPIX_Receive, sPIX_City, sPIX_Amount, sPIX_Description, sPIX_Identification, sPDF_Linha1, sPDF_linha2, stxid)
oPIX:Execute( )
if oPIX:erro_status = 200
    ...
    ...
    ...
else
    hwg_MsgInfo("REMOVA A FORMA DE PAGAMENTO"+ HB_EOL() + ;
                "E INCLUA NOVAMENTE PARA REPETIR"+ HB_EOL() + ;
                "A OPERAÇÃO", "OPERAÇÃO NÃO EFETUADA!!!")
endif

obs: se passar com o stxid ele vai somente fazer uma consulta a um pix existente
***********************************************************************************

como criar um WEBHOOK 
https://youtu.be/y-iCT7HexPY --> video explicando
https://insomnia.rest/download --> software utilizado na criacao da URL

https://groups.google.com/g/harbour-users/c/CBcrRAHnQSA WEB_SOQKET
https://github.com/FiveTechSoft/wsserver/blob/master/wsserver.prg WEB SOCKET EM HARBOUR

https://github.com/FiveTechSoft/wsserver

https://github.com/rafathefull/restful/blob/master/status_service.prg

https://dev.gerencianet.com.br/docs/api-pix-endpoints#exemplos-de-configura%C3%A7%C3%B5es-de-servidor
https://webhook.site/

*/

#include "hbclass.ch"
//#include "hbgtinfo.ch"

#define PDFCLASS_PORTRAIT  1
#define PDFCLASS_LANDSCAPE 2
#define PDFCLASS_TXT       3
#define PDFCLASS_ROLLS     4
#DEFINE WS_OK              200
#DEFINE WS_ERROR           400

CREATE CLASS PIXClass

*** Parametros de consultas ***
    VAR txid                INIT ""
    VAR id                  INIT 0
    VAR location            INIT ""
    VAR e2eId               INIT ""
    VAR data_Inicio         INIT ""                                                               // NO FORMATO "2020-10-22T16:01:35Z"
    VAR data_Fim            INIT ""                                                               // NO FORMATO "2020-10-22T16:01:35Z"

*** variaveis de retorno ***    
    VAR qrcode              INIT ""                                                             
    VAR qrcodeImage         INIT ""
    VAR qrcodeImagePDF      INIT ""
    VAR linkVisualizacao    INIT ""
    VAR ListaDeCobranca 
    VAR Hash_Retorno  
    VAR pix_url             INIT ""  
    VAR cFilename           INIT ""
    VAR status              INIT ""
    
*** variaveis de retorno de ERRO *** 
    VAR erro_status         INIT WS_OK
    VAR erro_nome           INIT ""
    VAR erro_mensagem       INIT ""

    METHOD Setup(sBanco, nEnviroment, sCertificado, sClient_Id, sClient_Secret, sPIX_Key, sPIX_Receive, sPIX_City, sPIX_Amount, sPIX_Description, sPIX_Identification, sPDF_Linha1, sPDF_linha2) //ok
    METHOD Execute( ) //ok 
    METHOD PDF_QRCode( ) //ok
    METHOD Consulta( sBanco, nEnviroment, sCertificado, sClient_Id, sClient_Secret, stxid) //ok
    METHOD Pix_String( ) //ok    

PROTECTED:

   **** Dados Dinamicos no momentos da Geracao
    VAR nPIX_AMOUNT         INIT ""                
    VAR cPIX_DESCRIPTION    INIT ""
    VAR cPIX_IDENTIFICATION INIT ""   
  
  **** Parametros Basicos cadastro da Empresa ****
    VAR cPIX_KEY            INIT ""                                                               // chave pix (CNPJ, email, celular)
    VAR cPIX_RECEIVER       INIT ""                                                               // Nome do Proprietario do PIX
    VAR cPIX_CITY           INIT ""                                                               // Nome da Cidade do proprietario do PIX
    VAR cPIX_ZIPCODE        INIT ""

**** Parametros Basicos do Ambiente ****
    VAR BANCO               INIT "000"                                                            // 000-API GENERICA, OUTRO VALOR PARA ROTA BASICA DO BANCO
    VAR ENVIROMENT_TYPE     INIT 1                                                                // 0-Homologação 1-Produção
    VAR MY_CERTIFICATE      INIT ""                                                               //CERTIFICADO DIGITAL DE HOMOLOGACAO/PRODUCAO GERADO PELO BANCO EFI
    VAR CLIENT_ID           INIT ""                                                               //ID DE HOMOLOGACAO/PRODUCAO DO BANCO EFI
    VAR CLIENT_SECRET       INIT ""                                                               //SENHA DE HOMOLOGACAO/PRODUCAO DO BANCO EFI

    VAR ROUTE_BASE          INIT ""
    VAR access_token        INIT ""                                           //token retornado pela autenticacao
    VAR expires_in          INIT 3600                                        // Tempo de expiração em segundos  
    VAR chave               INIT ""
    VAR devolutionCustomId  INIT ""
    VAR idEnvio             INIT ""
    VAR cPDF_Linha1         INIT ""
    VAR cPDF_Linha2         INIT ""


    METHOD Authorize(  ) //ok
    METHOD PrintQRCode ( ) //ok
       
    METHOD pix_config_webhook( chave )
    METHOD pix_get_webhook( chave )
    METHOD pix_list_webhook( data_Inicio, data_Fim )
    METHOD pix_delete_webhook( chave )

    METHOD pix_create_charge(  ) //ok
    METHOD pix_create_immediate_charge( ) //ok
    METHOD pix_detail_charge(  ) //ok

    METHOD pix_update_charge(  ) //ok
    METHOD pix_list_charges( ) //ok
    METHOD pix_generate_QRCode( ) //ok
    METHOD WS( cPostGet, cUrl, cBody ) //ok

ENDCLASS
************************************************************************************************************************************************************************************************************************
METHOD Setup(sBanco, nEnviroment, sCertificado, sClient_Id, sClient_Secret, sPIX_Key, sPIX_Receive, sPIX_City, sPIX_Amount, sPIX_Description, sPIX_Identification, sPDF_Linha1, sPDF_linha2) CLASS PIXClass
************************************************************************************************************************************************************************************************************************
LOCAL oBanco;

    ::txid := create_Txid(  ) 
    ::BANCO := IF(sBanco == Nil, "000", sBanco)
    ::ENVIROMENT_TYPE := IF(nEnviroment == Nil, 0, nEnviroment)
    ::MY_CERTIFICATE := IF(sCertificado == Nil, "", sCertificado)
    ::CLIENT_ID := IF(sClient_Id == Nil,"", sClient_Id)
    ::CLIENT_SECRET := IF(sClient_Secret == Nil,"", sClient_Secret)
    ::cPIX_KEY := IF(sPIX_Key == Nil,"", sPIX_Key)
    ::cPIX_RECEIVER := IF(sPIX_Receive == Nil,"", sPIX_Receive)
    ::cPIX_CITY := IF(sPIX_City  == Nil,"", sPIX_City)
    ::nPIX_AMOUNT := IF(sPIX_Amount  == Nil,"0.00", sPIX_Amount)
    ::cPIX_DESCRIPTION := IF(sPIX_Description  == Nil,"", sPIX_Description)
    ::cPIX_IDENTIFICATION := IF(sPIX_Identification == Nil,"", sPIX_Identification)
    ::cPDF_Linha1 := IF(sPDF_Linha1 == Nil,"", sPDF_Linha1)
    ::cPDF_Linha2 := IF(sPDF_Linha2 == Nil,"", sPDF_Linha2)
    ::cFileName:="C:\filesold\report\PIX_" + strzero(HB_RandomInt(1, 99999999),8,0) +'.PDF'

	FOR EACH oBanco IN hb_jsonDecode( CARREGA_RESOURCE( "BANCOS" ) )
		IF oBanco["value"] == ::BANCO
            IF ::ENVIROMENT_TYPE = 1
                ::ROUTE_BASE := oBanco["production"] 
            ELSE
                ::ROUTE_BASE := oBanco["homologation"] 
            ENDIF
		ENDIF
	NEXT
return Nil
************************************************************************************************************************************************************************************************************************
METHOD Execute( ) CLASS PIXClass
************************************************************************************************************************************************************************************************************************
    
    IF ::BANCO = "000"
        ::Pix_String(  )
        ::PrintQRCode( ) 
    ELSE
        ::Authorize(  )
        ::pix_create_charge(  )         // ou ::pix_create_immediate_charge(  )
        ::pix_generate_QRCode( )
        ::PrintQRCode( ) 
    endif
return Nil
************************************************************************************************************************************************************************************************************************
METHOD Consulta( sBanco, nEnviroment, sCertificado, sClient_Id, sClient_Secret, stxid) CLASS PIXClass
************************************************************************************************************************************************************************************************************************
    ::BANCO := IF(sBanco == Nil, "000", sBanco)
    ::ENVIROMENT_TYPE := IF(nEnviroment == Nil, 0, nEnviroment)
    ::MY_CERTIFICATE := IF(sCertificado == Nil, "", sCertificado)
    ::CLIENT_ID := IF(sClient_Id == Nil,"", sClient_Id)
    ::CLIENT_SECRET := IF(sClient_Secret == Nil,"", sClient_Secret)
    ::txid := IF(stxid == Nil,"", stxid)
    IF ::BANCO != "000"
        ::Authorize(  )
        ::pix_detail_charge(  )
    endif

return Nil
************************************************************************************************************************************************************************************************************************
METHOD Authorize(  ) CLASS PIXClass
************************************************************************************************************************************************************************************************************************
LOCAL cURL;
    , cRetorno;


    IF ::MY_CERTIFICATE != NIL
        cURL := ::ROUTE_BASE  + "/oauth/token?grantType=client_credentials"
        cURL +="&client_id=" + ::CLIENT_ID
        cURL +="&client_secret=" + ::CLIENT_SECRET  
        cRetorno := ::WS( "POST", cUrl, [{"grant_type": "client_credentials"}] )
        if ::erro_status = WS_OK
            ::access_token := hb_jsonDecode( cRetorno )["access_token"] 
            if EMPTY(::access_token)
                ::erro_status := WS_ERROR
                ::erro_nome := 'access_token:'
                ::erro_mensagem := cRetorno   
            ENDIF
        ENDIF
    ENDIF

return Nil   
************************************************************************************************************************************************************************************************************************
METHOD pix_config_webhook( chave ) CLASS PIXClass
************************************************************************************************************************************************************************************************************************
LOCAL cURL;
    , cRetorno;

    IF ::access_token != NIL
        cURL := ::ROUTE_BASE + "/webhook/:" + chave  
        cRetorno := ::WS( "PUT", cUrl, '[{"webhookUrl": "' + 'https://exemplo-pix/webhook' + '""}]' )
    ENDIF
return cRetorno
************************************************************************************************************************************************************************************************************************
METHOD pix_get_webhook( chave ) CLASS PIXClass
************************************************************************************************************************************************************************************************************************
LOCAL cURL;
    , cRetorno;

    IF ::access_token != NIL
        cURL := ::ROUTE_BASE  + "/webhook/:" + chave
        cRetorno := ::WS( "GET", cUrl, "" )
    ENDIF
return  cRetorno 
************************************************************************************************************************************************************************************************************************
METHOD pix_list_webhook( data_Inicio, data_Fim ) CLASS PIXClass
************************************************************************************************************************************************************************************************************************
LOCAL cURL;
    , cRetorno;

    IF ::access_token != NIL
        cURL := ::ROUTE_BASE + "/webhook/"
        cURL += "?inicio=" + data_Inicio 
        cURL += "?fim=" + data_Fim      
        cRetorno := ::WS( "GET", cUrl, "")
    ENDIF
return  cRetorno  
************************************************************************************************************************************************************************************************************************
METHOD pix_delete_webhook( chave ) CLASS PIXClass
************************************************************************************************************************************************************************************************************************
LOCAL cURL;
    , cRetorno;

    IF ::access_token != NIL
        cURL := ::ROUTE_BASE + "/webhook/:" + chave
        cRetorno := ::WS( "DELETE", cUrl, "" )
    ENDIF
return  cRetorno 
************************************************************************************************************************************************************************************************************************
METHOD pix_create_charge(  ) CLASS PIXClass
************************************************************************************************************************************************************************************************************************
LOCAL cBody;
    , cURL;
    , cRetorno;
    , hRetorno;


    if ::erro_status = WS_OK
        cBody:= '{'
        cBody+= '"calendario": {'
        cBody+=     '"expiracao": ' + ltrim(str(::expires_in)) 
        cBody+=     '},'
        cBody+= '"valor": {'
        cBody+=     '"original": "' + ::nPIX_AMOUNT + '"'
        cBody+=     '},'
        cBody+= '"chave": "' + ::cPIX_KEY + '",'
        cBody+= '"solicitacaoPagador": "' + ::cPIX_IDENTIFICATION + '"'
        cBody+= '}'
        cURL := ::ROUTE_BASE + "/cob/" + ::txid
        cRetorno := ::WS( "PUT", cUrl, cBody )
        if ::erro_status = WS_OK 
            hRetorno:=hb_jsonDecode( cRetorno )
            if Hb_HHasKey( hRetorno, "loc" )
                ::id := hRetorno["loc"]["id"]
                ::location := hRetorno["loc"]["location"]
            endif
        endif
    ENDIF

return Nil
************************************************************************************************************************************************************************************************************************
METHOD pix_create_immediate_charge(  ) CLASS PIXClass
************************************************************************************************************************************************************************************************************************
LOCAL cBody;
    , cURL;
    , cRetorno;
    , hRetorno;


    if ::erro_status = WS_OK
        cBody:= '{'
        cBody+= '"calendario": {'
        cBody+=     '"expiracao": ' + ltrim(str(::expires_in)) 
        cBody+=     '},'
    //    cBody+= '"devedor": {'
    //    cBody+=     '"cpf": "' + "13826018249" + '",'
    //    cBody+=     '"cnpj": "' + "05597127000153" + '",'
    //    cBody+=     '"nome": "' + 'NOME DO SEU CLIENTE' + '"'
    //    cBody+=     '},'
        cBody+= '"valor": {'
        cBody+=     '"original": "' + ::nPIX_AMOUNT + '"'
        cBody+=     '},'
        cBody+= '"chave": "' + ::cPIX_KEY + '",'
        cBody+= '"solicitacaoPagador": "' + ::cPIX_IDENTIFICATION + '"'
        cBody+= '}'
        cURL := ::ROUTE_BASE + "/cob"
        cRetorno := ::WS( "POST", cUrl, cBody )
        if ::erro_status = WS_OK 
            hRetorno:=hb_jsonDecode( cRetorno ) 
            if Hb_HHasKey( hRetorno, "txid" )
                ::txid :=hRetorno["txid"]
                ::id := hRetorno["loc"]["id"]
                ::location := hRetorno["loc"]["location"]
            ENDIF
        endif
    ENDIF

return Nil
************************************************************************************************************************************************************************************************************************
METHOD pix_detail_charge(  ) CLASS PIXClass
************************************************************************************************************************************************************************************************************************
LOCAL cURL;
    , cRetorno;
    , hRetorno;

    if ::erro_status = WS_OK
        cURL := ::ROUTE_BASE + "/cob/" + ::txid
        cRetorno := ::WS( "GET", cUrl, "" )
        if ::erro_status = WS_OK   
            hRetorno:=hb_jsonDecode( cRetorno ) 
            if Hb_HHasKey( hRetorno, "status" )
                ::status:=hRetorno["status"]
                ::e2eid:=hRetorno["pix"]["endToEndId"]
            endif
        endif
    ENDIF

return Nil
************************************************************************************************************************************************************************************************************************
METHOD pix_update_charge(  ) CLASS PIXClass
************************************************************************************************************************************************************************************************************************
LOCAL cBody;
    , cURL;
    , cRetorno;
    , hRetorno;

    if ::erro_status = WS_OK
        cBody:= '{'
        cBody+= '"valor": {'
        cBody+=     '"original": "' + ::nPIX_AMOUNT + '"'
        cBody+=     '}'
        cBody+= '}'
        cURL := ::ROUTE_BASE + "/cob/" + ::txid
        cRetorno := ::WS( "PATCH", cUrl, cBody )
        if ::erro_status = WS_OK 
            hRetorno:=hb_jsonDecode( cRetorno ) 
            if Hb_HHasKey( hRetorno, "txid" )
                ::txid :=hRetorno["txid"]
                ::id := hRetorno["loc"]["id"]
                ::location := hRetorno["loc"]["location"]
            ENDIF
        endif
    ENDIF
return Nil
************************************************************************************************************************************************************************************************************************
METHOD pix_list_charges(  ) CLASS PIXClass
************************************************************************************************************************************************************************************************************************
LOCAL cURL;
    , cRetorno;
    , hRetorno;

    if ::erro_status = WS_OK
        cURL := ::ROUTE_BASE + "/cob" 
        cURL += '?inicio=' + ::data_Inicio
        cURL += '&fim=' + ::data_Fim
        cRetorno := ::WS( "GET", cUrl, "" )
        if ::erro_status = WS_OK 
            hRetorno:=hb_jsonDecode( cRetorno ) 
            if Hb_HHasKey( hRetorno, "ListaDeCobranca" )
                ::ListaDeCobranca:=hRetorno["ListaDeCobranca"]
            endif
        endif
    ENDIF
return Nil
************************************************************************************************************************************************************************************************************************
METHOD pix_generate_QRCode( ) CLASS PIXClass
************************************************************************************************************************************************************************************************************************
LOCAL cURL;
    , cRetorno, hRetorno;
    , cBody:="";

    if ::erro_status = WS_OK
        cURL := ::ROUTE_BASE + "/loc/" + LTRIM(STR(::id,10,0)) + "/qrcode" 
        cRetorno := ::WS( "GET", cUrl, cBody )
        if ::erro_status = WS_OK 
            hRetorno:=hb_jsonDecode( cRetorno ) 
            if Hb_HHasKey( hRetorno, "qrcode" )
                ::qrcode :=hRetorno["qrcode"]
        //      ::qrcodeImage := hRetorno["qrcodeImage"]
                ::linkVisualizacao := hRetorno["linkVisualizacao"]
            ENDIF
        endif
    ENDIF
return  Nil
************************************************************************************************************************************************************************************************************************
METHOD WS( cPostGet, cUrl, cBody ) CLASS PIXClass
************************************************************************************************************************************************************************************************************************
LOCAL oServer;
    , cRetorno;
    , hRetorno;
        
        hb_Default( @cPostGet, "POST" )
        hb_Default( @cBody, "" )

        ::erro_status := WS_OK
        ::erro_nome := ""
        ::erro_mensagem := ""

        BEGIN SEQUENCE WITH {|o| break(o)}
            oServer := Win_OleCreateObject( "MSXML2.ServerXMLHTTP.6.0" )
        RECOVER
            ::erro_status := WS_ERROR
            ::erro_nome := 'Erro na Criação do Serviço:'
            ::erro_mensagem := 'MSXML2.ServerXMLHTTP.6.0'
            RETURN ""
        END SEQUENCE

        BEGIN SEQUENCE WITH {|o| break(o)}
            oServer:Open( cPostGet, cUrl, .F. )
        RECOVER
            ::erro_status := WS_ERROR
            ::erro_nome := 'Erro na abertura do Serviço:'
            ::erro_mensagem := 'OPEN'
            RETURN ""
        END SEQUENCE

        IF Empty(::access_token )
            oServer:setOption( 3, "CURRENT_USER\MY\" + ::MY_CERTIFICATE )
            oServer:SetRequestHeader( "Authorization", "Basic " + hb_base64Encode( ::CLIENT_ID + ":" + ::CLIENT_SECRET ) )
            oServer:SetRequestHeader( "Content-Type", "application/json" )
        ELSE
            oServer:SetRequestHeader( "Content-Type", "application/json" )
            oServer:SetRequestHeader( "Authorization", "Bearer " + ::access_token  )
        ENDIF

        BEGIN SEQUENCE WITH {|o| break(o)}
            oServer:Send( cBody )
        RECOVER
            ::erro_status := WS_ERROR
            ::erro_nome := ':API PIX'
            ::erro_mensagem := 'Erro na Coneccão com o Serviço'
            RETURN Nil
        END SEQUENCE

        oServer:WaitForResponse( ::expires_in )
        cRetorno := oServer:ResponseBody()
        hRetorno:=hb_jsonDecode( cRetorno ) 
        IF EMPTY(cRetorno)
            ::erro_status := WS_ERROR
            ::erro_nome := 'API PIX'
            ::erro_mensagem := 'Retorno de Dados Vazio'
        else
            if Hb_HHasKey( hRetorno, "mensagem" )
                ::erro_status := WS_ERROR
                ::erro_nome := hRetorno["nome"]
                ::erro_mensagem := hRetorno["mensagem"]
            endif  
        ENDIF
        
RETURN cRetorno
************************************************************************************************************************************************************************************************************************
METHOD Pix_String( ) CLASS PIXClass
************************************************************************************************************************************************************************************************************************
LOCAL cString

    cString := ""
    cString += get_p_value('00', '01')
//   cString += get_p_value('01', '11')
    cString += get_p_account_information(::cPIX_KEY, ::cPIX_RECEIVER, ::pix_url)
    cString += get_p_value('52', '0000')
    cString += get_p_value('53', '986')
    cString += get_p_value('54', ::nPIX_AMOUNT)
    cString += get_p_value('58', 'BR')
    cString += get_p_value('59', SUBSTR(::cPIX_DESCRIPTION,1,25))
    cString += get_p_value('60', ::cPIX_CITY)
    ** cString += get_p_value('61', '')
    cString += get_p_additional_data_field(::cPIX_IDENTIFICATION)
    cString += "6304"
    cString += hb_numtohex(hb_crcct(cString, 0xFFFF, 0x11021))

    ::qrcode := cString

return Nil
************************************************************************************************************************************************************************************************************************
STATIC function get_p_value(identify, value)
************************************************************************************************************************************************************************************************************************

return trim(identify + strzero(len(alltrim(value)), 2) + value)
************************************************************************************************************************************************************************************************************************
STATIC function get_p_account_information(key, description, url)
************************************************************************************************************************************************************************************************************************
Local base_pix := get_p_value('00', 'br.gov.bcb.pix')
Local info_string := ''

    if key != Nil
        info_string += get_p_value('01', key)
    elseif url != Nil
        info_string += get_p_value('25', url)
    endif

    info_string += get_p_value('02', description)

return get_p_value('26', base_pix + info_string)
************************************************************************************************************************************************************************************************************************
STATIC function get_p_additional_data_field(identification)
************************************************************************************************************************************************************************************************************************

    if identification != Nil
        return get_p_value('62', get_p_value('05', identification))
    endif

return get_p_value('62', get_p_value('05', '***'))

************************************************************************************************************************************************************************************************************************
FUNCTION create_Txid(  ) 
************************************************************************************************************************************************************************************************************************
Local cRetorno:="";
    , nCont;
    , equivalente:= {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',;
                    '0','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y',;
                    'Z','0','1','2','3','4','5','6','7','8','9'}

    For nCont:=1 to 32
        cRetorno += equivalente[HB_RandomInt(1, 62)]
    next

return cRetorno
******************************************************************************************************************************
METHOD PDF_QRCode( ) CLASS  PIXClass
******************************************************************************************************************************
LOCAL h1, iPDF, sPDF, hPDF, cFileName;

        h1:=::qrcodeImage
        iPDF:= Array( 1, 1 )
        iPDF[1, 1] := h1
        sPDF:= hb_base64Decode( iPDF[1, 1] ) 
        cFileName:="C:\filesold\report\PIX_" + strzero(HB_RandomInt(1, 99999999),8,0) +'.PDF'
        hPDF := FCreate(cFileName, 0) 
        FWrite(hPDF, sPDF)                                           
        FClose(hPDF)
        WAPI_ShellExecute( NIL, "OPEN", cFileName  ,"",NIL,5 )	

RETURN Nil
************************************************************************************************************************************************************************************************************************
METHOD PrintQRCode( ) CLASS PIXClass
************************************************************************************************************************************************************************************************************************
LOCAL oPDF;
    , nTamValor;   

    if ::erro_status = WS_OK
        oPDF := PDFClass()
        IF oPDF == NIL
            hwg_msginfo("Falha da criação do objeto PDF","ATENÇÃO!!!")
            RETURN .F.
        ENDIF
        oPDF:cFileName 	:= ::cFileName
        oPDF:SetType( PDFCLASS_ROLLS )
        oPDF:nPageHeight := 200
        oPDF:Begin()
        oPDF:AddPage()
        nTamValor := (38 - (len("Valor do PIX: " + LTRIM(TRANSFORM(::nPIX_AMOUNT,"@E 999,999,999.99" ))))) /2

        oPDF:DrawText( 0 , 8, "Leia o QR Code Pix e pague" , Nil, 8, "Helvetica-Bold", Nil, Nil )
        oPDF:DrawText( 0.7, 5, "utilizando o aplicativo do seu banco." , Nil, 8, "Helvetica-Bold", Nil, Nil )

        oPDF:DrawBarcodeQRCode( 1, 5, 0.25, ::qrcode  )
        oPDF:DrawText( 13.3 , 2.5, ::cPDF_Linha1, Nil, 8, "Helvetica-Bold", 90, Nil ) 
        oPDF:DrawText( 13.3 , 35 , ::cPDF_Linha2, Nil, 8, "Helvetica-Bold", 90, Nil )
        oPDF:DrawText( 14.5, nTamValor , "Valor do PIX: " + LTRIM(TRANSFORM(VAL(::nPIX_AMOUNT),"@E 999,999,999.99" )), Nil, 10, "Helvetica-Bold", Nil, Nil ) 
        oPDF:DrawLine( 15, 0, 15, 38, 3 )
        oPDF:End(  )
        oPDF:PrintPreview( )
    ENDIF

RETURN NIL
estou usando ela para o banco EFI e paragerar sem coneccao com o banco

e para fazer a chamada eu fiz assim

Código: Selecionar todos

                ::oPIX := PIXClass( ):New( )
                ::oPIX:Setup(oSQL_FLAG:Fields( "PIX_BANCO" ):Value, ;   //  METHOD Setup(sBanco, nEnviroment, sCertificado, sClient_Id, sClient_Secret, sPIX_Key, sPIX_Receive, sPIX_City, sPIX_Amount, sPIX_Description, sPIX_Identification, sPDF_Linha1, sPDF_linha2)
                           oSQL_FLAG:Fields( "PIX_ENVIROMENT" ):Value, ;
                           oSQL_FLAG:Fields( "PIX_CERTIFICADO" ):Value, ;
                           oSQL_FLAG:Fields( "PIX_CLIENT_ID" ):Value, ;
                           oSQL_FLAG:Fields( "PIX_CLIENT_SECRET" ):Value, ;
                           oSQL_FLAG:Fields( "PIX_CHAVE" ):Value, ;
                           oSQL_FLAG:Fields( "PIX_RECEBEDOR" ):Value, ;
                           oSQL_FLAG:Fields( "PIX_CIDADE" ):Value, ;
                           LTRIM(STR(oSQL:Fields( "VALOR" ):Value,10,2)), ;
                           RTRIM(UPPER(oSQL:Fields( "FILIAL" ):Value)) , ;
                           LTRIM(TRANSFORM(oSQL:Fields( "PEDIDOS_ID" ):Value,"99999999999" )), ;
                           oSQL_FLAG:Fields( "NOMEUSUARIO" ):Value, ;
                           "Pedido: " + LTRIM(TRANSFORM(oSQL:Fields( "PEDIDOS_ID" ):Value,"99999999999" )))
                ::oPIX:Execute( )
                if ::oPIX:erro_status = 200
                    ::PIX_IMPRESSO := .T.
                    h1 := FOpen(::oPIX:cFileName)          // abre o arquivo de imagem para leitura
                    tamanho := FSeek(h1, 0, 2)           // move o ponteiro pelo arquivo até o fim para pegar o tamanho
                    FSeek(h1, 0, 0)                      // volta para o início
                    h4 := Space(tamanho)                 // declara variável para receber o conteúdo do arquivo
                    FRead(h1, @h4, tamanho)              // faz a leitura do conteúdo do arquivo jogando-a na variável de memória
                    FClose(h1)                           // fecha o arquivo
                    h4 := hb_base64Encode(h4, tamanho)   // converte o conteúdo do arquivo em base64
                    cSQL:="UPDATE pedidospagamento SET "
                    cSQL+="pedidospagamento.PIX_ID = '"  + STRZERO(::oPIX:id,10,0) + "', "
                    cSQL+="pedidospagamento.PIX_TXID = '"  + ::oPIX:txid + "', "
                    if ! empty(::oPIX:location)
                        cSQL+="pedidospagamento.PIX_LOCATION = '"  + ::oPIX:location + "', "
                    endif
                    cSQL+="pedidospagamento.PIX_QRCODE = '"  + ::oPIX:qrcode + "', "
                    cSQL+="pedidospagamento.PIX_QRCODEIMAGE = '"  + h4 + "' "
                    cSQL+="WHERE pedidospagamento.PEDIDOS_ID = '" + STRZERO(::nPEDIDOS_ID,11,0)  + "' AND pedidospagamento.TIPPGTO_ID = '17' "
                    ConeccoesClass():ExecuteSQL(::oServer, cSQL)
                    HB_GTINFO( HB_GTI_CLIPBOARDDATA, ::oPIX:cFileName)
                    ::AtivarTimer( oDlg )
                else
                    hwg_MsgInfo("REMOVA A FORMA DE PAGAMENTO"+ HB_EOL() + ;
                                "E INCLUA NOVAMENTE PARA REPETIR"+ HB_EOL() + ;
                                "A OPERAÇÃO"+ HB_EOL() + HB_EOL() + ::oPIX:erro_mensagem, "OPERAÇÃO NÃO EFETUADA!!!")
                endif
            ENDIF
teste.jpg
ai gero o PDF usando a class_PDF

Gerar Qrcode com para Pagamento de PIX

Enviado: 17 Ago 2023 09:12
por Fernando queiroz
JoséQuintas escreveu:Fernando, tem erro na sua rotina, acho que ainda não ocorreu o problema mas pode ocorrer.

Em Get_P_Value()
Usa AllTrim() pra pegar o tamanho, e adiciona o valor.
Quem garante que o tamanho vai ficar igual?
Coloque AllTrim() no valor também.

Melhor ainda: primeiro AllTrim() no valor, e depois o resto, vai ser menos fonte.
Quintas feita a correção e funcionou certinho

QRCode ja com a correção
teste.jpg

Gerar Qrcode com para Pagamento de PIX

Enviado: 19 Ago 2023 14:13
por informais
Obrigado a Todos