-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Melhorias no Parser, Payload e criação da classe Reader para extrair …
…dados de um código Pix
- Loading branch information
1 parent
746d8d2
commit 7c5787d
Showing
11 changed files
with
901 additions
and
111 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,12 +6,36 @@ O **Pix** é o mais novo método de pagamento eletrônico criado pelo **Banco Ce | |
|
||
Essa biblioteca foi criada para ser utilizada principalmente com o plugin de **Woocommerce** [Pix por Piggly](https://wordpress.org/plugins/pix-por-piggly/). Mas, pode ser utilizada em qualquer sistema onde seja necessário a criação de payloads, códigos e QRCodes Pix. | ||
|
||
Se você apreciar a função desta biblioteca e quiser apoiar este trabalho, sinta-se livre para fazer qualquer doação para a chave aleatória Pix `aae2196f-5f93-46e4-89e6-73bf4138427b` ❤. | ||
> Confira também nossa micro interface pix em [piggly/php-pix-app](https://github.com/piggly-dev/php-pix-app) | ||
> Se você apreciar a função desta biblioteca e quiser apoiar este trabalho, sinta-se livre para fazer qualquer doação para a chave aleatória Pix `aae2196f-5f93-46e4-89e6-73bf4138427b` ❤. | ||
## Instalação | ||
|
||
Essa biblioteca pode ser instalada via **Composer** com `composer require piggly/php-pix`; | ||
|
||
### Atualização das versões 1.0.* para 1.1.0 | ||
|
||
Nenhum método foi alterado ou removido. As mesmas funções foram mantiadas, apenas a lógica interna de determinados métodos foram melhoradas e novas classes e recursos foram acoplados. A migração pode ser realizada tranquilamente e sem problemas. Algumas coisas que mudaram: | ||
|
||
* Se você utiliza os métodos `validate*()` do `Parser` para validar individualmente os tipos das chaves Pix, esses métodos não retornam mais uma `Exception`, mas um `boolean`. Somente o método `validate()` continua retornando uma `Exception`. Confira a mudança da código abaixo: | ||
|
||
```php | ||
// !! ANTES | ||
Parser::validateDocument($cpf); | ||
// -> trazia uma excessão e interrompia a reprodução do código. | ||
|
||
// !! AGORA | ||
$valid = Parser::validateDocument($cpf); | ||
// -> você precisa tratar excessões manualmente | ||
if ( !$valid ) | ||
{ throw new Exception('A chave de CPF/CNPJ não é válida.'); } | ||
|
||
// !! O MÉTODO VALIDATE() AINDA TRAZ EXCESSÕES | ||
Parser::validate($pixKeyType,$pixKey); | ||
// -> irá interromper o código se a chave não for válida. | ||
``` | ||
|
||
## Como o Pix funciona? | ||
|
||
De acordo com o [Manual do BR Code](https://www.bcb.gov.br/content/estabilidadefinanceira/SiteAssets/Manual%20do%20BR%20Code.pdf) e todas as [Especificações Técnicas](https://www.bcb.gov.br/content/estabilidadefinanceira/forumpireunioes/Anexo%20I%20-%20QRCodes%20-%20Especifica%C3%A7%C3%A3o%20-%20vers%C3%A3o%201-1.pdf), o Pix implmentado pelo Banco Central do Brasil adota todas as proposta do padrão EMV®1. As principais funções que essa biblioteca executa, são: | ||
|
@@ -21,11 +45,11 @@ De acordo com o [Manual do BR Code](https://www.bcb.gov.br/content/estabilidadef | |
|
||
### Padrão EMV®1 | ||
|
||
Por padrão, o **BR Code** utiliza apenas caracteres alfanuméricos, identificado pelo seguinte regex `[A-Za-z0-9\$\%\*\+\-\.\/\ ]`. A estrutura do código EMV®1 é composta por três conjuntos de caracteres: | ||
Por padrão, o **BR Code** utiliza apenas caracteres alfanuméricos, identificado pelo seguinte regex `[A-Za-z0-9\$\%\*\+\-\.\/\ \@]`. A estrutura do código EMV®1 é composta por três conjuntos de caracteres: | ||
|
||
1. ID `[\d]{2}`; | ||
2. Tamanho em caracteres do conteúdo `[\d]{2}`; | ||
3. Conteúdo `[A-Za-z0-9\$\%\*\+\-\.\/\ ]`. | ||
3. Conteúdo `[A-Za-z0-9\$\%\*\+\-\.\/\ \@]`. | ||
|
||
#### Exemplos | ||
|
||
|
@@ -39,46 +63,85 @@ O código `000200`, representa: | |
|
||
Cada campo **EMV®1** contém suas especificações, entre elas o tamanho do campo permitido, caracteres permitidos e afins. Além das chaves terem os tipos pré-definidos como: Chave Aleatória, CPF/CNPJ, E-mail e Telefone. Todas as validações são feitas por essa biblioteca: | ||
|
||
* Conteúdo do campo como `[A-Za-z0-9\$\%\*\+\-\.\/\ ]`; | ||
* Conteúdo do campo como `[A-Za-z0-9\$\%\*\+\-\.\/\ \@]`; | ||
* Chave aleatória no formato `uuid`; | ||
* Chave de CPF/CNPJ com um valor válido e apenas `numérico`; | ||
* Chave de E-mail com um valor válido e substituindo `@` por ` ` espaço; | ||
* Chave de E-mail com um valor válido; | ||
* Chave de Telefone com um valor válido e apenas `numérico`. | ||
|
||
> Alguns bancos podem ou não aceitar o caractere `@` para Chaves de E-mail. Atualizamos o plugin para ativar a substituição do `@` por espaço no e-mail `$pix->applyEmailWhitespace()` sinta-se livre para fazer os testes com a sua chave pix. | ||
### Classe `Parser` | ||
|
||
A classe `Parser` apresenta todos os métodos como `static` e segue o seguinte formato: | ||
|
||
* Métodos com `validate` validam se o valor da chave é compatível com o formato esperado por seu tipo, retornando `Exception` quando inválido; | ||
* Métodos com `validate` validam se o valor da chave é compatível com o formato esperado por seu tipo, retornando `true` quando verdadeiro e `false` quando inválido; | ||
* Métodos com `parse` apenas tratam os campos retirando todos os caracteres inválidos para serem utilizando, também seguindo o tipo da chave; | ||
* O método `validate()` que recebe a chave e o tipo da chave retornando uma `Exception` quando a chave/tipo forem incompatíveis ou inválidos; | ||
* O método `getKeyType()` traduz a chave recebida para um dos tipos correspondentes. Trará uma `Exception` se nenhum tipo válido for identificado; | ||
* O método `getAlias()` retorna a `label` conforme o tipo de chave. Por exemplo, ao receber `Parser::KEY_TYPE_RANDOM` retorna `Chave Aleatória`. | ||
|
||
### Classe `Payload` | ||
|
||
A classe `Payload` é responsável por montar o payload do Pix e segute o seguinte formato: | ||
|
||
* O método `applyEmailWhitespace()` determina que o `@` deve ser substituido por um espaço; | ||
* O método `applyValidCharacters()` determina que acentos e caracteres inválidos como `[\!\.\,\@\#\$\%\&\*\(\)\/\*\?]` deve ser removidos/substituídos nos campos do Pix. Esse efeito é aplicado em `description`, `merchantName`, `merchantCity` e `tid`; | ||
* * O método `applyUppercase()` transformas todos os caracteres dos campos em maiúsculo. Esse efeito é aplicado em `description`, `merchantName`, `merchantCity` e `tid`; | ||
* Métodos com `set` determinam valores para os atributos do Pix; | ||
* O método `getPixCode()` retorna o código Pix em formato de texto, agora pode ser enviado o `Payload::OUTPUT_SVG` ou `Payload::OUTPUT_PNG` para o formato de saída do QR Code; | ||
* O método `getQRCode` returna uma `string` no formato PNG `data:image/png;base64` e no formato SVG uma HTML tag. | ||
* O método `getPixCode()` retorna o código Pix em formato de texto; | ||
* O método `getQRCode()` retorna uma `string` formatada em `base64`. A saída pode ser controlada com os valores `Payload::OUTPUT_*` para o formato de saída do QR Code e, também, os valores `Payload::ECC_*` para controlar as porcentagens de perca de dados do QR Code. | ||
|
||
### Classe `Reader` | ||
|
||
> Cada banco determina as informações que a chave Pix terá. Nesses casos, quando o pix é configurado com informações incorretas, podem haver uma série de problemas de compatibilidade. Por conta disso, criamos essa classe. | ||
A classe `Reader` nasceu para ser um tradutor dos códigos pix. O objetivo é ler um código Pix gerado por determinado banco e extrair os seguintes dados: _Chave Pix, Tipo da Chave, Descrição, ID da Transação, Nome do Titular, Cidade e Valor_. | ||
|
||
> A classe é automática, ou seja, ao criar uma nova instância ela já irá extrair todos os dados do código Pix. | ||
* Métodos com `get` determinam valores que podem ser obtidos do código Pix; | ||
* O método `extract()` executa novamente a extração dos dados de um outro código Pix, por exemplo. | ||
|
||
> Você pode utilizar esses dados para, a partir de uma chave matriz, gerar um código Pix novo com a classe `Payload`. Assim cada dado será extraído de uma chave válida e não preenchido manualmente evitando erros e incompatíbilidades. | ||
### Os atributos do Pix | ||
|
||
> Somente os campos `description` e `tid` continuam a conter limitações de caracteres devido a muitas incompatibilidades que estavam surgindo. | ||
Os atributos **obrigatórios** do Pix são: | ||
|
||
* `Pix Key` alterado pelo método `setPixKey()` com o tipo e o valor da chave Pix; | ||
* `Merchant Name` alterado pelo método `setMerchantName()` com o nome do titular da conta como conta no banco. O tamanho máximo de caracteres foi retirado. | ||
* `Merchant City` alterado pelo método `setMerchantCity()` com a cidade do titular da conta como conta no banco. O tamanho máximo de caracteres foi retiado. | ||
* `Pix Key` alterado pelo método `setPixKey()` com o tipo `Parser::KEY_TYPE_*` e o valor da chave Pix; | ||
* `Merchant Name` alterado pelo método `setMerchantName()` com o nome do titular da conta como consta na instituição bancária. | ||
* `Merchant City` alterado pelo método `setMerchantCity()` com a cidade da agência da conta como consta na instituição bancária. | ||
|
||
Os atributos **opcionais** do Pix são: | ||
|
||
* `Point of Initiation Method` alterado pelo método `setAsReusable()` sendo `true` como código Pix reutilizável e `false` como código Pix utilizável apenas uma vez. | ||
* `Point of Initiation Method` alterado pelo método `setAsReusable()` sendo `true` como código Pix reutilizável e `false` como código Pix utilizável apenas uma vez. Para utilizar `true` deve-se haver um **PSP** autorizado para controlar os **QR Code Dinâmicos**. Ainda não implementamos conexões com **APIs** de **PSPs**. | ||
* `Merchant Account Information . Label` alterado pelo método `setDescription()` com a descrição do pagamento. Tamanho máximo de `36 caracteres`. | ||
* `Transaction Amount` alterado pelo método `setAmount()` com o valor da transação em `float`. Tamanho máximo de `13 caracteres`. | ||
* `Additional Data Field . Reference Label` alterado pelo método `setTid()` com o ID da transação. Tamanho máximo de `25 caracteres`. | ||
|
||
## Incompatibilidade de Chaves | ||
|
||
O **Pix** ainda é muito recente e, apenas das padronizações do **Banco Central do Brasil**, muitos bancos criaram algumas variações e definiram como aceitam determinadas chaves. A recomendação principal é: **utilize chaves aleatórias**. | ||
|
||
As chaves aleatórias seguem o padrão universal `uuid`, então, não tem o que cada banco inventar aqui. Elas precisam ser aceita no formato `v4`. Não detectamos qualquer problema de incompatibilidade com esses tipos de chaves. | ||
|
||
Algumas chaves que encontramos incompatibilidades para determinados bancos: | ||
|
||
* E-mail: alguns bancos aceitam `@`, outros aceitam espaço e outros aceitam ambos; | ||
* Telefone: alguns bancos aceitam `+55`, outros ignoram e outros aceitam com e sem `+55`; | ||
|
||
### Divergências entre Pix Copia & Cola e QR Codes | ||
|
||
Há alguns relatos que alguns bancos leem o **QR Code**, mas não leem o **Pix Copia & Cola**. Este não é um problema da biblioteca, o código Pix de ambos são o mesmo! Caso esteja curioso, abra um leitor de QR Code e leia o código é examente o mesmo que o **Pix Copia & Cola**. | ||
|
||
Nesse caso, tente utilizar as funções corretivas como `applyEmailWhitespace()`, `applyValidCharacters()` e `applyUppercase()`. Alguns bancos podem ter leituras diferentes e, talvez, existam caracteres inválidos para a leitura do **Pix Copia & Cola**. | ||
|
||
## Como utilizar? | ||
|
||
Em [samples/pix.php](samples/pix.php) você encontra um exemplo de implementação. Esta biblioteca é bem simples de utilizar e tudo que você precisa fazer é solicitar ao usuário ou ter os seguintes dados para gerar o Pix: | ||
Em [samples/payload.php](samples/payload.php) e [samples/reader.php](samples/reader.php) você encontra um exemplo de implementação. Esta biblioteca é bem simples de utilizar e tudo que você precisa fazer é solicitar ao usuário ou ter os seguintes dados para gerar o Pix: | ||
|
||
Obrigatórios: | ||
|
||
|
@@ -94,7 +157,7 @@ Opcionais: | |
* `$description = 'Pagamento 01';` | ||
* `$reusable = false;` | ||
|
||
Depois crie o objeto `Parser` e utilize os métodos `getPixCode()` ou `getQRCode()`, conforme as suas necessidades. | ||
Depois crie o objeto `Payload` e utilize os métodos `getPixCode()` ou `getQRCode()`, conforme as suas necessidades. Você também pode criar o objeto `Reader` para extrair os dados de uma chave pix válida. | ||
|
||
## Testes realizados | ||
|
||
|
@@ -111,15 +174,29 @@ O código Pix gerado por essa biblioteca, incluindo a função **QR Code** e **P | |
* PagPank; | ||
* Santander. | ||
|
||
Como o código utiliza o padrão do Pix é possível que funcione em todos os bancos. Mas, caso encontre problemas ou dificuldades hesite em abrir uma [Issue](https://github.com/piggly-dev/php-pix/issues) ou enviar um e-mail para [[email protected]](mailto:[email protected]). | ||
Como o código utiliza o padrão do Pix é possível que funcione em todos os bancos. Alguns bancos ainda estão resilientes em utilizar os padrões determinados. Então, caso encontre problemas ou dificuldades não hesite em abrir uma [Issue](https://github.com/piggly-dev/php-pix/issues) ou enviar um e-mail para [[email protected]](mailto:[email protected]). | ||
|
||
Ao enviar um e-mail ou abrir uma issue, certifique-se de informar: | ||
|
||
* Versão da Biblioteca: 1.1.0; | ||
* Banco Emitente: NuBank; | ||
* Banco Pagador: Inter; | ||
* Tipo de Erro: O **QR Code** é inválido; | ||
* Chave Pix Gerada: `00020101021126740014br.gov.bcb.pix0136aae2196f-5f93-46e4-89e6-73bf4138427b0212Pagamento 0152040000053039865406109.905802BR5913STUDIO PIGGLY6007Uberaba62130509034593-09630444C9`; | ||
|
||
## Futuras Implementações | ||
|
||
Queremos possibilitar o suporte para Pix Dinâmicos, esperamos em breve colocar um suporte as APIs para fazer esses tipos de transações. Por enquanto, a comunicação entre bancos e provedores de pagamento está muito complicada. Provavelmente, apenas extenderemos a class `Payload` para `DynamicPayload` permitindo a inclusão dos novos campos e criaremos interfaces e classes abstratas para cada um configurar para a API do seu PSP. | ||
|
||
Por enquanto, na classe `Reader` extraímos apenas as informações básicas e essenciais. Em breve, tornaremos o `Payload` ainda mais flexível e permitiremos que o `Reader` leia ainda mais dados. | ||
|
||
## Changelog | ||
|
||
Veja o arquivo [CHANGELOG](CHANGELOG.md) para informações sobre todas as mudanças no código. | ||
|
||
## Testes de Código | ||
|
||
Essa biblioteca utiliza o [PHPUnit](https://phpunit.de/). | ||
Essa biblioteca utiliza o [PHPUnit](https://phpunit.de/). Realizamos testes com todas as principais classes dessa aplicação. | ||
|
||
``` | ||
vendor/bin/phpunit | ||
|
@@ -136,7 +213,7 @@ Se você descobrir qualquer issue relacionada a segurança, por favor, envie um | |
## Créditos | ||
|
||
- [Caique Araujo](https://github.com/caiquearaujo) | ||
- [All Contributors](../../contributors) | ||
- [Todos os colaboradores](../../contributors) | ||
|
||
## Apoie o projeto | ||
|
||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?php | ||
|
||
use Piggly\Pix\Parser; | ||
use Piggly\Pix\Reader; | ||
use Piggly\Pix\Payload; | ||
|
||
// Sample | ||
$pixCode = '00020126770014BR.GOV.BCB.PIX0136aae2196f-5f93-46e4-89e6-73bf4138427b0215Descrição Teste52040000530398654041.005802BR5922Caique Monteiro Araujo6009SAO PAULO61080540900062160512NUR1pycKbhb063046BF7'; | ||
$reader = new Reader($pixCode); | ||
|
||
// User input | ||
// -> Required | ||
$keyValue = $reader->getPixKey(); | ||
$keyType = Parser::getKeyType($keyValue); | ||
$merchantName = $reader->getMerchantName(); | ||
$merchantCity = $reader->getMerchantCity(); | ||
|
||
// -> Optional | ||
$amount = 109.90; // Payment amount as float | ||
$tid = '034593-09'; // Transaction id | ||
$description = 'Pagamento 01'; // Any type of description, characters allowed | ||
$reusable = false; | ||
|
||
// Create the pix payload | ||
$pix = | ||
(new Payload()) | ||
// ->applyValidCharacters() | ||
// ->applyUppercase() | ||
// ->applyEmailWhitespace() | ||
->setPixKey($keyType, $keyValue) | ||
->setMerchantName($merchantName) | ||
->setMerchantCity($merchantCity) | ||
->setAmount($amount) | ||
->setTid($tid) | ||
->setDescription($description) | ||
->setAsReusable($reusable); | ||
|
||
// Prints: pix code | ||
echo $pix->getPixCode(); | ||
|
||
// Prints: <img style="margin:12px auto" src="{{base64}}" alt="QR Code de Pagamento" /> | ||
echo '<img style="margin:12px auto" src="'.$pix->getQRCode().'" alt="QR Code de Pagamento" />'; |
Oops, something went wrong.