Releases: piggly-dev/php-pix
Atualização completa
Veja as principais mudanças da versão 2.x.x:
- O padrão EMV MPM foi atualizado e remodelado para suportar novos campos que podem ser utilizados nos Pix;
- A validação e verificação das chaves Pix foi aprimorada;
- A leitura de um código Pix resulta em um objeto de EMVs mais flexível;
- Os modificadores do payload foram removidos, sendo que agora, todos os dados preenchidos são automaticamente tratados e cortados respeitando completamente o padrão EMV;
- A classe
BaseAPI
foi removida, adotando como sugestão a biblioteca piggly/php-api-client que traz muito mais flexibilidade e segurança; - Os payloads para APIs foram remodelados para serem mais eficientes e flexíveis.
Classe Parser
As mudanças na classe Parser foram apenas internas.
Classe Reader
Além das otimizações internas e os métodos já existentes previamente, novos métodos foram acrescentados:
getMPM()
retorna o gerenciador de campos EMV para obter qualquer campo adicional por ID;
getPixKey()
retorna a chave Pix (se houver);
getDescription()
retorna a descrição do Pix (se houver);
getUrl()
retorna a url do Pix (se houver);
getAmount()
retorna o valor do Pix (se houver);
getMerchantName()
retorna o nome do titular do Pix (se houver);
getMerchantCity()
retorna a cidade da conta titular do Pix (se houver);
getPostalCode()
retorna o CEP da conta titular do Pix (se houver);
getTid()
retorna o ID da transação do Pix (se houver).
O método export()
vai determinar se o tipo de objeto compatível com o Pix, seja ele StaticPayload
ou DynamicPayload
. Se não for possível determinar, pela ausência do Point of Initiation Method
, a presença ou ausência da URL determinará o formato.
Classes StaticPayload
e DynamicPayload
A classe Payload
deixa de existir, tornando-se AbstractPayload
e as derivações continuam a mesma, mas com melhor separação de responsabilidades. Um DynamicPayload
pode apenas:
setUrl()
, informando a URL do Pix no SPI.
Enquanto que em StaticPayload
, é possível:
setPixKey()
para definir a chave Pix;setDescription()
para indicar a descrição do Pix;setTid() e getTid()
com o ID de transação do Pix;setAmount()
com o valor a ser pago pelo Pix.
Ambas, podem usar:
setMerchantName()
para definir o nome do titular da conta Pix;setMerchantCity()
para definir a cidade da conta titular Pix;setPostalCode()
para definir o CEP da conta titular Pix.
Mas, os dois payloads contam o campos flexíveis agora. Assim, é possível mudar a estrutura de campos, adicionar novos campos e definir todos os valores através da classe MPM
com o método:
changeMpm()
que muda a estrutura de campo do Pix.
Entretanto cada payload aplica algumas regras no método acima para manter a consistência do mesmo.
Classes de Payloads da API
A classe de envio de requisições BaseApi
foi completamente removida, ela não era flexível o bastante e exigia muitas customizações. Por conta disso, a remoção. Entretanto, deixamos como sugestão a biblioteca piggly/php-api-client, que foi projetada para ser flexível e muito mais robusta que a solução anterior.
As classes de payloads são bem intuitivas e bem fáceis de utilizar, elas foram remodeladas para melhor (claro). Será preciso readaptar seus projetos para carregar as novas classes que migraram de namespace
.
Múltiplos tipos de Payload
Muitas alterações aconteceram. Abaixo descrevemos por classes o que mudou, o que continuou e como isso afeta o seu antigo código:
Tratamento de Exceções
Antes, todos os erros no código retornavam um objeto simples Exception
com uma mensagem sobre mais detalhes. Mas, agora, dividimos as principais exceções entre alguns tipos de objetos, são eles:
CannotParseKeyTypeException
: Impossível determinar o tipo da chave Pix;EmvIdIsRequiredException
: O campo EMV não foi preenchdo e é obrigatório;InvalidCobFieldException
: Algum campo COB está inválido;InvalidEmvFieldException
: Algum campo EMV está inválido;InvalidFieldException
: Algum campo está inválido;InvalidPixCodeException
: O código Pix recebido é inválido;InvalidPixKeyException
: A chave Pix informada é incompatível com o tipo;InvalidPixKeyTypeException
: O tipo de chave Pix informado é inválido.
As classes acima possuem métodos
get*()
personalizados para você obter de forma mais precisa dos dados de erros equivalentes.
Se você já tratava exceções, nada muda! Exceto que, agora, tem mais controle para tratar determinados tipos de erros.
Classe Reader
- O método
extract()
resultará em uma exceçãoInvalidPixCodeException
se o código Pix não foi um código Pix válido; - O método
export()
criará umPayload
compatível com o código Pix lido.
Classe Parser
- O método
getKeyType()
resultará em uma excessãoCannotParseKeyTypeException
se não for possível determinar o tipo da chave Pix; - Os métodos
validateCpf()
evalidateCnpj()
agora são públicos e podem ser utilizados individualmente; - O método
getRandom()
cria umastring
aleatória contendo25
caracteres entre[A-Za-z0-9]
; - O método
validate()
pode resultar em dois tipos de exceções:InvalidPixKeyTypeException
quando o tipo da chave é inválido;InvalidPixKeyException
quando a chave não é compatível com o tipo.
Classe Payload
- O valor padrão inicial do
tid
sempre será***
quando não preenchido; - O método
setPixKey()
pode resultar em dois tipos de exceções:InvalidPixKeyTypeException
quando o tipo da chave é inválido;InvalidPixKeyException
quando a chave não é compatível com o tipo; - O método
setDescription()
aceita até40
caracteres; - O método
setTid()
pode receber um valor vazio, quando acontecer, irá gerar um valor aleatório para o ID da transação com o métodoParser::getRandom()
; - O método
getTid()
foi adicionado; - O método
setAsReusable()
foi descontinuado (veja mais detalhes abaixo); - Ao definir alguns campos, eles podem retornar a exceção
EmvIdIsRequiredException
se o campo não estiver preenchido ouInvalidEmvFieldException
se o campo estiver incorreto.
Descontinuação do setAsReusable()
O método setAsReusable()
definia se um código Pix era único (dinâmico) ou reutilizável (estático). Ele continua valendo para criações manuais, entretanto, para organização do código, o Payload
foi dividido em duas classes:
- Classe
StaticPayload
: para códigos Pix estáticos; não muda nada, com excessão que sempre será um código reutilizável e ignora o métodosetAsReusable()
; - Classe
DynamicPayload
: para códigos Pix dinâmicos; altera o comportamento padrão doPayload
, pois ignora os métodossetPixKey()
,setDescription()
esetAsReusable()
. Os métodos ainda podem ser chamados, entretanto não alterarão valores noPayload
. Além disso, acrescenta o métodosetPayloadUrl()
com a URL do payload recebido pelo PSP (SPI). Cuidado ao utilizarsetTid()
alguns SPIs aceitam, enquanto outros não.
A classe Dynamic Payload está diretamente associada a um QR Code dinâmico e só pode ser utilizada após criação da cobrança via alguma API Pix. A api será responsável por criar a cobrança no SPI e retornar o
location
(uma URL que contem os dados do pix). Esselocation
deve ser adicionado emsetPayloadUrl()
.
Exemplo
// Montagem de um pix estático
$payload = (new StaticPayload())
->setMerchantName($merchantName)
->setMerchantCity($merchantCity)
->setPixKey($keyType, $keyValue)
->setDescription($description)
->setAmount($amount)
->setTid($tid);
// Montagem de um pix dinâmico
$payload = (new DynamicPayload())
->setMerchantName($merchantName)
->setMerchantCity($merchantCity)
->setAmount($amount)
->setPayloadUrl($url);
// Lendo um código pix e obtendo o payload
$payload = (new Reader($pixCode))->export();
Classe CobPayload
O problema com as APIs do Pix é que, mesmo com o Banco Central lançando o padrão de comunicação para ser adotado, muitos SPI fazem as coisas do seu jeito. A única maneira de desenvolve uma biblioteca compatível com todas as principais APIs do mercado é tendo acesso a elas. Entendemos que isso está distante do propósito deste projeto. Afinal, cada API deveria ter sua própria biblioteca e então utilizar a nossa para montar os códigos Pix.
Mas, decidimos implementar a classe
CobPayload
que utiliza o padrão do Banco Central do Brasil. Cada API deveria ter umPayload
parecido para implementar os métodos. Fique a vontade para criar conforme a API que irá utilizar.
É utilizada para tratamento dos dados da API Pix e segue os padrões determinados em bacen/pix-api. Essa classe auxilia você criar um payload mais limpo, assim como receber os dados da API Pix de uma forma muito mais orgânica e organizada.
Além dos métodos para obter/setar dados do CobPayload
, haverão dois métodos disponíveis sendo eles:
export()
: exporta todos os dados da classeCobPayload
para o array compatível com a API Pix;import()
: importa todos os dados de resposta da API Pix para os objetos relacionados criando umCobPayload
organizado.
O CobPayload
e as classes deviradas disponíveis em Entities/Cob/*
são bem flexíveis e fazem a importação/exportação de todos os dados disponíveis conforme os modelos padrões da API Pix, não há muito com o que se preocupar.
Em breve, vamos criar uma documentação detalhada sobre essas classes.
Exemplo
// Não implementamos ainda uma classe $api
$cobResponse = $api->getCob($tid);
// Cria o cob para normalizar os dados
$cob = (new CobPayload())->import($cobResponse);
// Nome do recebedor do Pix
$cob->getSender()->getName();
// Nome do devedor do Pix
$cob->getRecipient()->getName();
// Valor original do Pix
$cob->getAmount()->getOriginalAmount();
// Status da cobrança do Pix
$cob->getStatus();
// -> exemplos de dados
// Você também pode criar o seu cob e enviar via $api
$devedor = (new Entities\Cob\Person())->setDocument('12345678930');
$recebedor = (new Entities\Cob\Person())->setDocument('11222333000100');
$valor = (new Entities\Cob\Amount())->setOriginalAmount('1.00');
$calendario = (new Entities\Cob\Calendar())->setDueDate(DateTime::now()->add(new DateInterval('P10D')));
$cob = (new CobPayload())
->setSender($recebedor)
->setRecipient($devedor)
->setAmount($valor)
->setCalendar($calendario);
// Não implementamos ainda uma classe $api
// Envie o payload do cob
$cobResponse = $api->createCob($cob->export());
// Capture a resposta
$cob = (new CobPayload())->import($cobResponse);
// E, depois pode convertê-lo para um payload:
Lançamento do Leitor de Códigos Pix
Essa é a primeira grande mudança da biblioteca. Lapidamos melhor alguns métodos da classe Parser
, adicionamos modificadores na classe Payload
e criamos a classe Reader
para extrair dados de códigos Pix válidos. Confira as mudanças:
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*()
doParser
para validar individualmente os tipos das chaves Pix, esses métodos não retornam mais umaException
, mas umboolean
. Somente o métodovalidate()
continua retornando umaException
. Confira a mudança da código abaixo:
// !! 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.
Versão inicial da biblioteca
Um Payload
simples para criação de códigos Pix. Todos os bugs corrigidos.