Pagamento de um QR Code Dinâmico

Pré requisitos para implementação:

  • Possuir uma chave api da Celcoin, para mais informações acessar esse link

  • Ter familiaridade com apis Rest usando o protocolo OAuth 2.0.

  • Ter o produto/solução contratada, caso queira usar a funcionalidade em ambiente produtivo, por favor entre em contato com a nossa equipe comercial através do e-mail [email protected]. Para dúvidas técnicas, basta entrar em contato com o suporte através do link.

Essa funcionalidade, deve ser utilizada sempre que um usuário da sua aplicação deseja realizar o pagamento de um QR Code Pix dinâmico.

Por que usar um QR Code dinâmico?

  • Apresenta em seu escopo um rol extenso de campos passíveis de configuração por parte do recebedor.

  • Permite a realização de pagamento imediato ou com vencimento.

  • É usado uma única vez para uma transação específica.

  • Além do valor, permite a inserção de mais informações na modalidade com vencimento, como as regras de cálculo de juros, multa, descontos, entre outras.

  • É recomendado para recebedores que demandem funcionalidades facilitadoras do processo de conciliação, da integração de sistemas e da automatização de processos.

  • É gerada por meio da integração via API Pix. Segundo define o BCB, é possível gerar um único QR Code ou proporcionar uma geração em lote, necessária, por exemplo, para empresas prestadoras de serviço que desejam gerar faturas para toda sua base de clientes. Por isso, o QR Code Pix agiliza os processos das empresas, principalmente dos comércios.

Desta forma o caso de uso pode ser:

Como Fintech quero disponibilizar para os meus usuários a possibilidade de realizar pagamentos de QR Codes dinâmicos, para qualquer instituição financeira, uma vez que ele scanear, ou digitar o copia e cola, onde será retirado o saldo de sua conta e usado para pagar o emissor do QR Code.

Decodificar QR Code

Para iniciar o processo de pagamento de um QR Code é necessário realizar sua leitura, portanto é preciso decodificar ele, onde é gerado um código EMV(padrão criado para leitura de QR Codes Pix no Brasil, nos sistemas financeiros geralmente é nomeado de Pix Copia e Cola). Para isso, basta utilizar API Retorna as informações do QR Code a partir de um EMV.

Modelo de request:

curl --location --request POST 'https://sandbox.openfinance.celcoin.dev/pix/v1/emv' \
--header 'accept: application/json' \
--header 'Content-Type: application/json-patch+json' \
--header 'Authorization: Bearer {access_token}' \
--data-raw '{
  "emv":  "00020101021226930014br.gov.bcb.pix2571api-h.developer.celcoin.com.br/v1/p/v2/0223b7626a7247e58a35cfadb1c18ba85204000053039865802BR5907Celcoin6007Barueri61080120100562070503***6304CB07"
}'

Modelo de retorno:

{
    "type": "2",
    "collection": "1",
    "payloadFormatIndicator": "01",
    "merchantAccountInformation": {
        "url": "qrcode-h.pix.celcoin.com.br/pixqrcode/v2/cobv/dc0f2810232443c7224f50ad2edddb",
        "gui": "br.gov.bcb.pix",
        "key": null,
        "additionalInformation": null,
        "withdrawalServiceProvider": null
    },
    "merchantCategoryCode": 0,
    "transactionCurrency": 986,
    "transactionAmount": 0.0,
    "countryCode": "BR",
    "merchantName": "Celcoin",
    "merchantCity": "Barueri",
    "postalCode": "01201005",
    "initiationMethod": "12",
    "transactionIdentification": "***"
}

A propriedade type representa o tipo do QR Code, portanto deve ser validado se o que você está consultando é estático (representado pelo valor 1) ou dinâmico (2), fora isso, a propriedade collection determina se ele é immediate (imediato, representando pelo 1) ou duedate (com data de vencimento definida, representando pelo 2), é importante saber qual é o tipo e a collection do qrcode, pois isso irá definir como seguir com as integrações para a execução do pagamento.

Estrutura dos dados retornados:

CampoDescrição
typeTipo do QR Code (1 = estático, 2 = dinâmico)
collectionInforma se é COB (1) ou COBV (2)
payloadFormatIndicatorIndicador de formato de carga útil
merchantAccountInformationInformações sobre a cobrança atrelada ao QR Code
merchantCategoryCodeNúmero de quatro dígitos, listado na ISO 18245
transactionCurrencyCódigo da moeda corrente
transactionAmountValor da transação
countryCodeCódigo do país
merchantNameNome do emissor da cobrança
merchantCityCidade do emissor da cobrança
postalCodeCEP
initiationMethodRepresenta o tipo de pagamento
transactionIdentificationIdentificação da transação

O fluxo abaixo explica como dar continuidade no pagamento de QR Codes dinâmicos.

🚧

Recomendamos que seja armazenado temporariamente, ou em sua aplicação a propriedade url do objeto merchantAccountInformation, pois o seu valor será utilizado em requisições futuras para executar o pagamento do QR Code.

Caso você não tenha um EMV de um QR Code dinâmico immediate, para realizar os testes, basta criar um QR Code Location com a API da Celcoin Criar um QR Code (Location) e em seguida criar uma cobrança immediate coma API Criar nova cobrança imediata. Abaixo segue um modelo de request para criar o QR Code:

curl --location --request POST 'https://sandbox.openfinance.celcoin.dev/pix/v1/location' \
--header 'accept: application/json' \
--header 'Content-Type: application/json-patch+json' \
--header 'Authorization: Bearer {access_token}' \
--data-raw '{
  "clientRequestId": "9b26edb7cf254db09f5449c94bf13abc",
  "type": "COB",
  "merchant": {
    "postalCode": "01201005",
    "city": "Barueri",
    "merchantCategoryCode": "0000",
    "name": "Celcoin Pagamentos"
  }
}'

Abaixo segue um modelo de request para criar a cobrança imediata:

curl --location --request POST 'https://sandbox.openfinance.celcoin.dev/pix/v1/collection/immediate' \
--header 'accept: application/json' \
--header 'Content-Type: application/json-patch+json' \
--header 'Authorization: Bearer {access_token}' \
--data-raw '{
    "clientRequestId": "14232341231",
    "payerQuestion": "Não pagável após vencimento.",
    "key": "[email protected]",
    "locationId": 12730559,
    "debtor": {
        "name": "Fulano de Tal",
        "cnpj": "33188542046"
    },
    "amount": {
        "original": 15.00,
        "changeType": 0
    },
    "calendar": {
        "expiration": 86400
    },
    "additionalInformation": [
        {
            "value": "Assinatura de serviço",
            "key": "Produto 1"
        }
    ]
}'

Para criar QR Code dinâmico com vencimento veja mais detalhes nesse artigo.

📘

É importante ser usado a chave [email protected] em ambiente sandbox para conseguir finalizar seus testes, caso contrário será apresentado erro na hora de realizar a consulta da chave DICT.

Tipos de QR Code dinâmico

Como explicado anteriormente, quando falamos de QR Codes dinâmicos sabemos que é possível ter dois tipos, o imediato (immediate) e com data de vencimento (duedate). Uma vez que sua aplicação sabe qual é seu tipo, é necessário consultar a url que foi retornada na chamada de consulta EMV, porém cada QR Code tem uma API distinta para realizar essa busca, sendo immediate a API Carrega, valida e analisa a carga de json de uma Cobrança imediata (COB) e duedate a API Carrega, valida e analisa a carga de json de uma Cobrança com Vencimento (COBV). Vamos usar um QR Code Immediate para exemplificar as requisições.

🚧

Atenção

Perceba que deve ser removido o "https://" da url para realizar a requisição do payload, caso contrário a API da Celcoin não irá reconhecer a requisição.

Modelo de request:

curl --location --request GET 'https://sandbox.openfinance.celcoin.dev/pix/v1/collection/immediate/payload/api-h.developer.btgpactual.com%2Fv1%2Fp%2Fv2%2F0223b7626a7247e58a35cfadb1c18ba8' \
--header 'accept: application/json' \
--header 'Authorization: Bearer {access_token}'

Perceba que a propriedade url retornada na chamada de consulta EMV, deve ser encodada usando o padrão URL-encoded format, apenas dessa forma nossa api irá conseguir ler a url e retornar as informações do QR Code.

Para testar e entender o formato, recomendamos que use o link, para testar o processo de conversão da url disponibilizada em nossa api de consulta do EMV.

Criamos a GIF abaixo que mostra como realizamos a conversão e simulação da chamada em nossa api.

Modelo de retorno:

{
    "status": "ATIVA",
    "infoAdicionais": null,
    "txid": "kk6g232xel65a0daee4dd13kk9162847",
    "chave": "[email protected]",
    "solicitacaoPagador": "Aniversário do Jr.",
    "valor": {
        "original": "25.25",
        "abatimento": null,
        "desconto": null,
        "multa": null,
        "juros": null,
        "final": null,
        "modalidadeAlteracao": 0,
        "retirada": null
    },
    "calendario": {
        "criacao": "2022-03-07T12:23:36Z",
        "expiracao": 86400,
        "apresentacao": "2022-03-07T12:33:22Z",
        "validadeAposVencimento": 0
    },
    "revisao": 0
}

Perceba que o retorno disponibiliza a chave Pix, com ela deve ser realizado uma consulta no DICT através da api Retorna as informações do DICT utilizando uma chave cadastrada no Pix, para obter as informações de sua conta bancária.
Diferente do QR Code estático, o dinâmico tem um peculiaridade que é a data limite para ser pago.

O campo payerId é obrigatório devido a uma solicitação do banco central e deve ser preenchido com um CNPJ, sem os caracteres especiais, da sua instituição. Para testar essa consulta em sandbox recomendamos o uso da propriedade key populada com o valor [email protected], pois nosso ambiente está preparado para retornar a consulta deste e-mail.

Modelo de request:

curl --location --request POST 'https://sandbox.openfinance.celcoin.dev/pix/v1/dict/v2/key' \
--header 'accept: application/json' \
--header 'Content-Type: application/json-patch+json' \
--header 'Authorization: Bearer {access_token}' \
--data-raw '{
  "payerId": "11223344556",
  "key": "[email protected]"
}'

Modelo de retorno:

{
    "key": "[email protected]",
    "keyType": "EMAIL",
    "account": {
        "openingDate": "2020-08-13T13:49:03Z",
        "participant": "30306294",
        "branch": 20,
        "accountNumber": "42161",
        "accountType": "CACC"
    },
    "owner": {
        "taxIdNumber": "33188542046",
        "type": "NATURAL_PERSON",
        "name": "Fulano de Tal"
    },
    "endtoendid": "E1393589320220307124100850081406"
}

Note que no retorno é apresentado no objeto account nas propriedades branch(agência), accountNumber(número da conta), accountType(tipo da conta), os dados bancários da chave que foi consultada, no caso de uma pessoa física, ou empresa que irá receber a transferência. A propriedade participant representa o código da instituição financeira participante no ISPB (Instituição de Sistema de Pagamentos Brasileiros), ou seja, para onde será enviado o dinheiro.

No objeto owner será apresentado informações sobre o dono da chave, como taxindNumber(tipo do documento CPF, ou CNPJ), type(tipo de pessoa), sendo LEGAL_PERSON(pessoa jurídica) e NATURAL_PERSON(pessoa física) e name(o nome do dono).

Por fim, mas não menos importante, é apresentado a propriedade endtoend que seria o identificador de ponta a ponta da transação de consulta que também é utilizado para transferências com QR Code.

Pagamento do QR Code dinâmico

Após realizar a consulta da chave no DICT, deve ser realizado o pagamento do QR Code, para isso é necessário realizar uma chamada na api Iniciar pagamento Pix.

Modelo de request:

curl --location --request POST 'https://sandbox.openfinance.celcoin.dev/pix/v1/payment' \
--header 'accept: application/json' \
--header 'Content-Type: application/json-patch+json' \
--header 'Authorization: Bearer {access_token}' \
--data-raw '{
    "amount": 25.55,
    "clientCode": "145885412",
    "transactionIdentification": "testqrcodestaticcelcoin",
    "debitParty": {
        "account": "3794245",
        "branch": 30,
        "taxId": "13935893000109",
        "accountType": "CACC",
        "name": "IS2B - Integrated Solutions to Business S.A"
    },
    "creditParty": {
        "key": "[email protected]",
        "bank": "30306294",
        "account": "42161",
        "branch": 20,
        "taxId": "33188542046",
        "accountType": "CACC",
        "name": "Fulano de Tal"
    },
    "endtoendid": "E1393589320220307124100850081406"
    "initiationType": "DYNAMIC_QRCODE",
    "remittanceInformation": "Texto de mensagem",
    "paymentType": "IMMEDIATE",
    "urgency": "HIGH",
    "transactionType": "TRANSFER"
}'

Perceba que o pagamento de um QR Code também é uma transferência, para uma conta bancária, porém o corpo da requisição tem algumas alterações.

A propriedade amount, deve ser preenchido o valor a ser transferido, já na clientCode, deve ser utilizado um identificador único da sua aplicação.

O campo transactionIdentification, deve ser preenchido com dado retornadado no campo txid da API de consulta do payload, seja imediate, ou duedate.

O objeto debitParty, deve ser preenchido com os dados da conta bolsão da Celcoin e o objeto creditParty, deve ser populado com os dados da conta que vai receber o valor, retornados na chamada Retorna as informações do DICT utilizando uma chave cadastrada no Pix, onde a propriedade participant é igual a bank, accountNumber igual a account, taxId igual a taxindNumber.

A propriedade initiationType, deve ser populado com o valor DYNAMIC_QRCODE, para que a Celcoin entenda que sua aplicação está executando o pagamento de um QR Code dinâmico.

A propriedade urgency, deve ser populada com o valor HIGH para ser executada na hora.

A propriedade transactionType, deve ser populada com valor TRANSFER, pois estamos executando uma transferência de valores.

A propriedade paymentType, deve ser populada com IMMEDIATE para ser executada na hora.

A propriedade endToEndId, deve ser populada com o endToEndId da Consulta DICT (/pix/v1/dict/v2/key).

Ao realizar a chamada de payments, a Celcoin irá retirar o dinheiro da sua conta bolsão e executar a tentativa de transferência. Caso tudo ocorra como esperado, será enviado via webhook uma notificação, porém, se por algum motivo ocorrer uma falha, sua aplicação também será notificada via webhook, mas nesse cenário a Celcoin devolve o saldo retirado da conta, para ser usado em possíveis transações futuras.

Modelo de retorno:

{
    "transactionId": 9162909,
    "code": "SUCCESS",
    "slip": "     COMPROVANTE TRANSFERENCIA PIX      \n            07/03/2022 09:58            \n           TERM 11 AGENTE 999           \n                CONTROLE                \n    E1393589320220307125800721814129    \n----------------------------------------\n                PAGADOR                 \n\n                Contrato                \n            AG:1 CC:100548925           \n        CPF/CNPJ:23694719000175         \n----------------------------------------\n               RECEBEDOR                \n\n        30306294 AG:20 CC:42161         \n          CPF/CNPJ:09958359006          \n     CHAVE:[email protected]      \n----------------------------------------\n   DATA DO PAGAMENTO 07/03/2022 09:58   \n\n            VALOR R$ 25,5500            \n----------------------------------------\n              AUTENTICACAO              \n21.F8.55.97.74.6C.A7.3F.11.80.AA.21.CE.62.23.12\n",
    "slipAuth": "21.F8.55.97.74.6C.A7.3F.11.80.AA.21.CE.62.23.12",
    "endToEndId": "E1393589320220307125800721814129"
}

Note que será retornado o id da transação Celcoin (transactionID) e o endToEndId que seria o id da transação Pix fim a fim, esses campos devem ser armazenados em sua aplicação, pois a Celcoin irá enviar um gatilho em seu webhook, informando se a transação ocorreu com sucesso, ou não e com eles é possível realizar validações em sua aplicação.

O campo code exibe se a requisição ocorreu com sucesso ou não conforme abaixo:

  • SUCCESS = Pagamento realizado com sucesso;
  • SUCCESSFUL_WITH_ERROR = Pagamento realizado com sucesso, porém tivemos algum erro interno na hora de gerar comprovante;
  • ALREADY_PAID = Pagamento já foi realizado anteriormente (mesmo clientCode ou endToEndId);
  • ALREADY_PAYD_WITH_ERROR = Pagamento já foi realizado anteriormente (mesmo clientCode ou endToEndId), porém aconteceu algum erro como geração de comprovante.

Nos casos de retornos "SUCCESS" e "SUCCESSFUL_WITH_ERROR", o webhook será disparado confirmando a transação ou o erro ocorrido.

A propriedade slip devolve o comprovante do pagamento.

📘

Recomendamos que essas informações sejam persistidas do lado da sua aplicação, para o seu usuário confirmar se deseja realizar o pagamento.
Ele optando por realizar o pagamento deve ser realizado os processos abaixo, caso contrário basta encerrar a operação.

Recebendo status dos pagamentos via webhook

O webhook é uma forma de receber informações de maneira assíncrona, onde geralmente são disparados gatilhos, no formato JSON, quando um evento acontece. Após a Celcoin realizar a tentativa de transferência do valor para instituição bancária solicitada, ela irá disparar um gatilho (PAYMENT), no webhook de seu aplicativo, ou sistema, configurado pelo nosso time de suporte.

Para realizar a configuração de um webhook é necessário entrar em contato com a nossa equipe de suporte informando a url de seu webhook, senha e usuário, no formato BASIC, desta forma eles irão realizar o cadastro em nossa plataforma, para que seja possível o envio dos gatilhos.

Uma vez que a propriedade RequestBody.StatusCode.StatusId for igual a 2, seu usuário final pode ser notificado que a transferência ocorreu com sucesso, qualquer coisa diferente de 2, deve ser validado o retorno, tratado e apresentado ao usuário, criamos uma tabela que mostra quais são os possíveis retornos que podemos apresentar, para acessar basta clicar nesse link.

Para realizar testes em sandbox e receber o webhook de PAYMENTS com status igual 2(sucesso), deve ser utilizado o payload informado no começo do artigo.

Caso você queira simular o pagamento com status rejeitado, basta alterar o payload alterando o objeto creditParty da seguinte forma:

"creditParty": {
        "bank": "30306294",
        "account": "10545584",
        "branch": 0,
        "taxId": "11122233344",
        "accountType": "CACC",
        "name": "Celcoin"
    }

Exemplo de aplicação

Criamos o protótipo de um aplicativo para exemplificar a utilização da API: