PIX: Gerador de Código PIX com Google Spreadsheets

Guto Martins
UXips
Published in
18 min readJun 29, 2021

Pequeno tutorial de como usei as regras sobre o PIX do Banco Central e adaptei ao Google Spreadsheet para gerar código PIX Copia e Cola.

Google Sheets + Pix

O que é o PIX?

Sabem que o PIX é a onda do momento no mundo dos Pagamentos e Recebimentos.

O Pix é uma revolucionária metodologia de transação bancária que vem para derrubar os custos para empresas com a promessa de derrubar as tarifas bancárias, mas tudo que é bom dura pouco e já temos a notícia que as cobranças via empresas serão cobradas.

Assim como DOC, TED e cartões para pessoas físicas e jurídicas, o Pix nasce como uma nova opção — com redução de custos — para quem deseja fazer transações ou fazer/receber um pagamento de modo rápido e seguro.

Por que o PIX foi criado e quem oferece o serviço?

o Banco Central se preocupou em facilitar os pagamentos e proporcionar segurança, uma vez que diminui o uso de dinheiro físico. Porém, não será o Banco Central que irá oferecer o serviço.

Assim, essa demanda fica a cargo de instituições financeiras e empresas como: fintechs, meios de pagamentos e, é claro, os bancos. Essas instituições serão responsáveis por habilitar a opção “pix” em seus aplicativos.

Quem pode usar o PIX?

Desde que tenham conta bancária em alguma instituição financeira, qualquer um pode utilizar:

  • Pessoas físicas;
  • Pessoas e empresas;
  • Empresas;
  • Pessoas e governo;
  • Empresas e governo;
  • Governo e empresas.

Como funciona o pagamento usando PIX?

Diferente de DOC e TED que você precisa informar dados da conta, no PIX, basta informar uma chave fornecida pelo beneficiário, que pode ser:

  • E-mail: fulano_da_silva.recebedor@example.com
  • CPF: 12345678900
  • CNPJ: 00038166000105
  • Número Celular: +5561912345678
  • Chave aleatória (gerada pelo seu app financeiro): 123e4567-e12b-12d1-a456–426655440000

Outra forma de pagar com PIX

Além de realizar o pagamento via Chave fornecida, também é possível pagar via leitura de QRCode e através de um código PIX Copia e Cola.

Qualquer uma das opções acima é melhor que um boleto (que leva até 3 dias para ser compensado), e via PIX os valores transferidos caem na hora e essas transações estão sempre disponíveis, 24 horas por dia, 7 dias da semana.

E com esta introdução, enfim, chegamos no assunto, o Gerador de PIX, a ideia é gerar códigos para uso com no formato PIX Copia e Cola, o código gerado é igual o modelo abaixo e é o mesmo que é convertido para QRCode.

00020126570014br.gov.bcb.pix0111811177100250220testede envio de pix52040000530398654041.235802BR5914testechave cpf6008saopaulo62070503***6304E067

O Gerador de PIX via Google Sheets

A partir daqui começa um conteúdo técnico não muito aprofundado mas para dar contexto a solução proposta.

Google Sheets com linhas e colunas preenchidas para gerar um código PIX

O Gerador de PIX foi feito baseado no modelo de código dinâmico, abaixo está uma breve explicação da diferença entre o estático e o dinâmico:

Tipos de Códigos PIX: estáticos e dinâmicos

Em se tratando de Códigos/QR Codes gerado pelo Recebedor, o PIX admite dois tipos distintos: o Código/QR Code estático e o Código/QR Code dinâmico.

Para o desenvolvimento no Google Sheets, foi usado o código dinâmico, abaixo tem uma explicação entre as diferenças dos dois:

Código Estático

O Código estático apresenta um rol de funcionalidades compacto. São apenas 4 opções de configuração.

Primeiramente, o usuário do QR estático precisa necessariamente configurá-lo com uma chave válida no DICT (Diretório de Identificadores de Contas Transacionais).

As outras 3 configurações são opcionais: identificador da transação , um campo texto livre e o valor do pagamento.

Código Dinâmico (que será usado no Sheets)

O Código dinâmico dispõe de um rol de funcionalidades abrangente. O Código dinâmico também deve ser configurado para apresentar uma chave do DICT(Diretório de Identificadores de Contas Transacionais).

Apresenta a funcionalidade de conciliação via identificador da transação e exige a configuração de valor. Além disso, oferece outras capacidades como, por exemplo, semântica de data de vencimento e configuração de campos livres estruturados.

A característica que define o Código dinâmico reside em sua flexibilidade: o Código dinâmico, em sua estrutura interna, é configurado com uma URL que é acessada no momento de sua leitura. Essa funcionalidade abre possibilidades de uso interessantes porque as informações trazidas pela URL podem variar em função de diversos parâmetros.

A URL também cumpre o papel de reduzir a quantidade de dados codificados diretamente na imagem: o Código dinâmico contém somente as informações básicas do recebedor. O restante das informações é obtido em um webservice do PSP do recebedor com base nessa URL.

Ressalte-se que essa URL do Código dinâmico não se confunde com a iniciação por URL/link prevista no arranjo, detalhada em seção específica neste anexo. Admite-se, a critério do recebedor, que uma mesma URL seja reutilizada para vários pagamentos.

A parte efetivamente dinâmica é o conteúdo acessado através da URL (o payload complementar, em formato JSON). Desta forma, um mesmo Código Code dinâmico poderia ser utilizado para iniciar vários pagamentos com detalhes específicos diferentes, obtidos em diferentes acessos à mesma URL, variando de acordo com alguma lógica de negócio arbitrária.

fonte: Especificação PIX

Campos do Código Dinâmico retirado do Doc do Bacen.

Então vamos entender a formatação do Código PIX Dinâmico de Pagamento

Exemplo de Código PIX:

00020126570014br.gov.bcb.pix0111811177100250220testede envio de pix52040000530398654041.235802BR5914testechave cpf6008saopaulo62070503***6304E067

O código de pagamento é um campo de texto alfanumérico (A-Z,0–9) permitindo os caracteres especiais $ % * + - . / :.

Na estrutura EMV® os dois primeiros dígitos representam o código ID do emv e os dois dígitos seguintes contendo o tamanho do campo. O conteúdo do campo são os caracteres seguintes até a quantidade de caracteres estabelecida.

EMV®2 QRCPS — QRCode Specification for Payment Systems — QR Code para Sistemas de Pagamento. Trata-se de padrão aberto e gratuito, extensível, implementado em ecossistemas de outros países, que comporta os requisitos do sistema brasileiro com potencial para integração de esquemas existentes, favorecendo a adoção, reuso e otimização de recursos.

Exemplos de código EMV

No código 000200 temos:

  • 00 Código EMV 00 que representa o Payload Format Indicator;
  • 02 Indica que o conteúdo deste campo possui dois caracteres;
  • 00 O conteúdo deste campo é 00.

No código 5303986 temos:

  • 53 Código EMV 53 que indica a Transaction Currency, ou seja: a moeda da transação.
  • 03 Indica que o tamanho do campo possui três caracteres;
  • 986 Conteúdo do campo é 986, que é o código para BRL: real brasileiro na ISO4217.

No código 5802BR temos:

  • 58 Código EMV 58 que indica o Country Code.
  • 02 Indica que o tamanho do campo possui dois caracteres;
  • BR Conteúdo do campo é BR, que é o código do país Brasil conforme ISO3166-1 alpha 2.

Especificades do BR Code

BR Code é o padrão único para QR Codes a serem usados nos meios de pagamento no País.

O Pix utiliza o padrão BR Code do banco central, em especial os campos de ID 26 a 51. Esses campos possuem filhos que seguem o mesmo padrão do EMV explicado acima.

Exemplos BR Code

Observe o código: 26580014br.gov.bcb.pix013642a57095-84f3-4a42-b9fb-d08935c86f47, nele há:

  • 26 Código EMV 26 que representa o Merchant Account Information.
  • 58 Indica que o tamanho do campo possui 58 caracteres.
  • Demais caracteres representam o conteúdo do campo 0014br.gov.bcb.pix013642a57095-84f3-4a42-b9fb-d08935c86f47.

Nele, temos dois filhos:

O primeiro é 0014br.gov.bcb.pix:

  • 00 ID 00 representa o campo GUI do BRCode (obrigatório).
  • 14 Indica que o tamanho do campo possui 14 caracteres.
  • br.gov.bcb.pix é conteúdo do campo.

O segundo é 013642a57095-84f3-4a42-b9fb-d08935c86f47:

  • 01 O ID 01 representa a chave PIX, que pode ser uma chave aleatória (EVP), e-mail, telefone, CPF ou CNPJ.
  • 36 Indica que o tamanho do campo possui 36 caracteres.
  • 42a57095-84f3-4a42-b9fb-d08935c86f47 indica a chave pix do destinatário, no caso a chave em questão está no formato UUID que é uma chave aleatória (EVP).

Depois dessa introdução sobre o que é o PIX, vamos entrar no projeto

Como gerar código PIX e enviar por e-mail para o destinatário via Planilha Google

Planilha Google para Cobrança PIX

O Google Sheets vem com uma linguagem baseada em JavaScript chamada Apps Script. Neste tutorial, usaremos o Apps Script para gerar um código PIX Copia e Cola e disparar o email para o destinatário. As etapas levam menos de dez minutos para serem concluídas, mesmo que você nunca tenha escrito uma linha de código.

Vá para seu Google Sheets e crie uma nova planilha. Na primeira linha, crie o cabeçalho das coluna conforme os campos abaixo:

CHAVE PIXDESCRIÇÃO DO PAGAMENTONOME DO BENEFICIADOCIDADEVALOR (R$)E-MAILAÇÃOCÓDIGO PIXPAGAMENTO

abaixo tem uma breve explicação dos campos:

Campos Usados para gerar o código PIX

Para gerar o código PIX, formatei a planilha com os seguites campos:

Campos para Gerar o código PIX
  • Chave (Pode ser, CPF, CNPJ, Celular ou Chave Aleatória)
  • Descrição do Pagamento
  • Nome do Beneficiado
  • Cidade
  • Valor (R$)

Campos Extras Para Envio de E-mail e Feedbacks:

os campos extras são usados para envio da cobrança via pix e feedbacks das ações executadas:

Campos extras para gerar o código e enviar via email
  • E-mail (para o destino que receberá o link do PIX)
  • Ação (Campo dropdown para fazer o envio do email)
  • Código PIX (atualizado após o envio do email com o código enviado)
  • Pagamento (campo dropdown atualizado automaticamente após o envio com a opção aguardando e tem mais duas opções pago e cancelado)

Campos Select (DropDown) usando Validação de Dados

As colunas AÇÃO e PAGAMENTO, você irá criar uma validação de dados, clique na segunda linha da coluna AÇÃO e em seguida no menu Dados e Validação de Dados:

Abra o Menu Dados e em seguinda clique em Validação de Dados

Em validação de Dados, você irá definir uma lista de itens para gerar o menu Select (DropDown) da célula, então no campo Critérios, selecione Lista de itens e ao lado preencha com: ENVIAR EMAIL, ENVIADO COM SUCESSO, FALHA NO ENVIO, separados por vírgula:

Item Critérios, selecione Lista de itens e preencha o campo ao lado separando cada item com vírgula.

O resultado da célula será o abaixo:

Célula da coluna Ação

Siga os passos acima para a coluna PAGAMENTO e preencha a Lista de itens com: AGUARDANDO, PAGO, CANCELADO, então a célula ficará conforme abaixo:

Célula da coluna Pagamento

Agora vamos realizar a formatação condicional, para dar ênfase nas mudanças do select tanto de AÇÃO como de PAGAMENTO.

Selecione a linha dois da coluna de AÇÃO e clique no menu Formatar e em seguida Formatação Condicional.

Menu Formatar e Formatação condicional

Irá aparecer na lateral da tela o box com as configurações possíveis, clique em formatar célula e selecione a opção "O texto contém", defina no campo abaixo o texto, no exemplo abaixo: ENVIADO COM SUCESSO e logo abaixo no Estilo de Formatação, selecione a cor.

Box de Regra de Formatação

Para as outras opções do campo AÇÃO e PAGAMENTO, faça uma formatação condicional para os outros textos seguindo a instrução acima e cada opção ficará com uma cor conforme abaixo:

Opções da Coluna AÇÃO com formatação feita

Na coluna AÇÃO, a opção ENVIAR EMAIL, não precisa ter formatação condicional.

Abaixo são as formatações aplicadas na coluna PAGAMENTO

Opções da coluna PAGAMENTO com formatação feita

Ok, após ter feito estas configurações tanto na coluna AÇÃO como na coluna PAGAMENTO, é hora de replicar as configurações para as células abaixo dela, copie a célula configurada e cole nas linhas abaixo, até o final da planilha.

Configuração da planilha concluída, vamos adicionar os scripts para gerar o código PIX Copie e Cola.

Adicionando Scripts na Planilha

Ok, agora que configuramos a planilha, é hora de adicionarmos os scripts.

Importante: Neste tutorial, não irei focar em desenvolvimento de código, o foco é qualquer um criar esta planilha sem precisar programar e sim configurar o Google Sheets para realizar esta automatização.

Para isso, clique em Extensão e em seguida Apps Script, conforme abaixo:

Menu Extensões e em seguida Apps Script

Irá abrir uma nova tela para adicionar os scripts em sua planilha, conforme abaixo:

Tela do Apps Script do Google

Para realizar este Gerador de PIX, o arquivo Código.gs foi renomeado para enviarEmail.gs e em seguida criado um novo arquivo chamado pix.gs.

Arquivos enviarEmail.gs e pix.gs

O script enviarEmail.gs é o que faz contato com a planilha, pega os dados da linha solicitada, valida esses dados, envia para o script pix.gs gerar o código PIX e retorna com o envio do email e o código gerado.

Selecione o arquivo enviarEmail.gs e adicione o seguinte código:

function enviarEmail(e){   var EMAIL_SENT = "ENVIADO COM SUCESSO";  // Capture the cells value after it is edited
var EMAIL_FAIL = "FALHA NO ENVIO"; // Capture the cells value after it is edited
var assunto = 'Pagamento por PIX'; //subject mail
var txid = "***"; //txid always with ***
var valCell = e.value; //value to dropdown send mail
//var valCell = 'ENVIAR EMAIL'; //value to debug
var columnIndex = 6; // total columns to edit
var activeSheet = SpreadsheetApp.getActiveSheet();
var data = activeSheet.getDataRange().getValues();
var range = activeSheet.getActiveRange(); //Get the range of the cell
var startRow = range.getRow();
//var headings = activeSheet.getDataRange().offset(0, 0, 1).getValues()[0]; //get line header from sheet
var emailAddress = activeSheet.getRange(startRow, columnIndex, 1, 1).getValues().toString(); //get email to send
var emailCopy = ''; //optional send copy mail
var replyEmail =''; //optional send reply mail
var body = ""; //body mail
if (valCell == 'ENVIAR EMAIL') { //var valueHeader = activeSheet.getRange(1, 1, 1, columnIndex).getValues(); //get header var dataRange = activeSheet.getRange(startRow, 1, 1, columnIndex); var data = dataRange.getValues(); // Fetch values for each row in the Range. var headBody = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="x-apple-disable-message-reformatting"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta name="color-scheme" content="light dark"/> <meta name="supported-color-schemes" content="light dark"/> <title></title> <style type="text/css" rel="stylesheet" media="all"> /* Base ------------------------------ */ @import url("https://fonts.googleapis.com/css?family=Nunito+Sans:400,700&display=swap"); body{width: 100% !important; height: 100%; margin: 0; -webkit-text-size-adjust: none;}a{color: #3869D4;}a img{border: none;}td{word-break: break-word;}.preheader{display: none !important; visibility: hidden; mso-hide: all; font-size: 1px; line-height: 1px; max-height: 0; max-width: 0; opacity: 0; overflow: hidden;}/* Type ------------------------------ */ body, td, th{font-family: "Nunito Sans", Helvetica, Arial, sans-serif;}h1{margin-top: 0; color: #333333; font-size: 22px; font-weight: bold; text-align: left;}h2{margin-top: 0; color: #333333; font-size: 16px; font-weight: bold; text-align: left;}h3{margin-top: 0; color: #333333; font-size: 14px; font-weight: bold; text-align: left;}td, th{font-size: 16px;}p, ul, ol, blockquote{margin: .4em 0 1.1875em; font-size: 16px; line-height: 1.625;}p.sub{font-size: 13px;}/* Utilities ------------------------------ */ .align-right{text-align: right;}.align-left{text-align: left;}.align-center{text-align: center;}/* Buttons ------------------------------ */ .button{background-color: #3869D4; border-top: 10px solid #3869D4; border-right: 18px solid #3869D4; border-bottom: 10px solid #3869D4; border-left: 18px solid #3869D4; display: inline-block; color: #FFF; text-decoration: none; border-radius: 3px; box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16); -webkit-text-size-adjust: none; box-sizing: border-box;}.button--green{background-color: #22BC66; border-top: 10px solid #22BC66; border-right: 18px solid #22BC66; border-bottom: 10px solid #22BC66; border-left: 18px solid #22BC66;}.button--red{background-color: #FF6136; border-top: 10px solid #FF6136; border-right: 18px solid #FF6136; border-bottom: 10px solid #FF6136; border-left: 18px solid #FF6136;}@media only screen and (max-width: 500px){.button{width: 100% !important; text-align: center !important;}}/* Attribute list ------------------------------ */ .attributes{margin: 0 0 21px;}.attributes_content{background-color: #F4F4F7; padding: 16px;}.attributes_item{padding: 0;}/* Related Items ------------------------------ */ .related{width: 100%; margin: 0; padding: 25px 0 0 0; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0;}.related_item{padding: 10px 0; color: #CBCCCF; font-size: 15px; line-height: 18px;}.related_item-title{display: block; margin: .5em 0 0;}.related_item-thumb{display: block; padding-bottom: 10px;}.related_heading{border-top: 1px solid #CBCCCF; text-align: center; padding: 25px 0 10px;}/* Discount Code ------------------------------ */ .discount{width: 100%; margin: 0; padding: 24px; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0; background-color: #F4F4F7; border: 2px dashed #CBCCCF;}.discount_heading{text-align: center;}.discount_body{text-align: center; font-size: 15px;}/* Social Icons ------------------------------ */ .social{width: auto;}.social td{padding: 0; width: auto;}.social_icon{height: 20px; margin: 0 8px 10px 8px; padding: 0;}/* Data table ------------------------------ */ .purchase{width: 100%; margin: 0; padding: 35px 0; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0;}.purchase_content{width: 100%; margin: 0; padding: 25px 0 0 0; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0;}.purchase_item{padding: 10px 0; color: #51545E; font-size: 15px; line-height: 18px;}.purchase_heading{padding-bottom: 8px; border-bottom: 1px solid #EAEAEC;}.purchase_heading p{margin: 0; color: #85878E; font-size: 12px;}.purchase_footer{padding-top: 15px; border-top: 1px solid #EAEAEC;}.purchase_total{margin: 0; text-align: right; font-weight: bold; color: #333333;}.purchase_total--label{padding: 0 15px 0 0;}body{background-color: #F4F4F7; color: #51545E;}p{color: #51545E;}p.sub{color: #6B6E76;}.email-wrapper{width: 100%; margin: 0; padding: 0; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0; background-color: #F4F4F7;}.email-content{width: 100%; margin: 0; padding: 0; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0;}/* Masthead ----------------------- */ .email-masthead{padding: 25px 0; text-align: center;}.email-masthead_logo{width: 94px;}.email-masthead_name{font-size: 16px; font-weight: bold; color: #A8AAAF; text-decoration: none; text-shadow: 0 1px 0 white;}/* Body ------------------------------ */ .email-body{width: 100%; margin: 0; padding: 0; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0; background-color: #FFFFFF;}.email-body_inner{width: 570px; margin: 0 auto; padding: 0; -premailer-width: 570px; -premailer-cellpadding: 0; -premailer-cellspacing: 0; background-color: #FFFFFF;}.email-footer{width: 570px; margin: 0 auto; padding: 0; -premailer-width: 570px; -premailer-cellpadding: 0; -premailer-cellspacing: 0; text-align: center;}.email-footer p{color: #6B6E76;}.body-action{width: 100%; margin: 30px auto; padding: 0; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0; text-align: center;}.body-sub{margin-top: 25px; padding-top: 25px; border-top: 1px solid #EAEAEC;}.content-cell{padding: 35px;}/*Media Queries ------------------------------ */ @media only screen and (max-width: 600px){.email-body_inner, .email-footer{width: 100% !important;}}@media (prefers-color-scheme: dark){body, .email-body, .email-body_inner, .email-content, .email-wrapper, .email-masthead, .email-footer{background-color: #333333 !important; color: #FFF !important;}p, ul, ol, blockquote, h1, h2, h3, span, .purchase_item{color: #FFF !important;}.attributes_content, .discount{background-color: #222 !important;}.email-masthead_name{text-shadow: none !important;}}:root{color-scheme: light dark; supported-color-schemes: light dark;}</style><!--[if mso]> <style type="text/css"> .f-fallback{font-family: Arial, sans-serif;}</style><![endif]--> </head> <body> <table class="email-wrapper" width="100%" cellpadding="0" cellspacing="0" role="presentation"> <tr> <td align="center"> <table class="email-content" width="100%" cellpadding="0" cellspacing="0" role="presentation"> <tr> <td class="email-masthead"> <a href="#" class="f-fallback email-masthead_name"> Pagamento por PIX </a> </td></tr><tr> <td class="email-body" width="100%" cellpadding="0" cellspacing="0"> <table class="email-body_inner" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation"> <tr> <td class="content-cell"> <div class="f-fallback">'; var footBody = '</span></td></tr></table> </td></tr></table><p>Este código pode ser utilizado para mais de um pagamento</p><table class="body-action" align="center" width="100%" cellpadding="0" cellspacing="0" role="presentation"> <tr> <td align="center"> </td></tr></table> <table class="body-sub" role="presentation"><tr><td><p>Pagar com PIX é rápido e fácil.</p><ol><li>Abra o aplicativo do seu banco ou empresa de pagamento</li><li>Copie e Cole o Código PIX acima em seu aplicativo </li><li>Confirme as informações e realize o pagamento</li></ol> </td></tr></table> </div></td></tr></table> </td></tr><tr> <td> <table class="email-footer" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation"> <tr> <td class="content-cell" align="center"> <p class="f-fallback sub align-center">&copy; 2021 Gerador de Cobrança PIX.<br>Pix powered by Banco Central</p><p class="f-fallback sub align-center"> Guto Martins <br><a href="https://linkedin.com/in/joseaugustomartins" class="f-fallback">linkedin</a> </p></td></tr></table> </td></tr></table> </td></tr></table> </body></html>';for (i in data) { var chavePix = _clearKey(data[i][0]);
var descPix = data[i][1].toString();
var namePix = data[i][2].toString();
var cityPix = data[i][3].toString();
var idPix = txid.toString();
var valuePix = data[i][4].toString();
var emailPix = data[i][5].toString();
const pix = new Pix(
chavePix,
descPix,
namePix,
cityPix,
idPix,
valuePix
);
const payload = pix.getPayload();
var body = '<h1>Olá, '+emailPix+' ,</h1> <p>Aqui é <strong>'+namePix+'</strong>, estou enviado este código PIX para você realizar o pagamento do valor abaixo.</p><table width="100%" border="0" cellspacing="0" cellpadding="0" role="presentation"> <tr> <td align="center"> <p class="f-fallback button button--green" target="_blank"><strong>Valor: R$ '+valuePix+'</strong></p></td></tr><tr><td align="center"><p><strong>código PIX Copia e Cola</strong></p></td></tr></table> <table class="attributes" width="100%" cellpadding="0" cellspacing="0" role="presentation"> <tr> <td class="attributes_content"> <table width="100%" cellpadding="0" cellspacing="0" role="presentation"> <tr> <td class="attributes_item"> <span class="f-fallback">'+payload+''; var resultHtml = headBody+body+footBody; // Concatenate html if (valCell != EMAIL_SENT) { // Prevents sending duplicates if (checkMail(emailAddress) != null){ // Prevents invalid email MailApp.sendEmail(emailAddress,assunto,resultHtml,{name:"Pagamento de PIX", bcc:emailCopy,noReply:true, replyTo:replyEmail, htmlBody:resultHtml}); //send mail activeSheet.getRange(startRow, 7).setValue(EMAIL_SENT); //update cell with email sent }else{ activeSheet.getRange(startRow, 7).setValue(EMAIL_FAIL); //update cell with email fail } activeSheet.getRange(startRow, 8).setValue(payload); //update row column 8 with code PIX activeSheet.getRange(startRow, 9).setValue('AGUARDANDO'); //update row column 9 with AGUARDANDO PAGAMENTO SpreadsheetApp.flush(); // Make sure the cell is updated right away in case the script is interrupted } } }}function _removeAccent(valueText){//remove accent and space var textSpace = valueText.replace(" ","");
var on_accent = 'öüóőúéáàűíÖÜÓŐÚÉÁÀŰÍçÇ';
var off_accent = 'ouooueaauiOUOOUEAAUIcC';
var idoff = -1, new_text = '';
var lentext = textSpace.toString().length -1
for (i = 0; i <= lentext; i++) {
idoff = on_accent.search(textSpace.charAt(i));
if ( idoff == -1) {
new_text = new_text + textSpace.charAt(i);
} else {
new_text = new_text + off_accent.charAt(idoff);
}
}
var removeSpace = new_text.replace(/\s/g, "");
return removeSpace;
}
function _clearKey(value){//Clear Key CPF/CPNJ PHONE
var valueNew = value;
if (valueNew.match(/^([0-9]{3}\.?[0-9]{3}\.?[0-9]{3}\-?[0-9]{2}|[0-9]{2}\.?[0-9]{3}\.?[0-9]{3}\/?[0-9]{4}\-?[0-9]{2})$/) != null){
valueNew = valueNew.replace(/[^0-9]+/g, "");
//Logger.log("CPF/CPNJ "+valueNew);
}else if(valueNew.match(/(([(]?[0-9]{1,3}[)]?)|([(]?[0-9]{4}[)]?))\s*[)]?[-\s\.]?[(]?[0-9]{1,3}[)]?([-\s\.]?[0-9]{3})([-\s\.]?[0-9]{3,5})/) != null){
valueNew = "+55"+valueNew.replace(/[^0-9]+/g, "");
//Logger.log("FONE "+valueNew);
}else{
//Logger.log("OTHERS "+valueNew);
return valueNew;
}
return valueNew;}function checkMail(value){//function validate mail to send or fail var getEmail = value.match(/^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()\.,;\s@\"]+\.{0,1})+[^<>()\.,;:\s@\"]{2,})$/); return getEmail;}

Em seguida, clique me pix.gs e adicione o código abaixo:

/* source: https://github.com/gab618/pix-js */class Pix {constructor(pixKey, description, merchantName, merchantCity, txid, amount) {this.pixKey = pixKey;this.description = description;this.merchantName = merchantName;this.merchantCity = merchantCity;this.txid = txid;this.amount = amount;//this.amount = amount.toFixed(2);this.ID_PAYLOAD_FORMAT_INDICATOR = "00";this.ID_MERCHANT_ACCOUNT_INFORMATION = "26";this.ID_MERCHANT_ACCOUNT_INFORMATION_GUI = "00";this.ID_MERCHANT_ACCOUNT_INFORMATION_KEY = "01";this.ID_MERCHANT_ACCOUNT_INFORMATION_DESCRIPTION = "02";this.ID_MERCHANT_CATEGORY_CODE = "52";this.ID_TRANSACTION_CURRENCY = "53";this.ID_TRANSACTION_AMOUNT = "54";this.ID_COUNTRY_CODE = "58";this.ID_MERCHANT_NAME = "59";this.ID_MERCHANT_CITY = "60";this.ID_ADDITIONAL_DATA_FIELD_TEMPLATE = "62";this.ID_ADDITIONAL_DATA_FIELD_TEMPLATE_TXID = "05";this.ID_CRC16 = "63";}_getValue(id, value) {const size = String(value.length).padStart(2, "0");return id + size + value;}_getMechantAccountInfo() {const gui = this._getValue(this.ID_MERCHANT_ACCOUNT_INFORMATION_GUI,"br.gov.bcb.pix");const key = this._getValue(this.ID_MERCHANT_ACCOUNT_INFORMATION_KEY,this.pixKey);const description = this._getValue(this.ID_MERCHANT_ACCOUNT_INFORMATION_DESCRIPTION,this.description);return this._getValue(this.ID_MERCHANT_ACCOUNT_INFORMATION,gui + key + description);}_getAdditionalDataFieldTemplate() {const txid = this._getValue(this.ID_ADDITIONAL_DATA_FIELD_TEMPLATE_TXID,this.txid);return this._getValue(this.ID_ADDITIONAL_DATA_FIELD_TEMPLATE, txid);}getPayload() {const payload =this._getValue(this.ID_PAYLOAD_FORMAT_INDICATOR, "01") +this._getMechantAccountInfo() +this._getValue(this.ID_MERCHANT_CATEGORY_CODE, "0000") +this._getValue(this.ID_TRANSACTION_CURRENCY, "986") +this._getValue(this.ID_TRANSACTION_AMOUNT, this.amount) +this._getValue(this.ID_COUNTRY_CODE, "BR") +this._getValue(this.ID_MERCHANT_NAME, this.merchantName) +this._getValue(this.ID_MERCHANT_CITY, this.merchantCity) +this._getAdditionalDataFieldTemplate();return payload + this._getCRC16(payload);}_getCRC16(payload) {function ord(str) {return str.charCodeAt(0);}function dechex(number) {if (number < 0) {number = 0xffffffff + number + 1;}return parseInt(number, 10).toString(16);}//ADICIONA DADOS GERAIS NO PAYLOADpayload = payload + this.ID_CRC16 + "04";//DADOS DEFINIDOS PELO BACENlet polinomio = 0x1021;let resultado = 0xffff;let length;//CHECKSUMif ((length = payload.length) > 0) {for (let offset = 0; offset < length; offset++) {resultado ^= ord(payload[offset]) << 8;for (let bitwise = 0; bitwise < 8; bitwise++) {if ((resultado <<= 1) & 0x10000) resultado ^= polinomio;resultado &= 0xffff;}}}//RETORNA CÓDIGO CRC16 DE 4 CARACTERESreturn this.ID_CRC16 + "04" + dechex(resultado).toUpperCase();}};

Feito, clique em salvar ou crtl+S (win) ou command + s (mac) e por último vamos criar uma triggers(acionador), que tem a função de executar o script de acordo com a regra que você definir no acionador.

Neste caso o acionador irá disparar sempre que houver uma edição na planilha.

Para isso, clique em acionadores no canto da página e em seguida adicionar acionador.

Botão acionadores no canto esquerdo e em seguida no canto direito adicionar acionador, irá aparecer esta tela central

Então basta preencher os campos conforme a imagem acima, selecionar função enviarEmail, selecionar origem, da planilha e selecionar evento ao Editar.

O aviso de falha pode deixar como já aparece e clique em salvar.

Todas as configurações realizadas, preencha os campos para gerar o PIX e clique em ENVIAR EMAIL na coluna AÇÃO.

preencha os campos e clique em ação na opção ENVIAR EMAIL

Após o envio, a pessoa irá receber o seguinte template de email:

E-mail de cobrança que o destinatário recebe

Finalmente concluímos o Gerador de PIX Copia e Cola.

O que aprendi com isso

  • Durante o desenvolvimento, descobri necessidades de tratamentos, como tratar a chave pix quando é CPF/CNPJ e telefone, pois de acordo com a documentação do Banco Central, estas chaves não tem caracteres especiais, são somente números.
  • O campo cidade não deve ter caracteres especiais e a descrição e nome do beneficiado, tive que remover os espaçamentos para funcionar.
  • Também senti necessidade de dar feedback quando se cadastra um email em um formato errado, mas não consigo fazer tratamento quando colocam um email que não existe, por exemplo test@test1234.com.
  • Outro feedback que achei interessante colocar foi o código PIX gerado e o aviso de aguardando pagamento e a alteração para PAGO ou CANCELADO é manual, pois não temos feedback do pagamento realizado.

O que pode ser melhorado

  • Acredito que seja possível uma versão para enviar o código PIX via WhatsApp
  • Também ser possível gerar um QR Code do código PIX
  • Possivelmente transformar em um sistema de cobrança recorrente, todo dia X de cada mês disparar uma cobrança
  • Adicionar prazo de vencimento no código PIX

Fontes do conteúdo

Sobre mim

Sou Guto Martins, entusiasta sobre tecnologia, ux e ui, sempre buscando maneiras de obter conhecimento e melhorar a experiência de produtos.

Não deixe de comentar e curtir o conteúdo, isso me incentiva a escrever mais e caso queira me seguir, utilize este link: https://bit.ly/gutomartins

💡 Sabe como usar AI Prompts?

Simplifique suas tarefas repetitivas com templates de AI Prompts para ChatGPT e DALL-E na plataforma Uprompt.

Basta se cadastrar gratuitamente na nossa plataforma, selecionar entre centenas de prompts que você precisa e gerar resultados.

Confira em www.uprompt.com.br.

--

--